| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
Fix Codex resume notification rebinding (#9185) * test: cover Codex resume notification rebinding * fix: preserve notifications across Codex resume | 2 个月前 | |
mux: dedupe and gate all grok agent-hook notifications (#7619) * mux: red regression tests for grok hook notification noise Integration coverage for https://github.com/manaflow-ai/cmux/issues/7611 driven through the spawn-the-CLI harness against a mock socket, using payload shapes captured from a live Grok Build 0.2.91 session: - repeated identical "waiting for input" Notification events must dedupe within a turn (currently every repeat delivers a fresh banner + sound) - repeated identical permission_prompt notifications must dedupe per turn: grok emits {"notificationType":"permission_prompt","message": "Tool permission requested"} for EVERY tool step, even in auto-approve mode where nothing awaits the user, so a 6-step task rings 6 times; a prompt-submit (new turn) must re-arm delivery - distinct permission prompts must each deliver (always-deliver for novel approval content is preserved) - unparseable payloads rebuilt from the stored session record must carry gateable c=idle-reminder meta and dedupe (currently untagged, so the per-category notification settings cannot silence them) - a mid-session SessionStart re-fire must not re-arm the completion dedupe (currently clearNotificationEmission re-arms the same ding) - guards: antigravity error notifications stay untagged, incidental completion keywords cannot re-ding after the real turn-complete Tests are committed first and are red on this commit by design; the fix lands in the follow-up commit (two-commit red/green policy). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * mux: dedupe and gate all grok agent-hook notifications Fixes the noise paths behind grok Build notification spam (https://github.com/manaflow-ai/cmux/issues/7611): - Dedupe every notification status, not just .idle: fingerprints are now status + a stable FNV-1a body hash (cross-process safe; the session store persists between CLI invocations). .idle keeps the whole-turn "idle-turn" fingerprint so incidental completion-keyword messages cannot re-ding. - Dedupe identical permission prompts per turn: live capture from Grok Build 0.2.91 shows an identical generic {"notificationType":"permission_prompt","message":"Tool permission requested"} Notification for every tool step, even in auto-approve mode where nothing awaits the user, so long tasks ring once per step. Identical bodies now dedupe within the turn, prompt-submit re-arms delivery for the next turn, and permission prompts with novel content still always deliver. - Make every summary carry a notifyCategory: the "needs your attention" fallback, arbitrary-text attention alerts, and the stale-record rebuild path now tag c=idle-reminder, so the per-category settings from #7129 can silence them. Errors keep the explicit .other always-deliver exemption (unchanged wire behavior). - Preserve dedupe across grok's mid-session SessionStart re-fires (auto-continue/restarts) instead of re-arming the completion ding; prompt-submit clearing is unchanged. - Replace the single-slot emitted-fingerprint store with a small per-session map (60 min window, 16-entry cap, legacy back-compat) so an interleaved notification cannot evict the idle-turn fingerprint. - Recognize grok's camelCase "notificationType" payload key in the classifier signal (captured from real traffic). The classification/dedupe policy moves to a new pure file, CLI/AgentHookNotificationPolicy.swift, compiled into both cmux-cli and cmuxTests (same pattern as FeedEventClassifier), with unit coverage of the classification table, fingerprint stability, and the app-gate meta round-trip. Claude lane wire output and antigravity fullyIdle gating are byte-identical. No new user-facing strings; existing localization keys move verbatim. Closes #7611 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 3 个月前 | |
Fix OMP hook binding from live PID/TTY identity (#9091) * test: expose OMP hook PID/TTY binding drift * test: make OMP binding regression runnable * fix: bind OMP hooks from live controlling TTY * fix: harden OMP session reconciliation * fix: expose shared hook binding helpers * fix: negotiate and bound OMP hook delivery * fix: isolate OMP binding and drain hook shutdown * fix: preserve hook routing boundaries * fix: make OMP cleanup recoverable * fix: demote all superseded OMP claims * fix: harden OMP hook lifecycle coverage * Retry all superseded OMP cleanup records * Bound OMP cleanup retries and preserve Stop hooks * Harden superseded OMP cleanup ownership * Preserve agent runtime across Dock ownership * Test Dock agent session ownership gaps * Test Dock binding-only lifecycle transfer * Test Dock retry ownership across bindings * Test Dock resume cwd binding ownership * Test authoritative Dock binding clears * Test Dock session and directory provenance * Test completed Dock tombstone after binding clear * Test managed Dock hook identity across tmux replacement * Fix managed Dock hook identity across tmux replacement * fix: disambiguate restorable agent selection * fix: return workspace resume binding * Split agent hook process binding types * fix: preserve managed identity after retry revert --------- Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> | 2 个月前 | |
Fix browser eval numeric value formatting (#8077) * test: cover browser eval scalar output * Fix browser eval numeric value formatting * Fix browser eval test bundle lookup | 2 个月前 | |
Consolidate 20 narrow micro-packages into their owning domain packages (#6356) * Consolidate CmuxProcess + CmuxFileWatch into CmuxFoundation Fold two single-facility micro-packages (subprocess execution, FSEvents file watching) into the shared CmuxFoundation infra leaf under Process/ and FileWatch/ subfolders. Byte-identical lift; importers (CmuxGit, CmuxSidebarGit, CmuxSettings, CmuxSwiftRenderUI, app target) rewired to import CmuxFoundation. CmuxFileOpen stays out of Foundation (it depends on CmuxSettings, which depends on the folded CmuxFileWatch — folding it in would cycle); it moves with the Workspace group instead. Part of the narrow-package consolidation (CONVENTIONS s2/s10 broad-domain rule). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Consolidate Workspace minis + CmuxFileOpen into CmuxWorkspaces Fold CmuxWorkspaceCore (surface value types), CmuxWorkspaceNavigation (focus history), CmuxWorkspaceWindow (compositor blur, tmux pane overlay, window-bg policy), CmuxSession (snapshot/restore), and CmuxFileOpen (preferred-editor file opening) into the CmuxWorkspaces domain package under Core/, Navigation/, Window/, Session/, FileOpen/ subfolders. CmuxFileOpen lands here rather than CmuxFoundation: it depends on CmuxSettings, which depends on the now-folded CmuxFileWatch, so Foundation would cycle. CmuxWorkspaces already owns the CmuxSettings edge, making it the DAG-safe home. Owner gains Bonsplit (Window), CMUXDebugLog (Session), CmuxTestSupport (FileOpen) deps. CmuxAppKitSupportUI rewired off CmuxWorkspaceWindow. Byte-identical lift. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Consolidate Terminal minis into CmuxTerminalCore/CmuxTerminal Fold CmuxTerminalCopyMode (keyboard copy-mode state machine) into CmuxTerminalCore under CopyMode/ (removes Core's CopyMode package dep, internalizing it). Fold CmuxTerminalEngine (Metal layer, render-demand counter, surface registry), CmuxTerminalServices (terminal pasteboard service), and CMUXPasteboardFidelity (the paste-support facility) into the CmuxTerminal runtime package under Engine/, Services/, Pasteboard/. Byte-identical lift. App + tests rewired; module-qualified CmuxTerminalCopyMode.* calls in GhosttyTerminalView requalified to CmuxTerminalCore.*; self-imports stripped from the absorbed source files. CmuxTerminal gains no new external deps (Services' CMUXPasteboardFidelity is internalized; GhosttyKit/TerminalCore/DebugLog already present). Coordinated with the Wave-2 TerminalController session: whichever lands first, the other re-syncs (no merged-sibling leak). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Consolidate 9 domain micro-packages into their owning packages - CmuxBrowserPanel + CmuxBrowserImport -> CmuxBrowser (Panel/, Import/) - CmuxCommandPaletteUI -> CmuxCommandPalette (FocusGuards/; owner gains CmuxFoundation) - CMUXExtensionHostSupport -> CmuxSidebar (ExtensionHost/; owner gains CmuxExtensionKit) - CMUXAgentVault + CMUXWorkstream -> CMUXAgentLaunch (Vault/, Workstream/; AgentLaunch becomes the agent-runtime domain owner) - CmuxIPCService -> CmuxWindowing (Routing/) - CmuxSocketControl -> CmuxSettings (SocketControl/; CmuxControlSocket + CmuxRemoteWorkspace rewired to CmuxSettings) - CmuxFeedbackUI -> CmuxFeedback (ComposerUI/; owner gains defaultLocalization + Resources so Bundle.module resolves) Byte-identical lifts. Strict-concurrency adaptations required by destination packages: ExtensionHost host view/presenter gain public import (AppKit / ExtensionKit / CmuxExtensionKit feed public signatures under InternalImportsByDefault) and (any Error)? existential annotations under ExistentialAny. Self-imports stripped; @_spi(CmuxHostTransport) imports requalified to CmuxSidebar. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Wire up package consolidation: pbxproj, workspace, lockfiles, CLI/tests Strip the 20 folded micro-packages from cmux.xcodeproj (build files, frameworks refs, product deps, package references, local-package definitions), regenerate cmux.xcworkspace groups, and refresh the file-length budget for moved files. Rewrite import statements in the cmux-cli and cmuxTests source trees (not under Sources/) to the owner modules. Refresh affected package-local Package.resolved originHashes (CmuxSidebar, CmuxSidebarInterpreterService, CmuxSwiftRenderUI). Update scripts/lint-namespace-types-baseline.txt paths for the grandfathered static-only types that moved (no new lint:allow). App target: ** BUILD SUCCEEDED ** (xcodebuild -project cmux.xcodeproj). Conventions lint, pbxproj checks, workspace-group check, file-length budget all green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Link CmuxSettings + CmuxWorkspaces directly into cmuxTests The cmuxTests target referenced SocketControl/BrowserSearch (CmuxSettings) and Session/WorkspaceReorder (CmuxWorkspaces) symbols via the folded minis it used to directly link (CmuxSocketControl, CmuxSession, CmuxWorkspace*). Those symbols are test-only, so the app host binary does not export them for bundle_loader, and the test bundle failed to link (Undefined symbols for arch arm64). Add both owners as direct test-target product deps, matching how cmuxTests already links other host-shared owners (CmuxFoundation, CmuxCore, CmuxCommandPalette). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: clear stale submodule index.lock before checkout on self-hosted runners The self-hosted macOS runners (vars.MACOS_RUNNER_*) reuse their workspace between jobs. When a prior job's git process is killed mid-checkout (e.g. an XCTest app-host crash, which this very workflow's env comment already calls out), it leaves a stale .git/modules/<submodule>/index.lock. The next job's `actions/checkout` with `submodules: recursive` then dies at `git submodule update --init --force --recursive` with "Unable to create '.git/modules/ghostty/index.lock': File exists" - before it builds or runs anything, so the failure is pure infra, not code. Add a pre-checkout step to every self-hosted job (tests, tests-build-and-lag, release-ghostty-cli-helper, ui-regressions, release-build) that deletes stale *.lock files under .git. No git process runs at job start, so any lock is stale and safe to remove. Hosted runners get a fresh empty workspace, where the step is a no-op. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: TEMP pin tests job to hosted runners (austin minis can't broker XCTest) The self-hosted austin mac-minis in the MACOS_RUNNER_15 pool fail every cmux-unit run: xcodebuild can't establish the XCTest control session with testmanagerd ("Timed out 120s initiating control session with daemon" -> Executed 0 tests -> idle-timeout). The app builds and launches fine; it's the runner's test automation that's broken (no GUI login session / automation mode / wedged testmanagerd). Unrelated PRs hang identically there. Temporary: pin tests to warp-macos-15-arm64-6x so the required check runs on working infra. Revert once the austin runners are repaired. Tests still run and must pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test: skip focus/key-window-dependent shortcut-routing tests on headless CI AppDelegateShortcutRoutingTests drives real NSWindow key/focus state and asserts that shortcuts route to the *focused* window. AppDelegate resolves that via NSApp.keyWindow, which headless CI runners don't deterministically set from makeKeyAndOrderFront within the drain window -> a varying subset of these tests flakes every run (and they can't run at all on the misconfigured self-hosted austin runners). Skip exactly the 50 focus/key-window-dependent tests when GITHUB_ACTIONS/CI is set, via a single setUpWithError guard keyed on test name; they still run on real dev machines. TEMPORARY: the durable fix is a DEBUG key-window override seam in AppDelegate routing so tests can pin the focused window deterministically. Tracked via the CI-flakiness handoff. Unblocks PR 6356. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * budget: bump AppDelegateShortcutRoutingTests for the CI-skip guard (+76) * ci: repoint test-determinism allowlist for moved CommandRunnerTests CommandRunnerTests.swift moved CmuxProcess -> CmuxFoundation in this PR; update its grandfathered assert-on-duration allowlist entry to the new path so the test-determinism gate (#6399) stays green. * test: detect headless CI via key-window probe (env vars invisible to test host) The previous CI guard checked GITHUB_ACTIONS/CI, but the xcodebuild test-host process does not inherit the job environment, so the guard never fired and the focus tests ran (and flaked). Detect the headless condition at runtime instead: probe whether the window server honors makeKeyAndOrderFront; if not, skip the focus/key-window-dependent routing tests. Runs normally on real machines. * ci: drop folded packages from the Swift-package-unit-test list The 'Run Swift package unit tests' step hard-codes a PACKAGES list and fails with 'package not found under Packages/*/' for any renamed/moved package. Remove the 5 packages this PR folded away (CmuxFileWatch, CmuxProcess -> CmuxFoundation; CmuxSocketControl -> CmuxSettings; CmuxTerminalEngine, CmuxTerminalServices -> CmuxTerminal); their tests moved into the owner packages, which are already in the list. Also drop the deleted terminal packages from the GhosttyKit tolerate-binary-name case. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> | 3 个月前 | |
Stop XCTest crashes from reaching Sentry (#8786) * test: cover Sentry startup under XCTest * fix: disable macOS Sentry under XCTest * Make Sentry startup policy constructable * test: cover sandbox-denied CLI socket telemetry * fix: drop sandbox-denied CLI socket telemetry * fix: allow explicit Sentry opt-in under XCTest * Address Sentry startup review policy * Close Sentry test launch review gaps * Require provenance for Sentry suppression * Document Sentry suppression contract --------- Co-authored-by: lawrencecchen <54008264+lawrencecchen@users.noreply.github.com> | 2 个月前 | |
fix: make unsupported feed hooks fail neutral | 2 个月前 | |
fix: bound feed hook socket setup | 2 个月前 | |
Fix Codex resume notification rebinding (#9185) * test: cover Codex resume notification rebinding * fix: preserve notifications across Codex resume | 2 个月前 | |
Add Campfire support (#5813) * Add Campfire hook installation and session restore Campfire (the collaborative pi-based harness) becomes a first-class agent: - cmux hooks campfire install/uninstall writes a native extension to ${CAMPFIRE_CODING_AGENT_DIR:-~/.campfire/agent}/extensions/ cmux-campfire-session.ts; opt out per process with CMUX_CAMPFIRE_HOOKS_DISABLED=1 - the extension records the HOST role only (CAMPFIRE_SESSION_ROLE); a joiner is an ephemeral view whose argv carries the invite URL, a capability token that is never persisted or replayed - launch capture normalizes the bun-compiled argv (drops the bunfs virtual entry) and tags kind=campfire so restore runs campfire --session <id> instead of mis-resuming as plain pi - the extension subscribes to campfire's in-process observer bridge (Symbol.for campfire.observer.v1) and surfaces driver-actionable collaborative moments — a joiner waiting in the lobby, a capability ask — as cmux notifications - sanitizer policy preserves --relay/--model config flags and drops prompts, session selectors, --join-as, and invite URLs; environment policy replays CAMPFIRE_* config roots, never secrets, and drops the self-managed PI_PACKAGE_DIR so an upgraded binary is not pinned to a stale asset cache - Vault and Task Manager detect campfire processes (compiled binary and bun dev invocations) with sessions under ~/.campfire/agent/sessions - docs, en+ja (and 18 more locales) CLI strings, Swift + Python tests, CI hookup Verification: - swift test --package-path Packages/CMUXAgentLaunch (82 tests) - xcodebuild test -only-testing:cmuxTests/CampfireSupportTests (4 tests) - CMUX_CLI_BIN=... python3 tests/test_campfire_extension_install.py - xcodebuild build (full app, tagged derived data) - ./scripts/check-pbxproj.sh && ./scripts/lint-pbxproj-test-wiring.sh Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address PR review: Campfire session-dir precedence and relay-error privacy - VaultAgentProcessScanner: gate PI_CODING_AGENT_SESSION_DIR out of the campfire registration so Campfire (which embeds Pi) resolves sessions against CAMPFIRE_CODING_AGENT_SESSION_DIR / CAMPFIRE_CODING_AGENT_DIR instead of being silently pre-empted by a user's Pi session dir. pi/omp behavior unchanged. Adds a regression test. - CMUXCLI+CampfireExtension: drop the raw relay reason from the user-facing notification; emit a generic message per the error-privacy policy. - AgentLaunchEnvironmentPolicyTests: assert both pi and omp keep PI_PACKAGE_DIR (test previously only exercised pi). - test_campfire_extension_install: preserve falsey JSON-RPC ids (0) when echoing responses instead of rewriting them to "unknown". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Add Campfire Vault detection regression tests * Tighten Campfire Vault process detection * Add Campfire notification and Vault regressions * Fix Campfire notification and Vault matching * Cover structured Campfire observer payloads * Require Campfire argv cue for Vault fallback * Cover non-Campfire packages session argv * Use precise Campfire Vault entrypoint alternatives * Cover mentioned Campfire entrypoint argv * Constrain Campfire Vault alternates to runtimes * Address Campfire autoreview policy findings * Fix Campfire runtime Vault restore executable * Gate Campfire Vault detection to hosts * Fix Campfire Bun argv restore * Add failing test for alternate-only Vault detect rule A CmuxVaultAgentDetectRule that specifies only alternate criteria (no primary process names and no argvContains) currently matches every process: the empty primary criteria make primaryMatches return true before the alternate criteria are checked. This test asserts an unrelated `node` process is not classified, and fails without the fix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Address PR review: detect-rule matching, ts-node host, capability fallback - VaultAgentProcessScanner: gate the primary match on the presence of primary criteria so an alternate-only detect rule no longer matches every process (fixes the test added in the previous commit). - TaskManagerTypes: add `ts-node` to argumentHostBasenames so Task Manager classifies `ts-node …/campfire.ts` as Campfire, matching the hosts already recognized by Vault detection. - cmux CLI: route unknown/unmapped Campfire capability values to the localized fallback label instead of surfacing the raw identifier in user-facing notification copy. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Fix Campfire review blockers * Restore ghostty and bonsplit submodule pointers to main * Revert unrelated renderer-realizer shim; scoped to main's implementation * Drop PI_CODING_AGENT_SESSION_DIR from campfire resume environment The scanner already gates PI_CODING_AGENT_SESSION_DIR out when resolving Campfire session roots, but restore still replayed it into resumed Campfire processes. Since Campfire embeds Pi, a user's custom Pi session root could then receive resumed Campfire session state while cmux reads the Campfire root. Drop it for campfire resumes alongside PI_PACKAGE_DIR; pi/omp behavior is unchanged. * Recognize campfire script entrypoints under deno/tsx/ts-node hosts AgentLaunchCaptureTrust only treated node and bun as hosts that can run a Campfire entrypoint, so PID-based argv fallback dropped campfire hook captures launched via deno, tsx, or ts-node even though the rest of the Campfire support (normalizer, scanner, task manager) recognizes those hosts. Gate the campfire needle check on the same host set; the claude detection stays limited to node/bun. * Refresh Swift file length budget for campfire growth workflow-guard-tests failed on the file-length budget: the Campfire feature grows CLI/cmux.swift, VaultAgentProcessScanner, TaskManagerTypes, RestorableAgentSession, the CMUXAgentLaunch sanitizer files, and adds cmuxTests/CampfireSupportTests.swift past the tracked thresholds. Accept the feature growth in the budget; no unrelated entries changed. --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: lawrencecchen <54008264+lawrencecchen@users.noreply.github.com> | 2 个月前 | |
Fix OMP hook binding from live PID/TTY identity (#9091) * test: expose OMP hook PID/TTY binding drift * test: make OMP binding regression runnable * fix: bind OMP hooks from live controlling TTY * fix: harden OMP session reconciliation * fix: expose shared hook binding helpers * fix: negotiate and bound OMP hook delivery * fix: isolate OMP binding and drain hook shutdown * fix: preserve hook routing boundaries * fix: make OMP cleanup recoverable * fix: demote all superseded OMP claims * fix: harden OMP hook lifecycle coverage * Retry all superseded OMP cleanup records * Bound OMP cleanup retries and preserve Stop hooks * Harden superseded OMP cleanup ownership * Preserve agent runtime across Dock ownership * Test Dock agent session ownership gaps * Test Dock binding-only lifecycle transfer * Test Dock retry ownership across bindings * Test Dock resume cwd binding ownership * Test authoritative Dock binding clears * Test Dock session and directory provenance * Test completed Dock tombstone after binding clear * Test managed Dock hook identity across tmux replacement * Fix managed Dock hook identity across tmux replacement * fix: disambiguate restorable agent selection * fix: return workspace resume binding * Split agent hook process binding types * fix: preserve managed identity after retry revert --------- Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> | 2 个月前 | |
Fix OMP hook binding from live PID/TTY identity (#9091) * test: expose OMP hook PID/TTY binding drift * test: make OMP binding regression runnable * fix: bind OMP hooks from live controlling TTY * fix: harden OMP session reconciliation * fix: expose shared hook binding helpers * fix: negotiate and bound OMP hook delivery * fix: isolate OMP binding and drain hook shutdown * fix: preserve hook routing boundaries * fix: make OMP cleanup recoverable * fix: demote all superseded OMP claims * fix: harden OMP hook lifecycle coverage * Retry all superseded OMP cleanup records * Bound OMP cleanup retries and preserve Stop hooks * Harden superseded OMP cleanup ownership * Preserve agent runtime across Dock ownership * Test Dock agent session ownership gaps * Test Dock binding-only lifecycle transfer * Test Dock retry ownership across bindings * Test Dock resume cwd binding ownership * Test authoritative Dock binding clears * Test Dock session and directory provenance * Test completed Dock tombstone after binding clear * Test managed Dock hook identity across tmux replacement * Fix managed Dock hook identity across tmux replacement * fix: disambiguate restorable agent selection * fix: return workspace resume binding * Split agent hook process binding types * fix: preserve managed identity after retry revert --------- Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> | 2 个月前 | |
Fix OMP hook binding from live PID/TTY identity (#9091) * test: expose OMP hook PID/TTY binding drift * test: make OMP binding regression runnable * fix: bind OMP hooks from live controlling TTY * fix: harden OMP session reconciliation * fix: expose shared hook binding helpers * fix: negotiate and bound OMP hook delivery * fix: isolate OMP binding and drain hook shutdown * fix: preserve hook routing boundaries * fix: make OMP cleanup recoverable * fix: demote all superseded OMP claims * fix: harden OMP hook lifecycle coverage * Retry all superseded OMP cleanup records * Bound OMP cleanup retries and preserve Stop hooks * Harden superseded OMP cleanup ownership * Preserve agent runtime across Dock ownership * Test Dock agent session ownership gaps * Test Dock binding-only lifecycle transfer * Test Dock retry ownership across bindings * Test Dock resume cwd binding ownership * Test authoritative Dock binding clears * Test Dock session and directory provenance * Test completed Dock tombstone after binding clear * Test managed Dock hook identity across tmux replacement * Fix managed Dock hook identity across tmux replacement * fix: disambiguate restorable agent selection * fix: return workspace resume binding * Split agent hook process binding types * fix: preserve managed identity after retry revert --------- Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> | 2 个月前 | |
Fix OMP hook binding from live PID/TTY identity (#9091) * test: expose OMP hook PID/TTY binding drift * test: make OMP binding regression runnable * fix: bind OMP hooks from live controlling TTY * fix: harden OMP session reconciliation * fix: expose shared hook binding helpers * fix: negotiate and bound OMP hook delivery * fix: isolate OMP binding and drain hook shutdown * fix: preserve hook routing boundaries * fix: make OMP cleanup recoverable * fix: demote all superseded OMP claims * fix: harden OMP hook lifecycle coverage * Retry all superseded OMP cleanup records * Bound OMP cleanup retries and preserve Stop hooks * Harden superseded OMP cleanup ownership * Preserve agent runtime across Dock ownership * Test Dock agent session ownership gaps * Test Dock binding-only lifecycle transfer * Test Dock retry ownership across bindings * Test Dock resume cwd binding ownership * Test authoritative Dock binding clears * Test Dock session and directory provenance * Test completed Dock tombstone after binding clear * Test managed Dock hook identity across tmux replacement * Fix managed Dock hook identity across tmux replacement * fix: disambiguate restorable agent selection * fix: return workspace resume binding * Split agent hook process binding types * fix: preserve managed identity after retry revert --------- Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> | 2 个月前 | |
Preserve Codex --yolo across session restore (#8133) * test: preserve Codex yolo across session restore * Preserve Codex launch flags in restore bindings * test: cover current Codex restore flags * Require durable target for mapped Codex flags * Use live Codex PID for permission evidence --------- Co-authored-by: cmux-lawrence <cmux-lawrence@cmux-lawrences-Mac-mini.local> | 2 个月前 | |
Address review feedback on Amp Neo plugin PR (round 2) - Sanitize env for cmux status subprocesses (cubic P1 / codex P2): new statusEnvironment() strips AMP_API_KEY before spawning, mirroring what hookEnvironment already does for the lifecycle hook path. Without this, every set-status / log / clear-status child inherited the full plugin env including the Amp API key. - Localize the new schema description (codex P2): add descriptionKey 'schemaDescriptions.automation.ampIntegration' and populate entries for all 20 supported locales so the configuration docs render translated text instead of the English fallback. - Document the dual-catalog persistence pattern (CodeRabbit nitpick): add a comment near AutomationCatalogSection.ampIntegration explaining that several integration toggles intentionally share a userDefaultsKey across automation.* and integrations.* namespaces, and that this is by design — no precedence ambiguity, just two discovery paths into the same persisted slot. Amp-Thread-ID: https://ampcode.com/threads/T-019e45e6-2904-743f-95f5-5ed784b271a5 Co-authored-by: Amp <amp@ampcode.com> | 4 个月前 | |
Fix Claude bridge branch and resume failures (#7882) (#7900) * test: cover inherited Claude bridge sessions * Fix Claude bridge session identity leakage * Fix OMC Claude session identity inheritance * Harden independent Claude launch boundaries * Generate Claude launch environment policy * Preserve Claude Teams respawn trust * Run Claude launch policy test in CI * Preserve Claude auto-naming trust context | 2 个月前 | |
feat: opt-in AI auto-naming of workspaces and tabs from agent conversations (#5547) * feat: add custom-title provenance (user vs auto) to workspace and panel titles Workspace.customTitle and panelCustomTitles gain a CustomTitleSource so AI auto-naming can write titles without ever overwriting a user-set name. Auto writes are rejected over user titles and never clear; clearing a title resets provenance; provenance round-trips through session snapshots (absent provenance decodes as user-owned, so pre-provenance snapshots and carried panel moves stay conservative) and travels with detached surface transfers. * feat: add opt-in automation.workspaceAutoNaming setting New Bool setting (default off) following the claudeBinaryPath 4-layer precedent: typed catalog key, Settings > Automation card, cmux.json schema entry, and en/ja localization. The card notes that manual renames always win and that summarization uses the user's own agent binary, and annotates the Claude-hooks dependency when Claude Code Integration is off. * feat: add workspace.set_auto_title v2 socket method Applies an AI-generated title to a workspace (and optionally one of its panels) with auto provenance, so user-set titles are never overwritten. Gated app-side on the opt-in workspaceAutoNamingEnabled setting; a probe param reads the live setting state so hook processes honor mid-session toggles without an agent restart. * feat: auto-naming engine behind a dedicated async Claude Stop hook The wrapper registers an async 'hooks claude auto-name' Stop entry (long timeout, same mechanism as the async feed hook) so summarization never touches the sync 10s Stop budget. The handler probes the live setting and workspace ownership over the socket before any work, honors the active-session and nested-agent gates, evaluates a growth+interval throttle under the session-store lock with an in-flight marker (so concurrent Stops dedupe), reseeds the baseline on transcript compaction, and summarizes via the user's own claude binary - wrapper-aware resolution, env-aware model (ANTHROPIC_SMALL_FAST_MODEL else haiku), backend vars preserved, recursion vars scrubbed, hard deadline. The durable baseline advances only after a confirmed apply, so failures retry on the next qualifying Stop. Pure engine logic lives in CLI/CMUXCLI+AutoNaming.swift, compiled into both the CLI tool and cmux-unit so its throttle/extraction/sanitization behavior is unit tested. * feat: extend auto-naming to Codex sessions The codex generic-hook Stop case spawns a detached auto-name pass (via sh, fully detached from the hook's stdio) so the 5s sync hook budget is never touched. The pass resolves the rollout via findCodexTranscriptPath (the Stop payload does not reliably carry it), extracts conversation text from response_item message payloads with injected-context filtering, gates on the live setting probe plus the codex session store's isCurrent, shares the engine's throttle/in-flight/baseline semantics, and summarizes with the user's own codex binary (codex exec --output-last-message, hooks disabled for the call). Each agent names itself with its own binary, so codex-only machines need no claude install. * docs: document workspace auto-naming Feature doc covering the setting, precedence rules (user beats auto beats OSC), throttle and refresh behavior, language behavior, per-agent summarizer transport, and the no-LLM-without-opt-in guarantee; cross-linked from the agent-hooks and configuration docs. * fix: harden auto-naming from code review findings - Gate the codex detached spawn on a live setting probe so a disabled feature forks nothing on turn end (zero-behavior-change-when-off). - Synthesize a minimal session record in beginAutoNaming when the auto-name hook races the sync Stop hook's upsert, so the in-flight marker and reseeded baseline are never silently dropped. - Give the in-flight marker a grace window beyond the LLM deadline so a pass still in its termination/apply phase cannot be doubled by a concurrent Stop. - Bound the stdout drain wait and surface spawn/socket failures as telemetry breadcrumbs; remove the unused process-runner protocol. - Mark title provenance @Published on workspace and panels. - Document that pre-provenance custom titles restore user-owned, and the clear-name path that re-opens auto-naming. - Tests: probe ownership reporting, panel_only_if_multiple suppression, curly-quote and hard-cap sanitization, recursion-var scrub coverage, in-flight grace boundaries. * docs: clarify why sanitizeResponse gets currentTitle nil in the hook paths The previous comment read as if the unchanged-title fold applied at these call sites; it is deliberately bypassed so the explicit comparison below can distinguish topic-stable (advance baseline) from garbage (retry). * fix: localize the auto-naming schema description in all 20 locales; bound the codex sh reap Greptile review follow-ups: schemaDescriptions.automation.workspaceAutoNaming was added only to en/ja while every other locale already carries translated siblings under the same path - add it to the remaining 18 catalogs. Also bound the wait on the detached codex sh wrapper (it exits immediately by design, but a stalled fork must never eat the sync hook budget). * feat: extend workspace auto-naming adapters * fix: address workspace auto-naming review feedback * fix: avoid rescanning auto-naming transcripts * fix: skip auto-name spawn for user-owned workspaces * fix: avoid duplicate panel title publication * fix: harden workspace auto-naming hooks * fix: wire workspace auto-naming settings * fix: harden generic auto-naming hooks * fix: expose hook store record types to cli module * fix: skip unsafe gemini auto-naming runner * test: use try #require instead of try! in auto-naming tests #require already fails the test gracefully on nil; try! defeats that and crashes the runner. Switch the five auto-naming context/sanitize assertions to `try #require` and mark the enclosing @Test funcs as throws. Addresses CodeRabbit force_try finding on AutoNamingHookPayloadAdapterTests and the same pattern in the sibling Grok/Codex/Engine adapter tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test: use catalog key for workspace auto naming setting * fix: harden auto-naming summarizer state * feat: user-selectable auto-naming agent + Settings-only failure surface Add a "Naming Agent" picker to Settings → Automation → Workspace Auto-Naming that overrides which agent summarizes workspace/tab names for all sessions (cross-agent). Default stays "Automatic" (each session named by its own agent — unchanged behavior). Any agent is selectable; the six with summarizers (claude, codex, grok, opencode, pi, omp) drive naming, others fall back to the session's own agent so naming never breaks. - Shared AutoNamingAgentCatalog (CmuxSettings) is the single source for the picker and the CLI summarizer dispatch; setting stored as an open string so it stays fully customizable via cmux.json. - CLI: one shared summarizer dispatch keyed by agent, with per-chosen-agent env scrubbing; the override travels on the set_auto_title probe response. - Failures (rate limit / out of tokens / signed out / missing binary) never touch a tab/workspace title — they surface only as a Settings status line. - Localized (en+ja), schema + docs; tests cover the decision matrix, status store, and socket probe/failure behavior. Budget refreshed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: surface auto-naming "not installed" status that clear-on-apply wiped Autoreview (claude engine) found that when an override naming agent's binary is missing, the hook recorded the not_installed status BEFORE the same pass fell back to the session agent, applied a title, and the app's clear-on-apply immediately erased it — so the user was never told their chosen agent isn't installed. Report not_installed AFTER the fallback apply (gated on a title actually landing) across all three entry points and the shared pass, so the Settings note survives. A healthy pass (no missing override) still clears on apply, so a since-installed agent stops showing the note. Add a socket regression test for the apply-then-not_installed ordering. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: wire automation.autoNamingAgent into cmux.json file config Autoreview (claude engine) flagged that autoNamingAgent was documented as cmux.json-settable (schema, DocC, Settings configurationReview) but the file store never read it, so setting it in ~/.config/cmux/cmux.json was silently ignored — violating the repo config policy. Map automation.autoNamingAgent (open string) in KeyboardShortcutSettingsFileStore.parseAutomationSection and add it to the recognized JSON path set in CmuxSettingsJSONPathSupport, alongside workspaceAutoNaming. Add a file-store sync regression test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: cool down failed auto-naming passes to avoid per-turn summarizer respawn Autoreview (claude engine) found that a session that never produced a title would respawn the summarizer subprocess (claude -p / codex exec, up to 60s) on every turn end when the agent is rate-limited, out of quota, signed out, or timing out — because a failed pass advanced no throttle state, so the first-naming branch always re-proceeded. This wastes the user's agent quota and CPU, contrary to "worst case it just doesn't fire." Record autoNameLastAttemptAt on every completed pass (success or failure) and gate throttleDecision on it: the first-naming branch and the post-success path now honor minInterval (180s) since the last attempt, giving a fixed cooldown before retrying a failing summarizer. Backward-compatible (optional field, cooldown anchors on lastAttemptAt ?? lastNamedAt). Adds two throttle tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs: explain generic-summarizer env trade-off (autoreview P3) Generic agents need their own provider credentials; the broad scrubbed env is bounded by running the summarizer with tools/network disabled. Documents the conscious exception vs Codex's tight allowlist. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ci: fix package-conventions namespace-type lint + normalize pbxproj - Mark AutoNamingStatusStore / AutoNamingAgentCatalog with `lint:allow namespace-type` (stateless; UserDefaults injected per call), clearing the package-conventions-lint ERRORs. - Normalize cmux.xcodeproj/project.pbxproj (scripts/normalize-pbxproj.py) so the workflow-guard "objectVersion pin and normalization" check passes. - Refresh swift file length budget after merging origin/main. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * i18n: add autoNamingAgent schema description to all 18 remaining locales main expanded message catalogs from en/ja to 20 locales; the docs configuration page resolves each schema property's descriptionKey via next-intl per locale, so a missing key fails next build (Vercel). Adds schemaDescriptions.automation.autoNamingAgent to ar, bs, da, de, es, fr, it, km, ko, no, pl, pt-BR, ru, th, tr, uk, zh-CN, zh-TW. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: austinpower1258 <austinwang115@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> | 3 个月前 | |
feat: opt-in AI auto-naming of workspaces and tabs from agent conversations (#5547) * feat: add custom-title provenance (user vs auto) to workspace and panel titles Workspace.customTitle and panelCustomTitles gain a CustomTitleSource so AI auto-naming can write titles without ever overwriting a user-set name. Auto writes are rejected over user titles and never clear; clearing a title resets provenance; provenance round-trips through session snapshots (absent provenance decodes as user-owned, so pre-provenance snapshots and carried panel moves stay conservative) and travels with detached surface transfers. * feat: add opt-in automation.workspaceAutoNaming setting New Bool setting (default off) following the claudeBinaryPath 4-layer precedent: typed catalog key, Settings > Automation card, cmux.json schema entry, and en/ja localization. The card notes that manual renames always win and that summarization uses the user's own agent binary, and annotates the Claude-hooks dependency when Claude Code Integration is off. * feat: add workspace.set_auto_title v2 socket method Applies an AI-generated title to a workspace (and optionally one of its panels) with auto provenance, so user-set titles are never overwritten. Gated app-side on the opt-in workspaceAutoNamingEnabled setting; a probe param reads the live setting state so hook processes honor mid-session toggles without an agent restart. * feat: auto-naming engine behind a dedicated async Claude Stop hook The wrapper registers an async 'hooks claude auto-name' Stop entry (long timeout, same mechanism as the async feed hook) so summarization never touches the sync 10s Stop budget. The handler probes the live setting and workspace ownership over the socket before any work, honors the active-session and nested-agent gates, evaluates a growth+interval throttle under the session-store lock with an in-flight marker (so concurrent Stops dedupe), reseeds the baseline on transcript compaction, and summarizes via the user's own claude binary - wrapper-aware resolution, env-aware model (ANTHROPIC_SMALL_FAST_MODEL else haiku), backend vars preserved, recursion vars scrubbed, hard deadline. The durable baseline advances only after a confirmed apply, so failures retry on the next qualifying Stop. Pure engine logic lives in CLI/CMUXCLI+AutoNaming.swift, compiled into both the CLI tool and cmux-unit so its throttle/extraction/sanitization behavior is unit tested. * feat: extend auto-naming to Codex sessions The codex generic-hook Stop case spawns a detached auto-name pass (via sh, fully detached from the hook's stdio) so the 5s sync hook budget is never touched. The pass resolves the rollout via findCodexTranscriptPath (the Stop payload does not reliably carry it), extracts conversation text from response_item message payloads with injected-context filtering, gates on the live setting probe plus the codex session store's isCurrent, shares the engine's throttle/in-flight/baseline semantics, and summarizes with the user's own codex binary (codex exec --output-last-message, hooks disabled for the call). Each agent names itself with its own binary, so codex-only machines need no claude install. * docs: document workspace auto-naming Feature doc covering the setting, precedence rules (user beats auto beats OSC), throttle and refresh behavior, language behavior, per-agent summarizer transport, and the no-LLM-without-opt-in guarantee; cross-linked from the agent-hooks and configuration docs. * fix: harden auto-naming from code review findings - Gate the codex detached spawn on a live setting probe so a disabled feature forks nothing on turn end (zero-behavior-change-when-off). - Synthesize a minimal session record in beginAutoNaming when the auto-name hook races the sync Stop hook's upsert, so the in-flight marker and reseeded baseline are never silently dropped. - Give the in-flight marker a grace window beyond the LLM deadline so a pass still in its termination/apply phase cannot be doubled by a concurrent Stop. - Bound the stdout drain wait and surface spawn/socket failures as telemetry breadcrumbs; remove the unused process-runner protocol. - Mark title provenance @Published on workspace and panels. - Document that pre-provenance custom titles restore user-owned, and the clear-name path that re-opens auto-naming. - Tests: probe ownership reporting, panel_only_if_multiple suppression, curly-quote and hard-cap sanitization, recursion-var scrub coverage, in-flight grace boundaries. * docs: clarify why sanitizeResponse gets currentTitle nil in the hook paths The previous comment read as if the unchanged-title fold applied at these call sites; it is deliberately bypassed so the explicit comparison below can distinguish topic-stable (advance baseline) from garbage (retry). * fix: localize the auto-naming schema description in all 20 locales; bound the codex sh reap Greptile review follow-ups: schemaDescriptions.automation.workspaceAutoNaming was added only to en/ja while every other locale already carries translated siblings under the same path - add it to the remaining 18 catalogs. Also bound the wait on the detached codex sh wrapper (it exits immediately by design, but a stalled fork must never eat the sync hook budget). * feat: extend workspace auto-naming adapters * fix: address workspace auto-naming review feedback * fix: avoid rescanning auto-naming transcripts * fix: skip auto-name spawn for user-owned workspaces * fix: avoid duplicate panel title publication * fix: harden workspace auto-naming hooks * fix: wire workspace auto-naming settings * fix: harden generic auto-naming hooks * fix: expose hook store record types to cli module * fix: skip unsafe gemini auto-naming runner * test: use try #require instead of try! in auto-naming tests #require already fails the test gracefully on nil; try! defeats that and crashes the runner. Switch the five auto-naming context/sanitize assertions to `try #require` and mark the enclosing @Test funcs as throws. Addresses CodeRabbit force_try finding on AutoNamingHookPayloadAdapterTests and the same pattern in the sibling Grok/Codex/Engine adapter tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test: use catalog key for workspace auto naming setting * fix: harden auto-naming summarizer state * feat: user-selectable auto-naming agent + Settings-only failure surface Add a "Naming Agent" picker to Settings → Automation → Workspace Auto-Naming that overrides which agent summarizes workspace/tab names for all sessions (cross-agent). Default stays "Automatic" (each session named by its own agent — unchanged behavior). Any agent is selectable; the six with summarizers (claude, codex, grok, opencode, pi, omp) drive naming, others fall back to the session's own agent so naming never breaks. - Shared AutoNamingAgentCatalog (CmuxSettings) is the single source for the picker and the CLI summarizer dispatch; setting stored as an open string so it stays fully customizable via cmux.json. - CLI: one shared summarizer dispatch keyed by agent, with per-chosen-agent env scrubbing; the override travels on the set_auto_title probe response. - Failures (rate limit / out of tokens / signed out / missing binary) never touch a tab/workspace title — they surface only as a Settings status line. - Localized (en+ja), schema + docs; tests cover the decision matrix, status store, and socket probe/failure behavior. Budget refreshed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: surface auto-naming "not installed" status that clear-on-apply wiped Autoreview (claude engine) found that when an override naming agent's binary is missing, the hook recorded the not_installed status BEFORE the same pass fell back to the session agent, applied a title, and the app's clear-on-apply immediately erased it — so the user was never told their chosen agent isn't installed. Report not_installed AFTER the fallback apply (gated on a title actually landing) across all three entry points and the shared pass, so the Settings note survives. A healthy pass (no missing override) still clears on apply, so a since-installed agent stops showing the note. Add a socket regression test for the apply-then-not_installed ordering. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: wire automation.autoNamingAgent into cmux.json file config Autoreview (claude engine) flagged that autoNamingAgent was documented as cmux.json-settable (schema, DocC, Settings configurationReview) but the file store never read it, so setting it in ~/.config/cmux/cmux.json was silently ignored — violating the repo config policy. Map automation.autoNamingAgent (open string) in KeyboardShortcutSettingsFileStore.parseAutomationSection and add it to the recognized JSON path set in CmuxSettingsJSONPathSupport, alongside workspaceAutoNaming. Add a file-store sync regression test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: cool down failed auto-naming passes to avoid per-turn summarizer respawn Autoreview (claude engine) found that a session that never produced a title would respawn the summarizer subprocess (claude -p / codex exec, up to 60s) on every turn end when the agent is rate-limited, out of quota, signed out, or timing out — because a failed pass advanced no throttle state, so the first-naming branch always re-proceeded. This wastes the user's agent quota and CPU, contrary to "worst case it just doesn't fire." Record autoNameLastAttemptAt on every completed pass (success or failure) and gate throttleDecision on it: the first-naming branch and the post-success path now honor minInterval (180s) since the last attempt, giving a fixed cooldown before retrying a failing summarizer. Backward-compatible (optional field, cooldown anchors on lastAttemptAt ?? lastNamedAt). Adds two throttle tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs: explain generic-summarizer env trade-off (autoreview P3) Generic agents need their own provider credentials; the broad scrubbed env is bounded by running the summarizer with tools/network disabled. Documents the conscious exception vs Codex's tight allowlist. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ci: fix package-conventions namespace-type lint + normalize pbxproj - Mark AutoNamingStatusStore / AutoNamingAgentCatalog with `lint:allow namespace-type` (stateless; UserDefaults injected per call), clearing the package-conventions-lint ERRORs. - Normalize cmux.xcodeproj/project.pbxproj (scripts/normalize-pbxproj.py) so the workflow-guard "objectVersion pin and normalization" check passes. - Refresh swift file length budget after merging origin/main. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * i18n: add autoNamingAgent schema description to all 18 remaining locales main expanded message catalogs from en/ja to 20 locales; the docs configuration page resolves each schema property's descriptionKey via next-intl per locale, so a missing key fails next build (Vercel). Adds schemaDescriptions.automation.autoNamingAgent to ar, bs, da, de, es, fr, it, km, ko, no, pl, pt-BR, ru, th, tr, uk, zh-CN, zh-TW. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: austinpower1258 <austinwang115@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> | 3 个月前 | |
feat: opt-in AI auto-naming of workspaces and tabs from agent conversations (#5547) * feat: add custom-title provenance (user vs auto) to workspace and panel titles Workspace.customTitle and panelCustomTitles gain a CustomTitleSource so AI auto-naming can write titles without ever overwriting a user-set name. Auto writes are rejected over user titles and never clear; clearing a title resets provenance; provenance round-trips through session snapshots (absent provenance decodes as user-owned, so pre-provenance snapshots and carried panel moves stay conservative) and travels with detached surface transfers. * feat: add opt-in automation.workspaceAutoNaming setting New Bool setting (default off) following the claudeBinaryPath 4-layer precedent: typed catalog key, Settings > Automation card, cmux.json schema entry, and en/ja localization. The card notes that manual renames always win and that summarization uses the user's own agent binary, and annotates the Claude-hooks dependency when Claude Code Integration is off. * feat: add workspace.set_auto_title v2 socket method Applies an AI-generated title to a workspace (and optionally one of its panels) with auto provenance, so user-set titles are never overwritten. Gated app-side on the opt-in workspaceAutoNamingEnabled setting; a probe param reads the live setting state so hook processes honor mid-session toggles without an agent restart. * feat: auto-naming engine behind a dedicated async Claude Stop hook The wrapper registers an async 'hooks claude auto-name' Stop entry (long timeout, same mechanism as the async feed hook) so summarization never touches the sync 10s Stop budget. The handler probes the live setting and workspace ownership over the socket before any work, honors the active-session and nested-agent gates, evaluates a growth+interval throttle under the session-store lock with an in-flight marker (so concurrent Stops dedupe), reseeds the baseline on transcript compaction, and summarizes via the user's own claude binary - wrapper-aware resolution, env-aware model (ANTHROPIC_SMALL_FAST_MODEL else haiku), backend vars preserved, recursion vars scrubbed, hard deadline. The durable baseline advances only after a confirmed apply, so failures retry on the next qualifying Stop. Pure engine logic lives in CLI/CMUXCLI+AutoNaming.swift, compiled into both the CLI tool and cmux-unit so its throttle/extraction/sanitization behavior is unit tested. * feat: extend auto-naming to Codex sessions The codex generic-hook Stop case spawns a detached auto-name pass (via sh, fully detached from the hook's stdio) so the 5s sync hook budget is never touched. The pass resolves the rollout via findCodexTranscriptPath (the Stop payload does not reliably carry it), extracts conversation text from response_item message payloads with injected-context filtering, gates on the live setting probe plus the codex session store's isCurrent, shares the engine's throttle/in-flight/baseline semantics, and summarizes with the user's own codex binary (codex exec --output-last-message, hooks disabled for the call). Each agent names itself with its own binary, so codex-only machines need no claude install. * docs: document workspace auto-naming Feature doc covering the setting, precedence rules (user beats auto beats OSC), throttle and refresh behavior, language behavior, per-agent summarizer transport, and the no-LLM-without-opt-in guarantee; cross-linked from the agent-hooks and configuration docs. * fix: harden auto-naming from code review findings - Gate the codex detached spawn on a live setting probe so a disabled feature forks nothing on turn end (zero-behavior-change-when-off). - Synthesize a minimal session record in beginAutoNaming when the auto-name hook races the sync Stop hook's upsert, so the in-flight marker and reseeded baseline are never silently dropped. - Give the in-flight marker a grace window beyond the LLM deadline so a pass still in its termination/apply phase cannot be doubled by a concurrent Stop. - Bound the stdout drain wait and surface spawn/socket failures as telemetry breadcrumbs; remove the unused process-runner protocol. - Mark title provenance @Published on workspace and panels. - Document that pre-provenance custom titles restore user-owned, and the clear-name path that re-opens auto-naming. - Tests: probe ownership reporting, panel_only_if_multiple suppression, curly-quote and hard-cap sanitization, recursion-var scrub coverage, in-flight grace boundaries. * docs: clarify why sanitizeResponse gets currentTitle nil in the hook paths The previous comment read as if the unchanged-title fold applied at these call sites; it is deliberately bypassed so the explicit comparison below can distinguish topic-stable (advance baseline) from garbage (retry). * fix: localize the auto-naming schema description in all 20 locales; bound the codex sh reap Greptile review follow-ups: schemaDescriptions.automation.workspaceAutoNaming was added only to en/ja while every other locale already carries translated siblings under the same path - add it to the remaining 18 catalogs. Also bound the wait on the detached codex sh wrapper (it exits immediately by design, but a stalled fork must never eat the sync hook budget). * feat: extend workspace auto-naming adapters * fix: address workspace auto-naming review feedback * fix: avoid rescanning auto-naming transcripts * fix: skip auto-name spawn for user-owned workspaces * fix: avoid duplicate panel title publication * fix: harden workspace auto-naming hooks * fix: wire workspace auto-naming settings * fix: harden generic auto-naming hooks * fix: expose hook store record types to cli module * fix: skip unsafe gemini auto-naming runner * test: use try #require instead of try! in auto-naming tests #require already fails the test gracefully on nil; try! defeats that and crashes the runner. Switch the five auto-naming context/sanitize assertions to `try #require` and mark the enclosing @Test funcs as throws. Addresses CodeRabbit force_try finding on AutoNamingHookPayloadAdapterTests and the same pattern in the sibling Grok/Codex/Engine adapter tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test: use catalog key for workspace auto naming setting * fix: harden auto-naming summarizer state * feat: user-selectable auto-naming agent + Settings-only failure surface Add a "Naming Agent" picker to Settings → Automation → Workspace Auto-Naming that overrides which agent summarizes workspace/tab names for all sessions (cross-agent). Default stays "Automatic" (each session named by its own agent — unchanged behavior). Any agent is selectable; the six with summarizers (claude, codex, grok, opencode, pi, omp) drive naming, others fall back to the session's own agent so naming never breaks. - Shared AutoNamingAgentCatalog (CmuxSettings) is the single source for the picker and the CLI summarizer dispatch; setting stored as an open string so it stays fully customizable via cmux.json. - CLI: one shared summarizer dispatch keyed by agent, with per-chosen-agent env scrubbing; the override travels on the set_auto_title probe response. - Failures (rate limit / out of tokens / signed out / missing binary) never touch a tab/workspace title — they surface only as a Settings status line. - Localized (en+ja), schema + docs; tests cover the decision matrix, status store, and socket probe/failure behavior. Budget refreshed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: surface auto-naming "not installed" status that clear-on-apply wiped Autoreview (claude engine) found that when an override naming agent's binary is missing, the hook recorded the not_installed status BEFORE the same pass fell back to the session agent, applied a title, and the app's clear-on-apply immediately erased it — so the user was never told their chosen agent isn't installed. Report not_installed AFTER the fallback apply (gated on a title actually landing) across all three entry points and the shared pass, so the Settings note survives. A healthy pass (no missing override) still clears on apply, so a since-installed agent stops showing the note. Add a socket regression test for the apply-then-not_installed ordering. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: wire automation.autoNamingAgent into cmux.json file config Autoreview (claude engine) flagged that autoNamingAgent was documented as cmux.json-settable (schema, DocC, Settings configurationReview) but the file store never read it, so setting it in ~/.config/cmux/cmux.json was silently ignored — violating the repo config policy. Map automation.autoNamingAgent (open string) in KeyboardShortcutSettingsFileStore.parseAutomationSection and add it to the recognized JSON path set in CmuxSettingsJSONPathSupport, alongside workspaceAutoNaming. Add a file-store sync regression test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: cool down failed auto-naming passes to avoid per-turn summarizer respawn Autoreview (claude engine) found that a session that never produced a title would respawn the summarizer subprocess (claude -p / codex exec, up to 60s) on every turn end when the agent is rate-limited, out of quota, signed out, or timing out — because a failed pass advanced no throttle state, so the first-naming branch always re-proceeded. This wastes the user's agent quota and CPU, contrary to "worst case it just doesn't fire." Record autoNameLastAttemptAt on every completed pass (success or failure) and gate throttleDecision on it: the first-naming branch and the post-success path now honor minInterval (180s) since the last attempt, giving a fixed cooldown before retrying a failing summarizer. Backward-compatible (optional field, cooldown anchors on lastAttemptAt ?? lastNamedAt). Adds two throttle tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs: explain generic-summarizer env trade-off (autoreview P3) Generic agents need their own provider credentials; the broad scrubbed env is bounded by running the summarizer with tools/network disabled. Documents the conscious exception vs Codex's tight allowlist. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ci: fix package-conventions namespace-type lint + normalize pbxproj - Mark AutoNamingStatusStore / AutoNamingAgentCatalog with `lint:allow namespace-type` (stateless; UserDefaults injected per call), clearing the package-conventions-lint ERRORs. - Normalize cmux.xcodeproj/project.pbxproj (scripts/normalize-pbxproj.py) so the workflow-guard "objectVersion pin and normalization" check passes. - Refresh swift file length budget after merging origin/main. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * i18n: add autoNamingAgent schema description to all 18 remaining locales main expanded message catalogs from en/ja to 20 locales; the docs configuration page resolves each schema property's descriptionKey via next-intl per locale, so a missing key fails next build (Vercel). Adds schemaDescriptions.automation.autoNamingAgent to ar, bs, da, de, es, fr, it, km, ko, no, pl, pt-BR, ru, th, tr, uk, zh-CN, zh-TW. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: austinpower1258 <austinwang115@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> | 3 个月前 | |
Reduce Sentry CLI broken-pipe crashes and hangs (#6254) * Add closed-stderr CLI broken pipe regression test * Handle CLI broken pipes with safe stdio writes * Limit clean broken-pipe exits to fatal stderr writes * Drop CLI unit test that depends on cli-target internals The CLIBrokenPipeWriteTests class called cliWrite() directly, but that symbol lives in the cmux-cli target and is not visible from cmuxTests, so CI failed to compile. Even with visibility, calling Darwin.write into a closed pipe inside the XCTest host crashes the runner via SIGPIPE (only the CLI binary's main() ignores SIGPIPE). The existing E2E test exercises the same closed-stderr path through the real cmux binary, so coverage is preserved. Restore cliWrite and the disposition enum to private and harden the E2E test: - XCTWaiter().wait + early XCTFail on timeout instead of falling through to assertions on a still-running process - closeOnDealloc: false so the explicit defer is the sole owner of the stderr write fd Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add CLI broken-pipe regression coverage * Scope CLI SIGPIPE handling to write and launch paths * Address CI failures and review feedback on CLI broken-pipe PR - Fix defer block return error by gating cleanup on `installed` flag - Replace Python-based SIGPIPE probe with native `__sigpipe-inspect` subcommand; removes Python dependency and avoids masking inherited SIGPIPE disposition - Fix strdup type-inference error in exec-mode probe via explicit `[UnsafeMutablePointer<CChar>?]` typing - Convert auth status/login/logout `print()` callsites to `cliPrint()` so broken-pipe writes don't crash auth subcommands - Drain spawn-probe pipes before `waitUntilExit()` to prevent deadlock - Include `cliWriteFatalStderr` in stdio-safety audit summary Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use _exit in cliWrite EPIPE path to avoid deadlock under held lock cliWrite calls Darwin.exit while holding cliSIGPIPEDispositionLock (NSLock is non-reentrant). Any atexit handler that wrote through cliWrite/cliPrint would re-enter withCLISIGPIPEDisposition and deadlock. _exit also skips atexit/stdio flush, matching the default SIGPIPE termination this path replaces when stdout is closed by the consumer. Addresses Cursor Bugbot comment on PR #2993. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Poll for writable FD on EAGAIN in cliWrite Addresses Cursor bot review on PR #2993: the previous `case EINTR, EAGAIN, EWOULDBLOCK: continue` turned non-blocking writes into a busy-wait spin under the SIGPIPE disposition lock. Split EINTR (immediate retry) from EAGAIN/EWOULDBLOCK (block on poll(POLLOUT)) so a non-blocking stdio fd yields to the kernel instead of spinning. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use F_NOSIGPIPE on CLI stdio instead of per-write sigaction Every cliPrint was wrapped in withCLISIGPIPEIgnored, which took a process-wide NSLock and did three sigaction syscalls per write to temporarily install SIG_IGN around Darwin.write. For a command like `cmux help` (~142 lines) that added ~426 extra syscalls. Opt stdout/stderr into F_NOSIGPIPE once at CLI startup — the same per-FD pattern the socket path already uses via SO_NOSIGPIPE — so write(2) just returns EPIPE and the hot path is a single write syscall per call. Keeps withCLIDefaultSIGPIPEForChildLaunch for Process.run / exec paths in case the CLI was invoked with SIG_IGN inherited, but those are low-frequency and not on the stdio write path. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix CLI SIGPIPE child inheritance and pipe writes * Close CLI stdio disposition race CLI writes and child launch setup now share one lock around stdio disposition changes, so no write can run while inherited stdout/stderr have F_NOSIGPIPE temporarily cleared for a child process. Constraint: Cursor review identified a race between child-launch fd mutation and concurrent broken-pipe writes Rejected: Reintroduce process-wide SIGPIPE ignore | would make child processes inherit the wrong SIGPIPE disposition again Confidence: high Scope-risk: narrow Directive: Any future stdio-disposition mutation must coordinate with cliWrite via cliStdioDispositionLock Tested: bash scripts/check-cli-stdio-safety.sh; git diff --check on CLI/CMUXCLI+Process.swift Not-tested: macOS app/unit/UI workflows locally; awaiting PR CI * Keep SIGPIPE probe parsing compiler-compatible The CI Debug build uses Swift syntax rules that reject value-binding patterns inside expression-style array patterns, so the internal SIGPIPE inspection probe parses its optional output path through an explicit count check instead. This keeps the probe behavior unchanged while restoring build compatibility for the activation-session job. Constraint: PR iteration must rely on CI and must not run bare xcodebuild locally Rejected: Remove the probe output-path support | tests use it to inspect stdio state without relying on a live stdout Confidence: high Scope-risk: narrow Tested: bash scripts/check-cli-stdio-safety.sh; git diff --check -- CLI/CMUXCLI+Process.swift; rg conflict marker scan Not-tested: Local Xcode build prohibited by task instructions * Expose SIGPIPE inspection fixture to CLI tests The SIGPIPE child-disposition regression lives in CLINotifyProcessIntegrationTests after the main-branch test split, while the decoded inspection payload type was left private inside WorkspaceRemoteConnectionTests. Moving the fixture to file scope keeps the same assertions and lets the unit target compile. Constraint: CircleCI unit compile logs are the verification source; local Xcode test runs are prohibited Rejected: Duplicate the struct inside CLINotifyProcessIntegrationTests | unnecessary copy for a file-local test fixture Confidence: high Scope-risk: narrow Tested: bash scripts/check-cli-stdio-safety.sh; git diff --check -- cmuxTests/WorkspaceRemoteConnectionTests.swift; conflict-marker scan Not-tested: Local cmux-unit Xcode test run prohibited by task instructions * Fix CLI SIGPIPE feedback * Fix SIGPIPE probe inherited fd snapshot * Fix SIGPIPE exec probe argv typing * Fix CMUXCLI SIGPIPE snapshot initializer * Rerun CI for CLI broken pipe fix * Fix SIGPIPE inspect signal snapshot order * Fix tmux shell stdin broken pipe path * Centralize CLI no-sigpipe writes * Close CLI stdin pipes with safe FileHandle API * Add CLI stdio lock regression coverage * Fix CLI non-stdio write lock handling * Fix CLI poll hangup broken-pipe path * Route codex teams watcher stderr through CLI writer * Move non-stdio CLI lock probe into CLI * Avoid stdio lock for isolated child launches * Fix merged CLI stdio writes * Add PostHog flush deadlock regression test * Avoid synchronous PostHog flush during quit * fix: keep spawned CLI children on default SIGPIPE fds * test: split SIGPIPE regression coverage * Flush active analytics before shutdown * Keep PostHog analytics singleton construction private * Document PostHog analytics queue isolation * Split PostHog analytics tests * Rerun CI after runner cache miss * fix: suppress expected CLI socket Sentry noise * test: keep stale socket regression path short * fix: make Sentry noise filter instantiable * refactor: split CLI Sentry telemetry tests * fix: address Sentry crash reduction review feedback * fix: close CLI SIGPIPE review gaps --------- Co-authored-by: austinpower1258 <austinwang115@gmail.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> | 3 个月前 | |
feat: support resizing WKWebView browser viewports (#8072) * test(browser): cover WKWebView viewport emulation * feat(browser): emulate WKWebView viewports * docs(browser): explain WKWebView viewport sizing * fix(browser): preserve viewport across zoom and capture * fix(browser): close viewport review findings * test(browser): preserve reconciled host after capture * fix(browser): preserve current host after capture * test(browser): clean up viewport screenshots * fix(browser): import viewport geometry types * test(browser): cover viewport scale boundaries * fix(browser): bound and normalize viewport rendering * test(browser): cover viewport safety policies * fix(browser): bound viewport capture and inspector transitions * test(browser): cover inspector and zoomed full-page transitions * fix(browser): reconcile inspector and snapshot coordinates * test(browser): cover fullscreen and native zoom capture * fix(browser): reconcile fullscreen and native zoom capture * test(browser): assert runtime viewport dimensions * test(browser): gate runtime viewport regression * test(browser): await runtime viewport metrics * test: cover native viewport rounding at page zoom * fix: match native viewport rounding to WebKit * fix: preserve browser viewport presentation geometry * test: cover emulated viewport autoresizing mask * fix: disable raw viewport autoresizing while emulated * test: cover emulated viewport precision at page zoom * fix: preserve emulated viewport precision at page zoom * test: cover emulated viewport precision at default zoom * fix: preserve emulated viewport precision at default zoom * test: reject stale detached browser host restoration * fix: leave detached browser hosts unowned after capture * refactor: split browser viewport support types * test: report browser zoom render limits * fix: report browser zoom render limits * docs: keep viewport mode docs on public symbol * test: keep native browsers outside viewport host * fix: activate browser viewport host lazily * test: keep native portal layout passive * fix: keep native browser portal layout passive * test: preserve fractional zoom viewport dimensions * fix: preserve exact viewport dimensions at page zoom * test: cover near-integer zoom viewport rounding * ci: run CmuxBrowser package tests * fix: preserve near-integer zoom viewport dimensions * fix: keep viewport limit errors browser-generic | 2 个月前 | |
Add Campfire support (#5813) * Add Campfire hook installation and session restore Campfire (the collaborative pi-based harness) becomes a first-class agent: - cmux hooks campfire install/uninstall writes a native extension to ${CAMPFIRE_CODING_AGENT_DIR:-~/.campfire/agent}/extensions/ cmux-campfire-session.ts; opt out per process with CMUX_CAMPFIRE_HOOKS_DISABLED=1 - the extension records the HOST role only (CAMPFIRE_SESSION_ROLE); a joiner is an ephemeral view whose argv carries the invite URL, a capability token that is never persisted or replayed - launch capture normalizes the bun-compiled argv (drops the bunfs virtual entry) and tags kind=campfire so restore runs campfire --session <id> instead of mis-resuming as plain pi - the extension subscribes to campfire's in-process observer bridge (Symbol.for campfire.observer.v1) and surfaces driver-actionable collaborative moments — a joiner waiting in the lobby, a capability ask — as cmux notifications - sanitizer policy preserves --relay/--model config flags and drops prompts, session selectors, --join-as, and invite URLs; environment policy replays CAMPFIRE_* config roots, never secrets, and drops the self-managed PI_PACKAGE_DIR so an upgraded binary is not pinned to a stale asset cache - Vault and Task Manager detect campfire processes (compiled binary and bun dev invocations) with sessions under ~/.campfire/agent/sessions - docs, en+ja (and 18 more locales) CLI strings, Swift + Python tests, CI hookup Verification: - swift test --package-path Packages/CMUXAgentLaunch (82 tests) - xcodebuild test -only-testing:cmuxTests/CampfireSupportTests (4 tests) - CMUX_CLI_BIN=... python3 tests/test_campfire_extension_install.py - xcodebuild build (full app, tagged derived data) - ./scripts/check-pbxproj.sh && ./scripts/lint-pbxproj-test-wiring.sh Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address PR review: Campfire session-dir precedence and relay-error privacy - VaultAgentProcessScanner: gate PI_CODING_AGENT_SESSION_DIR out of the campfire registration so Campfire (which embeds Pi) resolves sessions against CAMPFIRE_CODING_AGENT_SESSION_DIR / CAMPFIRE_CODING_AGENT_DIR instead of being silently pre-empted by a user's Pi session dir. pi/omp behavior unchanged. Adds a regression test. - CMUXCLI+CampfireExtension: drop the raw relay reason from the user-facing notification; emit a generic message per the error-privacy policy. - AgentLaunchEnvironmentPolicyTests: assert both pi and omp keep PI_PACKAGE_DIR (test previously only exercised pi). - test_campfire_extension_install: preserve falsey JSON-RPC ids (0) when echoing responses instead of rewriting them to "unknown". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Add Campfire Vault detection regression tests * Tighten Campfire Vault process detection * Add Campfire notification and Vault regressions * Fix Campfire notification and Vault matching * Cover structured Campfire observer payloads * Require Campfire argv cue for Vault fallback * Cover non-Campfire packages session argv * Use precise Campfire Vault entrypoint alternatives * Cover mentioned Campfire entrypoint argv * Constrain Campfire Vault alternates to runtimes * Address Campfire autoreview policy findings * Fix Campfire runtime Vault restore executable * Gate Campfire Vault detection to hosts * Fix Campfire Bun argv restore * Add failing test for alternate-only Vault detect rule A CmuxVaultAgentDetectRule that specifies only alternate criteria (no primary process names and no argvContains) currently matches every process: the empty primary criteria make primaryMatches return true before the alternate criteria are checked. This test asserts an unrelated `node` process is not classified, and fails without the fix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Address PR review: detect-rule matching, ts-node host, capability fallback - VaultAgentProcessScanner: gate the primary match on the presence of primary criteria so an alternate-only detect rule no longer matches every process (fixes the test added in the previous commit). - TaskManagerTypes: add `ts-node` to argumentHostBasenames so Task Manager classifies `ts-node …/campfire.ts` as Campfire, matching the hosts already recognized by Vault detection. - cmux CLI: route unknown/unmapped Campfire capability values to the localized fallback label instead of surfacing the raw identifier in user-facing notification copy. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Fix Campfire review blockers * Restore ghostty and bonsplit submodule pointers to main * Revert unrelated renderer-realizer shim; scoped to main's implementation * Drop PI_CODING_AGENT_SESSION_DIR from campfire resume environment The scanner already gates PI_CODING_AGENT_SESSION_DIR out when resolving Campfire session roots, but restore still replayed it into resumed Campfire processes. Since Campfire embeds Pi, a user's custom Pi session root could then receive resumed Campfire session state while cmux reads the Campfire root. Drop it for campfire resumes alongside PI_PACKAGE_DIR; pi/omp behavior is unchanged. * Recognize campfire script entrypoints under deno/tsx/ts-node hosts AgentLaunchCaptureTrust only treated node and bun as hosts that can run a Campfire entrypoint, so PID-based argv fallback dropped campfire hook captures launched via deno, tsx, or ts-node even though the rest of the Campfire support (normalizer, scanner, task manager) recognizes those hosts. Gate the campfire needle check on the same host set; the claude detection stays limited to node/bun. * Refresh Swift file length budget for campfire growth workflow-guard-tests failed on the file-length budget: the Campfire feature grows CLI/cmux.swift, VaultAgentProcessScanner, TaskManagerTypes, RestorableAgentSession, the CMUXAgentLaunch sanitizer files, and adds cmuxTests/CampfireSupportTests.swift past the tracked thresholds. Accept the feature growth in the budget; no unrelated entries changed. --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: lawrencecchen <54008264+lawrencecchen@users.noreply.github.com> | 2 个月前 | |
Add Campfire support (#5813) * Add Campfire hook installation and session restore Campfire (the collaborative pi-based harness) becomes a first-class agent: - cmux hooks campfire install/uninstall writes a native extension to ${CAMPFIRE_CODING_AGENT_DIR:-~/.campfire/agent}/extensions/ cmux-campfire-session.ts; opt out per process with CMUX_CAMPFIRE_HOOKS_DISABLED=1 - the extension records the HOST role only (CAMPFIRE_SESSION_ROLE); a joiner is an ephemeral view whose argv carries the invite URL, a capability token that is never persisted or replayed - launch capture normalizes the bun-compiled argv (drops the bunfs virtual entry) and tags kind=campfire so restore runs campfire --session <id> instead of mis-resuming as plain pi - the extension subscribes to campfire's in-process observer bridge (Symbol.for campfire.observer.v1) and surfaces driver-actionable collaborative moments — a joiner waiting in the lobby, a capability ask — as cmux notifications - sanitizer policy preserves --relay/--model config flags and drops prompts, session selectors, --join-as, and invite URLs; environment policy replays CAMPFIRE_* config roots, never secrets, and drops the self-managed PI_PACKAGE_DIR so an upgraded binary is not pinned to a stale asset cache - Vault and Task Manager detect campfire processes (compiled binary and bun dev invocations) with sessions under ~/.campfire/agent/sessions - docs, en+ja (and 18 more locales) CLI strings, Swift + Python tests, CI hookup Verification: - swift test --package-path Packages/CMUXAgentLaunch (82 tests) - xcodebuild test -only-testing:cmuxTests/CampfireSupportTests (4 tests) - CMUX_CLI_BIN=... python3 tests/test_campfire_extension_install.py - xcodebuild build (full app, tagged derived data) - ./scripts/check-pbxproj.sh && ./scripts/lint-pbxproj-test-wiring.sh Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address PR review: Campfire session-dir precedence and relay-error privacy - VaultAgentProcessScanner: gate PI_CODING_AGENT_SESSION_DIR out of the campfire registration so Campfire (which embeds Pi) resolves sessions against CAMPFIRE_CODING_AGENT_SESSION_DIR / CAMPFIRE_CODING_AGENT_DIR instead of being silently pre-empted by a user's Pi session dir. pi/omp behavior unchanged. Adds a regression test. - CMUXCLI+CampfireExtension: drop the raw relay reason from the user-facing notification; emit a generic message per the error-privacy policy. - AgentLaunchEnvironmentPolicyTests: assert both pi and omp keep PI_PACKAGE_DIR (test previously only exercised pi). - test_campfire_extension_install: preserve falsey JSON-RPC ids (0) when echoing responses instead of rewriting them to "unknown". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Add Campfire Vault detection regression tests * Tighten Campfire Vault process detection * Add Campfire notification and Vault regressions * Fix Campfire notification and Vault matching * Cover structured Campfire observer payloads * Require Campfire argv cue for Vault fallback * Cover non-Campfire packages session argv * Use precise Campfire Vault entrypoint alternatives * Cover mentioned Campfire entrypoint argv * Constrain Campfire Vault alternates to runtimes * Address Campfire autoreview policy findings * Fix Campfire runtime Vault restore executable * Gate Campfire Vault detection to hosts * Fix Campfire Bun argv restore * Add failing test for alternate-only Vault detect rule A CmuxVaultAgentDetectRule that specifies only alternate criteria (no primary process names and no argvContains) currently matches every process: the empty primary criteria make primaryMatches return true before the alternate criteria are checked. This test asserts an unrelated `node` process is not classified, and fails without the fix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Address PR review: detect-rule matching, ts-node host, capability fallback - VaultAgentProcessScanner: gate the primary match on the presence of primary criteria so an alternate-only detect rule no longer matches every process (fixes the test added in the previous commit). - TaskManagerTypes: add `ts-node` to argumentHostBasenames so Task Manager classifies `ts-node …/campfire.ts` as Campfire, matching the hosts already recognized by Vault detection. - cmux CLI: route unknown/unmapped Campfire capability values to the localized fallback label instead of surfacing the raw identifier in user-facing notification copy. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Fix Campfire review blockers * Restore ghostty and bonsplit submodule pointers to main * Revert unrelated renderer-realizer shim; scoped to main's implementation * Drop PI_CODING_AGENT_SESSION_DIR from campfire resume environment The scanner already gates PI_CODING_AGENT_SESSION_DIR out when resolving Campfire session roots, but restore still replayed it into resumed Campfire processes. Since Campfire embeds Pi, a user's custom Pi session root could then receive resumed Campfire session state while cmux reads the Campfire root. Drop it for campfire resumes alongside PI_PACKAGE_DIR; pi/omp behavior is unchanged. * Recognize campfire script entrypoints under deno/tsx/ts-node hosts AgentLaunchCaptureTrust only treated node and bun as hosts that can run a Campfire entrypoint, so PID-based argv fallback dropped campfire hook captures launched via deno, tsx, or ts-node even though the rest of the Campfire support (normalizer, scanner, task manager) recognizes those hosts. Gate the campfire needle check on the same host set; the claude detection stays limited to node/bun. * Refresh Swift file length budget for campfire growth workflow-guard-tests failed on the file-length budget: the Campfire feature grows CLI/cmux.swift, VaultAgentProcessScanner, TaskManagerTypes, RestorableAgentSession, the CMUXAgentLaunch sanitizer files, and adds cmuxTests/CampfireSupportTests.swift past the tracked thresholds. Accept the feature growth in the budget; no unrelated entries changed. --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: lawrencecchen <54008264+lawrencecchen@users.noreply.github.com> | 2 个月前 | |
Add Campfire support (#5813) * Add Campfire hook installation and session restore Campfire (the collaborative pi-based harness) becomes a first-class agent: - cmux hooks campfire install/uninstall writes a native extension to ${CAMPFIRE_CODING_AGENT_DIR:-~/.campfire/agent}/extensions/ cmux-campfire-session.ts; opt out per process with CMUX_CAMPFIRE_HOOKS_DISABLED=1 - the extension records the HOST role only (CAMPFIRE_SESSION_ROLE); a joiner is an ephemeral view whose argv carries the invite URL, a capability token that is never persisted or replayed - launch capture normalizes the bun-compiled argv (drops the bunfs virtual entry) and tags kind=campfire so restore runs campfire --session <id> instead of mis-resuming as plain pi - the extension subscribes to campfire's in-process observer bridge (Symbol.for campfire.observer.v1) and surfaces driver-actionable collaborative moments — a joiner waiting in the lobby, a capability ask — as cmux notifications - sanitizer policy preserves --relay/--model config flags and drops prompts, session selectors, --join-as, and invite URLs; environment policy replays CAMPFIRE_* config roots, never secrets, and drops the self-managed PI_PACKAGE_DIR so an upgraded binary is not pinned to a stale asset cache - Vault and Task Manager detect campfire processes (compiled binary and bun dev invocations) with sessions under ~/.campfire/agent/sessions - docs, en+ja (and 18 more locales) CLI strings, Swift + Python tests, CI hookup Verification: - swift test --package-path Packages/CMUXAgentLaunch (82 tests) - xcodebuild test -only-testing:cmuxTests/CampfireSupportTests (4 tests) - CMUX_CLI_BIN=... python3 tests/test_campfire_extension_install.py - xcodebuild build (full app, tagged derived data) - ./scripts/check-pbxproj.sh && ./scripts/lint-pbxproj-test-wiring.sh Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address PR review: Campfire session-dir precedence and relay-error privacy - VaultAgentProcessScanner: gate PI_CODING_AGENT_SESSION_DIR out of the campfire registration so Campfire (which embeds Pi) resolves sessions against CAMPFIRE_CODING_AGENT_SESSION_DIR / CAMPFIRE_CODING_AGENT_DIR instead of being silently pre-empted by a user's Pi session dir. pi/omp behavior unchanged. Adds a regression test. - CMUXCLI+CampfireExtension: drop the raw relay reason from the user-facing notification; emit a generic message per the error-privacy policy. - AgentLaunchEnvironmentPolicyTests: assert both pi and omp keep PI_PACKAGE_DIR (test previously only exercised pi). - test_campfire_extension_install: preserve falsey JSON-RPC ids (0) when echoing responses instead of rewriting them to "unknown". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Add Campfire Vault detection regression tests * Tighten Campfire Vault process detection * Add Campfire notification and Vault regressions * Fix Campfire notification and Vault matching * Cover structured Campfire observer payloads * Require Campfire argv cue for Vault fallback * Cover non-Campfire packages session argv * Use precise Campfire Vault entrypoint alternatives * Cover mentioned Campfire entrypoint argv * Constrain Campfire Vault alternates to runtimes * Address Campfire autoreview policy findings * Fix Campfire runtime Vault restore executable * Gate Campfire Vault detection to hosts * Fix Campfire Bun argv restore * Add failing test for alternate-only Vault detect rule A CmuxVaultAgentDetectRule that specifies only alternate criteria (no primary process names and no argvContains) currently matches every process: the empty primary criteria make primaryMatches return true before the alternate criteria are checked. This test asserts an unrelated `node` process is not classified, and fails without the fix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Address PR review: detect-rule matching, ts-node host, capability fallback - VaultAgentProcessScanner: gate the primary match on the presence of primary criteria so an alternate-only detect rule no longer matches every process (fixes the test added in the previous commit). - TaskManagerTypes: add `ts-node` to argumentHostBasenames so Task Manager classifies `ts-node …/campfire.ts` as Campfire, matching the hosts already recognized by Vault detection. - cmux CLI: route unknown/unmapped Campfire capability values to the localized fallback label instead of surfacing the raw identifier in user-facing notification copy. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Fix Campfire review blockers * Restore ghostty and bonsplit submodule pointers to main * Revert unrelated renderer-realizer shim; scoped to main's implementation * Drop PI_CODING_AGENT_SESSION_DIR from campfire resume environment The scanner already gates PI_CODING_AGENT_SESSION_DIR out when resolving Campfire session roots, but restore still replayed it into resumed Campfire processes. Since Campfire embeds Pi, a user's custom Pi session root could then receive resumed Campfire session state while cmux reads the Campfire root. Drop it for campfire resumes alongside PI_PACKAGE_DIR; pi/omp behavior is unchanged. * Recognize campfire script entrypoints under deno/tsx/ts-node hosts AgentLaunchCaptureTrust only treated node and bun as hosts that can run a Campfire entrypoint, so PID-based argv fallback dropped campfire hook captures launched via deno, tsx, or ts-node even though the rest of the Campfire support (normalizer, scanner, task manager) recognizes those hosts. Gate the campfire needle check on the same host set; the claude detection stays limited to node/bun. * Refresh Swift file length budget for campfire growth workflow-guard-tests failed on the file-length budget: the Campfire feature grows CLI/cmux.swift, VaultAgentProcessScanner, TaskManagerTypes, RestorableAgentSession, the CMUXAgentLaunch sanitizer files, and adds cmuxTests/CampfireSupportTests.swift past the tracked thresholds. Accept the feature growth in the budget; no unrelated entries changed. --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: lawrencecchen <54008264+lawrencecchen@users.noreply.github.com> | 2 个月前 | |
fix: claude-hook success stdout renders as a visible OK block in Claude Code — emit a silent JSON ack (#7963) * test: claude-hook stdout must be a machine-consumable ack, not literal OK Claude Code renders any plain-text hook stdout as a visible "hook success: OK" block in the conversation transcript — for the prompt-submit hook that's a bare OK on every prompt in every cmux-hosted Claude Code session. A bare JSON object is consumed as structured hook output with nothing rendered, the same contract the echo '{}' no-op fallback in AgentHookDefinitions already relies on. Failing test first per the regression-test commit policy; the fix lands in the next commit. Refs #7962 * fix: emit a silent JSON ack from claude-hook success paths instead of OK Every claude-hook success path printed a literal OK (23 guard/tail sites in runClaudeHook, 5 in the PushNotification bridge) or echoed the control-socket ACK (print(response) after notify_target_async). Claude Code renders that stdout as a visible "hook success: OK" block in the conversation — on every prompt for prompt-submit. Replace them with printClaudeHookAck(), which prints {}: consumed by Claude Code as structured hook output with nothing rendered, matching the echo '{}' no-op fallback AgentHookDefinitions already installs for the disabled/no-CLI path. Success remains signaled by the exit code; errors still throw CLIError. The cron-create-guard decision output (guardResponse) is meaningful PreToolUse JSON and is untouched. The OK was never machine-consumed: no test asserted it as protocol (only two incidental stdout assertions, updated here), nothing parses hook stdout, and 81dd72c479 localized several of the prints on i18n review feedback — a parseable protocol token could not be localized. Fixes #7962 --------- Co-authored-by: Cameron Sjo <cameronsjo@users.noreply.github.com> | 2 个月前 | |
Resolve agent notification targets from live identity at delivery time (#7946) * Add failing regression tests for wrong-pane notification attribution (#7939) Two Claude agents in different workspaces must never see a turn-complete notification, unread ring, or status pill land on the other agent's pane: - CLI: stop must prefer the live agent-pid target over a polluted session record (#7391 drift) and heal the record; a moved pane's notification must follow the surface to its current workspace (#5781); SessionStart must not be poisoned by a stale debug.terminals tty row; legacy routing must survive an app without the resolver method. - App: a queued or synchronously delivered notification addressed with a stale workspace id but a live surface id must be retargeted to the surface's current workspace at delivery time instead of being dropped (async) or misfiled (sync). These tests fail on main; the fix lands in the follow-up commit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Resolve agent notification targets from live identity at delivery time (#7939) One authoritative hook-event -> live surface -> current pane/workspace resolution, shared by the CLI and the app: App: new `agent.resolve_delivery_target` control method backed by AgentDeliveryTargetResolution.swift. A `{pid}` probe resolves the pane that owns the agent process RIGHT NOW from two independent live signals (the process's controlling tty matched against surface pty devices, and the process's own stable CMUX_SURFACE_ID environment re-homed through workspaceContainingPanel); disagreement or ambiguity refuses to guess. A `{surface_id}` probe returns the workspace that currently hosts a known surface. The same resolver now retargets every in-app delivery path: queued notifications follow their surface to its current workspace instead of being dropped on a stale workspace claim, the sync notify path records under the surface's current workspace instead of misfiling, and notification click-through re-homes at click time. CLI: Claude hook routing goes through resolveClaudeHookDeliveryTarget, which puts live process identity above every persisted or spawn-time claim: live pid target first (beats a polluted session record - the issue #7391 resume/tty drift class - and heals it via the existing upserts and active-pointer self-heal), then the #7228 legacy chain unchanged, then moved-pane re-home (issue #5781 class) when the identity surface is no longer listed in the resolved workspace. Explicit --workspace/--surface flags bypass the probes, per-tool PreToolUse skips them for cheapness, and an app without the method degrades to the legacy chain exactly as before. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address review findings: pid_t overflow, stale queue keys, same-workspace rehome - agent.resolve_delivery_target: convert the caller-supplied pid with pid_t(exactly:) so an out-of-range 64-bit value degrades to the surface/workspace probes instead of trapping (socket-reachable crash). - Sync notification delivery: discard superseded pending notifications by their canonical identity (the surface) so an entry queued under a stale claimed workspace key cannot survive retargeting and duplicate/replace the newer notification. - Claude hook rehome: apply the app's identity-surface ownership answer even when the owning workspace is unchanged — a confirmed identity surface outranks the focused-surface fallback in the same workspace. - Regression tests for all three. Review findings from codex autoreview, Cursor Bugbot, Greptile, CodeRabbit on #7946. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address round-2 review: relay pid namespace, PreToolUse rehome, SessionEnd cleanup - Skip the live agent-pid probe on relay-backed socket connections: a hook running on an SSH/cloud host carries a remote pid that must not be resolved against the Mac's local process table. UUID-based probes and the legacy chain still apply. - Split allowsLiveProbe into allowsPidProbe: PreToolUse still skips the per-tool pid/tty scan, but the cheap {surface_id} re-home probe stays enabled so a mid-turn pane move cannot make PreToolUse mutate (and re-record via upsert) the old workspace's focused pane. - Route SessionEnd cleanup through the live target resolver: clear status/pid/notifications on the workspace that owns the pane NOW, not the consumed record's stale workspace (which also wiped unrelated panes' notifications there). Fork-parent cleanup uses the shared resolver too. - Harness regression tests for the SessionEnd and PreToolUse paths. Round-2 codex autoreview findings on #7946. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address round-3 review: shared live retargeting for all notify entrypoints - notification.create_for_caller: a preferred surface that moved out of the (stale, spawn-time) preferred workspace follows the surface to its current owner instead of falling back to the old workspace's focused pane — plain `cmux notify` from a moved pane hit the wrong pane. - notification.create_for_target / create_for_surface: resolve the surface's current owner before rejecting a stale workspace claim, so moved-pane deliveries retarget instead of erroring (matches the v1 notify_target guard fixed earlier; shared-behavior policy). - Pending-notification discard for a surface now always uses the canonical surface identity: a surface-scoped clear that raced the queue drain could leave a stale-keyed entry that re-delivered (resurrected) the notification right after the user dismissed it. - Regression tests for all three. Round-3 codex autoreview findings on #7946. Note: extends the fix to two sibling entrypoint files (TerminalNotificationCallerResolver.swift, TerminalController+ControlNotificationContext.swift) per the repo's shared-behavior policy — same bug class, same resolver path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address round-4 review: relay auth boundary, rebind discard, surface rehome - Revert live re-homing in notification.create_for_target: it is relay- reachable (RemoteDaemonProxyTunnel pins workspace_id to the relay's owner workspace), and the app-side membership guard is what confines a VM to its authorized workspace — a global surface lookup would allow cross-workspace injection from a leaked pane UUID. Moved-pane re-homing for relayed notifications is deferred until a trusted surface binding exists. Regression test pins the boundary. - notification.create_for_surface (local-only, not relay-reachable): re-home before BOTH rejects, including when the claimed routing workspace was closed, not just when it no longer lists the surface. - Restore exact enqueue-key semantics for the (tabId, surfaceId) discard used by rebindSurfaceNotifications: a surface-wide discard could drop a newer notification legitimately queued under the destination key during a pane move. Surface-scoped CLEARS now use the canonical by-surface discard through a dedicated helper (net-zero growth in the hard-capped store file). Regression tests for both semantics. Round-4 codex autoreview findings on #7946. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address round-5 review: authoritative surface in needs-input, SessionEnd scoping - PreToolUse AskUserQuestion/ExitPlanMode: when the resolver returned an authoritative live target, use its surface for the upsert, lifecycle, and needs-input notification instead of re-preferring the persisted session surface — a stale/closed record surface would re-pollute the record and pin the blocking prompt on the wrong pane. - SessionEnd: clear the resume binding on the live pane (and also on the record's surface when it differs, so a misfiled binding cannot survive), and scope the re-homed notification clear to the moved pane instead of wiping sibling panes in the destination workspace. - Regression tests: needs-input uses the resolved surface; re-homed SessionEnd clear is panel-scoped. Round-5 codex autoreview findings on #7946. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address round-6 review: env-only pid resolution must not be authoritative The inherited CMUX_SURFACE_ID is spawn-time evidence that can be leaked from the operator's focused pane (documented by testCodexHookOverridesLeakedEnvSurfaceWithProcessTTYBinding). When the controlling-tty lookup fails, promoting an env-only answer to an authoritative pid resolution could override a valid session record and recreate the wrong-pane bug. The env signal now only corroborates the unique kernel-tty match (extracted into the pure agentDeliveryTargetCombining with unit coverage); env-only refuses and the caller falls back to the legacy chain and re-home probes. Round-6 codex autoreview finding on #7946. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address PR review: async clear canonical identity, dead-workspace rehome priority - The async clear_notifications --tab --panel path (enqueueClearNotifications) still discarded pending deliveries by their enqueue-time key, leaving a stale-keyed entry to retarget and resurrect the cleared notification; it now discards by canonical surface identity like the store clear. Regression test added. - When the session record's workspace has died and the legacy chain falls back to the caller-tty workspace, the record surface's current owner now outranks that fallback: a stale tty row could otherwise mark an unrelated pane authoritative and skip the identity-surface re-home. Greptile PR review findings on #7946. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address Cursor review: SessionEnd staleness gate judges the pane being cleaned A record polluted to another agent's pane (#7391) whose own session is active there made SessionEnd's shouldApplyClaudeHookVisibleMutation gate look stale, skipping cleanup of the REAL pane — stranding its ring and status after exit. The gate now checks the live-resolved cleanup target (workspace + surface) instead of the consumed record's address; the two only differ in exactly the pollution case, where live is correct. Regression test sessionEndPollutedRecordStillClearsLivePane (foreign active session on the polluted record surface; cleanup must land on the live pid target). The SessionEnd/PreToolUse lifecycle tests move to a new ClaudeHookLifecycleCleanupTests.swift (wired into cmuxTests in project.pbxproj) to keep both suites under the 500-line file budget. Cursor Bugbot finding 3567171933 on #7946. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Add regression coverage for live-owner workspace clears * Address Cursor review: tab-wide clears resolve each pending entry's live owner A pending async notification queued under a stale claimed tabId DRAINS into the live workspace that owns its surface (#7939 retargeting), so a workspace-wide clear that matched only the enqueue key missed it and the notification reappeared right after the clear. Workspace-wide clears now discard by live delivery target: phase 1 snapshots the pending addresses (sequence + claimed key) under the bus lock, phase 2 resolves each entry's delivery target on the main actor (the same agentNotificationDeliveryTarget used at drain) and discards exactly the snapshotted sequences — entries enqueued between the phases are newer than the clear and deliberately survive. The v1 async clear_notifications --tab path stays enqueue-ordered: FIFO drains the stale entry into the live workspace BEFORE the clear barrier wipes it, so its end state was already clean (regression-pinned). The delivery extensions move from TerminalNotificationQueue.swift into TerminalNotificationLiveRetargetDelivery.swift (wired into the app target) to stay inside the file-length budget. Cursor Bugbot finding "Tab-wide clear misses stale queue" on #7946. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 2 个月前 | |
fix: require full-binding TTY uniqueness and suppress feed events on unresolved hooks - uniqueCallerTerminalBindingByTTY now requires every matching debug.terminals entry to agree on both workspace and surface, so a TTY reused across two panes of the same workspace no longer yields an arbitrary pane treated as the authoritative surface. resolveCallerSurfaceIdByTTY's no-provider branch (claude-hook surface resolution) uses the unique variant too; the non-hook fallback resolver and generic agent hooks intentionally keep first-match. - The unresolved no-op guards left didSendFeedTelemetry false, so the defer in runClaudeHook still pushed a session-feed event attributed to the raw, unvalidated workspace argument. The five guards without a prior telemetry send now mark telemetry handled before returning, making the no-op complete. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> | 3 个月前 | |
Resolve agent notification targets from live identity at delivery time (#7946) * Add failing regression tests for wrong-pane notification attribution (#7939) Two Claude agents in different workspaces must never see a turn-complete notification, unread ring, or status pill land on the other agent's pane: - CLI: stop must prefer the live agent-pid target over a polluted session record (#7391 drift) and heal the record; a moved pane's notification must follow the surface to its current workspace (#5781); SessionStart must not be poisoned by a stale debug.terminals tty row; legacy routing must survive an app without the resolver method. - App: a queued or synchronously delivered notification addressed with a stale workspace id but a live surface id must be retargeted to the surface's current workspace at delivery time instead of being dropped (async) or misfiled (sync). These tests fail on main; the fix lands in the follow-up commit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Resolve agent notification targets from live identity at delivery time (#7939) One authoritative hook-event -> live surface -> current pane/workspace resolution, shared by the CLI and the app: App: new `agent.resolve_delivery_target` control method backed by AgentDeliveryTargetResolution.swift. A `{pid}` probe resolves the pane that owns the agent process RIGHT NOW from two independent live signals (the process's controlling tty matched against surface pty devices, and the process's own stable CMUX_SURFACE_ID environment re-homed through workspaceContainingPanel); disagreement or ambiguity refuses to guess. A `{surface_id}` probe returns the workspace that currently hosts a known surface. The same resolver now retargets every in-app delivery path: queued notifications follow their surface to its current workspace instead of being dropped on a stale workspace claim, the sync notify path records under the surface's current workspace instead of misfiling, and notification click-through re-homes at click time. CLI: Claude hook routing goes through resolveClaudeHookDeliveryTarget, which puts live process identity above every persisted or spawn-time claim: live pid target first (beats a polluted session record - the issue #7391 resume/tty drift class - and heals it via the existing upserts and active-pointer self-heal), then the #7228 legacy chain unchanged, then moved-pane re-home (issue #5781 class) when the identity surface is no longer listed in the resolved workspace. Explicit --workspace/--surface flags bypass the probes, per-tool PreToolUse skips them for cheapness, and an app without the method degrades to the legacy chain exactly as before. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address review findings: pid_t overflow, stale queue keys, same-workspace rehome - agent.resolve_delivery_target: convert the caller-supplied pid with pid_t(exactly:) so an out-of-range 64-bit value degrades to the surface/workspace probes instead of trapping (socket-reachable crash). - Sync notification delivery: discard superseded pending notifications by their canonical identity (the surface) so an entry queued under a stale claimed workspace key cannot survive retargeting and duplicate/replace the newer notification. - Claude hook rehome: apply the app's identity-surface ownership answer even when the owning workspace is unchanged — a confirmed identity surface outranks the focused-surface fallback in the same workspace. - Regression tests for all three. Review findings from codex autoreview, Cursor Bugbot, Greptile, CodeRabbit on #7946. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address round-2 review: relay pid namespace, PreToolUse rehome, SessionEnd cleanup - Skip the live agent-pid probe on relay-backed socket connections: a hook running on an SSH/cloud host carries a remote pid that must not be resolved against the Mac's local process table. UUID-based probes and the legacy chain still apply. - Split allowsLiveProbe into allowsPidProbe: PreToolUse still skips the per-tool pid/tty scan, but the cheap {surface_id} re-home probe stays enabled so a mid-turn pane move cannot make PreToolUse mutate (and re-record via upsert) the old workspace's focused pane. - Route SessionEnd cleanup through the live target resolver: clear status/pid/notifications on the workspace that owns the pane NOW, not the consumed record's stale workspace (which also wiped unrelated panes' notifications there). Fork-parent cleanup uses the shared resolver too. - Harness regression tests for the SessionEnd and PreToolUse paths. Round-2 codex autoreview findings on #7946. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address round-3 review: shared live retargeting for all notify entrypoints - notification.create_for_caller: a preferred surface that moved out of the (stale, spawn-time) preferred workspace follows the surface to its current owner instead of falling back to the old workspace's focused pane — plain `cmux notify` from a moved pane hit the wrong pane. - notification.create_for_target / create_for_surface: resolve the surface's current owner before rejecting a stale workspace claim, so moved-pane deliveries retarget instead of erroring (matches the v1 notify_target guard fixed earlier; shared-behavior policy). - Pending-notification discard for a surface now always uses the canonical surface identity: a surface-scoped clear that raced the queue drain could leave a stale-keyed entry that re-delivered (resurrected) the notification right after the user dismissed it. - Regression tests for all three. Round-3 codex autoreview findings on #7946. Note: extends the fix to two sibling entrypoint files (TerminalNotificationCallerResolver.swift, TerminalController+ControlNotificationContext.swift) per the repo's shared-behavior policy — same bug class, same resolver path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address round-4 review: relay auth boundary, rebind discard, surface rehome - Revert live re-homing in notification.create_for_target: it is relay- reachable (RemoteDaemonProxyTunnel pins workspace_id to the relay's owner workspace), and the app-side membership guard is what confines a VM to its authorized workspace — a global surface lookup would allow cross-workspace injection from a leaked pane UUID. Moved-pane re-homing for relayed notifications is deferred until a trusted surface binding exists. Regression test pins the boundary. - notification.create_for_surface (local-only, not relay-reachable): re-home before BOTH rejects, including when the claimed routing workspace was closed, not just when it no longer lists the surface. - Restore exact enqueue-key semantics for the (tabId, surfaceId) discard used by rebindSurfaceNotifications: a surface-wide discard could drop a newer notification legitimately queued under the destination key during a pane move. Surface-scoped CLEARS now use the canonical by-surface discard through a dedicated helper (net-zero growth in the hard-capped store file). Regression tests for both semantics. Round-4 codex autoreview findings on #7946. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address round-5 review: authoritative surface in needs-input, SessionEnd scoping - PreToolUse AskUserQuestion/ExitPlanMode: when the resolver returned an authoritative live target, use its surface for the upsert, lifecycle, and needs-input notification instead of re-preferring the persisted session surface — a stale/closed record surface would re-pollute the record and pin the blocking prompt on the wrong pane. - SessionEnd: clear the resume binding on the live pane (and also on the record's surface when it differs, so a misfiled binding cannot survive), and scope the re-homed notification clear to the moved pane instead of wiping sibling panes in the destination workspace. - Regression tests: needs-input uses the resolved surface; re-homed SessionEnd clear is panel-scoped. Round-5 codex autoreview findings on #7946. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address round-6 review: env-only pid resolution must not be authoritative The inherited CMUX_SURFACE_ID is spawn-time evidence that can be leaked from the operator's focused pane (documented by testCodexHookOverridesLeakedEnvSurfaceWithProcessTTYBinding). When the controlling-tty lookup fails, promoting an env-only answer to an authoritative pid resolution could override a valid session record and recreate the wrong-pane bug. The env signal now only corroborates the unique kernel-tty match (extracted into the pure agentDeliveryTargetCombining with unit coverage); env-only refuses and the caller falls back to the legacy chain and re-home probes. Round-6 codex autoreview finding on #7946. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address PR review: async clear canonical identity, dead-workspace rehome priority - The async clear_notifications --tab --panel path (enqueueClearNotifications) still discarded pending deliveries by their enqueue-time key, leaving a stale-keyed entry to retarget and resurrect the cleared notification; it now discards by canonical surface identity like the store clear. Regression test added. - When the session record's workspace has died and the legacy chain falls back to the caller-tty workspace, the record surface's current owner now outranks that fallback: a stale tty row could otherwise mark an unrelated pane authoritative and skip the identity-surface re-home. Greptile PR review findings on #7946. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address Cursor review: SessionEnd staleness gate judges the pane being cleaned A record polluted to another agent's pane (#7391) whose own session is active there made SessionEnd's shouldApplyClaudeHookVisibleMutation gate look stale, skipping cleanup of the REAL pane — stranding its ring and status after exit. The gate now checks the live-resolved cleanup target (workspace + surface) instead of the consumed record's address; the two only differ in exactly the pollution case, where live is correct. Regression test sessionEndPollutedRecordStillClearsLivePane (foreign active session on the polluted record surface; cleanup must land on the live pid target). The SessionEnd/PreToolUse lifecycle tests move to a new ClaudeHookLifecycleCleanupTests.swift (wired into cmuxTests in project.pbxproj) to keep both suites under the 500-line file budget. Cursor Bugbot finding 3567171933 on #7946. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Add regression coverage for live-owner workspace clears * Address Cursor review: tab-wide clears resolve each pending entry's live owner A pending async notification queued under a stale claimed tabId DRAINS into the live workspace that owns its surface (#7939 retargeting), so a workspace-wide clear that matched only the enqueue key missed it and the notification reappeared right after the clear. Workspace-wide clears now discard by live delivery target: phase 1 snapshots the pending addresses (sequence + claimed key) under the bus lock, phase 2 resolves each entry's delivery target on the main actor (the same agentNotificationDeliveryTarget used at drain) and discards exactly the snapshotted sequences — entries enqueued between the phases are newer than the clear and deliberately survive. The v1 async clear_notifications --tab path stays enqueue-ordered: FIFO drains the stale entry into the live workspace BEFORE the clear barrier wipes it, so its end state was already clean (regression-pinned). The delivery extensions move from TerminalNotificationQueue.swift into TerminalNotificationLiveRetargetDelivery.swift (wired into the app target) to stay inside the file-length budget. Cursor Bugbot finding "Tab-wide clear misses stale queue" on #7946. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 2 个月前 | |
Drain hook stdin before neutral exits (#8863) * Test Codex disabled hook stdin drainage * Drain agent hook stdin before no-op exit * Test Codex hook script overwrite isolation * Isolate generated Codex hooks by content * Test content-addressed hook sanitization * Sanitize content-addressed Codex hooks * Test embedded hook path preservation * Share immutable Codex hook names * Test spaced Codex hook paths * Recognize spaced generated hook paths * Test generated hook ownership boundaries * Fail closed on generated hook ownership * Test compound hook command preservation * Reject shell syntax in generated hook paths * Test escaped hook command preservation * Reject escaped generated hook commands * Test multi-token hook command preservation * Recognize complete Codex hook injection block * Test legacy Codex hook schema stripping * Share versioned Codex hook injection schemas * Document Codex hook schema API | 2 个月前 | |
Add native iPhone and iPad Simulator panes (#7857) * tighten simulator shortcut and mutation paths * Harden simulator operation commit boundaries * Close simulator routing and deadline races * Reconcile simulator mutations during teardown * Preserve simulator caller routing context * Route ios commands from caller pane * Preserve explicit simulator routing and input recovery * Serialize simulator text recovery * Align simulator deadlines and selection rollback * Close simulator lifecycle commit races * Reject stale simulator discovery results * Bound simulator re-enable and batch capture * Select the integrated simulator display * Close simulator transition races * Gate simulator automation on readiness * Finish simulator selection generation checks * Bound simulator context work end to end * Verify simulator descendant identities * Validate simulator process ancestry * Bound simulator process shutdown * Supervise simulator command groups * Supervise simulator pane sessions * Contain every simulator subprocess * Test simulator routing and feature flag regressions * Fail closed on stale simulator state * Test simulator lifecycle review regressions * Bound simulator control lifecycles * Test simulator cross-pane ownership regressions * Serialize simulator cross-pane mutations * Test Web Inspector cross-worker ownership * Lease Web Inspector targets across workers * Test Web Inspector stale occupancy handoff * Refresh Web Inspector occupancy during handoff * Test Web Inspector occupancy timeout * Fail closed on incomplete Inspector occupancy * Test Inspector census and release regressions * Close Inspector refresh and release races * Test stale location route teardown * Preserve location route ownership through teardown * Test Simulator launch environment privacy * Test route commit during device switch * Test feature flag telemetry consent * Own Simulator mutations through teardown * Harden Simulator isolation and ownership * Persist Simulator mutation ownership across processes * Honor telemetry consent for remote flags * Preserve failed Simulator cleanup ownership * Propagate Simulator CLI routing errors * Fix Simulator operation task syntax * Inject Simulator ownership and keep context read-only * Resolve restored Simulator context without booting * Test late Simulator display identity publication * Attach Simulator callbacks before display discovery * Test Simulator mutation ownership boundaries * Harden Simulator mutation ownership semantics * Test current Simulator default-screen contract * Support current Simulator default-screen metadata * Isolate Simulator camera transport tests * Test forwarded Simulator screen metadata * Support forwarded Simulator screen metadata * Align Simulator overlay lifecycle test with visibility * Bound Simulator recovery assertion by time * Make Simulator input recovery test deterministic * Test Simulator landscape framebuffer direction * Correct Simulator landscape presentation direction * Bound Simulator frame publication test wait * Register Simulator replay state before delivery * Test Simulator review boundary cases * Test iOS screenshot surface identity errors * Normalize Simulator control boundaries * Isolate Simulator CLI contract environment * Test native Simulator orientation dialects * Unify native Simulator orientation semantics * Test landscape Simulator digitizer coordinates * Map landscape input into native digitizer space * Test stable Simulator app switcher hold * Hold app switcher gesture stationary * Test Simulator app switcher button timing * Open Simulator app switcher with double Home * Test installed iPad DeviceKit chrome fallback * Test bounded Simulator frame publication * Scale Simulator frames to pane geometry * Test Simulator frame ring replacement cleanup * Release obsolete Simulator frame rings * Route IndexNow jobs through configured runner * Remove wall-clock assertions from RPC event tests * Test frame ring adoption race * Retire Simulator frame rings after host adoption * Keep frame completion on MainActor * Snapshot Simulator activity log before lazy layout * Regenerate webview assets after main merge * Test Simulator core readiness ordering * Stream Simulator before optional capability probes * Test control-socket Simulator selection ownership * Exclude active Simulator control action from teardown * Test natural DeviceKit chrome cap geometry * Preserve native DeviceKit chrome artwork geometry * Fix design mode test payload shadowing * Make Simulator replay tests signal-driven * Fix Simulator pane test client conformance * Test immediate Simulator context discovery * Discover Simulator before context reads * Test Simulator production edge cases * Close Simulator production review findings * Fix Simulator integration test fixtures * Fix Simulator CLI routing call site * Fix Simulator focus test fixtures * Fix Simulator app test fixtures * Test Simulator capability hydration readiness * Wait for Simulator capability hydration * Test Simulator review edge cases * Close Simulator production review gaps * Avoid recursive Simulator picker comparison * Isolate Simulator picker observation * Test Simulator application row snapshots * Snapshot Simulator application picker rows * Test static Simulator frame presentation * Drive Simulator frames without display callbacks * Test Simulator visibility remounts * Keep Simulator frames through host remounts * Isolate Simulator visibility regression suite * Test Simulator frame pacing under input load * Pace Simulator framebuffer readback * Localize project surface labels * Test Camera Injector header cache identity * Invalidate Camera Injector cache for headers * Test Simulator RPC capability discovery * Advertise Simulator RPC capabilities * test(simulator): cover interactive frame priority * fix(simulator): prioritize frames after pointer input * test(simulator): cover native tap hold duration * fix(simulator): hold synthetic taps long enough for iPadOS * Test immediate Simulator frame presentation * Present Simulator frames without an extra tick * Test failed Simulator ownership publication * Reject unsafe Simulator ownership claims * test(simulator): cover framebuffer lifecycle bounds * fix(simulator): bound framebuffer lifecycle work * test(simulator): cover review lifecycle regressions * fix(simulator): close review lifecycle gaps * test(simulator): cover routing pacing and consent * fix(simulator): scope routing pacing and consent * test(simulator): cover screenshot and cached log readiness * fix(simulator): prepare capture without eager lifecycle work * test(simulator): report capture-ready live state * fix(simulator): report live capture-ready state * test(simulator): cover control-plane and frame wakeups * fix(simulator): signal frames and preserve errored flag cache * test(simulator): cover publication wakeup races * fix(simulator): bound publication wakeups * test(simulator): cover tool editor shortcut focus * fix(simulator): preserve tool editor focus ownership * test(simulator): cover flag omission and runner injection * fix(simulator): inject async owned command execution * test(simulator): cover file drop proposal readiness * fix(simulator): validate file drop proposals * test(simulator): cover compound inspector cleanup failure * fix(simulator): preserve failed inspector cleanup state * test(simulator): cover device-scoped tool state * fix(simulator): scope tool state to selected device * test(simulator): cover final release blockers * fix(simulator): close final release blockers * test(simulator): make frame scheduling assertions deterministic * test: update Ghostty surface config ABI lock * fix(simulator): clear final build gates * fix(build): import Dock lifecycle workspace types * test(web): isolate feedback route environment * fix(build): disambiguate Dock snapshot types * test(simulator): cover review ownership blockers * fix(simulator): scope camera cleanup ownership * fix(build): make resume policy returns explicit * test(simulator): cover camera cleanup ownership retries * fix(simulator): preserve camera cleanup ownership * fix(build): clear latest main gates * test(simulator): cover final review blockers * fix(simulator): await quit cleanup and index targets * refactor(simulator): satisfy production policy * test(simulator): cover camera cleanup on device switch * fix(simulator): clean camera state before device switch * test(simulator): retain quit cleanup after panel removal * fix(simulator): make quit await durable rollback * test(simulator): cover retained cleanup recovery * fix(simulator): recover retained camera cleanup * test(simulator): cover cleanup side effects * fix(simulator): restore external cleanup state * refactor(simulator): split camera authorization record * test(web): respect delegated discovery order * test(ios): assert transition math deterministically * fix(ci): repair current-main Swift integration * fix(ci): return closed workspace restore result * test(simulator): cover final review regressions * fix(simulator): close final lifecycle gaps * test(simulator): cover review lifecycle findings * fix(simulator): resolve review lifecycle findings * test(simulator): cover durable recovery journals * fix(simulator): persist mutation recovery journals * refactor(simulator): inject durable recovery paths * test(simulator): cover durable journal transitions * fix(simulator): make recovery transitions crash consistent * test(simulator): cover recovery compatibility gaps * fix(simulator): preserve recovery compatibility * test(simulator): cover recovery ownership handoff * fix(simulator): gate recovery ownership handoff * test(simulator): cover duplicate camera journals * fix(simulator): suppress stale durable camera journals * test(simulator): cover journal reconciliation races * fix(simulator): serialize journal reconciliation * test(simulator): cover identical journal paths * fix(simulator): normalize camera journal paths * test(simulator): cover journal URL hints * fix(simulator): compare normalized journal paths * refactor(simulator): split legacy route fixture * test(simulator): observe journal lock contention | 2 个月前 | |
CmuxFoundation: dissolve namespace-enums into value types / owning-type members (#6128) Remove every caseless namespace-enum in CmuxFoundation (the lint:allow namespace-type suppressions), giving each type genuine instance surface per the owner ruling. Logic, Defaults keys, file paths, and notification names are byte-identical; this is a shape change only. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> | 3 个月前 | |
Move diff viewer backend boundary to a Rust sidecar (#7804) * Add Rust diff viewer sidecar * Harden diff sidecar request handling * Close sidecar review gaps * Finish sidecar build and retry integration * Gate sidecar transport and webview checks * Remove sidecar setup and localization gaps * Extract diff sidecar process boundary * Use stdio for native diff sidecar transport * Satisfy Swift file length guard * Make custom scheme test deterministic * Address sidecar review findings * Test incremental diff tree source reuse * Make diff tree streaming linear * Verify diff correctness and streaming performance * Fix diff sidecar review regressions * Harden diff sidecar stdio RPC * Test bounded large diff rendering * Bound large diff UI updates * Harden large diff navigation * Fix diff sidecar isolation warning * Test mobile diff drawer close control * Make mobile diff drawer opaque * Harden mobile diff drawer dismissal * Refactor diff viewer bridge ownership * Preserve diff sidecar pipe ownership * Load diff sessions lazily through Rust * Keep Rust diff sessions alive while rendering * Split diff sidecar helpers from legacy files * Close diff sessions before page navigation * Close diff sessions before navigating * Track active diff sessions through navigation * Refresh generated diff viewer bundle * Keep diff source switching responsive * Open typed diff sessions in place * Update diff CLI file budget * Extract typed diff viewer writer * Build typed diff writer in CLI target * Expose shared diff shortcut payload * Share typed diff writer model types * Allow typed diff fallback input replacement * Open diff loading shell before asset setup * Bound typed branch base resolution * Avoid duplicate diff theme registration * Test custom-scheme asset fetch decoding * Decode deflated assets for diff scheme * Test cancellation of stale diff streams * Cancel stale diff sessions and cap patch writes * test: cover diff sidecar review regressions * fix: bound diff sidecar lifecycle * test: cover sidecar cancellation cleanup * fix: clean up cancelled sidecar process groups * test: require race-free sidecar process groups * fix: handshake sidecar process group startup * test: cover cancellation after patch rename * fix: retain cleanup ownership through registration * fix: bound sidecar startup and shutdown * test: cover branch picker repository switches * fix: close final sidecar lifecycle gaps * test: cover same-repo branch base changes * fix: preserve process group identity through shutdown * Make stale branch picker test state-driven * Test Last Turn switching and abandoned sidecar sessions * Keep typed diff sources and manifests recoverable * Test typed diff selector composition * Compose typed diff selector state * Rebuild diff webview assets * Test orphan cleanup and Last Turn repo switching * Close typed diff lifecycle gaps * Test pending cancellation and rotating orphan cleanup * Bound pending and remote diff resources * Cap sidecar queue and index temp cleanup * Bound server sessions and retain patch ownership * Make patch ownership and HTTP encoding durable * Test empty branch base selection * Keep empty branch and pending patch recovery available * Test branch base survives source switching * Preserve selected branch base across source switches * Retain generated patch ownership until lifecycle cleanup * Serialize token session publication * Keep concurrent diff sessions independently owned * Reconcile session cleanup with manifest lifecycle * Make session publication cancellation safe * Scope cancellation and close transactions correctly * Authorize session close by manifest ownership * Close discarded diff sessions safely * Cancel superseded diff sessions safely * Reserve diff session resources atomically * Protect active diff session patches * Preserve active typed diff sessions * Lease active diff sidecar sessions * Journal diff session resource ownership * Bound diff session recovery artifacts * Harden diff sidecar production artifact * Fix POSIX lock calls on Xcode 26.5 * Fix app-side lease locking on Xcode 26.5 * test: cover typed diff direct page lifecycle * fix: open typed diff session page directly * Fix sidecar verification for spaced paths | 2 个月前 | |
Trim release bundle size (#7589) * Trim release bundle size * Fix compressed markdown asset loading * Prefer deflated diff viewer assets * Split compressed asset helpers * Use failable deflated fixture decoding | 2 个月前 | |
Add smooth Vim and Emacs viewer navigation (#7921) * Add smooth Vim and Emacs viewer navigation * Fix Markdown viewer key routing and scroll step * Add Vim diff file navigation * Fix viewer navigation review findings * Fix viewer navigation test module import * Remove unavailable CLI test dependency * Reset Markdown smooth scroll after manual input * Reset smooth scroll for native navigation keys * Fix viewer shortcut context and chord stability * Fix command palette context availability * Fix viewer shortcut context routing * Route viewer shortcuts through native context * Navigate from visible diff file * Cache viewer bindings and preserve search input * Preserve editable Markdown input * Reset smooth target before file jumps * Extract viewer navigation helpers * Wire viewer helpers into app target * Route shortcuts in live remote diffs * Confirm live diff viewer page identity * Reset diff identity on navigation * Isolate diff viewer focus identity * Track isolated editable focus deeply * Align palette shortcut visibility context * Route all viewer key entrypoints safely * Scope viewer keys to focused webview * Split CmuxWebView support helpers * Import shortcut settings in viewer tests * Test inactive diff viewer URL trust * Trust only active diff viewer sessions * Test live HTTP diff viewer trust * Register live HTTP diff viewer sessions * Cache trusted viewer state off key path * Test cancelled diff navigation state * Restore viewer state after cancelled navigation * Close viewer navigation ordering gaps * Preserve diff search focus state * Handshake viewer navigation readiness * Test live diff viewer trust renewal * Renew active diff viewer trust * Fix merged command palette weak capture * Split viewer navigation support types | 2 个月前 | |
Custom sidebars: in-process renderer by default, Settings section, worker resize pump fix (#5867) * Add customSidebars.renderer setting (remote | inProcess, JSON-backed) New catalog section customSidebars with a JSON-backed renderer key (~/.config/cmux/cmux.json: { "customSidebars": { "renderer": "inProcess" } }), defaulting to the crash-isolated remote worker. Unknown raw values fall back to the safe default; covered by store-level behavior tests. Part of the sidebar vibe-coding architecture program (spike 2: in-process mount + containment + renderer flag). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Contain pathological sidebar sources with an evaluation node budget RecursionBudget grows a second axis: total produced RenderNodes (default 3000, an order of magnitude above a rich real sidebar). ForEach loops and ViewBuilder walks early-out once tripped, and the top-level evaluate returns nil for a truncated walk so the host's existing last-good-sticky publish keeps the previous render up instead of flashing a partial tree. A pathological ForEach(0..<100_000) now trips in milliseconds instead of handing SwiftUI a 100k-node tree that freezes the host. Covered by behavior tests at the interpreter level (nil + speed bound + no false trip at 400 rows) and at the publish level (CustomSidebarModel keeps the last good render when a saved edit trips the budget). Part of the sidebar vibe-coding architecture program (spike 2). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Mount custom sidebars through CustomSidebarSurface, switchable in-process CustomSidebarSurface is the single mount seam: it renders the selected custom sidebar through the out-of-process worker by default and mounts the previously never-used in-process CustomSidebarView when customSidebars.renderer is inProcess, switching live when the setting changes. In-process gains native input (hover, focus, keyboard) and same-frame resize for trusted local files; remote stays the containment lane and the default. ContentView reads the flag with @LiveSetting per main-window convention; the surface itself stays settings-agnostic so the package needs no settings dependency and tests can drive both branches. Documented in docs/custom-sidebars.md. Part of the sidebar vibe-coding architecture program (spike 2). This is the mount the live-eval engine (tier 1) lands on. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * SPIKE STUB (not for merge): textField RenderNode kind to prove input fidelity Lowers TextField("placeholder", text: $name) to a .textField node and renders it in-process as a real SwiftUI TextField backed by view-local @State. The static IR has no binding concept, so the typed value never round-trips into the interpreter environment; this exists purely to demonstrate that the in-process mount delivers native focus/caret/typing where the remote worker cannot. The real binding story is the live-eval engine (spike 1 of the program). Accepts the SwiftViewInterpreter.swift length-budget growth (669 -> 695) for the spike. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Render worker: timestamped debug instrumentation for geometry/repaint timing Adds CMUX_RENDER_WORKER_DEBUG-gated timing logs to the sidebar render worker: geometry application, rootView republish, and pump commits now log CACurrentMediaTime timestamps and pump duration. No behavior change. This makes the resize repaint lag measurable: with only this commit, a resize message logs "geometry applied" and a pump, but the visible repaint (the next "rootView republished" + pump) only appears when the next scene tick arrives, up to a full second later. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Render worker: display-link pump + immediate geometry invalidation Fixes the 1-3 s drag-resize repaint lag in remotely rendered custom sidebars. Two changes in the worker (CmuxSidebarRemoteRender): 1. The geometry handler now republishes rootView before its pump. Resizing the hosting view only marks AppKit layout dirty; SwiftUI's own render update waits for display-cycle work that never runs in the never-ordered window, so the old pump committed a stale tree and the visible repaint rode the host's next 1 s scene tick. 2. A display-refresh-driven pump (NSScreen.displayLink, macOS 14+, the non-deprecated CVDisplayLink replacement) commits invalidations that arrive between host messages. RemoteWorkerHostingView and RemoteWorkerWindow forward needsLayout/needsDisplay/viewsNeedDisplay flips into a RenderPumpGate; dirtiness resumes the paused link, each tick pumps at most once, and the first clean tick re-pauses it, so an idle worker has zero periodic wakeups (no timers, no polling). Geometry republishes reuse the cached interpretation and the displayed state, so a resize during a broken on-disk save keeps the last-good sticky render instead of flipping to an error state. Behavior tests cover the gate: arm/coalesce/pump/pause transitions and commit absorption of invalidations raised during a pump. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Render worker: park the display link at pump completion A pump's own layout work re-marks the hosting view dirty mid-commit, which resumed the link for one throwaway clean tick after every pump. Pausing directly in pumpCompleted() makes the idle worker truly wakeup-free between host messages. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Settings UI: Custom Sidebars section with enable toggle and renderer picker New settings section between Sidebar and Beta Features. The toggle binds to the existing betaFeatures.customSidebars defaults key (same gate as the Beta Features row); the picker binds to the customSidebars.renderer JSON key (remote | inProcess) through JSONValueModel and is disabled while custom sidebars are off. Search: section keywords, two curated entries, and the row-anchor contract lists updated. 10 new localized strings (en + ja). CmuxSettingsUI tests 30/30 green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Wire Custom Sidebars settings section into navigation, search, and CLI App-side SettingsNavigationTarget gains the customSidebars case (title, symbol, search text, alias, two setting entries, customSidebars.renderer path anchor) so settings search and socket navigation reach the new section, and the CLI accepts 'cmux settings open custom-sidebars'. Verified on the tagged inproc build: the command opens Settings scrolled to the section with the toggle and renderer picker rendered. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Default custom sidebars beta to on customSidebars.beta.enabled now defaults true. The catalog default is the single source of truth (readers fall back to key.defaultValue), so no other code changes. Users who toggled it off keep their stored false. Docs updated to describe the off switch instead of opt-in. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Revert "SPIKE STUB (not for merge): textField RenderNode kind to prove input fidelity" This reverts commit c24ada3362f37a211bead53ba73b64e3306237ba. * Default custom sidebars to the in-process renderer customSidebars.renderer now defaults to inProcess: native input (hover, focus, keyboard) and same-frame resize out of the box. The remote worker stays one settings flip away as the containment lane for untrusted sources; an explicit "remote" in cmux.json is honored unchanged. Renderer tests updated to the new default (72 green), docs and DocC flipped to match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Fix CustomSidebarSurface for window-owned worker client after main merge Threads the client binding from main's instant-remount change (PR 5864) through the surface seam, and defaults rendersInProcess to true to match the new renderer default. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Accept file-length budget growth for renderer default + settings section SwiftViewInterpreter 669->683 (node-budget containment), SettingsNavigation 589->599 (customSidebars nav case + search entries), SettingsWindowScene 523->531 (section mount), ContentView 19248->19256 (renderer flag wiring). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 3 个月前 | |
https://github.com/manaflow-ai/cmux/issues/3586 Finding 7: Retire Codex hook monitors (#3589) * Prevent orphaned Codex monitor processes Codex transcript monitors were launched as detached helper processes with only transcript parsing or a four-hour deadline to end their lifetime. Tie each monitor to an explicit turn lease, retire that lease from Stop/SessionEnd, and make the monitor leave when the owning socket/workspace/surface disappears. Constraint: macOS has no PR_SET_PDEATHSIG, and the monitor must outlive the prompt-submit hook process long enough to observe transcript failures. Rejected: Shorter monitor timeout | still permits orphan helpers after a completed turn. Rejected: Parent-PID death checks | the prompt-submit parent exits immediately by design. Confidence: medium Scope-risk: narrow Directive: Keep detached hook helpers tied to an explicit lifecycle owner; do not add long-running hook children without a retirement signal. Tested: git diff --check Not-tested: Local test execution per instruction; tagged reload build/launch runs after push. * Bound memory growth from stale surfaces and hidden priming The memory audit split into two bounded app-side leaks: V2 browser state was retained after surface teardown, and background workspace priming mounted hidden keepAllAlive terminal tabs just to run a SwiftUI task. This centralizes per-surface cleanup and moves priming off-screen while limiting it to the terminal tabs that would be visible if the workspace were selected. Constraint: Background terminal readiness should remain available without mounting every hidden tab view. Rejected: Keep the 0.001 opacity priming path | it materializes hidden terminal surfaces and recreates renderer/io thread triples while idle. Confidence: medium Scope-risk: moderate Directive: Do not re-pin pending background workspaces in the SwiftUI mounted workspace set without measuring idle thread and footprint growth. Tested: git diff --check; Python compile for tests_v2/test_background_workspace_idle_thread_footprint.py; ./scripts/reload.sh --tag issue-3586-memory-audit Not-tested: Local E2E/socket regression execution; repo policy routes those through CI or tagged app harnesses. * Keep Codex transcript monitors tied to live owners Review feedback exposed three ways transcript monitors could outlive their intended owner: turn-scoped stop events also retired unscoped leases, owner checks were a blocking socket round trip on every wait loop, and prompt-submit still spawned a detached monitor when lease creation failed. This keeps turn matching exact, makes owner checks short and periodic, requires a lease before spawning, and hardens the regression cleanup path. Constraint: Monitor liveness still needs to notice closed surfaces without adding recurring five-second stalls to the idle loop. Rejected: Keep per-loop owner RPCs with a longer timeout | it preserves correctness but makes every monitor iteration vulnerable to socket stalls. Confidence: medium Scope-risk: narrow Directive: Do not start a Codex transcript monitor from prompt-submit unless it has a lease that Stop/session-end can retire. Tested: git diff --check; python3 -m py_compile tests/test_codex_feed_hooks.py; ./scripts/reload.sh --tag issue-3586-cmux-app-memory-audit Not-tested: Local E2E/socket regression execution; repo policy routes those through CI or tagged app harnesses. * Keep monitor fixes within Swift file budgets The CI file-length guard rejected the accumulated Workspace and monitor-test growth. This keeps the behavior from the monitor ownership fixes but folds the background priming selector down, keeps the monitor test socket responses compact, and inlines the debug-stress broad start path at its only remaining call site. Constraint: CI enforces per-file Swift length budgets and should not be bypassed for this focused monitor/memory fix. Rejected: Refresh the file-length budget | the growth was local enough to reduce without accepting debt. Confidence: high Scope-risk: narrow Tested: python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv; git diff --check; python3 -m py_compile tests/test_codex_feed_hooks.py; ./scripts/reload.sh --tag issue-3586-cmux-app-memory-audit Not-tested: Local E2E/socket regression execution; repo policy routes those through CI or tagged app harnesses. * Preserve Codex hook responses when leases fail Lease creation failure should suppress detached monitor startup, but the hook still has to reach its normal JSON stdout response. Keeping the monitor start behind an if-let preserves the no-lease/no-monitor invariant without returning early from runGenericAgentHook. Constraint: Codex hook callers expect a JSON response on stdout even when optional monitor setup fails. Rejected: guard-return on lease failure | skips the protocol response and can make the caller hang or fail. Confidence: high Scope-risk: narrow Directive: Keep monitor lease failure non-fatal to hook output; never return before the final hook response solely because optional monitor setup failed. Tested: git diff --check; python3 -m py_compile tests/test_codex_feed_hooks.py; python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv; ./scripts/reload.sh --tag issue-3586-cmux-app-memory-audit Not-tested: Local E2E/socket regression execution; repo policy routes those through CI or tagged app harnesses. * Keep relay-backed Codex monitors alive across polls Relay socket clients close their TCP connection after each request, so a later owner-liveness poll can see socketFD == -1 even though the relay endpoint is still available. Reconnecting relay clients inside the liveness probe lets the following surface.list request reuse a fresh authenticated connection while leaving Unix socket polling behavior unchanged. Constraint: Relay-backed SocketClient instances intentionally close after send, unlike long-lived Unix socket clients. Rejected: Remove the liveness probe entirely | would widen Unix-socket failure handling instead of fixing the relay-specific stale-FD case. Confidence: high Scope-risk: narrow Directive: Keep relay reconnect behavior paired with per-request close semantics; do not treat socketFD == -1 as owner loss for relay endpoints without attempting reconnect. Tested: git diff --check; python3 -m py_compile tests/test_codex_feed_hooks.py; python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv; ./scripts/reload.sh --tag issue-3586-cmux-app-memory-audit Not-tested: Local E2E/socket regression execution; repo policy routes those through CI or tagged app harnesses. * Keep Codex monitors through transient owner checks Owner liveness now distinguishes confirmed owner loss from an inconclusive surface.list call. A closed socket or successful empty/missing owner list still stops the monitor, but a transient RPC timeout no longer kills an active transcript monitor before it can inspect and publish terminal transcript state. Lease pruning is also best-effort so stale cleanup cannot prevent the primary lease write. Constraint: Owner checks use a short timeout and can race transient app startup or busy-loop delays. Rejected: Treat every surface.list error as owner loss | a 1-second timeout can be transient and should not permanently silence an active Codex session. Rejected: Let prune failure abort lease creation | cleanup is non-essential compared with preventing detached monitors. Confidence: high Scope-risk: narrow Directive: Only confirmed owner-gone states should stop the monitor; keep transient RPC failures bounded by the 4-hour monitor deadline rather than immediate exit. Tested: git diff --check; python3 -m py_compile tests/test_codex_feed_hooks.py; python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv; ./scripts/reload.sh --tag issue-3586-cmux-app-memory-audit Not-tested: Local Python socket regression execution; repo policy routes socket tests through CI/tagged harnesses. * Keep background priming and Codex lease cleanup bounded Stop hooks now retire Codex monitor leases only when Codex provides an explicit turn id, leaving session-wide leases for SessionEnd. Background workspace priming no longer bridges cancellation through a retained continuation; it uses a bounded cancellation-aware wait loop and only primes terminal panels selected in visible panes. The hook and idle-budget tests cover the new Stop behavior and clarify failure output. Constraint: SwiftUI .task(id:) cancels prior background-prime tasks when the pending workspace set changes. Constraint: Stop without a turn id must not act like SessionEnd for Codex monitor leases. Rejected: Keep observer-backed checked continuation and add cancellation plumbing | polling for at most two seconds deletes the retained observer/subscription path entirely. Rejected: Fall back to focused or first terminal for background priming | that can load hidden terminals when visible panes are non-terminal. Confidence: high Scope-risk: moderate Directive: Keep background priming tied to visible terminal pane targets; do not reintroduce hidden-terminal fallback startup without a resource budget test. Tested: git diff --check; python3 -m py_compile tests/test_codex_feed_hooks.py tests_v2/test_background_workspace_idle_thread_footprint.py; python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv; ./scripts/reload.sh --tag issue-3586-cmux-app-memory-audit Not-tested: Local Python socket/E2E regression execution; repo policy routes those through CI/tagged harnesses. * Avoid polling while waiting for background workspace priming Greptile flagged the 50ms sleep loop as a regression from event-driven priming. The wait now listens for pending-load, workspace, panel, and terminal readiness events, while retaining explicit timeout and cancellation cleanup so old SwiftUI tasks do not keep subscriptions alive. Constraint: Background workspace priming must not poll or materialize hidden terminals unnecessarily Rejected: Keep the short Task.sleep loop | still wakes periodically while idle and triggered review feedback Confidence: high Scope-risk: narrow Directive: Keep this wait event-driven; add new readiness events instead of reintroducing periodic polling Tested: git diff --check; python3 -m py_compile tests/test_codex_feed_hooks.py tests_v2/test_background_workspace_idle_thread_footprint.py; python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv; ./scripts/reload.sh --tag issue-3586-cmux-app-memory-audit Not-tested: Local E2E/UI/socket tests, per repo policy * Keep background-prime retries and teardown failures observable Fresh review feedback found three small gaps after the event-driven waiter landed: timeout was still clearing pending background loads, one monitor-liveness assertion used a one-shot process snapshot, and workspace cleanup failures could disappear. This keeps timeout completion tied to the real prime state and makes the Python harness failures explicit without running local socket E2E tests. Constraint: Local E2E/socket tests are not run in this repo; verification must use compile/build guards locally and CI for runtime coverage Rejected: Clear pending background loads after timeout | hides slow primes as completed and prevents later observation Confidence: high Scope-risk: narrow Directive: Timeout paths may stop waiting, but must not mark background priming complete unless the terminal surface is actually loaded Tested: git diff --check; python3 -m py_compile tests/test_codex_feed_hooks.py tests_v2/test_background_workspace_idle_thread_footprint.py; python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv; ./scripts/reload.sh --tag issue-3586-cmux-app-memory-audit Not-tested: Local E2E/UI/socket tests, per repo policy * Prove session-wide monitors survive turnless stops The regression check now samples the monitor for a short window after a Stop hook without a turn id, so a premature lease retirement cannot pass by being observed only once. This keeps the test focused on the session-wide lease invariant while staying local to the hook regression coverage. Constraint: Local E2E and socket tests are not run in this workspace; validation uses syntax checks and the tagged Debug reload gate. Rejected: Rely on wait_for_monitor_pids(present: true) | it only proves eventual presence, not continued survival through the Stop-to-SessionEnd gap. Confidence: high Scope-risk: narrow Tested: git diff --check; python3 -m py_compile tests/test_codex_feed_hooks.py tests_v2/test_background_workspace_idle_thread_footprint.py; python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv; ./scripts/reload.sh --tag issue-3586-cmux-app-memory-audit Not-tested: Local socket regression execution per repo policy; CI will run the behavioral tests. * Keep background-prime waiter cleanup explicit The event-driven background-prime waiter owns Combine subscriptions, notification observers, and timeout work items. Adding an explicit deinit fallback satisfies the repo lint rule and makes abandoned waiters drain cleanup through the same path as normal completion. Constraint: ContentView.swift is at a strict line budget, so the helper is intentionally compact while preserving the existing cleanup ordering. Rejected: Leave cleanup only in finish(reason:) | CodeRabbit flagged the required_deinit rule and abandoned waiters would rely on normal completion only. Confidence: high Scope-risk: narrow Directive: This waiter is main-actor owned; keep deinit cleanup synchronous with MainActor isolation unless the waiter is moved behind a nonisolated owner. Tested: git diff --check; python3 -m py_compile tests/test_codex_feed_hooks.py tests_v2/test_background_workspace_idle_thread_footprint.py; python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv; ./scripts/reload.sh --tag issue-3586-cmux-app-memory-audit Not-tested: Local socket regression execution per repo policy; CI will run the behavioral tests. * Keep pending background primes retrying after timeout Timed-out background workspace primes must remain pending so slow surfaces are not marked done, but the worker also needs to keep making progress when the pending key does not change. The priming task now loops over the current pending set until it is empty or cancelled, so a single slow workspace retries through the same event-driven wait path instead of stalling permanently. Constraint: The wait path must remain event-driven and avoid Task.sleep polling on the main actor. Rejected: Clear pending IDs on timeout | it hides cold-start failures and prevents later retries. Rejected: Add a retry generation state key | the existing worker can retry without expanding SwiftUI state surface. Confidence: high Scope-risk: narrow Tested: git diff --check; python3 -m py_compile tests/test_codex_feed_hooks.py tests_v2/test_background_workspace_idle_thread_footprint.py; python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv; ./scripts/reload.sh --tag issue-3586-cmux-app-memory-audit Not-tested: Local socket/UI regression execution per repo policy; CI will run behavioral coverage. * Store codex monitor lease ids in retirement form Lease retirement trims session and turn ids before matching, so lease creation now stores the same normalized values. All-whitespace session ids fail closed by skipping monitor launch instead of writing a lease that the retire path can never match. Constraint: Monitor leases must remain reaped by Stop/SessionEnd without relying on the 4-hour stale lease deadline. Rejected: Normalize only during retirement | existing leases written with whitespace would still miss exact equality checks. Confidence: high Scope-risk: narrow Tested: git diff --check; python3 -m py_compile tests/test_codex_feed_hooks.py tests_v2/test_background_workspace_idle_thread_footprint.py; python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv; ./scripts/reload.sh --tag issue-3586-cmux-app-memory-audit Not-tested: Local socket regression execution per repo policy; CI will run behavioral coverage. * Avoid off-main actor assertion during waiter teardown BackgroundWorkspacePrimeWaiter only needs to drain MainActor-isolated cleanup state during destruction, but normal deinit can run from whichever thread releases the last reference. Swift isolated deinit gives the destructor the class actor isolation instead of asserting the current executor. Constraint: Swift deinit for global-actor classes is not guaranteed to start on MainActor Rejected: Keep MainActor.assumeIsolated | can trap if the last release happens off-main Confidence: high Scope-risk: narrow Tested: git diff --check; python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv; ./scripts/reload.sh --tag issue-3586-cmux-app-memory-audit Not-tested: Full GitHub/CircleCI rerun after this commit * Keep waiter teardown compatible with CI Swift The previous isolated deinit fix avoided an off-main MainActor assertion, but Xcode 16.4 gates that syntax behind an experimental frontend flag. The waiter now owns its small continuation/cleanup state behind an NSLock so deinit can safely drain cleanup from whichever thread releases the final reference. Constraint: CI builds use Xcode 16.4 without IsolatedDeinit enabled Rejected: Enable the experimental frontend flag | broad build-setting change for a one-line helper Rejected: Restore MainActor.assumeIsolated in deinit | reintroduces the off-main trap called out by review Confidence: high Scope-risk: narrow Tested: git diff --check; python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv; ./scripts/reload.sh --tag issue-3586-cmux-app-memory-audit Not-tested: Full GitHub/CircleCI rerun after this commit * Treat relay reconnect misses as inconclusive owner checks Codex monitors use surface.list to prove owner loss. A relay-backed SocketClient may be between short-lived relay connections when the owner check runs, so a failed reconnect should not be treated as definitive workspace disappearance. The monitor now keeps waiting on relay reconnect failures and still exits when surface.list succeeds with no matching owner. Constraint: Relay-backed CLI sends intentionally close the socket after each request Rejected: Exit monitors on relay reconnect failure | transient relay restarts can orphan otherwise live work Confidence: high Scope-risk: narrow Tested: git diff --check; python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv; ./scripts/reload.sh --tag issue-3586-cmux-app-memory-audit Not-tested: Full GitHub/CircleCI rerun after this commit * Bound background priming retries Hidden workspace priming should keep trying briefly when a terminal surface is slow, but a permanently stuck surface must not keep a SwiftUI task loop alive forever. This caps timeout retries per workspace inside the active priming task and then clears the pending flag, while removing the now-dead pending-load mount reconciliation subscription. Constraint: Background priming runs from a SwiftUI task keyed by pending workspace ids, so leaving an id pending indefinitely keeps work scheduled without visible user value. Rejected: Complete on the first timeout | would avoid the loop but gives slow terminal surfaces no retry budget. Confidence: high Scope-risk: narrow Directive: Do not re-add pendingBackgroundWorkspaceLoadIds to mounted workspace reconciliation unless pending ids again affect mounted workspace selection. Tested: git diff --check Tested: python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv Tested: ./scripts/reload.sh --tag issue-3586-cmux-app-memory-audit * Keep background priming lifecycle state in one owner Background workspace priming was split between ContentView, a waiter, and task-local retry counters. Moving the lifecycle into a dedicated MainActor coordinator gives the retry ledger the same lifetime as the view-owned task and removes the subscription retain cycle that made waiter deinit cleanup unreliable. Constraint: Do not run xcodebuild locally; validation must avoid the prohibited build path. Rejected: Keep timeout counts local to primePendingBackgroundWorkspaces | SwiftUI task-id restarts reset local state when pending IDs change. Confidence: medium Scope-risk: moderate Directive: Keep background priming ownership in BackgroundWorkspacePrimeCoordinator; ContentView should only start the task. Tested: git diff --cached --check; swiftc -parse Sources/BackgroundWorkspacePrimeCoordinator.swift Not-tested: Full app build and CI before push. * Keep background prime timeout cancellation structured The background prime waiter still needs synchronous cleanup because task cancellation can arrive outside the MainActor path, but the timeout itself should be owned by a cancellable Swift task instead of a GCD work item. Constraint: Do not run xcodebuild locally; PR verification must come from CI and the required tagged reload command. Rejected: Leave DispatchQueue.main.asyncAfter in place | review guidance flagged the timeout pattern as avoidable even though it was not a correctness failure. Confidence: medium Scope-risk: narrow Directive: Keep waiter cleanup tied to the waiter so cancellation removes observers and timeout tasks together. Tested: swiftc -parse Sources/BackgroundWorkspacePrimeCoordinator.swift; git diff --check; git diff --cached --check Not-tested: Full app build or local test suite before push. * Keep background priming and monitor leases observable CodeRabbit found three places where lifecycle failures could be hidden: unreadable lease files were treated as retired, background-prime waiters could wait for their timeout instead of state-change wakeups, and diagnostic subprocesses in the idle-footprint regression had no timeout. Constraint: Do not run xcodebuild locally; use CI and the required tagged reload for build validation. Rejected: Treat unreadable lease files as retired | transient or future-format records should not cause monitor teardown. Rejected: Rely only on the two-second prime timeout | workspace removal and pending-state changes are observable state transitions and should wake the waiter immediately. Confidence: medium Scope-risk: moderate Directive: Keep prime waiter subscriptions weakly captured and registered through Waiter cleanup to avoid reintroducing retain cycles. Tested: swiftc -parse Sources/BackgroundWorkspacePrimeCoordinator.swift; python3 -m py_compile tests_v2/test_background_workspace_idle_thread_footprint.py; git diff --check; git diff --cached --check Not-tested: Full app build or local test suite before push. * Prove Codex monitor survives lease write failure A failed hook-state directory can make lease persistence unavailable before the monitor starts. This regression test keeps that filesystem failure separate from monitor visibility so the fallback path is covered through the hook entrypoint instead of source-shape assertions. Constraint: Regression tests should exercise observable hook behavior rather than checked-in metadata or source snippets Confidence: high Scope-risk: narrow Directive: Keep this as a hook-level process test; a unit-only check would miss monitor launch behavior Tested: python3 -m py_compile tests/test_codex_feed_hooks.py Not-tested: full hook regression script; repo policy runs tests in CI * Keep Codex status visible when leases cannot persist Lease files are the preferred stop/session-end retirement signal, but they are not the only bound on the transcript monitor. When the hook-state filesystem rejects the lease write, the hook now still starts the monitor and records a breadcrumb so the user-facing status path is not silently suppressed. Constraint: The hook protocol must still print the JSON response from the common exit path Rejected: Treat lease creation failure as a hard monitor-start failure | suppresses the Codex status indicator for transient filesystem errors Rejected: Print a stderr diagnostic from the hook | risks noisy hook output while telemetry breadcrumbs fit existing CLI diagnostics Confidence: high Scope-risk: narrow Directive: Keep lease retirement optional; monitor lifetime must also remain bounded by owner checks, transcript completion, and deadline Tested: swiftc -parse CLI/cmux.swift Tested: git diff --check Not-tested: local full test run; repo policy runs tests in CI * Retry CI after transient Zig download outage CircleCI macos-debug-build failed before project code ran because the shared Install zig step received HTTP 500 from ziglang.org. The CircleCI rerun API is unavailable without credentials in this environment, so this empty commit retriggers the branch pipeline without changing source files. Constraint: Do not run local xcodebuild; CI must validate the macOS build Rejected: Modify install-zig behavior for one transient upstream 500 | unrelated to this PR's code and not needed if the mirror responds Confidence: medium Scope-risk: narrow Directive: Revert/drop this empty commit only if a credentialed CircleCI rerun is available and preserving a retry commit is undesirable Tested: CircleCI failed at Install zig before project build/test steps Not-tested: No local tests or builds; this commit has no file changes * Bound Zig downloads in hosted CI The retry-only commit showed the PR can be blocked before project code runs when ziglang.org returns an HTTP 500 or stalls during Install zig. The CircleCI rerun API is not available from this environment, so the CI installer now uses bounded retries for the Zig archive and signature downloads in the active PR macOS paths. Constraint: Do not run local xcodebuild; hosted CI must validate macOS builds Rejected: Keep pushing empty retry commits | leaves CI dependent on a single upstream download attempt Confidence: high Scope-risk: narrow Directive: Keep Zig downloads bounded; unbounded curl calls can wedge activation and CircleCI before project tests run Tested: git diff --check Tested: ruby YAML.load_file for .circleci/config.yml and .github/workflows/perf-activation.yml Not-tested: hosted CI retry behavior until pushed * Allow slow Zig downloads while bounding stalls Activation-session proved that the Zig archive can make steady progress at very low throughput on hosted macOS runners. The previous max-time bound converted that slow progress into a failure, so the installer now bounds connection setup and true stalled transfers while allowing slow downloads to complete. Constraint: Hosted macOS CI depends on ziglang.org for Zig 0.15.2 Rejected: Keep a fixed 180-second max-time | failed a progressing download at 8MB/48MB Confidence: high Scope-risk: narrow Directive: Use curl speed limits for stall detection here; avoid total max-time limits unless the artifact is cached or mirrored Tested: gh run view 25424705963 --repo manaflow-ai/cmux --log-failed Tested: git diff --check Tested: ruby YAML.load_file for .circleci/config.yml and .github/workflows/perf-activation.yml Not-tested: hosted CI completion until pushed * Resume partial Zig downloads in CI CircleCI unit tests failed before project tests ran because ziglang.org reset the archive connection after multiple partial downloads. The server supports byte ranges, so the retry helper now resumes the partial artifact and allows more attempts instead of discarding progress on every retry. Constraint: Hosted CI must install Zig 0.15.2 before macOS builds/tests Rejected: Keep restarting each archive attempt from byte zero | repeated resets can prevent completion even while the server makes progress Confidence: high Scope-risk: narrow Directive: Preserve --continue-at - for this download path unless CI uses a cached or mirrored Zig artifact Tested: CircleCI job 3087 failed in Install zig before tests Tested: curl Range probe returned HTTP 206 for the Zig archive Tested: git diff --check Tested: ruby YAML.load_file for .circleci/config.yml and .github/workflows/perf-activation.yml Not-tested: hosted CI completion until pushed * Make Codex monitor lease state observable Codex monitor startup can intentionally proceed without a lease when the hook-state filesystem is unavailable, so every launch attempt now records whether a lease was present and captures start failures with the same context. This keeps the degraded lifecycle visible without making lease persistence a second hard dependency for status updates. Constraint: Lease creation failure must not suppress Codex status monitor startup. Rejected: Treat missing leases as fatal | this regresses the graceful-degradation path requested by review feedback. Confidence: high Scope-risk: narrow Directive: Keep monitor lifecycle telemetry centralized at startCodexTranscriptMonitor when adding new lease modes. Tested: git diff --check; swiftc -parse CLI/cmux.swift Not-tested: Local unit/UI tests per repo policy; CI will run after push. * Keep CLI file length within guard after merge The merge from origin/main moved CLI/cmux.swift over the Swift file-length budget. The install-preview renderer was already a self-contained CMUXCLI static helper, so it now lives in CMUXCLI+InstallPreview.swift and is registered with the CLI target without changing behavior. Constraint: Do not edit .yml or .yaml files while updating this PR. Rejected: Increase the Swift file-length budget | the guard failure is better handled by splitting a self-contained helper out of the oversized file. Confidence: high Scope-risk: narrow Directive: Keep future cmux.swift growth behind extension files when helpers are self-contained. Tested: python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv; swiftc -parse CLI/cmux.swift CLI/CMUXCLI+InstallPreview.swift; plutil -lint GhosttyTabs.xcodeproj/project.pbxproj; git diff --check Not-tested: Local app build/tests per repo policy; PR CI will validate after push. * Clean all surface identifiers on close Workspace close paths can see both the stable panel UUID used by the socket/API surface model and the Bonsplit tab UUID used by layout. TerminalController now removes per-surface state for every UUID handed to the close lifecycle before Workspace drops its mapping, so stale browser handles and telemetry queues cannot survive under either identifier. Constraint: PR review flagged split ownership between panel IDs and Bonsplit TabIDs during surface cleanup Rejected: Switch cleanup to Bonsplit TabID only | current socket/API surface refs and browser state are still keyed by stable panel UUIDs Confidence: high Scope-risk: narrow Directive: Surface lifecycle cleanup must run before Workspace removes surfaceIdToPanelId so both identifiers are still available Tested: python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv Tested: git diff --check Tested: swiftc -parse Sources/TerminalController.swift Sources/Workspace.swift Not-tested: local app reload deferred until CI is green so the mandated reload command remains the final shell command * Keep cleanup lifetimes actor-safe Fresh PR review found two cleanup paths that were technically correct only by accident: BackgroundWorkspacePrimeCoordinator touched MainActor-isolated state from deinit, and retired Codex monitor leases shared the active lease expiration window. The coordinator deinit now remains explicit without reading actor-isolated storage, and monitor lease pruning now uses a separate retired-lease grace period while treating a pruned lease file as retirement for monitors that wake after cleanup. Constraint: Never run xcodebuild directly; CI owns full build and test coverage. Rejected: Delete retired lease files immediately | monitors can be sleeping on filesystem events, so a short grace window keeps the retired marker observable. Confidence: high Scope-risk: narrow Directive: Keep retired lease retention separate from active lease max age; Stop/SessionEnd should retire leases promptly without waiting for the four-hour monitor lifetime. Tested: swiftc -parse CLI/cmux.swift Sources/BackgroundWorkspacePrimeCoordinator.swift Tested: python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv Tested: git diff --check Not-tested: Local XCTest or app build per repository policy; GitHub Actions will verify. * Preserve CLI source membership after main merge The origin/main merge reused the same PBX build/file reference IDs for CMUXCLI+InstallPreview.swift and CMUXCLI+Events.swift. Xcode preserved only one source membership, so the Hermes hook extension could not see printInstallPreview and the events file appeared twice in the build phase. Assigning CMUXCLI+Events.swift independent PBX IDs keeps both extension files compiled exactly once. Constraint: Build only through scripts/reload.sh; the failure was observed through the required tagged reload. Constraint: Never edit YAML workflow files; no YAML files changed. Rejected: Move printInstallPreview back into cmux.swift | that would undo the file-length cleanup and keep a malformed project reference. Confidence: high Scope-risk: narrow Directive: Keep CMUXCLI+InstallPreview.swift and CMUXCLI+Events.swift on distinct PBXFileReference/PBXBuildFile IDs whenever merging project.pbxproj. Tested: plutil -lint GhosttyTabs.xcodeproj/project.pbxproj Tested: swiftc -parse CLI/cmux.swift CLI/CMUXCLI+InstallPreview.swift CLI/CMUXCLI+HermesAgentHooks.swift CLI/CMUXCLI+Events.swift CLI/CMUXCLI+AgentHookDefinitions.swift Sources/Workspace.swift Tested: python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv Tested: git diff --check Not-tested: Full local test suite per repository policy; CI and reload.sh will verify. * Preserve background prime timeout debt across restarts SwiftUI restarts the background prime task whenever the pending workspace set changes, so cancellation is a lifecycle interruption rather than a successful prime result. The coordinator now models prime completion with typed reasons and only clears timeout counters for terminal outcomes. Constraint: PR review flagged repeated task cancellation as a path that can defeat the force-completion guard Rejected: Keep stringly typed completion reasons | cancellation and terminal outcomes need explicit accounting semantics Confidence: high Scope-risk: narrow Directive: Do not clear timeoutCounts for cooperative cancellation unless pending state was actually resolved Tested: swiftc -parse Sources/BackgroundWorkspacePrimeCoordinator.swift Tested: python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv Tested: git diff --check Not-tested: Full app build and test matrix pending CI/reload per repository policy * Keep merged app code inside Swift budget After merging current main, the combined branch exceeded the cmux Swift file length budget in GhosttyTerminalView and Workspace. This follow-up keeps the merge reviewable by compacting comments/test-only accessors and returning the background-prime panel list directly without changing runtime behavior. Constraint: Do not edit YAML files or refresh budget metadata for inherited main growth Rejected: Increase the file length budget | accepts avoidable debt instead of trimming local line growth Confidence: high Scope-risk: narrow Directive: Keep future merge follow-ups behavior-neutral unless CI exposes a real regression Tested: swiftc -parse Sources/GhosttyTerminalView.swift Sources/Workspace.swift Sources/BackgroundWorkspacePrimeCoordinator.swift CLI/CMUXCLI+Events.swift CLI/CMUXCLI+Process.swift CLI/CMUXCLI+InstallPreview.swift Sources/CmuxSettingsJSONPathSupport.swift Sources/GhosttyNSView+IMEComposition.swift Sources/App/WorkspaceRuntimeSettings.swift Tested: python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv Tested: plutil -lint GhosttyTabs.xcodeproj/project.pbxproj Tested: git diff --check Not-tested: Full app build and test matrix pending CI/reload per repository policy * Keep window drag suppression helpers available to tests Expose the window movability suppression helpers expected by the unit test suite and route the folder-drag sendEvent guard through the same helper path. This preserves the existing folder drag behavior while making the merged mainline tests compile again. Constraint: CI unit tests compile test sources against internal app helpers Rejected: Patch the tests only | would leave the production guard on a duplicated path Confidence: high Scope-risk: narrow Tested: git diff --check; ./scripts/reload.sh --tag issue-3586-cmux-app-memory-audit Not-tested: Local unit tests (repo policy prefers CI) * Preserve background workspace startup contract Background workspace priming needs a mounted SwiftUI host only while a hidden terminal surface is being started. The durable pending load id now stays pending across timeouts, while a separate mount pin gives the coordinator a bounded render surface to retry from. Constraint: Hidden terminal startup still depends on an attached AppKit view/window. Rejected: Clear pending loads after retry timeout | loses initial_command execution until manual workspace selection. Confidence: high Scope-risk: narrow Tested: ./scripts/reload.sh --tag fix-bg-workspace-prime Not-tested: tests_v2 background socket regression; repo policy routes E2E/socket tests through CI or VM. * Keep background prime mounts through timeout Timeouts during hidden workspace priming should not clear or unmount a pending background load because that pending state is the contract that keeps initial commands eligible to start without selecting the workspace. The timeout path now leaves the retained hidden mount in place while waiting for a terminal surface readiness signal or a later completion path. This removes repeated mount release/reacquire churn without regressing background workspace startup. Constraint: Non-focused workspace.create with initial_command must continue starting before user selection. Rejected: Complete pending background loads on timeout | drops the initial-command startup obligation before a Ghostty surface exists. Rejected: Release the hidden mount on timeout | causes repeated remount churn while the pending id remains active. Confidence: high Scope-risk: narrow Directive: Do not clear pendingBackgroundWorkspaceLoadIds on timeout unless background initial-command startup has another owner. Tested: git diff --check Tested: ./scripts/reload.sh --tag issue-3586-cmux-app-memory-audit Not-tested: tests_v2/test_workspace_create_background_starts_terminal.py locally; repo policy runs socket E2E via CI/VM. | 4 个月前 | |
fix: preserve claude-teams tmux routing (#9033) * test: preserve claude teams tmux launch context * fix: preserve claude teams tmux routing * fix: scope claude teams tmux routing * fix: harden claude teams launch routing * fix: close tmux compat review gaps * fix: require inherited tmux launch identity * fix: validate managed launcher context * fix: preserve non-launch management commands * fix: cover managed launcher aliases * fix: validate remote managed launch context * test: cover managed teams launch invariants * fix: keep managed teams shims authoritative * fix: preserve managed launcher compatibility * fix: harden managed launch classification * fix: reject ambiguous Claude debug filters * fix: require context for session hosts * fix: keep managed child identity coherent * test: migrate OMO plugin without a session * fix: preserve non-launch command compatibility * fix: align managed launch policy ownership * test: cover moved teams launch identity * fix: honor shell snapshot argument contract * fix: preserve managed launcher operator commands * fix: preserve managed launcher shell contracts * fix: close managed launcher review gaps * test: keep focused cmux sockets below AF_UNIX limits * fix: require launch context for ultrareview * fix: preserve managed launcher compatibility * fix: preserve Claude passthrough arguments * fix: preserve managed provider passthrough * test: cover managed launcher operator commands * fix: preserve managed launcher team operators * test: cover nested Codex Teams help * fix: pass nested Codex Teams help through * test: cover Claude Teams shell wrapper reentry * fix: harden managed Teams launch identity * test: consolidate managed Teams regressions * test: cover managed provider administrative help * fix: preserve managed provider administrative help * test: cover Claude forward subagent text flag * fix: recognize Claude forward subagent text flag * test: cover OMO subcommand global options * fix: preserve OMO subcommand global options * test: keep Claude import surface-bound * fix: require surface context for Claude import * test: cover Codex Teams help subcommand * fix: pass Codex Teams help through * fix: preserve managed wrapper root help * fix: apply retry binding predicate to both phases * test: handle teammate column equalization * test: model managed tmux focus changes * test: expect tmux-compatible pane IDs * fix: capture RPC session actor immutably | 2 个月前 | |
Add Hermes Agent hook support (#3585) * Add Hermes Agent hook support * Keep Hermes support within Swift budgets * Fix Hermes review feedback after main merge * Address Hermes follow-up review feedback * Tighten Hermes launch sanitization * Preserve Hermes inline hook YAML on uninstall * Keep Hermes hook installer split out --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com> | 5 个月前 | |
Reduce Sentry CLI broken-pipe crashes and hangs (#6254) * Add closed-stderr CLI broken pipe regression test * Handle CLI broken pipes with safe stdio writes * Limit clean broken-pipe exits to fatal stderr writes * Drop CLI unit test that depends on cli-target internals The CLIBrokenPipeWriteTests class called cliWrite() directly, but that symbol lives in the cmux-cli target and is not visible from cmuxTests, so CI failed to compile. Even with visibility, calling Darwin.write into a closed pipe inside the XCTest host crashes the runner via SIGPIPE (only the CLI binary's main() ignores SIGPIPE). The existing E2E test exercises the same closed-stderr path through the real cmux binary, so coverage is preserved. Restore cliWrite and the disposition enum to private and harden the E2E test: - XCTWaiter().wait + early XCTFail on timeout instead of falling through to assertions on a still-running process - closeOnDealloc: false so the explicit defer is the sole owner of the stderr write fd Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add CLI broken-pipe regression coverage * Scope CLI SIGPIPE handling to write and launch paths * Address CI failures and review feedback on CLI broken-pipe PR - Fix defer block return error by gating cleanup on `installed` flag - Replace Python-based SIGPIPE probe with native `__sigpipe-inspect` subcommand; removes Python dependency and avoids masking inherited SIGPIPE disposition - Fix strdup type-inference error in exec-mode probe via explicit `[UnsafeMutablePointer<CChar>?]` typing - Convert auth status/login/logout `print()` callsites to `cliPrint()` so broken-pipe writes don't crash auth subcommands - Drain spawn-probe pipes before `waitUntilExit()` to prevent deadlock - Include `cliWriteFatalStderr` in stdio-safety audit summary Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use _exit in cliWrite EPIPE path to avoid deadlock under held lock cliWrite calls Darwin.exit while holding cliSIGPIPEDispositionLock (NSLock is non-reentrant). Any atexit handler that wrote through cliWrite/cliPrint would re-enter withCLISIGPIPEDisposition and deadlock. _exit also skips atexit/stdio flush, matching the default SIGPIPE termination this path replaces when stdout is closed by the consumer. Addresses Cursor Bugbot comment on PR #2993. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Poll for writable FD on EAGAIN in cliWrite Addresses Cursor bot review on PR #2993: the previous `case EINTR, EAGAIN, EWOULDBLOCK: continue` turned non-blocking writes into a busy-wait spin under the SIGPIPE disposition lock. Split EINTR (immediate retry) from EAGAIN/EWOULDBLOCK (block on poll(POLLOUT)) so a non-blocking stdio fd yields to the kernel instead of spinning. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use F_NOSIGPIPE on CLI stdio instead of per-write sigaction Every cliPrint was wrapped in withCLISIGPIPEIgnored, which took a process-wide NSLock and did three sigaction syscalls per write to temporarily install SIG_IGN around Darwin.write. For a command like `cmux help` (~142 lines) that added ~426 extra syscalls. Opt stdout/stderr into F_NOSIGPIPE once at CLI startup — the same per-FD pattern the socket path already uses via SO_NOSIGPIPE — so write(2) just returns EPIPE and the hot path is a single write syscall per call. Keeps withCLIDefaultSIGPIPEForChildLaunch for Process.run / exec paths in case the CLI was invoked with SIG_IGN inherited, but those are low-frequency and not on the stdio write path. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix CLI SIGPIPE child inheritance and pipe writes * Close CLI stdio disposition race CLI writes and child launch setup now share one lock around stdio disposition changes, so no write can run while inherited stdout/stderr have F_NOSIGPIPE temporarily cleared for a child process. Constraint: Cursor review identified a race between child-launch fd mutation and concurrent broken-pipe writes Rejected: Reintroduce process-wide SIGPIPE ignore | would make child processes inherit the wrong SIGPIPE disposition again Confidence: high Scope-risk: narrow Directive: Any future stdio-disposition mutation must coordinate with cliWrite via cliStdioDispositionLock Tested: bash scripts/check-cli-stdio-safety.sh; git diff --check on CLI/CMUXCLI+Process.swift Not-tested: macOS app/unit/UI workflows locally; awaiting PR CI * Keep SIGPIPE probe parsing compiler-compatible The CI Debug build uses Swift syntax rules that reject value-binding patterns inside expression-style array patterns, so the internal SIGPIPE inspection probe parses its optional output path through an explicit count check instead. This keeps the probe behavior unchanged while restoring build compatibility for the activation-session job. Constraint: PR iteration must rely on CI and must not run bare xcodebuild locally Rejected: Remove the probe output-path support | tests use it to inspect stdio state without relying on a live stdout Confidence: high Scope-risk: narrow Tested: bash scripts/check-cli-stdio-safety.sh; git diff --check -- CLI/CMUXCLI+Process.swift; rg conflict marker scan Not-tested: Local Xcode build prohibited by task instructions * Expose SIGPIPE inspection fixture to CLI tests The SIGPIPE child-disposition regression lives in CLINotifyProcessIntegrationTests after the main-branch test split, while the decoded inspection payload type was left private inside WorkspaceRemoteConnectionTests. Moving the fixture to file scope keeps the same assertions and lets the unit target compile. Constraint: CircleCI unit compile logs are the verification source; local Xcode test runs are prohibited Rejected: Duplicate the struct inside CLINotifyProcessIntegrationTests | unnecessary copy for a file-local test fixture Confidence: high Scope-risk: narrow Tested: bash scripts/check-cli-stdio-safety.sh; git diff --check -- cmuxTests/WorkspaceRemoteConnectionTests.swift; conflict-marker scan Not-tested: Local cmux-unit Xcode test run prohibited by task instructions * Fix CLI SIGPIPE feedback * Fix SIGPIPE probe inherited fd snapshot * Fix SIGPIPE exec probe argv typing * Fix CMUXCLI SIGPIPE snapshot initializer * Rerun CI for CLI broken pipe fix * Fix SIGPIPE inspect signal snapshot order * Fix tmux shell stdin broken pipe path * Centralize CLI no-sigpipe writes * Close CLI stdin pipes with safe FileHandle API * Add CLI stdio lock regression coverage * Fix CLI non-stdio write lock handling * Fix CLI poll hangup broken-pipe path * Route codex teams watcher stderr through CLI writer * Move non-stdio CLI lock probe into CLI * Avoid stdio lock for isolated child launches * Fix merged CLI stdio writes * Add PostHog flush deadlock regression test * Avoid synchronous PostHog flush during quit * fix: keep spawned CLI children on default SIGPIPE fds * test: split SIGPIPE regression coverage * Flush active analytics before shutdown * Keep PostHog analytics singleton construction private * Document PostHog analytics queue isolation * Split PostHog analytics tests * Rerun CI after runner cache miss * fix: suppress expected CLI socket Sentry noise * test: keep stale socket regression path short * fix: make Sentry noise filter instantiable * refactor: split CLI Sentry telemetry tests * fix: address Sentry crash reduction review feedback * fix: close CLI SIGPIPE review gaps --------- Co-authored-by: austinpower1258 <austinwang115@gmail.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> | 3 个月前 | |
Add native iPhone and iPad Simulator panes (#7857) * tighten simulator shortcut and mutation paths * Harden simulator operation commit boundaries * Close simulator routing and deadline races * Reconcile simulator mutations during teardown * Preserve simulator caller routing context * Route ios commands from caller pane * Preserve explicit simulator routing and input recovery * Serialize simulator text recovery * Align simulator deadlines and selection rollback * Close simulator lifecycle commit races * Reject stale simulator discovery results * Bound simulator re-enable and batch capture * Select the integrated simulator display * Close simulator transition races * Gate simulator automation on readiness * Finish simulator selection generation checks * Bound simulator context work end to end * Verify simulator descendant identities * Validate simulator process ancestry * Bound simulator process shutdown * Supervise simulator command groups * Supervise simulator pane sessions * Contain every simulator subprocess * Test simulator routing and feature flag regressions * Fail closed on stale simulator state * Test simulator lifecycle review regressions * Bound simulator control lifecycles * Test simulator cross-pane ownership regressions * Serialize simulator cross-pane mutations * Test Web Inspector cross-worker ownership * Lease Web Inspector targets across workers * Test Web Inspector stale occupancy handoff * Refresh Web Inspector occupancy during handoff * Test Web Inspector occupancy timeout * Fail closed on incomplete Inspector occupancy * Test Inspector census and release regressions * Close Inspector refresh and release races * Test stale location route teardown * Preserve location route ownership through teardown * Test Simulator launch environment privacy * Test route commit during device switch * Test feature flag telemetry consent * Own Simulator mutations through teardown * Harden Simulator isolation and ownership * Persist Simulator mutation ownership across processes * Honor telemetry consent for remote flags * Preserve failed Simulator cleanup ownership * Propagate Simulator CLI routing errors * Fix Simulator operation task syntax * Inject Simulator ownership and keep context read-only * Resolve restored Simulator context without booting * Test late Simulator display identity publication * Attach Simulator callbacks before display discovery * Test Simulator mutation ownership boundaries * Harden Simulator mutation ownership semantics * Test current Simulator default-screen contract * Support current Simulator default-screen metadata * Isolate Simulator camera transport tests * Test forwarded Simulator screen metadata * Support forwarded Simulator screen metadata * Align Simulator overlay lifecycle test with visibility * Bound Simulator recovery assertion by time * Make Simulator input recovery test deterministic * Test Simulator landscape framebuffer direction * Correct Simulator landscape presentation direction * Bound Simulator frame publication test wait * Register Simulator replay state before delivery * Test Simulator review boundary cases * Test iOS screenshot surface identity errors * Normalize Simulator control boundaries * Isolate Simulator CLI contract environment * Test native Simulator orientation dialects * Unify native Simulator orientation semantics * Test landscape Simulator digitizer coordinates * Map landscape input into native digitizer space * Test stable Simulator app switcher hold * Hold app switcher gesture stationary * Test Simulator app switcher button timing * Open Simulator app switcher with double Home * Test installed iPad DeviceKit chrome fallback * Test bounded Simulator frame publication * Scale Simulator frames to pane geometry * Test Simulator frame ring replacement cleanup * Release obsolete Simulator frame rings * Route IndexNow jobs through configured runner * Remove wall-clock assertions from RPC event tests * Test frame ring adoption race * Retire Simulator frame rings after host adoption * Keep frame completion on MainActor * Snapshot Simulator activity log before lazy layout * Regenerate webview assets after main merge * Test Simulator core readiness ordering * Stream Simulator before optional capability probes * Test control-socket Simulator selection ownership * Exclude active Simulator control action from teardown * Test natural DeviceKit chrome cap geometry * Preserve native DeviceKit chrome artwork geometry * Fix design mode test payload shadowing * Make Simulator replay tests signal-driven * Fix Simulator pane test client conformance * Test immediate Simulator context discovery * Discover Simulator before context reads * Test Simulator production edge cases * Close Simulator production review findings * Fix Simulator integration test fixtures * Fix Simulator CLI routing call site * Fix Simulator focus test fixtures * Fix Simulator app test fixtures * Test Simulator capability hydration readiness * Wait for Simulator capability hydration * Test Simulator review edge cases * Close Simulator production review gaps * Avoid recursive Simulator picker comparison * Isolate Simulator picker observation * Test Simulator application row snapshots * Snapshot Simulator application picker rows * Test static Simulator frame presentation * Drive Simulator frames without display callbacks * Test Simulator visibility remounts * Keep Simulator frames through host remounts * Isolate Simulator visibility regression suite * Test Simulator frame pacing under input load * Pace Simulator framebuffer readback * Localize project surface labels * Test Camera Injector header cache identity * Invalidate Camera Injector cache for headers * Test Simulator RPC capability discovery * Advertise Simulator RPC capabilities * test(simulator): cover interactive frame priority * fix(simulator): prioritize frames after pointer input * test(simulator): cover native tap hold duration * fix(simulator): hold synthetic taps long enough for iPadOS * Test immediate Simulator frame presentation * Present Simulator frames without an extra tick * Test failed Simulator ownership publication * Reject unsafe Simulator ownership claims * test(simulator): cover framebuffer lifecycle bounds * fix(simulator): bound framebuffer lifecycle work * test(simulator): cover review lifecycle regressions * fix(simulator): close review lifecycle gaps * test(simulator): cover routing pacing and consent * fix(simulator): scope routing pacing and consent * test(simulator): cover screenshot and cached log readiness * fix(simulator): prepare capture without eager lifecycle work * test(simulator): report capture-ready live state * fix(simulator): report live capture-ready state * test(simulator): cover control-plane and frame wakeups * fix(simulator): signal frames and preserve errored flag cache * test(simulator): cover publication wakeup races * fix(simulator): bound publication wakeups * test(simulator): cover tool editor shortcut focus * fix(simulator): preserve tool editor focus ownership * test(simulator): cover flag omission and runner injection * fix(simulator): inject async owned command execution * test(simulator): cover file drop proposal readiness * fix(simulator): validate file drop proposals * test(simulator): cover compound inspector cleanup failure * fix(simulator): preserve failed inspector cleanup state * test(simulator): cover device-scoped tool state * fix(simulator): scope tool state to selected device * test(simulator): cover final release blockers * fix(simulator): close final release blockers * test(simulator): make frame scheduling assertions deterministic * test: update Ghostty surface config ABI lock * fix(simulator): clear final build gates * fix(build): import Dock lifecycle workspace types * test(web): isolate feedback route environment * fix(build): disambiguate Dock snapshot types * test(simulator): cover review ownership blockers * fix(simulator): scope camera cleanup ownership * fix(build): make resume policy returns explicit * test(simulator): cover camera cleanup ownership retries * fix(simulator): preserve camera cleanup ownership * fix(build): clear latest main gates * test(simulator): cover final review blockers * fix(simulator): await quit cleanup and index targets * refactor(simulator): satisfy production policy * test(simulator): cover camera cleanup on device switch * fix(simulator): clean camera state before device switch * test(simulator): retain quit cleanup after panel removal * fix(simulator): make quit await durable rollback * test(simulator): cover retained cleanup recovery * fix(simulator): recover retained camera cleanup * test(simulator): cover cleanup side effects * fix(simulator): restore external cleanup state * refactor(simulator): split camera authorization record * test(web): respect delegated discovery order * test(ios): assert transition math deterministically * fix(ci): repair current-main Swift integration * fix(ci): return closed workspace restore result * test(simulator): cover final review regressions * fix(simulator): close final lifecycle gaps * test(simulator): cover review lifecycle findings * fix(simulator): resolve review lifecycle findings * test(simulator): cover durable recovery journals * fix(simulator): persist mutation recovery journals * refactor(simulator): inject durable recovery paths * test(simulator): cover durable journal transitions * fix(simulator): make recovery transitions crash consistent * test(simulator): cover recovery compatibility gaps * fix(simulator): preserve recovery compatibility * test(simulator): cover recovery ownership handoff * fix(simulator): gate recovery ownership handoff * test(simulator): cover duplicate camera journals * fix(simulator): suppress stale durable camera journals * test(simulator): cover journal reconciliation races * fix(simulator): serialize journal reconciliation * test(simulator): cover identical journal paths * fix(simulator): normalize camera journal paths * test(simulator): cover journal URL hints * fix(simulator): compare normalized journal paths * refactor(simulator): split legacy route fixture * test(simulator): observe journal lock contention | 2 个月前 | |
Fix Kimi hook config path and migrate legacy block (#8278) * test: cover Kimi hook config location migration * fix: install Kimi hooks in active config * test: bound Kimi hook CLI subprocess * test: cover unreadable legacy Kimi config * fix: tolerate legacy Kimi cleanup failures * test: cover aliased Kimi config paths * fix: preserve hooks across Kimi config aliases * test: match installed Kimi hook commands * test: require confirmation for Kimi migration * fix: confirm Kimi config migration together * refactor: keep Kimi config edits local * test: cover unreadable legacy Kimi uninstall config * fix: tolerate legacy Kimi uninstall cleanup errors | 2 个月前 | |
Fix aggregate memory ownership reporting | 2 个月前 | |
Fix aggregate memory ownership reporting | 2 个月前 | |
Fix stale SSH workspace connection status (#9085) * test: cover authoritative SSH terminal liveness * fix: derive SSH status from terminal liveness * fix: close SSH terminal lifecycle races * fix: authenticate SSH terminal readiness * fix: bind SSH liveness to terminal authority * fix: make Dock SSH readiness transactional * test: assert remote terminal end acceptance * test: reject retired PTY lifecycle readiness * fix: revalidate PTY lifecycle at readiness commit * test: cover remote readiness lifecycle races * fix: harden remote terminal lifecycle ownership * test: cover stale remote terminal generations * fix: authenticate remote terminal lifecycle callbacks * fix: bound remote lifecycle commit side effects * chore: document remote lifecycle ownership boundaries * test: cover reordered remote readiness callbacks * fix: order remote terminal lifecycle callbacks * test: cover remaining SSH lifecycle ordering gaps * fix: close remaining SSH lifecycle ordering gaps * test: cover lossy SSH liveness reconciliation * fix: make SSH liveness reconciliation resilient * test: cover remaining SSH liveness races * fix: close remaining SSH liveness races * test: cover Mosh and transient SSH readiness * fix: make terminal readiness authoritative * test: cover premature terminal readiness * fix: require proven terminal readiness * test: pass Dock readiness attempt generation * test: cover remote lifecycle review regressions * fix: preserve remote lifecycle routing * fix: retire orphaned remote lifecycles * test: cover raw SSH readiness gating * fix: decouple raw SSH readiness reporting * test: cover restored SSH lifecycle reporting * fix: restore SSH lifecycle authority * test: cover SSH lifecycle review regressions * fix: close SSH lifecycle review gaps * test: cover bounded SSH readiness lifecycle * fix: bound persistent SSH readiness retries * test: expose queued SSH readiness duplicates * fix: coalesce persistent SSH readiness delivery * fix: compile remote lifecycle app adapters * fix: satisfy ssh readiness closeout policy --------- Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> | 2 个月前 | |
Add CLI window targeting (#4211) * Add CLI window targeting * Address CLI window routing review feedback * Honor window routing in tree fallback * Fix window route UI test warning * Preserve sidebar metadata text after separator * Fix window routing review findings * Fix ssh global window routing * Validate pane handles against target window * Reject unresolved window refs * Fix CLI window contract test fake * Tighten CLI window contract fake * Scope move-surface indexes by window * Validate surfaces against target window * Preserve move-surface source window semantics * Preserve right-sidebar window handle resolution * test: cover case-insensitive VM window UUIDs * fix: validate VM window UUIDs case-insensitively * test: cover tmux window flag positional parsing * fix: strip window target flags from tmux command text * test: cover omitted surface with targeted workspace * fix: leave omitted targets scoped to workspace * test: cover move-surface indexed window scope * fix: scope indexed move-surface lookup * test: cover notify surface refs across window workspaces * fix: resolve notify surface refs within window * fix: preserve cross-window surface moves * Fix notify surface UUID routing * Fix indexed notify window routing * Keep move-surface source refs unscoped * Keep move-surface source indexes unscoped * Make surface resume window routing local --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com> | 4 个月前 | |
Fix OMP hook binding from live PID/TTY identity (#9091) * test: expose OMP hook PID/TTY binding drift * test: make OMP binding regression runnable * fix: bind OMP hooks from live controlling TTY * fix: harden OMP session reconciliation * fix: expose shared hook binding helpers * fix: negotiate and bound OMP hook delivery * fix: isolate OMP binding and drain hook shutdown * fix: preserve hook routing boundaries * fix: make OMP cleanup recoverable * fix: demote all superseded OMP claims * fix: harden OMP hook lifecycle coverage * Retry all superseded OMP cleanup records * Bound OMP cleanup retries and preserve Stop hooks * Harden superseded OMP cleanup ownership * Preserve agent runtime across Dock ownership * Test Dock agent session ownership gaps * Test Dock binding-only lifecycle transfer * Test Dock retry ownership across bindings * Test Dock resume cwd binding ownership * Test authoritative Dock binding clears * Test Dock session and directory provenance * Test completed Dock tombstone after binding clear * Test managed Dock hook identity across tmux replacement * Fix managed Dock hook identity across tmux replacement * fix: disambiguate restorable agent selection * fix: return workspace resume binding * Split agent hook process binding types * fix: preserve managed identity after retry revert --------- Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> | 2 个月前 | |
Order Feed acknowledgments after publication | 2 个月前 | |
Update built-in Pi hook integration (#7008) * test: cover current Pi hook extension parity * fix: update Pi hook extension parity * fix: address Pi hook review findings * fix: tighten Pi hook review fixes * fix: harden Pi hook environment allowlist * fix: address Pi hook review followups * refactor: split Pi extension source * fix: honor Pi hook disable flag * test: tighten Pi resume binding harness * chore: retrigger external checks * test: stabilize generic hook CLI expectations * fix: preserve Pi notification fallback * test: stabilize CLI socket harness --------- Co-authored-by: cmux <cmux@cmuxs-Mac-mini.local> | 3 个月前 | |
Fix blocking Pi hook dispatch | 2 个月前 | |
Bound Feed deadline composition | 2 个月前 | |
Bound best-effort Feed delivery | 2 个月前 | |
Emit Pi compact and subagent lifecycle Feed events (#9106) * test: cover Pi compact and subagent feed events * fix: emit Pi compact and subagent feed events | 2 个月前 | |
Diff viewer: searchable, uncapped branch base picker with smart defaults (#6484) * Diff viewer: searchable uncapped branch base picker with smart defaults Replace the 4-item base <select> with a command-palette-style searchable popover over all refs (suggested/worktrees/branches/remotes/recent), backed by on-demand branch-diff regeneration so the picker is no longer capped at a handful of pre-rendered base pages. - Smart default base with reason + confidence: branch.<name>.cmuxBase -> PR base -> merge-base --fork-point -> origin/HEAD. Toolbar shows the ref, reason, and ahead/behind. - New diff-viewer-server routes /__cmux_diff_viewer_refs (grouped refs JSON) and /__cmux_diff_viewer_branch (regenerate + 302); mirrored in the in-app cmux-diff-viewer:// scheme handler via a per-group session descriptor. - React BranchBasePicker: fuzzy filter, keyboard nav, raw-ref escape hatch, inline regenerate spinner. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff base picker: keep the base ref visible, never crushed The Base button toolbar control was starved: source+repo selects ate the toolbar-left space, leaving the primary base button ~87px, so the ref collapsed to its 6ch floor while the reason/ahead-behind showed (priority inversion flagged in UX review). - Wrap reason+ahead/behind in .base-picker-meta with a high flex-shrink so it collapses before the ref ever ellipsizes (font/width-independent guarantee). - Compact and highly-shrink the source/repo selects; give #base-picker a 156px min-width floor so it wins space as the primary toolbar action. - Container queries cleanly hide ahead/behind then reason at narrow widths (no mid-glyph clipping); full value exposed via the button title tooltip. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff base picker: make Suggested section disjoint from the rest The heuristic default bases (Suggested, top section) previously also appeared in worktrees/branches/remotes/recent, so e.g. origin/main showed twice. Exclude any ref surfaced in Suggested from every section below it, so the top section reads cleanly as the picker's nondeterministic guesses and the lists below are the deterministic remainder. Sections are now disjoint. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff base picker: show head->base comparison, stop selects vanishing, hide redundant file picker Three fixes from dogfood feedback: - Comparison was one-sided: the toolbar showed only the base, so users could not tell what it was compared against. Add headRef to the payload and render the control as `<current-branch> -> <base> (<reason>) +a -b`, making both sides of the diff explicit. - Regression: the source/repo selects could shrink to zero width and disappear in a narrow panel (introduced when the base button was given space priority). Floor #source-select/#repo-select with a real min-width and lower shrink so they always stay visible; the source select especially must never vanish since it signals unstaged/staged/branch/last-turn. - The toolbar jump-to-file select duplicates the right Files sidebar. Hide it (and collapse the centered grid track) when the sidebar is visible, which also frees the space the above two fixes need; it stays when the sidebar is hidden or the panel auto-hides it (<=520px). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff base picker: cache refs (stale-while-revalidate) + dedupe gh call Opening the picker took ~3s because /__cmux_diff_viewer_refs recomputed everything on every open and called gh pr view (a GitHub network round-trip) twice per request. - Memoize the gh PR-base lookup per repo (30s TTL, lock-guarded), collapsing the double call to one network hit. This alone cuts the cold open ~3s -> 0.69s. - Stale-while-revalidate refs cache: a 0600 .refs-cache-<sha256(repo)>.json in the secure dir holds the last result; the HTTP endpoint returns it instantly and recomputes in the background when older than 20s (dogpile-guarded). The one-shot scheme/CLI path serves fresh-enough cache or computes synchronously. Warm reopen ~1ms (690x). Output JSON is byte-identical; corrupt/mismatched caches fall back to compute. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff base picker: keep source/repo switchers after picking a base Picking a new base navigated to a regenerated page that wrote sourceOptions and repoOptions as empty arrays, so the source (Branch/unstaged/staged/last-turn) and repo selects disappeared, leaving only the base picker. Persist the sibling page filenames (repoRoot -> source slug -> basename) in the branch session, then rebuild the switcher options in both regenerate paths (HTTP + scheme) via the current-origin mapper: source options point at the existing per-source pages with Branch reselected onto the new pick page, repo options point at each repo's branch page. Filenames are origin/port independent so they survive a server restart; old sessions without the map fall back to the prior empty behavior. Verified the regenerated page now carries 4 source options (Branch selected) and the repo options. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Remove diff-branch-picker design doc from the PR Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff toolbar: content-sized pickers with max-widths and shrink priorities The source/repo selects had a fixed flex-basis (76px/92px) and no grow, so they truncated their value even when the toolbar had free space (the base picker's flex-grow:1 absorbed it) - the repo select showed 'worktrees,' clipped. Size each picker to its content (flex-basis auto) with a max-width cap, a min-width floor, and flex-shrink as an explicit priority: repo shrinks first, then source, and the base comparison shrinks last. So with free space the repo label expands to its 188px cap, the source select fits longer values like 'Last turn', and when space runs out they ellipsize in priority order instead of one being stuck truncated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff toolbar: size source/repo selects to selected value via field-sizing Replace the fixed/capped width with field-sizing:content so each native select is as wide as its CURRENTLY SELECTED value (native selects otherwise size to their widest option, and a fixed flex-basis truncated long values even with free space). No max-width: the picker grows/shrinks with the chosen value and never truncates when there is room. flex-shrink still encodes priority (repo gives width first, base last) for the cramped case; min-width floors keep the chevron visible. Verified field-sizing:content renders correctly in the diff viewer WKWebView. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff toolbar: size the file (jump) picker to its selected value too Apply field-sizing:content to #jump-select like the source/repo selects, so the toolbar file picker sizes to the selected file path instead of stretching to fill; max-width:100% still caps it at the toolbar-middle track. The jump select only appears when the Files sidebar is hidden. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff toolbar: ellipsis-truncate select values instead of hard clip Add overflow:hidden + white-space:nowrap + text-overflow:ellipsis to the source/repo/base/jump selects so a value too long for the available width (capped at the track, or shrunk under flex pressure) truncates with an ellipsis instead of clipping mid-glyph. With field-sizing the full value shows when there is room; the ellipsis only appears when the toolbar is genuinely cramped. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * CI: refresh Swift file-length budget for the branch picker additions The branch base picker adds cohesive server/payload/cache code to three existing files (CLI/cmux_open.swift +1498, Sources/Panels/BrowserPanel.swift +179, CLI/cmux.swift +2). These are already large files tracked by the broader god-file decomposition effort; splitting them is that refactor's job, not this feature PR. Accept the growth in the checked-in budget as known debt. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff branch picker: address autoreview + review-bot findings Structured review (P1/P2): - Fix scheme-origin regenerate URL: it was built as cmux-diff-viewer://token/token/... (double token) and failed to load; build host=token, path=requestPath. - Make custom-scheme refs/regenerate tasks lifecycle-safe: register the WKURLSchemeTask before dispatch and route all callbacks (success, failure, timeout) through performSchemeTaskCallback so a stopped/cancelled task is never touched (WebKit crash class). - Localize the branch picker labels: add the branchPicker* keys to the Swift DiffViewerLabels payload + Localizable.xcstrings (en + ja) so non-English locales no longer fall back to English web defaults. Review-bot (CodeRabbit/Greptile): - Omit the branchPicker payload when the session write fails (was try?), so the page falls back to the legacy base select instead of advertising 404 endpoints. - Collision-resistant regenerate filenames (append a short SHA-256 of the ref). - flock the manifest read-modify-write to avoid lost regenerated pages on concurrent base selections. - Bound the bundled-CLI call with a timeout off the file-serving queue. - HTML-attribute-escape the meta-refresh URL. - Token-bind the custom-scheme refs/regenerate commands to the session token. - CSS: lowercase currentcolor, drop duplicate min-width. - React: validate full branchPicker shape before opting in, drop unused param, autoFocus -> callback-ref focus, stable row keys. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff picker: install CLI termination handler before run() (fix exit race) runBundledDiffViewerCommand set process.terminationHandler after process.run(), so a fast-exiting command (e.g. a cached refs request) could terminate before the handler was attached, leaving the exited semaphore unsignaled. The timeout path would then terminate/kill and wait forever on that semaphore, hanging the restored custom-scheme picker request and leaking a GCD worker. Set the handler before run(). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff picker: render the branch diff against the smart base; scope regenerate repo auth to the session - P1 correctness: the branch page rendered its diff against the legacy resolvedGitBranchDiffBaseRef (origin/HEAD) while the toolbar advertised the smart base (cmuxBase/PR/fork-point), so they could disagree. Make the smart-resolved DiffBranchBase the single source of truth: it now drives the branch DiffSourceContext used for the merge-base + git diff AND the picker's currentRef (cached per repo so gh runs once). Explicit --base still honored. - P2 security: regenerate authorized repoRoot against the global allow-list (any active session). Add diffViewerSessionAllowsRepo and authorize against the requested group's session only, on both the HTTP and scheme paths. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff picker: pure-Swift hex encoder (P0) + token-gate HTTP endpoints (P1) - P0: the refs-cache key, base-slug collision suffix, and asset content key hashed SHA-256 bytes to hex with String(format: %02x ...), the Foundation format pattern that previously caused unbounded memory growth/crashes in concurrent git/path code (PR 5347). These run from the concurrent picker endpoints. Replace with a pure-Swift nibble-lookup hex encoder; verified byte-identical over all 256 byte values so cache filenames/slugs are stable. - P1: /__cmux_diff_viewer_refs and /__cmux_diff_viewer_branch authorized by repo/group only, bypassing the unguessable diff-viewer token that file serving requires. Add the token to the refsURL/regenerate URLs and require it (refs: token must own a session allow-listing the repo; regenerate: session.token == token). Frontend is transparent (URLs used verbatim). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff picker: deferred Branch page uses smart base; localize reason labels - P1: the deferred Branch page (when the initial source is not branch) set its base from the legacy branchBaseForOptions while its picker advertised the smart base, so switching to Branch could render against the wrong base. Use selectedBranchBase?.ref there too. - P3: the row/button reason showed the raw English contract tag (fork point, created from) instead of the localized text. Backend currentReason now sends the localized diffBranchBaseReasonLabel; the row renderer prefers the localized secondary over the raw reason. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff picker: resolve endpoints against current origin (restore-safe) + prune session/cache files - P2: persisted pages embed absolute http://127.0.0.1:<port> picker URLs, so after restore through cmux-diff-viewer:// (and a new port) the picker fetched a dead origin. Rebase refsURL/regenerate to a root-relative path before fetch/navigate so they resolve against the current page under both the HTTP server and the custom scheme. resolveDiffNavigationURL passes relative URLs through unchanged. - P2: extend pruneDiffViewerFiles to age-prune .branch-session-*.json, .refs-cache-*.json, and stale .lock files (were accumulating unbounded and slowing the per-request session-allow-list scan). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff picker: scheme handler reloads manifest on miss (restored regenerate 404) When a restored cmux-diff-viewer:// page selects a new base, the regenerate route runs the bundled CLI in a child process that appends the new page to .manifest-<token>.json on disk. The parent scheme handler kept the token's stale in-memory filesByPath, so registeredFile(for:) 404'd the redirected page. On an active-session miss, reload the manifest from disk once and retry, which closes the whole stale-in-memory-manifest class (any out-of-band append is picked up). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff picker: bound branches/remotes refs scans (--count) against pathological repos The refs endpoint serialized every refs/heads + refs/remotes entry per popover open (data collection/cache/transfer unbounded even though the UI render is capped). Add a generous git-source --count=5000 bound so a repo with tens of thousands of refs cannot allocate an unbounded payload; effectively uncapped for any realistic repo. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff picker: don't default to the branch's own upstream; scope regen base replace - P1 (regression): the smart-base fork-point step used @{upstream}. For a branch pushed with 'git push -u origin <branch>', @{upstream} is the branch's own remote ref, so the diff compared the branch against itself and hid every pushed commit. Only use the upstream when it is an integration branch (its leaf name differs from the current branch); otherwise fall through to origin/HEAD/main. The rendered diff still computes merge-base HEAD <base>, preserving fork-point semantics for a real integration upstream. - P3: the regenerate template replaced the bare __CMUX_REF__ sentinel globally, which could rewrite an occurrence inside an arbitrary repo path. Scope the replace to the 'base=__CMUX_REF__' query token. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff picker: own-upstream guard handles slash branch names Round-9 guard compared only the last path component, so feature/foo tracking origin/feature/foo (foo != feature/foo) was wrongly treated as an integration base and the branch diffed against itself. Strip only the remote prefix and compare the full remainder to the branch name. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Diff picker: surface current base in refs + smart base/picker on repo-switched pages - P2: include the current base ref in the refsURL so reopening the picker after regenerating against a raw/manual base re-surfaces it as the manual Suggested row (the server already read base; only the URL omitted it). - P2: repo-switched Branch pages reused only the explicit base and lost the picker. Compute the per-repo smart base (cached smartBranchBase) for each non-selected repo and set its branchPickerBase, so switching repos keeps the smart base + picker with that repo's own endpoints. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> | 3 个月前 | |
CLI remote PTY classifier: map pty.resize.notification like pty.write.notification (#7401) CodeRabbit review finding: the bridge-side error mapping treats both requiredPTYWriteNotificationCapability and requiredPTYResizeNotificationCapability as the persistent-PTY-capability family, but the CLI classifier (faithfully extracted from the legacy inline helper) only matched pty.write.notification. A resize-capability failure whose message names only the capability would fall through to the generic message instead of the reconnect guidance. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> | 3 个月前 | |
Run cmux iOS over authenticated Iroh transport (#7908) * feat(iroh): bridge the production Swift endpoint * feat(iroh): run the mac host transport * test(iroh): reject local binding substitution * test(ios): cover pooled fallback route * fix(iroh): bind discovery to the local app instance * fix(ios): retain successful pooled route * test(iroh): require online-first host policy fallback * feat(iroh): start hosts from verified offline policy * feat(iroh): persist mac offline host policy * fix(iroh): reject partial online binding rotation * test(iroh): reject unvalidated private fallback * feat(iroh): own iOS endpoint and multistream sessions * fix(iroh): revalidate private fallback paths * fix(iroh): accept JSON media type parameters * ci(iroh): test full app on Intel Sonoma * ci(iroh): run transport tests on Intel Sonoma * test(iroh): cover abandoned relay reservations * fix(iroh): expire abandoned relay reservations * feat(iroh): expose admitted host multistream sessions * test(iroh): require bounded incoming streams * fix(iroh): bound peer-created QUIC streams * feat(iroh): defer iOS transport activation * feat(ios): prefer verified Iroh routes * test(iroh): preserve endpoint on preferred port collision * test(iroh): cover LAN rendezvous consistency * fix(iroh): fall back from occupied preferred port * feat(iroh): derive private rotating LAN aliases * fix(iroh): serialize LAN discovery with revocation * feat(iroh): make secure pairing the default * docs(iroh): record offline and LAN trust boundaries * feat(iroh): cache verified client policy offline * docs(iroh): add Apple and proxy launch caveats * docs(iroh): clarify Apple local network prompting * test(iroh): cover offline cache teardown races * fix(iroh): fence offline cache teardown * test(iroh): cover online admission leases * feat(iroh): gate online admission leases * feat(iroh): add authenticated Bonjour LAN fallback * feat(iroh): enforce online revocation leases * test(iroh): cover offline admission leases * test(iroh): cover canonical trust errors * fix(iroh): harden trust broker boundaries * fix(iroh): bound offline admission leases * test(iroh): cover policy refresh revision races * fix(iroh): fence admission policy refreshes * docs(iroh): narrow private network release scope * test(tailscale): reject unbound bearer routes * fix(mobile): state private network boundaries * test(tailscale): reject unbound bearer routes Cover numeric-only Tailscale bearer routes and reject authorization, DNS, and route substitution before transport writes. * docs(iroh): specify NAT authorization barrier * fix(tailscale): bind bearer writes to live tunnel * test(iroh): require acknowledged NAT admission barrier * test(tailscale): reject route-only transport bypass * fix(tailscale): close route-only transport bypass * fix(iroh): acknowledge NAT admission before app streams * test(iroh): hide database failure details * fix(iroh): defer reservation constraint validation * test(iroh): retain revocation monitor after handoff * fix(iroh): retain revocation monitor for connection * test(iroh): reject broker credential redirects * fix(iroh): block broker credential redirects * test(iroh): fail closed on terminal foreground policy * fix(iroh): fail closed on terminal policy refresh * test(iroh): prevent raw fallback after admission failure * fix(iroh): pin authenticated pairings to Iroh * test(auth): reject device registry redirects * test(iroh): lock registration identity and relay bootstrap * fix(iroh): preserve registration trust identity * fix(auth): reject credentialed API redirects * test(iroh): keep direct paths out of cloud storage * fix(iroh): keep direct paths device local * test(iroh): evict remotely closed client sessions * test(iroh): recover dead session on foreground * test(iroh): prevent server path-hint disclosure * fix(iroh): recover suspended client sessions * fix(iroh): keep private paths off server surfaces * test(iroh): reject overlapping LAN bootstrap routes * fix(iroh): reject ambiguous LAN interfaces * test(iroh): bound pending admissions per identity * fix(iroh): limit pending admissions per peer * test(iroh): require owned server event stream * test(auth): bound credentialed HTTP responses * test(iroh): reject concurrent control owners * fix(auth): cap credentialed HTTP responses * test(iroh): cover firewall dependency failures * fix(iroh): bound firewall availability checks * feat(iroh): deliver server events on owned stream * test(iroh): cap stalled firewall work * test(iroh): bound active sessions per binding * fix(iroh): cap stalled firewall work * fix(iroh): cap active sessions per binding * test(iroh): require firewall timeout recovery * fix(iroh): abort stalled firewall checks * fix(ci): isolate Iroh transport test suites * test(iroh): route revocation to broker delete * fix(iroh): send revocation to broker route * test(mobile): bound concurrent RPC work * fix(mobile): cap concurrent RPC work * test(mobile): bound decoded frame batches * fix(mobile): cap decoded frame batches * test(iroh): bound pending Bonjour resolves * test(iroh): gate reserved application lanes * test(iroh): retain failed binding revocations * fix(iroh): bound pending Bonjour resolves * fix(iroh): gate reserved application lanes * docs(iroh): narrow production multistream claims * build(iroh): pin attested Swift fork release * test(iroh): require retry-safe binding revocation * fix(iroh): make binding revocation retry-safe * fix(iroh): durably retry binding revocations * build(iroh): lock iOS Swift fork release * test(iroh): retain Bonjour observation lifetime * test(auth): prepare before raced sign-out clear * test(iroh): quarantine failed sign-out persistence * test(ios): quarantine failed Iroh sign-out * fix(iroh): quarantine incomplete sign-out teardown * fix(iroh): clear host network state in quarantine * fix(auth): quarantine Iroh before sign-out clear * fix(ios): quarantine incomplete Iroh sign-out * fix(mobile): type Iroh binding snapshot * fix(ios): wait for auth clear before Iroh recovery * build(iroh): lock app Swift fork release * fix(iroh): persist secrets in ad-hoc debug builds * test(iroh): require local-only HTTP minter opt-in * feat(iroh): add loopback relay minter runner * test(tailscale): require numeric registry targets * feat(iroh): gate local relay minter HTTP * fix(iroh): normalize local minter opt-in * test(ios): require tagged API origin bake * fix(ios): bake tagged API origin * fix(tailscale): pin MagicDNS remotes to peer IPs * fix(tailscale): reject inactive peer snapshots * build(iroh): pin hardened FFI release * test(auth): preserve auto-login during token reads * test(auth): preserve manual sign-in during token reads * test(iroh): require startup network event delivery * fix(iroh): establish endpoint observation before activation * fix(auth): preserve active session writers * test(iroh): accept existing binding registration responses * fix(iroh): accept existing binding relay status * test(iroh): keep host active after refresh throttling * fix(iroh): preserve host during broker throttling * test(iroh): preserve client during broker throttling * fix(iroh): retain verified policy during broker outages * fix(iroh): decode broker dates on older macOS * test(iroh): reject synthetic network change floods * fix(iroh): observe address changes without feedback loop * test(iroh): accept canonical UUID identity case * fix(iroh): canonicalize pinned device UUIDs * fix(iroh): harden compatibility and private routes * refactor(iroh): split runtime ownership boundaries * test(iroh): repair authorization suite split boundaries * test(iroh): link mobile RPC authorization tests * test(iroh): support compatibility compilers * test(iroh): cover uppercase UUID fallback paths * fix(iroh): canonicalize device UUID authority * test(iroh): support Intel Sonoma compiler * test(iroh): avoid non-Sendable fixture captures * fix(updater): handle Intel-only Sparkle reason * test(iroh): cover bearer and discovery overload * fix(iroh): close route and discovery gaps * fix(ci): close Iroh compatibility regressions * feat(iroh): integrate endpoint-bound relay fleet * fix(ci): wrap command timers for Intel Swift * fix(ios): expose relay deployment to Sendable factory * test(ci): cover private networking on Intel Sonoma * test(ci): support Intel Swift Testing macros * test(iroh): expose relay refresh expiry gap * fix(iroh): retry relay refresh before expiry * fix(ios): serialize Iroh quarantine recovery * refactor(auth): isolate lifecycle revision API * fix(ci): eliminate Iroh Swift 6 warnings * fix(ci): support Intel Xcode 16.2 * fix(ci): mark canvas clock sleep sendable * fix(ci): bridge canvas preferences to main actor * fix(ci): support sidebar git on Xcode 16.2 * fix(ci): mark RPC termination handler sendable * fix(ci): support CLI on Xcode 16.2 * fix(ci): support app target on Xcode 16.2 * fix(ci): finish Xcode 16.2 source compatibility * iroh: point the broker relay fleet at the 7 self-hosted relay.cmux.dev URLs Replaces the 4 hosted iroh.link relays with our self-hosted fleet in both allowlists (web MANAGED_RELAY_URLS + presence worker APPROVED_IROH_RELAY_URLS, kept in lockstep) and the tests that referenced hosted URLs. The self-hosted relays run iroh-relay 1.0.2 behind per-region MIG+L4-LB (zero-downtime upgrades), gated by the cmux EdDSA JWT that /api/relay/token (merged, #7879) mints. * fix(ci): support trailing closure on Xcode 16.2 * ci: allow Intel compatibility suite to finish * test(ci): avoid Xcode 16.2 require recursion * ci: focus Intel compatibility coverage * fix(ci): stabilize replay ownership and Intel budget * test(ios): isolate authoritative resync coverage * feat(iroh): add secure flexible relay policy * test(iroh): split relay runtime coverage * test(iroh): allow self-hosted broker without legacy minter * fix(iroh): make hosted relay minter optional * test(iroh): cover public firewall host fallback * fix(iroh): use public host for firewall checks * fix(iroh): keep accepts and sign-out responsive * test(iroh): reproduce lost online reachability * fix(iroh): republish endpoint online routes * test(iroh): reproduce coalesced route refresh * fix(iroh): replay coalesced route refreshes * refactor(iroh): split oversized runtime files * test(iroh): cover lifecycle refresh races * fix(iroh): fence lifecycle refresh work * test(ios): reproduce loopback dev auto-pair race * test(ios): cover redacted dev Iroh attach URLs * fix(ios): wait for redacted Iroh dev attach ticket * test(ios): reproduce Iroh cold-start attach race * fix(ios): await Iroh before dev auto-pair * feat(iroh): add server-driven relay preferences * feat(iroh): complete relay controls and multistream runtime * ci: rehearse staging migrations from dispatched branch * Make managed Iroh credentials server-driven * feat(iroh): expose redacted live path diagnostics * security(iroh): stage relay policy key rotation * fix(iroh): use instance-scoped host display name * test(iroh): require dev attach targets to prefer identity routes * fix(iroh): prefer identity routes for dev attach * fix(web): include shared relay catalog in Next root * test(web): keep relay catalog inside Next boundary * fix(web): generate relay catalog inside runtime boundaries * test(mobile): cover transport lifetime ownership * fix(mobile): retain Iroh transport lifetime * test(iroh): cover relay policy clock skew * fix(iroh): tolerate bounded relay policy clock skew * test(iroh): cover admitted session lifetime * fix(iroh): separate admission and session lifetimes * test(iroh): cover relay and route renewal stalls * fix(iroh): keep relay routes renewed through storage stalls * test(iroh): cover nonblocking binding persistence * fix(iroh): publish bindings before secure persistence * test(iroh): cover strict transport verification modes * feat(iroh): add strict transport verification modes * test(iroh): await nonblocking relay persistence * test(iroh): cover live peer connection quotas * fix(iroh): bound live sessions per endpoint * test(iroh): cover broker-aware route renewal backoff * fix(iroh): back off broker route renewal retries * test(mobile): cover superseded Iroh transport cleanup * fix(iroh): close unowned mobile sessions * test(iroh): reproduce stale reconnect sessions * fix(iroh): replace stale peer sessions on admission * feat(iroh): add debug transport mode menu * Add regression coverage for Iroh merge blockers * Fix Iroh relay and reconnect merge blockers --------- Co-authored-by: lawrencecchen <54008264+lawrencecchen@users.noreply.github.com> Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> Co-authored-by: Aziz Albahar <aziz@manaflow.ai> | 2 个月前 | |
refactor: extract Kimi hook logic into dedicated files with tests and localized strings - Move the Kimi TOML [[hooks]] block transformation from CLI/cmux.swift into the CMUXAgentLaunch package as KimiCodeHookConfig, mirroring HermesAgentHookConfig/RovoDevHookConfig, and add a behavioral test suite (exact install layout, idempotence, reinstall, round-trip uninstall, TOML escaping, and a regression for the orphaned-begin-marker line skip fixed in eff68a125d). - Move the CLI file-IO wrapper to CLI/CMUXCLI+KimiHooks.swift and route every user-facing message through String(localized:) with cli.hooks.kimi.* keys (all locales; Japanese translated), addressing the open review threads. - Offset the CLI/cmux.swift and CMUXCLI+AgentHookDefinitions.swift file-length budgets by moving the RovoDev hook installers to CLI/CMUXCLI+RovoDevHooks.swift and the agent catalog to CLI/CMUXCLI+AgentHookCatalog.swift (pure moves). - Wire the three new CLI files into cmux.xcodeproj. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> | 3 个月前 | |
Reduce Sentry CLI broken-pipe crashes and hangs (#6254) * Add closed-stderr CLI broken pipe regression test * Handle CLI broken pipes with safe stdio writes * Limit clean broken-pipe exits to fatal stderr writes * Drop CLI unit test that depends on cli-target internals The CLIBrokenPipeWriteTests class called cliWrite() directly, but that symbol lives in the cmux-cli target and is not visible from cmuxTests, so CI failed to compile. Even with visibility, calling Darwin.write into a closed pipe inside the XCTest host crashes the runner via SIGPIPE (only the CLI binary's main() ignores SIGPIPE). The existing E2E test exercises the same closed-stderr path through the real cmux binary, so coverage is preserved. Restore cliWrite and the disposition enum to private and harden the E2E test: - XCTWaiter().wait + early XCTFail on timeout instead of falling through to assertions on a still-running process - closeOnDealloc: false so the explicit defer is the sole owner of the stderr write fd Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add CLI broken-pipe regression coverage * Scope CLI SIGPIPE handling to write and launch paths * Address CI failures and review feedback on CLI broken-pipe PR - Fix defer block return error by gating cleanup on `installed` flag - Replace Python-based SIGPIPE probe with native `__sigpipe-inspect` subcommand; removes Python dependency and avoids masking inherited SIGPIPE disposition - Fix strdup type-inference error in exec-mode probe via explicit `[UnsafeMutablePointer<CChar>?]` typing - Convert auth status/login/logout `print()` callsites to `cliPrint()` so broken-pipe writes don't crash auth subcommands - Drain spawn-probe pipes before `waitUntilExit()` to prevent deadlock - Include `cliWriteFatalStderr` in stdio-safety audit summary Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use _exit in cliWrite EPIPE path to avoid deadlock under held lock cliWrite calls Darwin.exit while holding cliSIGPIPEDispositionLock (NSLock is non-reentrant). Any atexit handler that wrote through cliWrite/cliPrint would re-enter withCLISIGPIPEDisposition and deadlock. _exit also skips atexit/stdio flush, matching the default SIGPIPE termination this path replaces when stdout is closed by the consumer. Addresses Cursor Bugbot comment on PR #2993. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Poll for writable FD on EAGAIN in cliWrite Addresses Cursor bot review on PR #2993: the previous `case EINTR, EAGAIN, EWOULDBLOCK: continue` turned non-blocking writes into a busy-wait spin under the SIGPIPE disposition lock. Split EINTR (immediate retry) from EAGAIN/EWOULDBLOCK (block on poll(POLLOUT)) so a non-blocking stdio fd yields to the kernel instead of spinning. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use F_NOSIGPIPE on CLI stdio instead of per-write sigaction Every cliPrint was wrapped in withCLISIGPIPEIgnored, which took a process-wide NSLock and did three sigaction syscalls per write to temporarily install SIG_IGN around Darwin.write. For a command like `cmux help` (~142 lines) that added ~426 extra syscalls. Opt stdout/stderr into F_NOSIGPIPE once at CLI startup — the same per-FD pattern the socket path already uses via SO_NOSIGPIPE — so write(2) just returns EPIPE and the hot path is a single write syscall per call. Keeps withCLIDefaultSIGPIPEForChildLaunch for Process.run / exec paths in case the CLI was invoked with SIG_IGN inherited, but those are low-frequency and not on the stdio write path. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix CLI SIGPIPE child inheritance and pipe writes * Close CLI stdio disposition race CLI writes and child launch setup now share one lock around stdio disposition changes, so no write can run while inherited stdout/stderr have F_NOSIGPIPE temporarily cleared for a child process. Constraint: Cursor review identified a race between child-launch fd mutation and concurrent broken-pipe writes Rejected: Reintroduce process-wide SIGPIPE ignore | would make child processes inherit the wrong SIGPIPE disposition again Confidence: high Scope-risk: narrow Directive: Any future stdio-disposition mutation must coordinate with cliWrite via cliStdioDispositionLock Tested: bash scripts/check-cli-stdio-safety.sh; git diff --check on CLI/CMUXCLI+Process.swift Not-tested: macOS app/unit/UI workflows locally; awaiting PR CI * Keep SIGPIPE probe parsing compiler-compatible The CI Debug build uses Swift syntax rules that reject value-binding patterns inside expression-style array patterns, so the internal SIGPIPE inspection probe parses its optional output path through an explicit count check instead. This keeps the probe behavior unchanged while restoring build compatibility for the activation-session job. Constraint: PR iteration must rely on CI and must not run bare xcodebuild locally Rejected: Remove the probe output-path support | tests use it to inspect stdio state without relying on a live stdout Confidence: high Scope-risk: narrow Tested: bash scripts/check-cli-stdio-safety.sh; git diff --check -- CLI/CMUXCLI+Process.swift; rg conflict marker scan Not-tested: Local Xcode build prohibited by task instructions * Expose SIGPIPE inspection fixture to CLI tests The SIGPIPE child-disposition regression lives in CLINotifyProcessIntegrationTests after the main-branch test split, while the decoded inspection payload type was left private inside WorkspaceRemoteConnectionTests. Moving the fixture to file scope keeps the same assertions and lets the unit target compile. Constraint: CircleCI unit compile logs are the verification source; local Xcode test runs are prohibited Rejected: Duplicate the struct inside CLINotifyProcessIntegrationTests | unnecessary copy for a file-local test fixture Confidence: high Scope-risk: narrow Tested: bash scripts/check-cli-stdio-safety.sh; git diff --check -- cmuxTests/WorkspaceRemoteConnectionTests.swift; conflict-marker scan Not-tested: Local cmux-unit Xcode test run prohibited by task instructions * Fix CLI SIGPIPE feedback * Fix SIGPIPE probe inherited fd snapshot * Fix SIGPIPE exec probe argv typing * Fix CMUXCLI SIGPIPE snapshot initializer * Rerun CI for CLI broken pipe fix * Fix SIGPIPE inspect signal snapshot order * Fix tmux shell stdin broken pipe path * Centralize CLI no-sigpipe writes * Close CLI stdin pipes with safe FileHandle API * Add CLI stdio lock regression coverage * Fix CLI non-stdio write lock handling * Fix CLI poll hangup broken-pipe path * Route codex teams watcher stderr through CLI writer * Move non-stdio CLI lock probe into CLI * Avoid stdio lock for isolated child launches * Fix merged CLI stdio writes * Add PostHog flush deadlock regression test * Avoid synchronous PostHog flush during quit * fix: keep spawned CLI children on default SIGPIPE fds * test: split SIGPIPE regression coverage * Flush active analytics before shutdown * Keep PostHog analytics singleton construction private * Document PostHog analytics queue isolation * Split PostHog analytics tests * Rerun CI after runner cache miss * fix: suppress expected CLI socket Sentry noise * test: keep stale socket regression path short * fix: make Sentry noise filter instantiable * refactor: split CLI Sentry telemetry tests * fix: address Sentry crash reduction review feedback * fix: close CLI SIGPIPE review gaps --------- Co-authored-by: austinpower1258 <austinwang115@gmail.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> | 3 个月前 | |
Add first-class Mosh transport for remote workspaces (#8442) * Add Mosh transport for remote workspaces * Localize Mosh docs across supported locales * Align Mosh transport error fallback * Test Mosh persistent PTY normalization * Disable persistent PTY state for Mosh terminals * Add first-class mosh and mosh-tmux profiles * Test remote mosh-server resolution outside PATH * Stage managed bootstrap for Mosh terminals * Test Mosh management lane activation * Activate Mosh management lane before terminal * Test tmux workspace rebinding on reattach * Rebind tmux sessions to current remote workspace * Test unsupported Mosh snapshot restore * Use canonical Mosh restore support gate * Test new tmux session workspace binding * Bind new tmux sessions to current workspace * Test bounded Mosh fallback launcher * Keep Mosh fallback launcher bounded * Test tmux default command window target * Target tmux default command at session window * Preserve user ZDOTDIR in tmux shells * Test remote relay Git metadata reporting * Test tmux relay metadata parity * Report remote shell metadata through relay * Test remote prompt relay metadata parity * Synchronize prompt relay behavior tests * Run remote prompt metadata through relay * Test tmux initial command delivery * Deliver initial command to new tmux session * Align Mosh builders with package policy * Test tmux session target separators * Reject tmux session target separators --------- Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> | 2 个月前 | |
Chain SSH config RemoteCommand into cmux interactive sessions (#9114) * Add failing SSH RemoteCommand chaining tests * Chain SSH config RemoteCommand into interactive sessions * Preserve SSH RemoteCommand across workspace restore * Bound SSH config resolution and sanitize RemoteCommand * Preserve RemoteCommand intent for fallback restores * Reuse resolved SSH executable across startup * fix(ssh): pin managed hops to system OpenSSH * test(ssh): use Swift Testing for remote command regressions * test: cover SSH config fallback and resume chaining * fix: keep managed SSH launch and resume resilient * test: cover SSH resume and config fallback precedence * fix: define SSH command precedence during recovery * test: cover authoritative SSH and Mosh fallbacks * test: inspect generated SSH fallback artifact * fix: preserve authoritative SSH and Mosh command fallbacks * test: cover Mosh config-resolution fallback * fix: retain SSH fallback when Mosh config is unavailable * test: cover RemoteCommand token expansion * test: cover raw RemoteCommand token output * test: instantiate RemoteCommand policy fixture * test: drop synthetic raw SSH config fixture * docs: record SSH config token expansion contract * test: cover SSH and Mosh fallback consistency * fix: align SSH fallback transport and command intent * test: execute restored RemoteCommand through SSH quoting * fix: preserve RemoteCommand quoting across SSH restore --------- Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> | 2 个月前 | |
Chain SSH config RemoteCommand into cmux interactive sessions (#9114) * Add failing SSH RemoteCommand chaining tests * Chain SSH config RemoteCommand into interactive sessions * Preserve SSH RemoteCommand across workspace restore * Bound SSH config resolution and sanitize RemoteCommand * Preserve RemoteCommand intent for fallback restores * Reuse resolved SSH executable across startup * fix(ssh): pin managed hops to system OpenSSH * test(ssh): use Swift Testing for remote command regressions * test: cover SSH config fallback and resume chaining * fix: keep managed SSH launch and resume resilient * test: cover SSH resume and config fallback precedence * fix: define SSH command precedence during recovery * test: cover authoritative SSH and Mosh fallbacks * test: inspect generated SSH fallback artifact * fix: preserve authoritative SSH and Mosh command fallbacks * test: cover Mosh config-resolution fallback * fix: retain SSH fallback when Mosh config is unavailable * test: cover RemoteCommand token expansion * test: cover raw RemoteCommand token output * test: instantiate RemoteCommand policy fixture * test: drop synthetic raw SSH config fixture * docs: record SSH config token expansion contract * test: cover SSH and Mosh fallback consistency * fix: align SSH fallback transport and command intent * test: execute restored RemoteCommand through SSH quoting * fix: preserve RemoteCommand quoting across SSH restore --------- Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> | 2 个月前 | |
Add first-class Mosh transport for remote workspaces (#8442) * Add Mosh transport for remote workspaces * Localize Mosh docs across supported locales * Align Mosh transport error fallback * Test Mosh persistent PTY normalization * Disable persistent PTY state for Mosh terminals * Add first-class mosh and mosh-tmux profiles * Test remote mosh-server resolution outside PATH * Stage managed bootstrap for Mosh terminals * Test Mosh management lane activation * Activate Mosh management lane before terminal * Test tmux workspace rebinding on reattach * Rebind tmux sessions to current remote workspace * Test unsupported Mosh snapshot restore * Use canonical Mosh restore support gate * Test new tmux session workspace binding * Bind new tmux sessions to current workspace * Test bounded Mosh fallback launcher * Keep Mosh fallback launcher bounded * Test tmux default command window target * Target tmux default command at session window * Preserve user ZDOTDIR in tmux shells * Test remote relay Git metadata reporting * Test tmux relay metadata parity * Report remote shell metadata through relay * Test remote prompt relay metadata parity * Synchronize prompt relay behavior tests * Run remote prompt metadata through relay * Test tmux initial command delivery * Deliver initial command to new tmux session * Align Mosh builders with package policy * Test tmux session target separators * Reject tmux session target separators --------- Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> | 2 个月前 | |
Prevent stalled remote PTY starts and bound wedged reattach loops (#9111) * test(remote): reproduce PTY hub start wedge * fix(remote): isolate persistent PTY session startup * test: bound zero-progress SSH PTY reattach churn * fix: stop zero-progress SSH PTY attach loops * test: prove concurrent PTY starts coalesce * Fix SSH PTY retry policy target ownership * fix: bound managed SSH PTY retry churn * fix: isolate stalled remote PTY attaches * fix: close remote PTY attach teardown races * fix: preserve remote PTY session generations * fix: harden remote PTY lifecycle handoffs * fix: bound PTY exit output draining * test: preserve remote PTY capacity failures * fix: retry remote PTY capacity failures * test: bound remote PTY capacity recovery * fix: bound remote PTY start waiters * test: update persistent PTY retry contract * test(remote): hide retained fast-exit generations * fix(remote): separate retained and live PTY state * test: preserve daemon transport after PTY attach timeout * fix: isolate PTY attach call timeouts * test: cancel timed-out remote PTY attaches * fix(remote): cancel timed-out PTY attach requests * fix(remote): bound PTY attach cancellation writes * fix(remote): use cancellable attach timeout timers * test(remote): pin canceled start publication race * fix(remote): linearize PTY start waiter cancellation * test(remote): assert timeout cancellation ordering * test(remote): expose completed attachment context leak * fix(remote): release completed attachment contexts * test(remote): advertise attach cancellation in bridge fixture * test(remote): expose canceled anonymous PTY retention * fix(remote): terminate canceled anonymous PTY starts * test(remote): distinguish replay from live PTY output * fix(remote): exclude replay from attach progress * test(remote): require cancellable attachment identities * fix(remote): require cancellable attachment ids | 2 个月前 | |
Use Swift Testing for SSH manual reconnect coverage | 3 个月前 | |
Fix stale SSH workspace connection status (#9085) * test: cover authoritative SSH terminal liveness * fix: derive SSH status from terminal liveness * fix: close SSH terminal lifecycle races * fix: authenticate SSH terminal readiness * fix: bind SSH liveness to terminal authority * fix: make Dock SSH readiness transactional * test: assert remote terminal end acceptance * test: reject retired PTY lifecycle readiness * fix: revalidate PTY lifecycle at readiness commit * test: cover remote readiness lifecycle races * fix: harden remote terminal lifecycle ownership * test: cover stale remote terminal generations * fix: authenticate remote terminal lifecycle callbacks * fix: bound remote lifecycle commit side effects * chore: document remote lifecycle ownership boundaries * test: cover reordered remote readiness callbacks * fix: order remote terminal lifecycle callbacks * test: cover remaining SSH lifecycle ordering gaps * fix: close remaining SSH lifecycle ordering gaps * test: cover lossy SSH liveness reconciliation * fix: make SSH liveness reconciliation resilient * test: cover remaining SSH liveness races * fix: close remaining SSH liveness races * test: cover Mosh and transient SSH readiness * fix: make terminal readiness authoritative * test: cover premature terminal readiness * fix: require proven terminal readiness * test: pass Dock readiness attempt generation * test: cover remote lifecycle review regressions * fix: preserve remote lifecycle routing * fix: retire orphaned remote lifecycles * test: cover raw SSH readiness gating * fix: decouple raw SSH readiness reporting * test: cover restored SSH lifecycle reporting * fix: restore SSH lifecycle authority * test: cover SSH lifecycle review regressions * fix: close SSH lifecycle review gaps * test: cover bounded SSH readiness lifecycle * fix: bound persistent SSH readiness retries * test: expose queued SSH readiness duplicates * fix: coalesce persistent SSH readiness delivery * fix: compile remote lifecycle app adapters * fix: satisfy ssh readiness closeout policy --------- Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> | 2 个月前 | |
Fix Codex session restore authority after 0.64.17 (#6712) * test: cover stale codex session listing * fix: filter stale session list rows * fix: include cwd-filtered session records * fix: localize sessions help headers * Fix Codex restore binding authority * Fix restore regression test file budgets * Fix CLI helper test target membership * Prevent foreign hook env from restoring mapped Codex sessions * Reject process-only Codex restore evidence * Preserve durable Codex resume bindings * Keep default Codex resume binding * Keep durable Codex launch records in store * Require evidence for ambient Codex fallback * Trust sourced Codex argv evidence * Keep plain Codex records restorable * Separate rejected Codex launch captures * Fail closed for rejected Codex captures * Persist rejected Codex launch captures * Unify rejected hook evidence handling * Split hook session store file * Preserve legacy Codex argv records * Reject weak ambient Codex targets before direct routing * Keep env-routed hooks targetable without local tty * Fail closed on nil Codex restore evidence * Show launch-backed sessions by default * Require launch records for sessions list launch backing * Preserve mapped resume evidence against weak captures * Require concrete mapped evidence for weak Codex fallback * Accept legacy Codex argv evidence * Persist explicit default Codex launch evidence * Reject weak Codex process launch evidence * Keep default Codex evidence below richer records * Avoid persisting weak prompt submit evidence * Reject weak Codex launch evidence on reload * Trust process Codex argv despite weak env * Strip weak Codex launch env on restore load * Use preferred cwd for stop resume updates * Let default Codex evidence heal weak records * Mention terminal_id in surface.resume target validation doc comment Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 3 个月前 | |
Keep forkable sessions with stale pids (#6803) * Add stale pid fork diagnostics regression tests * Preserve forkable sessions with stale pids * Add fork diagnostics command-builder regression * Share fork argv diagnostics * Clarify fork startup diagnostics * Harden fork diagnostics metadata * Resolve fork diagnostics policy findings * Add fork diagnostics review regressions * Address fork diagnostics review feedback * Add OpenCode fork support diagnostic regression * Split fork command diagnostics from support * Add Claude transcript fork diagnostic regression * Treat transcript-backed Claude sessions as restorable * Add fork startup environment diagnostic regression * Count full fork startup command in diagnostics * Add Claude transcript lookup diagnostic regression * Mirror Claude transcript lookup in fork diagnostics * Split fork diagnostics regressions * Add PID reuse fork diagnostic regression * Flag saved PIDs as restore risk * Add OpenCode version probe diagnostic regression * Probe OpenCode version for fork diagnostics * Add Codex fork prompt tag regression * Preserve Codex fork prompt tags * Address fork diagnostics review feedback * Add Claude workflow fork diagnostic regression * Resolve Claude workflow fork diagnostics * Keep fork diagnostic tests under length budget * Address workflow and fork tag review findings * Align Claude workflow session list identity * Preserve Codex fork tags in hook capture * Add OpenCode fork trust regression * Trust only verified launch captures in fork diagnostics * Address sessions list diagnostic review feedback | 3 个月前 | |
Fix Pi and OMP fork actions in tab context menus (#8173) * Add failing Pi context menu fork test * Expose native Pi fork actions * Add failing Pi family fork argv tests * Use Pi family fork session values * Preserve Pi family fork compatibility * Keep persisted Pi fork ownership * Migrate historical Pi fork registrations * Preserve explicit Pi fork overrides * Keep fork marker parsing local * Gate Pi forks on installed capability * Harden Pi fork capability checks * Probe Pi fork support by core version * Use effective Pi fork launcher version * Bound Pi fork capability probes * Wire Pi capability cache into app * Align Pi probe and fork execution * Fail closed on unverified Pi CLI forks * Validate Pi version probe results * Remove forbidden iOS workspace lockfile * Restore tri-state Bonsplit fork availability * Silence fork probe concurrency warnings * Keep Pi fork fix scoped to app behavior * Test Pi probe cache environment isolation * Key fork probes by effective environment * Test metadata-only Pi fork overrides * Gate built-in Pi fork command semantics * Test Pi-family shared fork cache identity * Include probe identity in fork support cache * Test bounded fork probe cache eviction * Bound fork probe caches * Restore process termination gate helper * Test fork probe cache review regressions * Fix fork probe cache review regressions * Satisfy fork probe review policies * Fix cross-SDK probe drain read * Address fork probe review findings * Prefer registration identity for Pi family probes * Harden Pi family probe execution * Require Pi family identity in wrapper versions * Tighten Pi fork capability cache identity * Bind Pi family probe versions to agent tokens * Kill Pi fork probe process groups on timeout * Fix fork probe refresh cache ownership * Fix fork validation request lifecycle * Fail closed and restart fork validation refreshes * Expire fork executable watches before budget checks * Restart queued fork validations after follow-up refreshes * Avoid async nil-coalescing in palette fork probe * Type palette fork executable fingerprints explicitly * Bound command palette fork probe expiry lifecycle * Drain fork probe output off the Swift executor * Share fork executable watchers across panels * Fix fork probe drain data append * Avoid overlapping fork probe buffer access * Merge concurrent fork executable watch installs * Scope fork watch invalidation and pipe inheritance * Harden fork probe cache activation | 2 个月前 | |
Add Campfire support (#5813) * Add Campfire hook installation and session restore Campfire (the collaborative pi-based harness) becomes a first-class agent: - cmux hooks campfire install/uninstall writes a native extension to ${CAMPFIRE_CODING_AGENT_DIR:-~/.campfire/agent}/extensions/ cmux-campfire-session.ts; opt out per process with CMUX_CAMPFIRE_HOOKS_DISABLED=1 - the extension records the HOST role only (CAMPFIRE_SESSION_ROLE); a joiner is an ephemeral view whose argv carries the invite URL, a capability token that is never persisted or replayed - launch capture normalizes the bun-compiled argv (drops the bunfs virtual entry) and tags kind=campfire so restore runs campfire --session <id> instead of mis-resuming as plain pi - the extension subscribes to campfire's in-process observer bridge (Symbol.for campfire.observer.v1) and surfaces driver-actionable collaborative moments — a joiner waiting in the lobby, a capability ask — as cmux notifications - sanitizer policy preserves --relay/--model config flags and drops prompts, session selectors, --join-as, and invite URLs; environment policy replays CAMPFIRE_* config roots, never secrets, and drops the self-managed PI_PACKAGE_DIR so an upgraded binary is not pinned to a stale asset cache - Vault and Task Manager detect campfire processes (compiled binary and bun dev invocations) with sessions under ~/.campfire/agent/sessions - docs, en+ja (and 18 more locales) CLI strings, Swift + Python tests, CI hookup Verification: - swift test --package-path Packages/CMUXAgentLaunch (82 tests) - xcodebuild test -only-testing:cmuxTests/CampfireSupportTests (4 tests) - CMUX_CLI_BIN=... python3 tests/test_campfire_extension_install.py - xcodebuild build (full app, tagged derived data) - ./scripts/check-pbxproj.sh && ./scripts/lint-pbxproj-test-wiring.sh Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address PR review: Campfire session-dir precedence and relay-error privacy - VaultAgentProcessScanner: gate PI_CODING_AGENT_SESSION_DIR out of the campfire registration so Campfire (which embeds Pi) resolves sessions against CAMPFIRE_CODING_AGENT_SESSION_DIR / CAMPFIRE_CODING_AGENT_DIR instead of being silently pre-empted by a user's Pi session dir. pi/omp behavior unchanged. Adds a regression test. - CMUXCLI+CampfireExtension: drop the raw relay reason from the user-facing notification; emit a generic message per the error-privacy policy. - AgentLaunchEnvironmentPolicyTests: assert both pi and omp keep PI_PACKAGE_DIR (test previously only exercised pi). - test_campfire_extension_install: preserve falsey JSON-RPC ids (0) when echoing responses instead of rewriting them to "unknown". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Add Campfire Vault detection regression tests * Tighten Campfire Vault process detection * Add Campfire notification and Vault regressions * Fix Campfire notification and Vault matching * Cover structured Campfire observer payloads * Require Campfire argv cue for Vault fallback * Cover non-Campfire packages session argv * Use precise Campfire Vault entrypoint alternatives * Cover mentioned Campfire entrypoint argv * Constrain Campfire Vault alternates to runtimes * Address Campfire autoreview policy findings * Fix Campfire runtime Vault restore executable * Gate Campfire Vault detection to hosts * Fix Campfire Bun argv restore * Add failing test for alternate-only Vault detect rule A CmuxVaultAgentDetectRule that specifies only alternate criteria (no primary process names and no argvContains) currently matches every process: the empty primary criteria make primaryMatches return true before the alternate criteria are checked. This test asserts an unrelated `node` process is not classified, and fails without the fix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Address PR review: detect-rule matching, ts-node host, capability fallback - VaultAgentProcessScanner: gate the primary match on the presence of primary criteria so an alternate-only detect rule no longer matches every process (fixes the test added in the previous commit). - TaskManagerTypes: add `ts-node` to argumentHostBasenames so Task Manager classifies `ts-node …/campfire.ts` as Campfire, matching the hosts already recognized by Vault detection. - cmux CLI: route unknown/unmapped Campfire capability values to the localized fallback label instead of surfacing the raw identifier in user-facing notification copy. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Fix Campfire review blockers * Restore ghostty and bonsplit submodule pointers to main * Revert unrelated renderer-realizer shim; scoped to main's implementation * Drop PI_CODING_AGENT_SESSION_DIR from campfire resume environment The scanner already gates PI_CODING_AGENT_SESSION_DIR out when resolving Campfire session roots, but restore still replayed it into resumed Campfire processes. Since Campfire embeds Pi, a user's custom Pi session root could then receive resumed Campfire session state while cmux reads the Campfire root. Drop it for campfire resumes alongside PI_PACKAGE_DIR; pi/omp behavior is unchanged. * Recognize campfire script entrypoints under deno/tsx/ts-node hosts AgentLaunchCaptureTrust only treated node and bun as hosts that can run a Campfire entrypoint, so PID-based argv fallback dropped campfire hook captures launched via deno, tsx, or ts-node even though the rest of the Campfire support (normalizer, scanner, task manager) recognizes those hosts. Gate the campfire needle check on the same host set; the claude detection stays limited to node/bun. * Refresh Swift file length budget for campfire growth workflow-guard-tests failed on the file-length budget: the Campfire feature grows CLI/cmux.swift, VaultAgentProcessScanner, TaskManagerTypes, RestorableAgentSession, the CMUXAgentLaunch sanitizer files, and adds cmuxTests/CampfireSupportTests.swift past the tracked thresholds. Accept the feature growth in the budget; no unrelated entries changed. --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: lawrencecchen <54008264+lawrencecchen@users.noreply.github.com> | 2 个月前 | |
Keep forkable sessions with stale pids (#6803) * Add stale pid fork diagnostics regression tests * Preserve forkable sessions with stale pids * Add fork diagnostics command-builder regression * Share fork argv diagnostics * Clarify fork startup diagnostics * Harden fork diagnostics metadata * Resolve fork diagnostics policy findings * Add fork diagnostics review regressions * Address fork diagnostics review feedback * Add OpenCode fork support diagnostic regression * Split fork command diagnostics from support * Add Claude transcript fork diagnostic regression * Treat transcript-backed Claude sessions as restorable * Add fork startup environment diagnostic regression * Count full fork startup command in diagnostics * Add Claude transcript lookup diagnostic regression * Mirror Claude transcript lookup in fork diagnostics * Split fork diagnostics regressions * Add PID reuse fork diagnostic regression * Flag saved PIDs as restore risk * Add OpenCode version probe diagnostic regression * Probe OpenCode version for fork diagnostics * Add Codex fork prompt tag regression * Preserve Codex fork prompt tags * Address fork diagnostics review feedback * Add Claude workflow fork diagnostic regression * Resolve Claude workflow fork diagnostics * Keep fork diagnostic tests under length budget * Address workflow and fork tag review findings * Align Claude workflow session list identity * Preserve Codex fork tags in hook capture * Add OpenCode fork trust regression * Trust only verified launch captures in fork diagnostics * Address sessions list diagnostic review feedback | 3 个月前 | |
Add native iPhone and iPad Simulator panes (#7857) * tighten simulator shortcut and mutation paths * Harden simulator operation commit boundaries * Close simulator routing and deadline races * Reconcile simulator mutations during teardown * Preserve simulator caller routing context * Route ios commands from caller pane * Preserve explicit simulator routing and input recovery * Serialize simulator text recovery * Align simulator deadlines and selection rollback * Close simulator lifecycle commit races * Reject stale simulator discovery results * Bound simulator re-enable and batch capture * Select the integrated simulator display * Close simulator transition races * Gate simulator automation on readiness * Finish simulator selection generation checks * Bound simulator context work end to end * Verify simulator descendant identities * Validate simulator process ancestry * Bound simulator process shutdown * Supervise simulator command groups * Supervise simulator pane sessions * Contain every simulator subprocess * Test simulator routing and feature flag regressions * Fail closed on stale simulator state * Test simulator lifecycle review regressions * Bound simulator control lifecycles * Test simulator cross-pane ownership regressions * Serialize simulator cross-pane mutations * Test Web Inspector cross-worker ownership * Lease Web Inspector targets across workers * Test Web Inspector stale occupancy handoff * Refresh Web Inspector occupancy during handoff * Test Web Inspector occupancy timeout * Fail closed on incomplete Inspector occupancy * Test Inspector census and release regressions * Close Inspector refresh and release races * Test stale location route teardown * Preserve location route ownership through teardown * Test Simulator launch environment privacy * Test route commit during device switch * Test feature flag telemetry consent * Own Simulator mutations through teardown * Harden Simulator isolation and ownership * Persist Simulator mutation ownership across processes * Honor telemetry consent for remote flags * Preserve failed Simulator cleanup ownership * Propagate Simulator CLI routing errors * Fix Simulator operation task syntax * Inject Simulator ownership and keep context read-only * Resolve restored Simulator context without booting * Test late Simulator display identity publication * Attach Simulator callbacks before display discovery * Test Simulator mutation ownership boundaries * Harden Simulator mutation ownership semantics * Test current Simulator default-screen contract * Support current Simulator default-screen metadata * Isolate Simulator camera transport tests * Test forwarded Simulator screen metadata * Support forwarded Simulator screen metadata * Align Simulator overlay lifecycle test with visibility * Bound Simulator recovery assertion by time * Make Simulator input recovery test deterministic * Test Simulator landscape framebuffer direction * Correct Simulator landscape presentation direction * Bound Simulator frame publication test wait * Register Simulator replay state before delivery * Test Simulator review boundary cases * Test iOS screenshot surface identity errors * Normalize Simulator control boundaries * Isolate Simulator CLI contract environment * Test native Simulator orientation dialects * Unify native Simulator orientation semantics * Test landscape Simulator digitizer coordinates * Map landscape input into native digitizer space * Test stable Simulator app switcher hold * Hold app switcher gesture stationary * Test Simulator app switcher button timing * Open Simulator app switcher with double Home * Test installed iPad DeviceKit chrome fallback * Test bounded Simulator frame publication * Scale Simulator frames to pane geometry * Test Simulator frame ring replacement cleanup * Release obsolete Simulator frame rings * Route IndexNow jobs through configured runner * Remove wall-clock assertions from RPC event tests * Test frame ring adoption race * Retire Simulator frame rings after host adoption * Keep frame completion on MainActor * Snapshot Simulator activity log before lazy layout * Regenerate webview assets after main merge * Test Simulator core readiness ordering * Stream Simulator before optional capability probes * Test control-socket Simulator selection ownership * Exclude active Simulator control action from teardown * Test natural DeviceKit chrome cap geometry * Preserve native DeviceKit chrome artwork geometry * Fix design mode test payload shadowing * Make Simulator replay tests signal-driven * Fix Simulator pane test client conformance * Test immediate Simulator context discovery * Discover Simulator before context reads * Test Simulator production edge cases * Close Simulator production review findings * Fix Simulator integration test fixtures * Fix Simulator CLI routing call site * Fix Simulator focus test fixtures * Fix Simulator app test fixtures * Test Simulator capability hydration readiness * Wait for Simulator capability hydration * Test Simulator review edge cases * Close Simulator production review gaps * Avoid recursive Simulator picker comparison * Isolate Simulator picker observation * Test Simulator application row snapshots * Snapshot Simulator application picker rows * Test static Simulator frame presentation * Drive Simulator frames without display callbacks * Test Simulator visibility remounts * Keep Simulator frames through host remounts * Isolate Simulator visibility regression suite * Test Simulator frame pacing under input load * Pace Simulator framebuffer readback * Localize project surface labels * Test Camera Injector header cache identity * Invalidate Camera Injector cache for headers * Test Simulator RPC capability discovery * Advertise Simulator RPC capabilities * test(simulator): cover interactive frame priority * fix(simulator): prioritize frames after pointer input * test(simulator): cover native tap hold duration * fix(simulator): hold synthetic taps long enough for iPadOS * Test immediate Simulator frame presentation * Present Simulator frames without an extra tick * Test failed Simulator ownership publication * Reject unsafe Simulator ownership claims * test(simulator): cover framebuffer lifecycle bounds * fix(simulator): bound framebuffer lifecycle work * test(simulator): cover review lifecycle regressions * fix(simulator): close review lifecycle gaps * test(simulator): cover routing pacing and consent * fix(simulator): scope routing pacing and consent * test(simulator): cover screenshot and cached log readiness * fix(simulator): prepare capture without eager lifecycle work * test(simulator): report capture-ready live state * fix(simulator): report live capture-ready state * test(simulator): cover control-plane and frame wakeups * fix(simulator): signal frames and preserve errored flag cache * test(simulator): cover publication wakeup races * fix(simulator): bound publication wakeups * test(simulator): cover tool editor shortcut focus * fix(simulator): preserve tool editor focus ownership * test(simulator): cover flag omission and runner injection * fix(simulator): inject async owned command execution * test(simulator): cover file drop proposal readiness * fix(simulator): validate file drop proposals * test(simulator): cover compound inspector cleanup failure * fix(simulator): preserve failed inspector cleanup state * test(simulator): cover device-scoped tool state * fix(simulator): scope tool state to selected device * test(simulator): cover final release blockers * fix(simulator): close final release blockers * test(simulator): make frame scheduling assertions deterministic * test: update Ghostty surface config ABI lock * fix(simulator): clear final build gates * fix(build): import Dock lifecycle workspace types * test(web): isolate feedback route environment * fix(build): disambiguate Dock snapshot types * test(simulator): cover review ownership blockers * fix(simulator): scope camera cleanup ownership * fix(build): make resume policy returns explicit * test(simulator): cover camera cleanup ownership retries * fix(simulator): preserve camera cleanup ownership * fix(build): clear latest main gates * test(simulator): cover final review blockers * fix(simulator): await quit cleanup and index targets * refactor(simulator): satisfy production policy * test(simulator): cover camera cleanup on device switch * fix(simulator): clean camera state before device switch * test(simulator): retain quit cleanup after panel removal * fix(simulator): make quit await durable rollback * test(simulator): cover retained cleanup recovery * fix(simulator): recover retained camera cleanup * test(simulator): cover cleanup side effects * fix(simulator): restore external cleanup state * refactor(simulator): split camera authorization record * test(web): respect delegated discovery order * test(ios): assert transition math deterministically * fix(ci): repair current-main Swift integration * fix(ci): return closed workspace restore result * test(simulator): cover final review regressions * fix(simulator): close final lifecycle gaps * test(simulator): cover review lifecycle findings * fix(simulator): resolve review lifecycle findings * test(simulator): cover durable recovery journals * fix(simulator): persist mutation recovery journals * refactor(simulator): inject durable recovery paths * test(simulator): cover durable journal transitions * fix(simulator): make recovery transitions crash consistent * test(simulator): cover recovery compatibility gaps * fix(simulator): preserve recovery compatibility * test(simulator): cover recovery ownership handoff * fix(simulator): gate recovery ownership handoff * test(simulator): cover duplicate camera journals * fix(simulator): suppress stale durable camera journals * test(simulator): cover journal reconciliation races * fix(simulator): serialize journal reconciliation * test(simulator): cover identical journal paths * fix(simulator): normalize camera journal paths * test(simulator): cover journal URL hints * fix(simulator): compare normalized journal paths * refactor(simulator): split legacy route fixture * test(simulator): observe journal lock contention | 2 个月前 | |
Add native iPhone and iPad Simulator panes (#7857) * tighten simulator shortcut and mutation paths * Harden simulator operation commit boundaries * Close simulator routing and deadline races * Reconcile simulator mutations during teardown * Preserve simulator caller routing context * Route ios commands from caller pane * Preserve explicit simulator routing and input recovery * Serialize simulator text recovery * Align simulator deadlines and selection rollback * Close simulator lifecycle commit races * Reject stale simulator discovery results * Bound simulator re-enable and batch capture * Select the integrated simulator display * Close simulator transition races * Gate simulator automation on readiness * Finish simulator selection generation checks * Bound simulator context work end to end * Verify simulator descendant identities * Validate simulator process ancestry * Bound simulator process shutdown * Supervise simulator command groups * Supervise simulator pane sessions * Contain every simulator subprocess * Test simulator routing and feature flag regressions * Fail closed on stale simulator state * Test simulator lifecycle review regressions * Bound simulator control lifecycles * Test simulator cross-pane ownership regressions * Serialize simulator cross-pane mutations * Test Web Inspector cross-worker ownership * Lease Web Inspector targets across workers * Test Web Inspector stale occupancy handoff * Refresh Web Inspector occupancy during handoff * Test Web Inspector occupancy timeout * Fail closed on incomplete Inspector occupancy * Test Inspector census and release regressions * Close Inspector refresh and release races * Test stale location route teardown * Preserve location route ownership through teardown * Test Simulator launch environment privacy * Test route commit during device switch * Test feature flag telemetry consent * Own Simulator mutations through teardown * Harden Simulator isolation and ownership * Persist Simulator mutation ownership across processes * Honor telemetry consent for remote flags * Preserve failed Simulator cleanup ownership * Propagate Simulator CLI routing errors * Fix Simulator operation task syntax * Inject Simulator ownership and keep context read-only * Resolve restored Simulator context without booting * Test late Simulator display identity publication * Attach Simulator callbacks before display discovery * Test Simulator mutation ownership boundaries * Harden Simulator mutation ownership semantics * Test current Simulator default-screen contract * Support current Simulator default-screen metadata * Isolate Simulator camera transport tests * Test forwarded Simulator screen metadata * Support forwarded Simulator screen metadata * Align Simulator overlay lifecycle test with visibility * Bound Simulator recovery assertion by time * Make Simulator input recovery test deterministic * Test Simulator landscape framebuffer direction * Correct Simulator landscape presentation direction * Bound Simulator frame publication test wait * Register Simulator replay state before delivery * Test Simulator review boundary cases * Test iOS screenshot surface identity errors * Normalize Simulator control boundaries * Isolate Simulator CLI contract environment * Test native Simulator orientation dialects * Unify native Simulator orientation semantics * Test landscape Simulator digitizer coordinates * Map landscape input into native digitizer space * Test stable Simulator app switcher hold * Hold app switcher gesture stationary * Test Simulator app switcher button timing * Open Simulator app switcher with double Home * Test installed iPad DeviceKit chrome fallback * Test bounded Simulator frame publication * Scale Simulator frames to pane geometry * Test Simulator frame ring replacement cleanup * Release obsolete Simulator frame rings * Route IndexNow jobs through configured runner * Remove wall-clock assertions from RPC event tests * Test frame ring adoption race * Retire Simulator frame rings after host adoption * Keep frame completion on MainActor * Snapshot Simulator activity log before lazy layout * Regenerate webview assets after main merge * Test Simulator core readiness ordering * Stream Simulator before optional capability probes * Test control-socket Simulator selection ownership * Exclude active Simulator control action from teardown * Test natural DeviceKit chrome cap geometry * Preserve native DeviceKit chrome artwork geometry * Fix design mode test payload shadowing * Make Simulator replay tests signal-driven * Fix Simulator pane test client conformance * Test immediate Simulator context discovery * Discover Simulator before context reads * Test Simulator production edge cases * Close Simulator production review findings * Fix Simulator integration test fixtures * Fix Simulator CLI routing call site * Fix Simulator focus test fixtures * Fix Simulator app test fixtures * Test Simulator capability hydration readiness * Wait for Simulator capability hydration * Test Simulator review edge cases * Close Simulator production review gaps * Avoid recursive Simulator picker comparison * Isolate Simulator picker observation * Test Simulator application row snapshots * Snapshot Simulator application picker rows * Test static Simulator frame presentation * Drive Simulator frames without display callbacks * Test Simulator visibility remounts * Keep Simulator frames through host remounts * Isolate Simulator visibility regression suite * Test Simulator frame pacing under input load * Pace Simulator framebuffer readback * Localize project surface labels * Test Camera Injector header cache identity * Invalidate Camera Injector cache for headers * Test Simulator RPC capability discovery * Advertise Simulator RPC capabilities * test(simulator): cover interactive frame priority * fix(simulator): prioritize frames after pointer input * test(simulator): cover native tap hold duration * fix(simulator): hold synthetic taps long enough for iPadOS * Test immediate Simulator frame presentation * Present Simulator frames without an extra tick * Test failed Simulator ownership publication * Reject unsafe Simulator ownership claims * test(simulator): cover framebuffer lifecycle bounds * fix(simulator): bound framebuffer lifecycle work * test(simulator): cover review lifecycle regressions * fix(simulator): close review lifecycle gaps * test(simulator): cover routing pacing and consent * fix(simulator): scope routing pacing and consent * test(simulator): cover screenshot and cached log readiness * fix(simulator): prepare capture without eager lifecycle work * test(simulator): report capture-ready live state * fix(simulator): report live capture-ready state * test(simulator): cover control-plane and frame wakeups * fix(simulator): signal frames and preserve errored flag cache * test(simulator): cover publication wakeup races * fix(simulator): bound publication wakeups * test(simulator): cover tool editor shortcut focus * fix(simulator): preserve tool editor focus ownership * test(simulator): cover flag omission and runner injection * fix(simulator): inject async owned command execution * test(simulator): cover file drop proposal readiness * fix(simulator): validate file drop proposals * test(simulator): cover compound inspector cleanup failure * fix(simulator): preserve failed inspector cleanup state * test(simulator): cover device-scoped tool state * fix(simulator): scope tool state to selected device * test(simulator): cover final release blockers * fix(simulator): close final release blockers * test(simulator): make frame scheduling assertions deterministic * test: update Ghostty surface config ABI lock * fix(simulator): clear final build gates * fix(build): import Dock lifecycle workspace types * test(web): isolate feedback route environment * fix(build): disambiguate Dock snapshot types * test(simulator): cover review ownership blockers * fix(simulator): scope camera cleanup ownership * fix(build): make resume policy returns explicit * test(simulator): cover camera cleanup ownership retries * fix(simulator): preserve camera cleanup ownership * fix(build): clear latest main gates * test(simulator): cover final review blockers * fix(simulator): await quit cleanup and index targets * refactor(simulator): satisfy production policy * test(simulator): cover camera cleanup on device switch * fix(simulator): clean camera state before device switch * test(simulator): retain quit cleanup after panel removal * fix(simulator): make quit await durable rollback * test(simulator): cover retained cleanup recovery * fix(simulator): recover retained camera cleanup * test(simulator): cover cleanup side effects * fix(simulator): restore external cleanup state * refactor(simulator): split camera authorization record * test(web): respect delegated discovery order * test(ios): assert transition math deterministically * fix(ci): repair current-main Swift integration * fix(ci): return closed workspace restore result * test(simulator): cover final review regressions * fix(simulator): close final lifecycle gaps * test(simulator): cover review lifecycle findings * fix(simulator): resolve review lifecycle findings * test(simulator): cover durable recovery journals * fix(simulator): persist mutation recovery journals * refactor(simulator): inject durable recovery paths * test(simulator): cover durable journal transitions * fix(simulator): make recovery transitions crash consistent * test(simulator): cover recovery compatibility gaps * fix(simulator): preserve recovery compatibility * test(simulator): cover recovery ownership handoff * fix(simulator): gate recovery ownership handoff * test(simulator): cover duplicate camera journals * fix(simulator): suppress stale durable camera journals * test(simulator): cover journal reconciliation races * fix(simulator): serialize journal reconciliation * test(simulator): cover identical journal paths * fix(simulator): normalize camera journal paths * test(simulator): cover journal URL hints * fix(simulator): compare normalized journal paths * refactor(simulator): split legacy route fixture * test(simulator): observe journal lock contention | 2 个月前 | |
Add native iPhone and iPad Simulator panes (#7857) * tighten simulator shortcut and mutation paths * Harden simulator operation commit boundaries * Close simulator routing and deadline races * Reconcile simulator mutations during teardown * Preserve simulator caller routing context * Route ios commands from caller pane * Preserve explicit simulator routing and input recovery * Serialize simulator text recovery * Align simulator deadlines and selection rollback * Close simulator lifecycle commit races * Reject stale simulator discovery results * Bound simulator re-enable and batch capture * Select the integrated simulator display * Close simulator transition races * Gate simulator automation on readiness * Finish simulator selection generation checks * Bound simulator context work end to end * Verify simulator descendant identities * Validate simulator process ancestry * Bound simulator process shutdown * Supervise simulator command groups * Supervise simulator pane sessions * Contain every simulator subprocess * Test simulator routing and feature flag regressions * Fail closed on stale simulator state * Test simulator lifecycle review regressions * Bound simulator control lifecycles * Test simulator cross-pane ownership regressions * Serialize simulator cross-pane mutations * Test Web Inspector cross-worker ownership * Lease Web Inspector targets across workers * Test Web Inspector stale occupancy handoff * Refresh Web Inspector occupancy during handoff * Test Web Inspector occupancy timeout * Fail closed on incomplete Inspector occupancy * Test Inspector census and release regressions * Close Inspector refresh and release races * Test stale location route teardown * Preserve location route ownership through teardown * Test Simulator launch environment privacy * Test route commit during device switch * Test feature flag telemetry consent * Own Simulator mutations through teardown * Harden Simulator isolation and ownership * Persist Simulator mutation ownership across processes * Honor telemetry consent for remote flags * Preserve failed Simulator cleanup ownership * Propagate Simulator CLI routing errors * Fix Simulator operation task syntax * Inject Simulator ownership and keep context read-only * Resolve restored Simulator context without booting * Test late Simulator display identity publication * Attach Simulator callbacks before display discovery * Test Simulator mutation ownership boundaries * Harden Simulator mutation ownership semantics * Test current Simulator default-screen contract * Support current Simulator default-screen metadata * Isolate Simulator camera transport tests * Test forwarded Simulator screen metadata * Support forwarded Simulator screen metadata * Align Simulator overlay lifecycle test with visibility * Bound Simulator recovery assertion by time * Make Simulator input recovery test deterministic * Test Simulator landscape framebuffer direction * Correct Simulator landscape presentation direction * Bound Simulator frame publication test wait * Register Simulator replay state before delivery * Test Simulator review boundary cases * Test iOS screenshot surface identity errors * Normalize Simulator control boundaries * Isolate Simulator CLI contract environment * Test native Simulator orientation dialects * Unify native Simulator orientation semantics * Test landscape Simulator digitizer coordinates * Map landscape input into native digitizer space * Test stable Simulator app switcher hold * Hold app switcher gesture stationary * Test Simulator app switcher button timing * Open Simulator app switcher with double Home * Test installed iPad DeviceKit chrome fallback * Test bounded Simulator frame publication * Scale Simulator frames to pane geometry * Test Simulator frame ring replacement cleanup * Release obsolete Simulator frame rings * Route IndexNow jobs through configured runner * Remove wall-clock assertions from RPC event tests * Test frame ring adoption race * Retire Simulator frame rings after host adoption * Keep frame completion on MainActor * Snapshot Simulator activity log before lazy layout * Regenerate webview assets after main merge * Test Simulator core readiness ordering * Stream Simulator before optional capability probes * Test control-socket Simulator selection ownership * Exclude active Simulator control action from teardown * Test natural DeviceKit chrome cap geometry * Preserve native DeviceKit chrome artwork geometry * Fix design mode test payload shadowing * Make Simulator replay tests signal-driven * Fix Simulator pane test client conformance * Test immediate Simulator context discovery * Discover Simulator before context reads * Test Simulator production edge cases * Close Simulator production review findings * Fix Simulator integration test fixtures * Fix Simulator CLI routing call site * Fix Simulator focus test fixtures * Fix Simulator app test fixtures * Test Simulator capability hydration readiness * Wait for Simulator capability hydration * Test Simulator review edge cases * Close Simulator production review gaps * Avoid recursive Simulator picker comparison * Isolate Simulator picker observation * Test Simulator application row snapshots * Snapshot Simulator application picker rows * Test static Simulator frame presentation * Drive Simulator frames without display callbacks * Test Simulator visibility remounts * Keep Simulator frames through host remounts * Isolate Simulator visibility regression suite * Test Simulator frame pacing under input load * Pace Simulator framebuffer readback * Localize project surface labels * Test Camera Injector header cache identity * Invalidate Camera Injector cache for headers * Test Simulator RPC capability discovery * Advertise Simulator RPC capabilities * test(simulator): cover interactive frame priority * fix(simulator): prioritize frames after pointer input * test(simulator): cover native tap hold duration * fix(simulator): hold synthetic taps long enough for iPadOS * Test immediate Simulator frame presentation * Present Simulator frames without an extra tick * Test failed Simulator ownership publication * Reject unsafe Simulator ownership claims * test(simulator): cover framebuffer lifecycle bounds * fix(simulator): bound framebuffer lifecycle work * test(simulator): cover review lifecycle regressions * fix(simulator): close review lifecycle gaps * test(simulator): cover routing pacing and consent * fix(simulator): scope routing pacing and consent * test(simulator): cover screenshot and cached log readiness * fix(simulator): prepare capture without eager lifecycle work * test(simulator): report capture-ready live state * fix(simulator): report live capture-ready state * test(simulator): cover control-plane and frame wakeups * fix(simulator): signal frames and preserve errored flag cache * test(simulator): cover publication wakeup races * fix(simulator): bound publication wakeups * test(simulator): cover tool editor shortcut focus * fix(simulator): preserve tool editor focus ownership * test(simulator): cover flag omission and runner injection * fix(simulator): inject async owned command execution * test(simulator): cover file drop proposal readiness * fix(simulator): validate file drop proposals * test(simulator): cover compound inspector cleanup failure * fix(simulator): preserve failed inspector cleanup state * test(simulator): cover device-scoped tool state * fix(simulator): scope tool state to selected device * test(simulator): cover final release blockers * fix(simulator): close final release blockers * test(simulator): make frame scheduling assertions deterministic * test: update Ghostty surface config ABI lock * fix(simulator): clear final build gates * fix(build): import Dock lifecycle workspace types * test(web): isolate feedback route environment * fix(build): disambiguate Dock snapshot types * test(simulator): cover review ownership blockers * fix(simulator): scope camera cleanup ownership * fix(build): make resume policy returns explicit * test(simulator): cover camera cleanup ownership retries * fix(simulator): preserve camera cleanup ownership * fix(build): clear latest main gates * test(simulator): cover final review blockers * fix(simulator): await quit cleanup and index targets * refactor(simulator): satisfy production policy * test(simulator): cover camera cleanup on device switch * fix(simulator): clean camera state before device switch * test(simulator): retain quit cleanup after panel removal * fix(simulator): make quit await durable rollback * test(simulator): cover retained cleanup recovery * fix(simulator): recover retained camera cleanup * test(simulator): cover cleanup side effects * fix(simulator): restore external cleanup state * refactor(simulator): split camera authorization record * test(web): respect delegated discovery order * test(ios): assert transition math deterministically * fix(ci): repair current-main Swift integration * fix(ci): return closed workspace restore result * test(simulator): cover final review regressions * fix(simulator): close final lifecycle gaps * test(simulator): cover review lifecycle findings * fix(simulator): resolve review lifecycle findings * test(simulator): cover durable recovery journals * fix(simulator): persist mutation recovery journals * refactor(simulator): inject durable recovery paths * test(simulator): cover durable journal transitions * fix(simulator): make recovery transitions crash consistent * test(simulator): cover recovery compatibility gaps * fix(simulator): preserve recovery compatibility * test(simulator): cover recovery ownership handoff * fix(simulator): gate recovery ownership handoff * test(simulator): cover duplicate camera journals * fix(simulator): suppress stale durable camera journals * test(simulator): cover journal reconciliation races * fix(simulator): serialize journal reconciliation * test(simulator): cover identical journal paths * fix(simulator): normalize camera journal paths * test(simulator): cover journal URL hints * fix(simulator): compare normalized journal paths * refactor(simulator): split legacy route fixture * test(simulator): observe journal lock contention | 2 个月前 | |
Add native iPhone and iPad Simulator panes (#7857) * tighten simulator shortcut and mutation paths * Harden simulator operation commit boundaries * Close simulator routing and deadline races * Reconcile simulator mutations during teardown * Preserve simulator caller routing context * Route ios commands from caller pane * Preserve explicit simulator routing and input recovery * Serialize simulator text recovery * Align simulator deadlines and selection rollback * Close simulator lifecycle commit races * Reject stale simulator discovery results * Bound simulator re-enable and batch capture * Select the integrated simulator display * Close simulator transition races * Gate simulator automation on readiness * Finish simulator selection generation checks * Bound simulator context work end to end * Verify simulator descendant identities * Validate simulator process ancestry * Bound simulator process shutdown * Supervise simulator command groups * Supervise simulator pane sessions * Contain every simulator subprocess * Test simulator routing and feature flag regressions * Fail closed on stale simulator state * Test simulator lifecycle review regressions * Bound simulator control lifecycles * Test simulator cross-pane ownership regressions * Serialize simulator cross-pane mutations * Test Web Inspector cross-worker ownership * Lease Web Inspector targets across workers * Test Web Inspector stale occupancy handoff * Refresh Web Inspector occupancy during handoff * Test Web Inspector occupancy timeout * Fail closed on incomplete Inspector occupancy * Test Inspector census and release regressions * Close Inspector refresh and release races * Test stale location route teardown * Preserve location route ownership through teardown * Test Simulator launch environment privacy * Test route commit during device switch * Test feature flag telemetry consent * Own Simulator mutations through teardown * Harden Simulator isolation and ownership * Persist Simulator mutation ownership across processes * Honor telemetry consent for remote flags * Preserve failed Simulator cleanup ownership * Propagate Simulator CLI routing errors * Fix Simulator operation task syntax * Inject Simulator ownership and keep context read-only * Resolve restored Simulator context without booting * Test late Simulator display identity publication * Attach Simulator callbacks before display discovery * Test Simulator mutation ownership boundaries * Harden Simulator mutation ownership semantics * Test current Simulator default-screen contract * Support current Simulator default-screen metadata * Isolate Simulator camera transport tests * Test forwarded Simulator screen metadata * Support forwarded Simulator screen metadata * Align Simulator overlay lifecycle test with visibility * Bound Simulator recovery assertion by time * Make Simulator input recovery test deterministic * Test Simulator landscape framebuffer direction * Correct Simulator landscape presentation direction * Bound Simulator frame publication test wait * Register Simulator replay state before delivery * Test Simulator review boundary cases * Test iOS screenshot surface identity errors * Normalize Simulator control boundaries * Isolate Simulator CLI contract environment * Test native Simulator orientation dialects * Unify native Simulator orientation semantics * Test landscape Simulator digitizer coordinates * Map landscape input into native digitizer space * Test stable Simulator app switcher hold * Hold app switcher gesture stationary * Test Simulator app switcher button timing * Open Simulator app switcher with double Home * Test installed iPad DeviceKit chrome fallback * Test bounded Simulator frame publication * Scale Simulator frames to pane geometry * Test Simulator frame ring replacement cleanup * Release obsolete Simulator frame rings * Route IndexNow jobs through configured runner * Remove wall-clock assertions from RPC event tests * Test frame ring adoption race * Retire Simulator frame rings after host adoption * Keep frame completion on MainActor * Snapshot Simulator activity log before lazy layout * Regenerate webview assets after main merge * Test Simulator core readiness ordering * Stream Simulator before optional capability probes * Test control-socket Simulator selection ownership * Exclude active Simulator control action from teardown * Test natural DeviceKit chrome cap geometry * Preserve native DeviceKit chrome artwork geometry * Fix design mode test payload shadowing * Make Simulator replay tests signal-driven * Fix Simulator pane test client conformance * Test immediate Simulator context discovery * Discover Simulator before context reads * Test Simulator production edge cases * Close Simulator production review findings * Fix Simulator integration test fixtures * Fix Simulator CLI routing call site * Fix Simulator focus test fixtures * Fix Simulator app test fixtures * Test Simulator capability hydration readiness * Wait for Simulator capability hydration * Test Simulator review edge cases * Close Simulator production review gaps * Avoid recursive Simulator picker comparison * Isolate Simulator picker observation * Test Simulator application row snapshots * Snapshot Simulator application picker rows * Test static Simulator frame presentation * Drive Simulator frames without display callbacks * Test Simulator visibility remounts * Keep Simulator frames through host remounts * Isolate Simulator visibility regression suite * Test Simulator frame pacing under input load * Pace Simulator framebuffer readback * Localize project surface labels * Test Camera Injector header cache identity * Invalidate Camera Injector cache for headers * Test Simulator RPC capability discovery * Advertise Simulator RPC capabilities * test(simulator): cover interactive frame priority * fix(simulator): prioritize frames after pointer input * test(simulator): cover native tap hold duration * fix(simulator): hold synthetic taps long enough for iPadOS * Test immediate Simulator frame presentation * Present Simulator frames without an extra tick * Test failed Simulator ownership publication * Reject unsafe Simulator ownership claims * test(simulator): cover framebuffer lifecycle bounds * fix(simulator): bound framebuffer lifecycle work * test(simulator): cover review lifecycle regressions * fix(simulator): close review lifecycle gaps * test(simulator): cover routing pacing and consent * fix(simulator): scope routing pacing and consent * test(simulator): cover screenshot and cached log readiness * fix(simulator): prepare capture without eager lifecycle work * test(simulator): report capture-ready live state * fix(simulator): report live capture-ready state * test(simulator): cover control-plane and frame wakeups * fix(simulator): signal frames and preserve errored flag cache * test(simulator): cover publication wakeup races * fix(simulator): bound publication wakeups * test(simulator): cover tool editor shortcut focus * fix(simulator): preserve tool editor focus ownership * test(simulator): cover flag omission and runner injection * fix(simulator): inject async owned command execution * test(simulator): cover file drop proposal readiness * fix(simulator): validate file drop proposals * test(simulator): cover compound inspector cleanup failure * fix(simulator): preserve failed inspector cleanup state * test(simulator): cover device-scoped tool state * fix(simulator): scope tool state to selected device * test(simulator): cover final release blockers * fix(simulator): close final release blockers * test(simulator): make frame scheduling assertions deterministic * test: update Ghostty surface config ABI lock * fix(simulator): clear final build gates * fix(build): import Dock lifecycle workspace types * test(web): isolate feedback route environment * fix(build): disambiguate Dock snapshot types * test(simulator): cover review ownership blockers * fix(simulator): scope camera cleanup ownership * fix(build): make resume policy returns explicit * test(simulator): cover camera cleanup ownership retries * fix(simulator): preserve camera cleanup ownership * fix(build): clear latest main gates * test(simulator): cover final review blockers * fix(simulator): await quit cleanup and index targets * refactor(simulator): satisfy production policy * test(simulator): cover camera cleanup on device switch * fix(simulator): clean camera state before device switch * test(simulator): retain quit cleanup after panel removal * fix(simulator): make quit await durable rollback * test(simulator): cover retained cleanup recovery * fix(simulator): recover retained camera cleanup * test(simulator): cover cleanup side effects * fix(simulator): restore external cleanup state * refactor(simulator): split camera authorization record * test(web): respect delegated discovery order * test(ios): assert transition math deterministically * fix(ci): repair current-main Swift integration * fix(ci): return closed workspace restore result * test(simulator): cover final review regressions * fix(simulator): close final lifecycle gaps * test(simulator): cover review lifecycle findings * fix(simulator): resolve review lifecycle findings * test(simulator): cover durable recovery journals * fix(simulator): persist mutation recovery journals * refactor(simulator): inject durable recovery paths * test(simulator): cover durable journal transitions * fix(simulator): make recovery transitions crash consistent * test(simulator): cover recovery compatibility gaps * fix(simulator): preserve recovery compatibility * test(simulator): cover recovery ownership handoff * fix(simulator): gate recovery ownership handoff * test(simulator): cover duplicate camera journals * fix(simulator): suppress stale durable camera journals * test(simulator): cover journal reconciliation races * fix(simulator): serialize journal reconciliation * test(simulator): cover identical journal paths * fix(simulator): normalize camera journal paths * test(simulator): cover journal URL hints * fix(simulator): compare normalized journal paths * refactor(simulator): split legacy route fixture * test(simulator): observe journal lock contention | 2 个月前 | |
Add native iPhone and iPad Simulator panes (#7857) * tighten simulator shortcut and mutation paths * Harden simulator operation commit boundaries * Close simulator routing and deadline races * Reconcile simulator mutations during teardown * Preserve simulator caller routing context * Route ios commands from caller pane * Preserve explicit simulator routing and input recovery * Serialize simulator text recovery * Align simulator deadlines and selection rollback * Close simulator lifecycle commit races * Reject stale simulator discovery results * Bound simulator re-enable and batch capture * Select the integrated simulator display * Close simulator transition races * Gate simulator automation on readiness * Finish simulator selection generation checks * Bound simulator context work end to end * Verify simulator descendant identities * Validate simulator process ancestry * Bound simulator process shutdown * Supervise simulator command groups * Supervise simulator pane sessions * Contain every simulator subprocess * Test simulator routing and feature flag regressions * Fail closed on stale simulator state * Test simulator lifecycle review regressions * Bound simulator control lifecycles * Test simulator cross-pane ownership regressions * Serialize simulator cross-pane mutations * Test Web Inspector cross-worker ownership * Lease Web Inspector targets across workers * Test Web Inspector stale occupancy handoff * Refresh Web Inspector occupancy during handoff * Test Web Inspector occupancy timeout * Fail closed on incomplete Inspector occupancy * Test Inspector census and release regressions * Close Inspector refresh and release races * Test stale location route teardown * Preserve location route ownership through teardown * Test Simulator launch environment privacy * Test route commit during device switch * Test feature flag telemetry consent * Own Simulator mutations through teardown * Harden Simulator isolation and ownership * Persist Simulator mutation ownership across processes * Honor telemetry consent for remote flags * Preserve failed Simulator cleanup ownership * Propagate Simulator CLI routing errors * Fix Simulator operation task syntax * Inject Simulator ownership and keep context read-only * Resolve restored Simulator context without booting * Test late Simulator display identity publication * Attach Simulator callbacks before display discovery * Test Simulator mutation ownership boundaries * Harden Simulator mutation ownership semantics * Test current Simulator default-screen contract * Support current Simulator default-screen metadata * Isolate Simulator camera transport tests * Test forwarded Simulator screen metadata * Support forwarded Simulator screen metadata * Align Simulator overlay lifecycle test with visibility * Bound Simulator recovery assertion by time * Make Simulator input recovery test deterministic * Test Simulator landscape framebuffer direction * Correct Simulator landscape presentation direction * Bound Simulator frame publication test wait * Register Simulator replay state before delivery * Test Simulator review boundary cases * Test iOS screenshot surface identity errors * Normalize Simulator control boundaries * Isolate Simulator CLI contract environment * Test native Simulator orientation dialects * Unify native Simulator orientation semantics * Test landscape Simulator digitizer coordinates * Map landscape input into native digitizer space * Test stable Simulator app switcher hold * Hold app switcher gesture stationary * Test Simulator app switcher button timing * Open Simulator app switcher with double Home * Test installed iPad DeviceKit chrome fallback * Test bounded Simulator frame publication * Scale Simulator frames to pane geometry * Test Simulator frame ring replacement cleanup * Release obsolete Simulator frame rings * Route IndexNow jobs through configured runner * Remove wall-clock assertions from RPC event tests * Test frame ring adoption race * Retire Simulator frame rings after host adoption * Keep frame completion on MainActor * Snapshot Simulator activity log before lazy layout * Regenerate webview assets after main merge * Test Simulator core readiness ordering * Stream Simulator before optional capability probes * Test control-socket Simulator selection ownership * Exclude active Simulator control action from teardown * Test natural DeviceKit chrome cap geometry * Preserve native DeviceKit chrome artwork geometry * Fix design mode test payload shadowing * Make Simulator replay tests signal-driven * Fix Simulator pane test client conformance * Test immediate Simulator context discovery * Discover Simulator before context reads * Test Simulator production edge cases * Close Simulator production review findings * Fix Simulator integration test fixtures * Fix Simulator CLI routing call site * Fix Simulator focus test fixtures * Fix Simulator app test fixtures * Test Simulator capability hydration readiness * Wait for Simulator capability hydration * Test Simulator review edge cases * Close Simulator production review gaps * Avoid recursive Simulator picker comparison * Isolate Simulator picker observation * Test Simulator application row snapshots * Snapshot Simulator application picker rows * Test static Simulator frame presentation * Drive Simulator frames without display callbacks * Test Simulator visibility remounts * Keep Simulator frames through host remounts * Isolate Simulator visibility regression suite * Test Simulator frame pacing under input load * Pace Simulator framebuffer readback * Localize project surface labels * Test Camera Injector header cache identity * Invalidate Camera Injector cache for headers * Test Simulator RPC capability discovery * Advertise Simulator RPC capabilities * test(simulator): cover interactive frame priority * fix(simulator): prioritize frames after pointer input * test(simulator): cover native tap hold duration * fix(simulator): hold synthetic taps long enough for iPadOS * Test immediate Simulator frame presentation * Present Simulator frames without an extra tick * Test failed Simulator ownership publication * Reject unsafe Simulator ownership claims * test(simulator): cover framebuffer lifecycle bounds * fix(simulator): bound framebuffer lifecycle work * test(simulator): cover review lifecycle regressions * fix(simulator): close review lifecycle gaps * test(simulator): cover routing pacing and consent * fix(simulator): scope routing pacing and consent * test(simulator): cover screenshot and cached log readiness * fix(simulator): prepare capture without eager lifecycle work * test(simulator): report capture-ready live state * fix(simulator): report live capture-ready state * test(simulator): cover control-plane and frame wakeups * fix(simulator): signal frames and preserve errored flag cache * test(simulator): cover publication wakeup races * fix(simulator): bound publication wakeups * test(simulator): cover tool editor shortcut focus * fix(simulator): preserve tool editor focus ownership * test(simulator): cover flag omission and runner injection * fix(simulator): inject async owned command execution * test(simulator): cover file drop proposal readiness * fix(simulator): validate file drop proposals * test(simulator): cover compound inspector cleanup failure * fix(simulator): preserve failed inspector cleanup state * test(simulator): cover device-scoped tool state * fix(simulator): scope tool state to selected device * test(simulator): cover final release blockers * fix(simulator): close final release blockers * test(simulator): make frame scheduling assertions deterministic * test: update Ghostty surface config ABI lock * fix(simulator): clear final build gates * fix(build): import Dock lifecycle workspace types * test(web): isolate feedback route environment * fix(build): disambiguate Dock snapshot types * test(simulator): cover review ownership blockers * fix(simulator): scope camera cleanup ownership * fix(build): make resume policy returns explicit * test(simulator): cover camera cleanup ownership retries * fix(simulator): preserve camera cleanup ownership * fix(build): clear latest main gates * test(simulator): cover final review blockers * fix(simulator): await quit cleanup and index targets * refactor(simulator): satisfy production policy * test(simulator): cover camera cleanup on device switch * fix(simulator): clean camera state before device switch * test(simulator): retain quit cleanup after panel removal * fix(simulator): make quit await durable rollback * test(simulator): cover retained cleanup recovery * fix(simulator): recover retained camera cleanup * test(simulator): cover cleanup side effects * fix(simulator): restore external cleanup state * refactor(simulator): split camera authorization record * test(web): respect delegated discovery order * test(ios): assert transition math deterministically * fix(ci): repair current-main Swift integration * fix(ci): return closed workspace restore result * test(simulator): cover final review regressions * fix(simulator): close final lifecycle gaps * test(simulator): cover review lifecycle findings * fix(simulator): resolve review lifecycle findings * test(simulator): cover durable recovery journals * fix(simulator): persist mutation recovery journals * refactor(simulator): inject durable recovery paths * test(simulator): cover durable journal transitions * fix(simulator): make recovery transitions crash consistent * test(simulator): cover recovery compatibility gaps * fix(simulator): preserve recovery compatibility * test(simulator): cover recovery ownership handoff * fix(simulator): gate recovery ownership handoff * test(simulator): cover duplicate camera journals * fix(simulator): suppress stale durable camera journals * test(simulator): cover journal reconciliation races * fix(simulator): serialize journal reconciliation * test(simulator): cover identical journal paths * fix(simulator): normalize camera journal paths * test(simulator): cover journal URL hints * fix(simulator): compare normalized journal paths * refactor(simulator): split legacy route fixture * test(simulator): observe journal lock contention | 2 个月前 | |
Add native iPhone and iPad Simulator panes (#7857) * tighten simulator shortcut and mutation paths * Harden simulator operation commit boundaries * Close simulator routing and deadline races * Reconcile simulator mutations during teardown * Preserve simulator caller routing context * Route ios commands from caller pane * Preserve explicit simulator routing and input recovery * Serialize simulator text recovery * Align simulator deadlines and selection rollback * Close simulator lifecycle commit races * Reject stale simulator discovery results * Bound simulator re-enable and batch capture * Select the integrated simulator display * Close simulator transition races * Gate simulator automation on readiness * Finish simulator selection generation checks * Bound simulator context work end to end * Verify simulator descendant identities * Validate simulator process ancestry * Bound simulator process shutdown * Supervise simulator command groups * Supervise simulator pane sessions * Contain every simulator subprocess * Test simulator routing and feature flag regressions * Fail closed on stale simulator state * Test simulator lifecycle review regressions * Bound simulator control lifecycles * Test simulator cross-pane ownership regressions * Serialize simulator cross-pane mutations * Test Web Inspector cross-worker ownership * Lease Web Inspector targets across workers * Test Web Inspector stale occupancy handoff * Refresh Web Inspector occupancy during handoff * Test Web Inspector occupancy timeout * Fail closed on incomplete Inspector occupancy * Test Inspector census and release regressions * Close Inspector refresh and release races * Test stale location route teardown * Preserve location route ownership through teardown * Test Simulator launch environment privacy * Test route commit during device switch * Test feature flag telemetry consent * Own Simulator mutations through teardown * Harden Simulator isolation and ownership * Persist Simulator mutation ownership across processes * Honor telemetry consent for remote flags * Preserve failed Simulator cleanup ownership * Propagate Simulator CLI routing errors * Fix Simulator operation task syntax * Inject Simulator ownership and keep context read-only * Resolve restored Simulator context without booting * Test late Simulator display identity publication * Attach Simulator callbacks before display discovery * Test Simulator mutation ownership boundaries * Harden Simulator mutation ownership semantics * Test current Simulator default-screen contract * Support current Simulator default-screen metadata * Isolate Simulator camera transport tests * Test forwarded Simulator screen metadata * Support forwarded Simulator screen metadata * Align Simulator overlay lifecycle test with visibility * Bound Simulator recovery assertion by time * Make Simulator input recovery test deterministic * Test Simulator landscape framebuffer direction * Correct Simulator landscape presentation direction * Bound Simulator frame publication test wait * Register Simulator replay state before delivery * Test Simulator review boundary cases * Test iOS screenshot surface identity errors * Normalize Simulator control boundaries * Isolate Simulator CLI contract environment * Test native Simulator orientation dialects * Unify native Simulator orientation semantics * Test landscape Simulator digitizer coordinates * Map landscape input into native digitizer space * Test stable Simulator app switcher hold * Hold app switcher gesture stationary * Test Simulator app switcher button timing * Open Simulator app switcher with double Home * Test installed iPad DeviceKit chrome fallback * Test bounded Simulator frame publication * Scale Simulator frames to pane geometry * Test Simulator frame ring replacement cleanup * Release obsolete Simulator frame rings * Route IndexNow jobs through configured runner * Remove wall-clock assertions from RPC event tests * Test frame ring adoption race * Retire Simulator frame rings after host adoption * Keep frame completion on MainActor * Snapshot Simulator activity log before lazy layout * Regenerate webview assets after main merge * Test Simulator core readiness ordering * Stream Simulator before optional capability probes * Test control-socket Simulator selection ownership * Exclude active Simulator control action from teardown * Test natural DeviceKit chrome cap geometry * Preserve native DeviceKit chrome artwork geometry * Fix design mode test payload shadowing * Make Simulator replay tests signal-driven * Fix Simulator pane test client conformance * Test immediate Simulator context discovery * Discover Simulator before context reads * Test Simulator production edge cases * Close Simulator production review findings * Fix Simulator integration test fixtures * Fix Simulator CLI routing call site * Fix Simulator focus test fixtures * Fix Simulator app test fixtures * Test Simulator capability hydration readiness * Wait for Simulator capability hydration * Test Simulator review edge cases * Close Simulator production review gaps * Avoid recursive Simulator picker comparison * Isolate Simulator picker observation * Test Simulator application row snapshots * Snapshot Simulator application picker rows * Test static Simulator frame presentation * Drive Simulator frames without display callbacks * Test Simulator visibility remounts * Keep Simulator frames through host remounts * Isolate Simulator visibility regression suite * Test Simulator frame pacing under input load * Pace Simulator framebuffer readback * Localize project surface labels * Test Camera Injector header cache identity * Invalidate Camera Injector cache for headers * Test Simulator RPC capability discovery * Advertise Simulator RPC capabilities * test(simulator): cover interactive frame priority * fix(simulator): prioritize frames after pointer input * test(simulator): cover native tap hold duration * fix(simulator): hold synthetic taps long enough for iPadOS * Test immediate Simulator frame presentation * Present Simulator frames without an extra tick * Test failed Simulator ownership publication * Reject unsafe Simulator ownership claims * test(simulator): cover framebuffer lifecycle bounds * fix(simulator): bound framebuffer lifecycle work * test(simulator): cover review lifecycle regressions * fix(simulator): close review lifecycle gaps * test(simulator): cover routing pacing and consent * fix(simulator): scope routing pacing and consent * test(simulator): cover screenshot and cached log readiness * fix(simulator): prepare capture without eager lifecycle work * test(simulator): report capture-ready live state * fix(simulator): report live capture-ready state * test(simulator): cover control-plane and frame wakeups * fix(simulator): signal frames and preserve errored flag cache * test(simulator): cover publication wakeup races * fix(simulator): bound publication wakeups * test(simulator): cover tool editor shortcut focus * fix(simulator): preserve tool editor focus ownership * test(simulator): cover flag omission and runner injection * fix(simulator): inject async owned command execution * test(simulator): cover file drop proposal readiness * fix(simulator): validate file drop proposals * test(simulator): cover compound inspector cleanup failure * fix(simulator): preserve failed inspector cleanup state * test(simulator): cover device-scoped tool state * fix(simulator): scope tool state to selected device * test(simulator): cover final release blockers * fix(simulator): close final release blockers * test(simulator): make frame scheduling assertions deterministic * test: update Ghostty surface config ABI lock * fix(simulator): clear final build gates * fix(build): import Dock lifecycle workspace types * test(web): isolate feedback route environment * fix(build): disambiguate Dock snapshot types * test(simulator): cover review ownership blockers * fix(simulator): scope camera cleanup ownership * fix(build): make resume policy returns explicit * test(simulator): cover camera cleanup ownership retries * fix(simulator): preserve camera cleanup ownership * fix(build): clear latest main gates * test(simulator): cover final review blockers * fix(simulator): await quit cleanup and index targets * refactor(simulator): satisfy production policy * test(simulator): cover camera cleanup on device switch * fix(simulator): clean camera state before device switch * test(simulator): retain quit cleanup after panel removal * fix(simulator): make quit await durable rollback * test(simulator): cover retained cleanup recovery * fix(simulator): recover retained camera cleanup * test(simulator): cover cleanup side effects * fix(simulator): restore external cleanup state * refactor(simulator): split camera authorization record * test(web): respect delegated discovery order * test(ios): assert transition math deterministically * fix(ci): repair current-main Swift integration * fix(ci): return closed workspace restore result * test(simulator): cover final review regressions * fix(simulator): close final lifecycle gaps * test(simulator): cover review lifecycle findings * fix(simulator): resolve review lifecycle findings * test(simulator): cover durable recovery journals * fix(simulator): persist mutation recovery journals * refactor(simulator): inject durable recovery paths * test(simulator): cover durable journal transitions * fix(simulator): make recovery transitions crash consistent * test(simulator): cover recovery compatibility gaps * fix(simulator): preserve recovery compatibility * test(simulator): cover recovery ownership handoff * fix(simulator): gate recovery ownership handoff * test(simulator): cover duplicate camera journals * fix(simulator): suppress stale durable camera journals * test(simulator): cover journal reconciliation races * fix(simulator): serialize journal reconciliation * test(simulator): cover identical journal paths * fix(simulator): normalize camera journal paths * test(simulator): cover journal URL hints * fix(simulator): compare normalized journal paths * refactor(simulator): split legacy route fixture * test(simulator): observe journal lock contention | 2 个月前 | |
Add native iPhone and iPad Simulator panes (#7857) * tighten simulator shortcut and mutation paths * Harden simulator operation commit boundaries * Close simulator routing and deadline races * Reconcile simulator mutations during teardown * Preserve simulator caller routing context * Route ios commands from caller pane * Preserve explicit simulator routing and input recovery * Serialize simulator text recovery * Align simulator deadlines and selection rollback * Close simulator lifecycle commit races * Reject stale simulator discovery results * Bound simulator re-enable and batch capture * Select the integrated simulator display * Close simulator transition races * Gate simulator automation on readiness * Finish simulator selection generation checks * Bound simulator context work end to end * Verify simulator descendant identities * Validate simulator process ancestry * Bound simulator process shutdown * Supervise simulator command groups * Supervise simulator pane sessions * Contain every simulator subprocess * Test simulator routing and feature flag regressions * Fail closed on stale simulator state * Test simulator lifecycle review regressions * Bound simulator control lifecycles * Test simulator cross-pane ownership regressions * Serialize simulator cross-pane mutations * Test Web Inspector cross-worker ownership * Lease Web Inspector targets across workers * Test Web Inspector stale occupancy handoff * Refresh Web Inspector occupancy during handoff * Test Web Inspector occupancy timeout * Fail closed on incomplete Inspector occupancy * Test Inspector census and release regressions * Close Inspector refresh and release races * Test stale location route teardown * Preserve location route ownership through teardown * Test Simulator launch environment privacy * Test route commit during device switch * Test feature flag telemetry consent * Own Simulator mutations through teardown * Harden Simulator isolation and ownership * Persist Simulator mutation ownership across processes * Honor telemetry consent for remote flags * Preserve failed Simulator cleanup ownership * Propagate Simulator CLI routing errors * Fix Simulator operation task syntax * Inject Simulator ownership and keep context read-only * Resolve restored Simulator context without booting * Test late Simulator display identity publication * Attach Simulator callbacks before display discovery * Test Simulator mutation ownership boundaries * Harden Simulator mutation ownership semantics * Test current Simulator default-screen contract * Support current Simulator default-screen metadata * Isolate Simulator camera transport tests * Test forwarded Simulator screen metadata * Support forwarded Simulator screen metadata * Align Simulator overlay lifecycle test with visibility * Bound Simulator recovery assertion by time * Make Simulator input recovery test deterministic * Test Simulator landscape framebuffer direction * Correct Simulator landscape presentation direction * Bound Simulator frame publication test wait * Register Simulator replay state before delivery * Test Simulator review boundary cases * Test iOS screenshot surface identity errors * Normalize Simulator control boundaries * Isolate Simulator CLI contract environment * Test native Simulator orientation dialects * Unify native Simulator orientation semantics * Test landscape Simulator digitizer coordinates * Map landscape input into native digitizer space * Test stable Simulator app switcher hold * Hold app switcher gesture stationary * Test Simulator app switcher button timing * Open Simulator app switcher with double Home * Test installed iPad DeviceKit chrome fallback * Test bounded Simulator frame publication * Scale Simulator frames to pane geometry * Test Simulator frame ring replacement cleanup * Release obsolete Simulator frame rings * Route IndexNow jobs through configured runner * Remove wall-clock assertions from RPC event tests * Test frame ring adoption race * Retire Simulator frame rings after host adoption * Keep frame completion on MainActor * Snapshot Simulator activity log before lazy layout * Regenerate webview assets after main merge * Test Simulator core readiness ordering * Stream Simulator before optional capability probes * Test control-socket Simulator selection ownership * Exclude active Simulator control action from teardown * Test natural DeviceKit chrome cap geometry * Preserve native DeviceKit chrome artwork geometry * Fix design mode test payload shadowing * Make Simulator replay tests signal-driven * Fix Simulator pane test client conformance * Test immediate Simulator context discovery * Discover Simulator before context reads * Test Simulator production edge cases * Close Simulator production review findings * Fix Simulator integration test fixtures * Fix Simulator CLI routing call site * Fix Simulator focus test fixtures * Fix Simulator app test fixtures * Test Simulator capability hydration readiness * Wait for Simulator capability hydration * Test Simulator review edge cases * Close Simulator production review gaps * Avoid recursive Simulator picker comparison * Isolate Simulator picker observation * Test Simulator application row snapshots * Snapshot Simulator application picker rows * Test static Simulator frame presentation * Drive Simulator frames without display callbacks * Test Simulator visibility remounts * Keep Simulator frames through host remounts * Isolate Simulator visibility regression suite * Test Simulator frame pacing under input load * Pace Simulator framebuffer readback * Localize project surface labels * Test Camera Injector header cache identity * Invalidate Camera Injector cache for headers * Test Simulator RPC capability discovery * Advertise Simulator RPC capabilities * test(simulator): cover interactive frame priority * fix(simulator): prioritize frames after pointer input * test(simulator): cover native tap hold duration * fix(simulator): hold synthetic taps long enough for iPadOS * Test immediate Simulator frame presentation * Present Simulator frames without an extra tick * Test failed Simulator ownership publication * Reject unsafe Simulator ownership claims * test(simulator): cover framebuffer lifecycle bounds * fix(simulator): bound framebuffer lifecycle work * test(simulator): cover review lifecycle regressions * fix(simulator): close review lifecycle gaps * test(simulator): cover routing pacing and consent * fix(simulator): scope routing pacing and consent * test(simulator): cover screenshot and cached log readiness * fix(simulator): prepare capture without eager lifecycle work * test(simulator): report capture-ready live state * fix(simulator): report live capture-ready state * test(simulator): cover control-plane and frame wakeups * fix(simulator): signal frames and preserve errored flag cache * test(simulator): cover publication wakeup races * fix(simulator): bound publication wakeups * test(simulator): cover tool editor shortcut focus * fix(simulator): preserve tool editor focus ownership * test(simulator): cover flag omission and runner injection * fix(simulator): inject async owned command execution * test(simulator): cover file drop proposal readiness * fix(simulator): validate file drop proposals * test(simulator): cover compound inspector cleanup failure * fix(simulator): preserve failed inspector cleanup state * test(simulator): cover device-scoped tool state * fix(simulator): scope tool state to selected device * test(simulator): cover final release blockers * fix(simulator): close final release blockers * test(simulator): make frame scheduling assertions deterministic * test: update Ghostty surface config ABI lock * fix(simulator): clear final build gates * fix(build): import Dock lifecycle workspace types * test(web): isolate feedback route environment * fix(build): disambiguate Dock snapshot types * test(simulator): cover review ownership blockers * fix(simulator): scope camera cleanup ownership * fix(build): make resume policy returns explicit * test(simulator): cover camera cleanup ownership retries * fix(simulator): preserve camera cleanup ownership * fix(build): clear latest main gates * test(simulator): cover final review blockers * fix(simulator): await quit cleanup and index targets * refactor(simulator): satisfy production policy * test(simulator): cover camera cleanup on device switch * fix(simulator): clean camera state before device switch * test(simulator): retain quit cleanup after panel removal * fix(simulator): make quit await durable rollback * test(simulator): cover retained cleanup recovery * fix(simulator): recover retained camera cleanup * test(simulator): cover cleanup side effects * fix(simulator): restore external cleanup state * refactor(simulator): split camera authorization record * test(web): respect delegated discovery order * test(ios): assert transition math deterministically * fix(ci): repair current-main Swift integration * fix(ci): return closed workspace restore result * test(simulator): cover final review regressions * fix(simulator): close final lifecycle gaps * test(simulator): cover review lifecycle findings * fix(simulator): resolve review lifecycle findings * test(simulator): cover durable recovery journals * fix(simulator): persist mutation recovery journals * refactor(simulator): inject durable recovery paths * test(simulator): cover durable journal transitions * fix(simulator): make recovery transitions crash consistent * test(simulator): cover recovery compatibility gaps * fix(simulator): preserve recovery compatibility * test(simulator): cover recovery ownership handoff * fix(simulator): gate recovery ownership handoff * test(simulator): cover duplicate camera journals * fix(simulator): suppress stale durable camera journals * test(simulator): cover journal reconciliation races * fix(simulator): serialize journal reconciliation * test(simulator): cover identical journal paths * fix(simulator): normalize camera journal paths * test(simulator): cover journal URL hints * fix(simulator): compare normalized journal paths * refactor(simulator): split legacy route fixture * test(simulator): observe journal lock contention | 2 个月前 | |
Fix #7947: keep Claude hooks authorized after socket rebinds (#7953) * Add regression for capability auth across socket rebinds * Authenticate reparented socket clients with capabilities | 2 个月前 | |
CLI: shorter unknown-command errors with suggestions, copy polish (#7329) * CLI: shorter unknown-command errors with suggestions, copy polish Unknown commands no longer dump the full usage; both dispatch paths now throw one short error with a 'Did you mean' suggestion (edit distance over topLevelCommandNames) and exit 2. The pre-socket --help path previously exited 0 for unknown commands. Replaced the three 'Unable to' messages with Failed to/Couldn't per failure class, standardized the help hint to "Run 'cmux --help' for the full command list.", and tightened the usage() header prose; the Commands and Environment blocks are byte-identical. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Move command suggestion helpers to CMUXCLI+CommandSuggestions.swift workflow-guard-tests failed because the new helpers pushed CLI/cmux.swift 47 lines over its length budget. Move unknownCommandError, suggestedCommandName, editDistance, and topLevelCommandNames into a new extension file (wired into the pbxproj) and ratchet the budget entry down to the new 34499-line count. No behavior change; verified on the rebuilt clicpy tag. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Retrigger CI on WarpBuild runners Blacksmith macOS-15 lane is backlogged (jobs queued 2h+); repo runner vars flipped back to warp for this run. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Retrigger CI: display jobs to WarpBuild too MACOS_RUNNER_DISPLAY was still pointing at the backlogged Blacksmith macOS-15 lane. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * select-ci-xcode: never pick a beta Xcode over a stable one On the WarpBuild macos-26 image, Xcode_27.0_Beta.app outranks every stable 26.x by SDK version, so the release gate built against the 27.0 beta SDK and hit a Swift type-checker timeout in CMUXMobileCore. Skip beta-named Xcodes unless no stable Xcode exists on the runner. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 3 个月前 | |
Reduce Sentry CLI broken-pipe crashes and hangs (#6254) * Add closed-stderr CLI broken pipe regression test * Handle CLI broken pipes with safe stdio writes * Limit clean broken-pipe exits to fatal stderr writes * Drop CLI unit test that depends on cli-target internals The CLIBrokenPipeWriteTests class called cliWrite() directly, but that symbol lives in the cmux-cli target and is not visible from cmuxTests, so CI failed to compile. Even with visibility, calling Darwin.write into a closed pipe inside the XCTest host crashes the runner via SIGPIPE (only the CLI binary's main() ignores SIGPIPE). The existing E2E test exercises the same closed-stderr path through the real cmux binary, so coverage is preserved. Restore cliWrite and the disposition enum to private and harden the E2E test: - XCTWaiter().wait + early XCTFail on timeout instead of falling through to assertions on a still-running process - closeOnDealloc: false so the explicit defer is the sole owner of the stderr write fd Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add CLI broken-pipe regression coverage * Scope CLI SIGPIPE handling to write and launch paths * Address CI failures and review feedback on CLI broken-pipe PR - Fix defer block return error by gating cleanup on `installed` flag - Replace Python-based SIGPIPE probe with native `__sigpipe-inspect` subcommand; removes Python dependency and avoids masking inherited SIGPIPE disposition - Fix strdup type-inference error in exec-mode probe via explicit `[UnsafeMutablePointer<CChar>?]` typing - Convert auth status/login/logout `print()` callsites to `cliPrint()` so broken-pipe writes don't crash auth subcommands - Drain spawn-probe pipes before `waitUntilExit()` to prevent deadlock - Include `cliWriteFatalStderr` in stdio-safety audit summary Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use _exit in cliWrite EPIPE path to avoid deadlock under held lock cliWrite calls Darwin.exit while holding cliSIGPIPEDispositionLock (NSLock is non-reentrant). Any atexit handler that wrote through cliWrite/cliPrint would re-enter withCLISIGPIPEDisposition and deadlock. _exit also skips atexit/stdio flush, matching the default SIGPIPE termination this path replaces when stdout is closed by the consumer. Addresses Cursor Bugbot comment on PR #2993. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Poll for writable FD on EAGAIN in cliWrite Addresses Cursor bot review on PR #2993: the previous `case EINTR, EAGAIN, EWOULDBLOCK: continue` turned non-blocking writes into a busy-wait spin under the SIGPIPE disposition lock. Split EINTR (immediate retry) from EAGAIN/EWOULDBLOCK (block on poll(POLLOUT)) so a non-blocking stdio fd yields to the kernel instead of spinning. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use F_NOSIGPIPE on CLI stdio instead of per-write sigaction Every cliPrint was wrapped in withCLISIGPIPEIgnored, which took a process-wide NSLock and did three sigaction syscalls per write to temporarily install SIG_IGN around Darwin.write. For a command like `cmux help` (~142 lines) that added ~426 extra syscalls. Opt stdout/stderr into F_NOSIGPIPE once at CLI startup — the same per-FD pattern the socket path already uses via SO_NOSIGPIPE — so write(2) just returns EPIPE and the hot path is a single write syscall per call. Keeps withCLIDefaultSIGPIPEForChildLaunch for Process.run / exec paths in case the CLI was invoked with SIG_IGN inherited, but those are low-frequency and not on the stdio write path. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix CLI SIGPIPE child inheritance and pipe writes * Close CLI stdio disposition race CLI writes and child launch setup now share one lock around stdio disposition changes, so no write can run while inherited stdout/stderr have F_NOSIGPIPE temporarily cleared for a child process. Constraint: Cursor review identified a race between child-launch fd mutation and concurrent broken-pipe writes Rejected: Reintroduce process-wide SIGPIPE ignore | would make child processes inherit the wrong SIGPIPE disposition again Confidence: high Scope-risk: narrow Directive: Any future stdio-disposition mutation must coordinate with cliWrite via cliStdioDispositionLock Tested: bash scripts/check-cli-stdio-safety.sh; git diff --check on CLI/CMUXCLI+Process.swift Not-tested: macOS app/unit/UI workflows locally; awaiting PR CI * Keep SIGPIPE probe parsing compiler-compatible The CI Debug build uses Swift syntax rules that reject value-binding patterns inside expression-style array patterns, so the internal SIGPIPE inspection probe parses its optional output path through an explicit count check instead. This keeps the probe behavior unchanged while restoring build compatibility for the activation-session job. Constraint: PR iteration must rely on CI and must not run bare xcodebuild locally Rejected: Remove the probe output-path support | tests use it to inspect stdio state without relying on a live stdout Confidence: high Scope-risk: narrow Tested: bash scripts/check-cli-stdio-safety.sh; git diff --check -- CLI/CMUXCLI+Process.swift; rg conflict marker scan Not-tested: Local Xcode build prohibited by task instructions * Expose SIGPIPE inspection fixture to CLI tests The SIGPIPE child-disposition regression lives in CLINotifyProcessIntegrationTests after the main-branch test split, while the decoded inspection payload type was left private inside WorkspaceRemoteConnectionTests. Moving the fixture to file scope keeps the same assertions and lets the unit target compile. Constraint: CircleCI unit compile logs are the verification source; local Xcode test runs are prohibited Rejected: Duplicate the struct inside CLINotifyProcessIntegrationTests | unnecessary copy for a file-local test fixture Confidence: high Scope-risk: narrow Tested: bash scripts/check-cli-stdio-safety.sh; git diff --check -- cmuxTests/WorkspaceRemoteConnectionTests.swift; conflict-marker scan Not-tested: Local cmux-unit Xcode test run prohibited by task instructions * Fix CLI SIGPIPE feedback * Fix SIGPIPE probe inherited fd snapshot * Fix SIGPIPE exec probe argv typing * Fix CMUXCLI SIGPIPE snapshot initializer * Rerun CI for CLI broken pipe fix * Fix SIGPIPE inspect signal snapshot order * Fix tmux shell stdin broken pipe path * Centralize CLI no-sigpipe writes * Close CLI stdin pipes with safe FileHandle API * Add CLI stdio lock regression coverage * Fix CLI non-stdio write lock handling * Fix CLI poll hangup broken-pipe path * Route codex teams watcher stderr through CLI writer * Move non-stdio CLI lock probe into CLI * Avoid stdio lock for isolated child launches * Fix merged CLI stdio writes * Add PostHog flush deadlock regression test * Avoid synchronous PostHog flush during quit * fix: keep spawned CLI children on default SIGPIPE fds * test: split SIGPIPE regression coverage * Flush active analytics before shutdown * Keep PostHog analytics singleton construction private * Document PostHog analytics queue isolation * Split PostHog analytics tests * Rerun CI after runner cache miss * fix: suppress expected CLI socket Sentry noise * test: keep stale socket regression path short * fix: make Sentry noise filter instantiable * refactor: split CLI Sentry telemetry tests * fix: address Sentry crash reduction review feedback * fix: close CLI SIGPIPE review gaps --------- Co-authored-by: austinpower1258 <austinwang115@gmail.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> | 3 个月前 | |
Reduce Sentry CLI broken-pipe crashes and hangs (#6254) * Add closed-stderr CLI broken pipe regression test * Handle CLI broken pipes with safe stdio writes * Limit clean broken-pipe exits to fatal stderr writes * Drop CLI unit test that depends on cli-target internals The CLIBrokenPipeWriteTests class called cliWrite() directly, but that symbol lives in the cmux-cli target and is not visible from cmuxTests, so CI failed to compile. Even with visibility, calling Darwin.write into a closed pipe inside the XCTest host crashes the runner via SIGPIPE (only the CLI binary's main() ignores SIGPIPE). The existing E2E test exercises the same closed-stderr path through the real cmux binary, so coverage is preserved. Restore cliWrite and the disposition enum to private and harden the E2E test: - XCTWaiter().wait + early XCTFail on timeout instead of falling through to assertions on a still-running process - closeOnDealloc: false so the explicit defer is the sole owner of the stderr write fd Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add CLI broken-pipe regression coverage * Scope CLI SIGPIPE handling to write and launch paths * Address CI failures and review feedback on CLI broken-pipe PR - Fix defer block return error by gating cleanup on `installed` flag - Replace Python-based SIGPIPE probe with native `__sigpipe-inspect` subcommand; removes Python dependency and avoids masking inherited SIGPIPE disposition - Fix strdup type-inference error in exec-mode probe via explicit `[UnsafeMutablePointer<CChar>?]` typing - Convert auth status/login/logout `print()` callsites to `cliPrint()` so broken-pipe writes don't crash auth subcommands - Drain spawn-probe pipes before `waitUntilExit()` to prevent deadlock - Include `cliWriteFatalStderr` in stdio-safety audit summary Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use _exit in cliWrite EPIPE path to avoid deadlock under held lock cliWrite calls Darwin.exit while holding cliSIGPIPEDispositionLock (NSLock is non-reentrant). Any atexit handler that wrote through cliWrite/cliPrint would re-enter withCLISIGPIPEDisposition and deadlock. _exit also skips atexit/stdio flush, matching the default SIGPIPE termination this path replaces when stdout is closed by the consumer. Addresses Cursor Bugbot comment on PR #2993. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Poll for writable FD on EAGAIN in cliWrite Addresses Cursor bot review on PR #2993: the previous `case EINTR, EAGAIN, EWOULDBLOCK: continue` turned non-blocking writes into a busy-wait spin under the SIGPIPE disposition lock. Split EINTR (immediate retry) from EAGAIN/EWOULDBLOCK (block on poll(POLLOUT)) so a non-blocking stdio fd yields to the kernel instead of spinning. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use F_NOSIGPIPE on CLI stdio instead of per-write sigaction Every cliPrint was wrapped in withCLISIGPIPEIgnored, which took a process-wide NSLock and did three sigaction syscalls per write to temporarily install SIG_IGN around Darwin.write. For a command like `cmux help` (~142 lines) that added ~426 extra syscalls. Opt stdout/stderr into F_NOSIGPIPE once at CLI startup — the same per-FD pattern the socket path already uses via SO_NOSIGPIPE — so write(2) just returns EPIPE and the hot path is a single write syscall per call. Keeps withCLIDefaultSIGPIPEForChildLaunch for Process.run / exec paths in case the CLI was invoked with SIG_IGN inherited, but those are low-frequency and not on the stdio write path. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix CLI SIGPIPE child inheritance and pipe writes * Close CLI stdio disposition race CLI writes and child launch setup now share one lock around stdio disposition changes, so no write can run while inherited stdout/stderr have F_NOSIGPIPE temporarily cleared for a child process. Constraint: Cursor review identified a race between child-launch fd mutation and concurrent broken-pipe writes Rejected: Reintroduce process-wide SIGPIPE ignore | would make child processes inherit the wrong SIGPIPE disposition again Confidence: high Scope-risk: narrow Directive: Any future stdio-disposition mutation must coordinate with cliWrite via cliStdioDispositionLock Tested: bash scripts/check-cli-stdio-safety.sh; git diff --check on CLI/CMUXCLI+Process.swift Not-tested: macOS app/unit/UI workflows locally; awaiting PR CI * Keep SIGPIPE probe parsing compiler-compatible The CI Debug build uses Swift syntax rules that reject value-binding patterns inside expression-style array patterns, so the internal SIGPIPE inspection probe parses its optional output path through an explicit count check instead. This keeps the probe behavior unchanged while restoring build compatibility for the activation-session job. Constraint: PR iteration must rely on CI and must not run bare xcodebuild locally Rejected: Remove the probe output-path support | tests use it to inspect stdio state without relying on a live stdout Confidence: high Scope-risk: narrow Tested: bash scripts/check-cli-stdio-safety.sh; git diff --check -- CLI/CMUXCLI+Process.swift; rg conflict marker scan Not-tested: Local Xcode build prohibited by task instructions * Expose SIGPIPE inspection fixture to CLI tests The SIGPIPE child-disposition regression lives in CLINotifyProcessIntegrationTests after the main-branch test split, while the decoded inspection payload type was left private inside WorkspaceRemoteConnectionTests. Moving the fixture to file scope keeps the same assertions and lets the unit target compile. Constraint: CircleCI unit compile logs are the verification source; local Xcode test runs are prohibited Rejected: Duplicate the struct inside CLINotifyProcessIntegrationTests | unnecessary copy for a file-local test fixture Confidence: high Scope-risk: narrow Tested: bash scripts/check-cli-stdio-safety.sh; git diff --check -- cmuxTests/WorkspaceRemoteConnectionTests.swift; conflict-marker scan Not-tested: Local cmux-unit Xcode test run prohibited by task instructions * Fix CLI SIGPIPE feedback * Fix SIGPIPE probe inherited fd snapshot * Fix SIGPIPE exec probe argv typing * Fix CMUXCLI SIGPIPE snapshot initializer * Rerun CI for CLI broken pipe fix * Fix SIGPIPE inspect signal snapshot order * Fix tmux shell stdin broken pipe path * Centralize CLI no-sigpipe writes * Close CLI stdin pipes with safe FileHandle API * Add CLI stdio lock regression coverage * Fix CLI non-stdio write lock handling * Fix CLI poll hangup broken-pipe path * Route codex teams watcher stderr through CLI writer * Move non-stdio CLI lock probe into CLI * Avoid stdio lock for isolated child launches * Fix merged CLI stdio writes * Add PostHog flush deadlock regression test * Avoid synchronous PostHog flush during quit * fix: keep spawned CLI children on default SIGPIPE fds * test: split SIGPIPE regression coverage * Flush active analytics before shutdown * Keep PostHog analytics singleton construction private * Document PostHog analytics queue isolation * Split PostHog analytics tests * Rerun CI after runner cache miss * fix: suppress expected CLI socket Sentry noise * test: keep stale socket regression path short * fix: make Sentry noise filter instantiable * refactor: split CLI Sentry telemetry tests * fix: address Sentry crash reduction review feedback * fix: close CLI SIGPIPE review gaps --------- Co-authored-by: austinpower1258 <austinwang115@gmail.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> | 3 个月前 | |
fix: preserve claude-teams tmux routing (#9033) * test: preserve claude teams tmux launch context * fix: preserve claude teams tmux routing * fix: scope claude teams tmux routing * fix: harden claude teams launch routing * fix: close tmux compat review gaps * fix: require inherited tmux launch identity * fix: validate managed launcher context * fix: preserve non-launch management commands * fix: cover managed launcher aliases * fix: validate remote managed launch context * test: cover managed teams launch invariants * fix: keep managed teams shims authoritative * fix: preserve managed launcher compatibility * fix: harden managed launch classification * fix: reject ambiguous Claude debug filters * fix: require context for session hosts * fix: keep managed child identity coherent * test: migrate OMO plugin without a session * fix: preserve non-launch command compatibility * fix: align managed launch policy ownership * test: cover moved teams launch identity * fix: honor shell snapshot argument contract * fix: preserve managed launcher operator commands * fix: preserve managed launcher shell contracts * fix: close managed launcher review gaps * test: keep focused cmux sockets below AF_UNIX limits * fix: require launch context for ultrareview * fix: preserve managed launcher compatibility * fix: preserve Claude passthrough arguments * fix: preserve managed provider passthrough * test: cover managed launcher operator commands * fix: preserve managed launcher team operators * test: cover nested Codex Teams help * fix: pass nested Codex Teams help through * test: cover Claude Teams shell wrapper reentry * fix: harden managed Teams launch identity * test: consolidate managed Teams regressions * test: cover managed provider administrative help * fix: preserve managed provider administrative help * test: cover Claude forward subagent text flag * fix: recognize Claude forward subagent text flag * test: cover OMO subcommand global options * fix: preserve OMO subcommand global options * test: keep Claude import surface-bound * fix: require surface context for Claude import * test: cover Codex Teams help subcommand * fix: pass Codex Teams help through * fix: preserve managed wrapper root help * fix: apply retry binding predicate to both phases * test: handle teammate column equalization * test: model managed tmux focus changes * test: expect tmux-compatible pane IDs * fix: capture RPC session actor immutably | 2 个月前 | |
Fix resize-pane for remote tmux mirror panes (#7837) * test: cover remote tmux mirror pane resize * Fix remote tmux mirror pane resize * Clamp remote tmux pane resize to one cell | 2 个月前 | |
fix: preserve claude-teams tmux routing (#9033) * test: preserve claude teams tmux launch context * fix: preserve claude teams tmux routing * fix: scope claude teams tmux routing * fix: harden claude teams launch routing * fix: close tmux compat review gaps * fix: require inherited tmux launch identity * fix: validate managed launcher context * fix: preserve non-launch management commands * fix: cover managed launcher aliases * fix: validate remote managed launch context * test: cover managed teams launch invariants * fix: keep managed teams shims authoritative * fix: preserve managed launcher compatibility * fix: harden managed launch classification * fix: reject ambiguous Claude debug filters * fix: require context for session hosts * fix: keep managed child identity coherent * test: migrate OMO plugin without a session * fix: preserve non-launch command compatibility * fix: align managed launch policy ownership * test: cover moved teams launch identity * fix: honor shell snapshot argument contract * fix: preserve managed launcher operator commands * fix: preserve managed launcher shell contracts * fix: close managed launcher review gaps * test: keep focused cmux sockets below AF_UNIX limits * fix: require launch context for ultrareview * fix: preserve managed launcher compatibility * fix: preserve Claude passthrough arguments * fix: preserve managed provider passthrough * test: cover managed launcher operator commands * fix: preserve managed launcher team operators * test: cover nested Codex Teams help * fix: pass nested Codex Teams help through * test: cover Claude Teams shell wrapper reentry * fix: harden managed Teams launch identity * test: consolidate managed Teams regressions * test: cover managed provider administrative help * fix: preserve managed provider administrative help * test: cover Claude forward subagent text flag * fix: recognize Claude forward subagent text flag * test: cover OMO subcommand global options * fix: preserve OMO subcommand global options * test: keep Claude import surface-bound * fix: require surface context for Claude import * test: cover Codex Teams help subcommand * fix: pass Codex Teams help through * fix: preserve managed wrapper root help * fix: apply retry binding predicate to both phases * test: handle teammate column equalization * test: model managed tmux focus changes * test: expect tmux-compatible pane IDs * fix: capture RPC session actor immutably | 2 个月前 | |
Add top snapshots and Task Manager window (#3290) * Add cmux top resource tree * Make cmux top live and cheap by default * Add Task Manager window for top metrics * Split Task Manager files for Swift budget * Tighten Task Manager rows * Move Task Manager to Window menu * Use SwiftUI Window command for Task Manager * Address top review feedback * Refresh refs before top snapshots --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com> | 5 个月前 | |
Move diff viewer backend boundary to a Rust sidecar (#7804) * Add Rust diff viewer sidecar * Harden diff sidecar request handling * Close sidecar review gaps * Finish sidecar build and retry integration * Gate sidecar transport and webview checks * Remove sidecar setup and localization gaps * Extract diff sidecar process boundary * Use stdio for native diff sidecar transport * Satisfy Swift file length guard * Make custom scheme test deterministic * Address sidecar review findings * Test incremental diff tree source reuse * Make diff tree streaming linear * Verify diff correctness and streaming performance * Fix diff sidecar review regressions * Harden diff sidecar stdio RPC * Test bounded large diff rendering * Bound large diff UI updates * Harden large diff navigation * Fix diff sidecar isolation warning * Test mobile diff drawer close control * Make mobile diff drawer opaque * Harden mobile diff drawer dismissal * Refactor diff viewer bridge ownership * Preserve diff sidecar pipe ownership * Load diff sessions lazily through Rust * Keep Rust diff sessions alive while rendering * Split diff sidecar helpers from legacy files * Close diff sessions before page navigation * Close diff sessions before navigating * Track active diff sessions through navigation * Refresh generated diff viewer bundle * Keep diff source switching responsive * Open typed diff sessions in place * Update diff CLI file budget * Extract typed diff viewer writer * Build typed diff writer in CLI target * Expose shared diff shortcut payload * Share typed diff writer model types * Allow typed diff fallback input replacement * Open diff loading shell before asset setup * Bound typed branch base resolution * Avoid duplicate diff theme registration * Test custom-scheme asset fetch decoding * Decode deflated assets for diff scheme * Test cancellation of stale diff streams * Cancel stale diff sessions and cap patch writes * test: cover diff sidecar review regressions * fix: bound diff sidecar lifecycle * test: cover sidecar cancellation cleanup * fix: clean up cancelled sidecar process groups * test: require race-free sidecar process groups * fix: handshake sidecar process group startup * test: cover cancellation after patch rename * fix: retain cleanup ownership through registration * fix: bound sidecar startup and shutdown * test: cover branch picker repository switches * fix: close final sidecar lifecycle gaps * test: cover same-repo branch base changes * fix: preserve process group identity through shutdown * Make stale branch picker test state-driven * Test Last Turn switching and abandoned sidecar sessions * Keep typed diff sources and manifests recoverable * Test typed diff selector composition * Compose typed diff selector state * Rebuild diff webview assets * Test orphan cleanup and Last Turn repo switching * Close typed diff lifecycle gaps * Test pending cancellation and rotating orphan cleanup * Bound pending and remote diff resources * Cap sidecar queue and index temp cleanup * Bound server sessions and retain patch ownership * Make patch ownership and HTTP encoding durable * Test empty branch base selection * Keep empty branch and pending patch recovery available * Test branch base survives source switching * Preserve selected branch base across source switches * Retain generated patch ownership until lifecycle cleanup * Serialize token session publication * Keep concurrent diff sessions independently owned * Reconcile session cleanup with manifest lifecycle * Make session publication cancellation safe * Scope cancellation and close transactions correctly * Authorize session close by manifest ownership * Close discarded diff sessions safely * Cancel superseded diff sessions safely * Reserve diff session resources atomically * Protect active diff session patches * Preserve active typed diff sessions * Lease active diff sidecar sessions * Journal diff session resource ownership * Bound diff session recovery artifacts * Harden diff sidecar production artifact * Fix POSIX lock calls on Xcode 26.5 * Fix app-side lease locking on Xcode 26.5 * test: cover typed diff direct page lifecycle * fix: open typed diff session page directly * Fix sidecar verification for spaced paths | 2 个月前 | |
Tell coding agents workspace todos are user-owned (#8566) * Tell coding agents workspace todos are user-owned Colleagues' coding agents have been populating workspace checklists and pinning statuses unprompted: the todo-controls release flag enabled the feature org-wide, and `cmux todo --help` described the checklist as 'writable by you and by agents', which agents exploring the CLI read as an invitation to mirror their plans into it. State the ownership policy in the surfaces agents actually read: the `cmux todo` and `cmux workspace status` help now tell agents not to touch items or status pins unless the user explicitly asks (statuses already track agent activity via inference), and the CLI contract doc records the same policy. en/ja catalog entries updated to match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Clarify the agent policy covers both checklist and status pins Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 2 个月前 | |
Fix OMP hook binding from live PID/TTY identity (#9091) * test: expose OMP hook PID/TTY binding drift * test: make OMP binding regression runnable * fix: bind OMP hooks from live controlling TTY * fix: harden OMP session reconciliation * fix: expose shared hook binding helpers * fix: negotiate and bound OMP hook delivery * fix: isolate OMP binding and drain hook shutdown * fix: preserve hook routing boundaries * fix: make OMP cleanup recoverable * fix: demote all superseded OMP claims * fix: harden OMP hook lifecycle coverage * Retry all superseded OMP cleanup records * Bound OMP cleanup retries and preserve Stop hooks * Harden superseded OMP cleanup ownership * Preserve agent runtime across Dock ownership * Test Dock agent session ownership gaps * Test Dock binding-only lifecycle transfer * Test Dock retry ownership across bindings * Test Dock resume cwd binding ownership * Test authoritative Dock binding clears * Test Dock session and directory provenance * Test completed Dock tombstone after binding clear * Test managed Dock hook identity across tmux replacement * Fix managed Dock hook identity across tmux replacement * fix: disambiguate restorable agent selection * fix: return workspace resume binding * Split agent hook process binding types * fix: preserve managed identity after retry revert --------- Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> | 2 个月前 | |
Fix Codex resume notification rebinding (#9185) * test: cover Codex resume notification rebinding * fix: preserve notifications across Codex resume | 2 个月前 | |
Fix Codex resume notification rebinding (#9185) * test: cover Codex resume notification rebinding * fix: preserve notifications across Codex resume | 2 个月前 | |
Fix Codex resume notification rebinding (#9185) * test: cover Codex resume notification rebinding * fix: preserve notifications across Codex resume | 2 个月前 | |
Fix Codex resume notification rebinding (#9185) * test: cover Codex resume notification rebinding * fix: preserve notifications across Codex resume | 2 个月前 | |
Fix Codex resume notification rebinding (#9185) * test: cover Codex resume notification rebinding * fix: preserve notifications across Codex resume | 2 个月前 | |
Keep Codex permission hooks non-blocking (#5507) * test: cover non-blocking Codex feed permissions * fix: keep Codex permission hooks non-blocking * feat: bridge Codex app-server approvals to Feed * Validate Codex Teams launch cwd * Address Codex Teams approval review findings * Align Feed TUI Codex permission modes * Handle unsupported Codex app-server requests * Close Codex watcher on unsupported requests * Preserve persistent Codex file approvals * Close Codex watcher on unresolved approvals * Honor Codex advertised approval decisions * Bound Codex approval item cache * Convert Feed coordinator tests to Swift Testing * Ignore unsupported Codex watcher requests * Share Codex approval bridge with tests * Serialize Feed coordinator tests * Gate Codex persistent approval modes per request * Keep Codex approval scopes explicit * Avoid denial for unsupported Codex persistent replies * Isolate Codex watcher approval waits * Gate Codex approval actions by capability * Treat file-change approvals as one-shot by default * Validate Codex notification approval actions * Close Codex approval feed sockets * Harden Codex approval feed bridge * Fix feed capability test encoder call * Keep Codex watcher approvals soft fallback * Answer Codex watcher approval fallbacks * Keep Codex approval fallback native | 3 个月前 | |
Fix Codex resume notification rebinding (#9185) * test: cover Codex resume notification rebinding * fix: preserve notifications across Codex resume | 2 个月前 | |
Fix Codex resume notification rebinding (#9185) * test: cover Codex resume notification rebinding * fix: preserve notifications across Codex resume | 2 个月前 | |
Fix Codex resume notification rebinding (#9185) * test: cover Codex resume notification rebinding * fix: preserve notifications across Codex resume | 2 个月前 | |
fix: make unsupported feed hooks fail neutral | 2 个月前 | |
Add native iPhone and iPad Simulator panes (#7857) * tighten simulator shortcut and mutation paths * Harden simulator operation commit boundaries * Close simulator routing and deadline races * Reconcile simulator mutations during teardown * Preserve simulator caller routing context * Route ios commands from caller pane * Preserve explicit simulator routing and input recovery * Serialize simulator text recovery * Align simulator deadlines and selection rollback * Close simulator lifecycle commit races * Reject stale simulator discovery results * Bound simulator re-enable and batch capture * Select the integrated simulator display * Close simulator transition races * Gate simulator automation on readiness * Finish simulator selection generation checks * Bound simulator context work end to end * Verify simulator descendant identities * Validate simulator process ancestry * Bound simulator process shutdown * Supervise simulator command groups * Supervise simulator pane sessions * Contain every simulator subprocess * Test simulator routing and feature flag regressions * Fail closed on stale simulator state * Test simulator lifecycle review regressions * Bound simulator control lifecycles * Test simulator cross-pane ownership regressions * Serialize simulator cross-pane mutations * Test Web Inspector cross-worker ownership * Lease Web Inspector targets across workers * Test Web Inspector stale occupancy handoff * Refresh Web Inspector occupancy during handoff * Test Web Inspector occupancy timeout * Fail closed on incomplete Inspector occupancy * Test Inspector census and release regressions * Close Inspector refresh and release races * Test stale location route teardown * Preserve location route ownership through teardown * Test Simulator launch environment privacy * Test route commit during device switch * Test feature flag telemetry consent * Own Simulator mutations through teardown * Harden Simulator isolation and ownership * Persist Simulator mutation ownership across processes * Honor telemetry consent for remote flags * Preserve failed Simulator cleanup ownership * Propagate Simulator CLI routing errors * Fix Simulator operation task syntax * Inject Simulator ownership and keep context read-only * Resolve restored Simulator context without booting * Test late Simulator display identity publication * Attach Simulator callbacks before display discovery * Test Simulator mutation ownership boundaries * Harden Simulator mutation ownership semantics * Test current Simulator default-screen contract * Support current Simulator default-screen metadata * Isolate Simulator camera transport tests * Test forwarded Simulator screen metadata * Support forwarded Simulator screen metadata * Align Simulator overlay lifecycle test with visibility * Bound Simulator recovery assertion by time * Make Simulator input recovery test deterministic * Test Simulator landscape framebuffer direction * Correct Simulator landscape presentation direction * Bound Simulator frame publication test wait * Register Simulator replay state before delivery * Test Simulator review boundary cases * Test iOS screenshot surface identity errors * Normalize Simulator control boundaries * Isolate Simulator CLI contract environment * Test native Simulator orientation dialects * Unify native Simulator orientation semantics * Test landscape Simulator digitizer coordinates * Map landscape input into native digitizer space * Test stable Simulator app switcher hold * Hold app switcher gesture stationary * Test Simulator app switcher button timing * Open Simulator app switcher with double Home * Test installed iPad DeviceKit chrome fallback * Test bounded Simulator frame publication * Scale Simulator frames to pane geometry * Test Simulator frame ring replacement cleanup * Release obsolete Simulator frame rings * Route IndexNow jobs through configured runner * Remove wall-clock assertions from RPC event tests * Test frame ring adoption race * Retire Simulator frame rings after host adoption * Keep frame completion on MainActor * Snapshot Simulator activity log before lazy layout * Regenerate webview assets after main merge * Test Simulator core readiness ordering * Stream Simulator before optional capability probes * Test control-socket Simulator selection ownership * Exclude active Simulator control action from teardown * Test natural DeviceKit chrome cap geometry * Preserve native DeviceKit chrome artwork geometry * Fix design mode test payload shadowing * Make Simulator replay tests signal-driven * Fix Simulator pane test client conformance * Test immediate Simulator context discovery * Discover Simulator before context reads * Test Simulator production edge cases * Close Simulator production review findings * Fix Simulator integration test fixtures * Fix Simulator CLI routing call site * Fix Simulator focus test fixtures * Fix Simulator app test fixtures * Test Simulator capability hydration readiness * Wait for Simulator capability hydration * Test Simulator review edge cases * Close Simulator production review gaps * Avoid recursive Simulator picker comparison * Isolate Simulator picker observation * Test Simulator application row snapshots * Snapshot Simulator application picker rows * Test static Simulator frame presentation * Drive Simulator frames without display callbacks * Test Simulator visibility remounts * Keep Simulator frames through host remounts * Isolate Simulator visibility regression suite * Test Simulator frame pacing under input load * Pace Simulator framebuffer readback * Localize project surface labels * Test Camera Injector header cache identity * Invalidate Camera Injector cache for headers * Test Simulator RPC capability discovery * Advertise Simulator RPC capabilities * test(simulator): cover interactive frame priority * fix(simulator): prioritize frames after pointer input * test(simulator): cover native tap hold duration * fix(simulator): hold synthetic taps long enough for iPadOS * Test immediate Simulator frame presentation * Present Simulator frames without an extra tick * Test failed Simulator ownership publication * Reject unsafe Simulator ownership claims * test(simulator): cover framebuffer lifecycle bounds * fix(simulator): bound framebuffer lifecycle work * test(simulator): cover review lifecycle regressions * fix(simulator): close review lifecycle gaps * test(simulator): cover routing pacing and consent * fix(simulator): scope routing pacing and consent * test(simulator): cover screenshot and cached log readiness * fix(simulator): prepare capture without eager lifecycle work * test(simulator): report capture-ready live state * fix(simulator): report live capture-ready state * test(simulator): cover control-plane and frame wakeups * fix(simulator): signal frames and preserve errored flag cache * test(simulator): cover publication wakeup races * fix(simulator): bound publication wakeups * test(simulator): cover tool editor shortcut focus * fix(simulator): preserve tool editor focus ownership * test(simulator): cover flag omission and runner injection * fix(simulator): inject async owned command execution * test(simulator): cover file drop proposal readiness * fix(simulator): validate file drop proposals * test(simulator): cover compound inspector cleanup failure * fix(simulator): preserve failed inspector cleanup state * test(simulator): cover device-scoped tool state * fix(simulator): scope tool state to selected device * test(simulator): cover final release blockers * fix(simulator): close final release blockers * test(simulator): make frame scheduling assertions deterministic * test: update Ghostty surface config ABI lock * fix(simulator): clear final build gates * fix(build): import Dock lifecycle workspace types * test(web): isolate feedback route environment * fix(build): disambiguate Dock snapshot types * test(simulator): cover review ownership blockers * fix(simulator): scope camera cleanup ownership * fix(build): make resume policy returns explicit * test(simulator): cover camera cleanup ownership retries * fix(simulator): preserve camera cleanup ownership * fix(build): clear latest main gates * test(simulator): cover final review blockers * fix(simulator): await quit cleanup and index targets * refactor(simulator): satisfy production policy * test(simulator): cover camera cleanup on device switch * fix(simulator): clean camera state before device switch * test(simulator): retain quit cleanup after panel removal * fix(simulator): make quit await durable rollback * test(simulator): cover retained cleanup recovery * fix(simulator): recover retained camera cleanup * test(simulator): cover cleanup side effects * fix(simulator): restore external cleanup state * refactor(simulator): split camera authorization record * test(web): respect delegated discovery order * test(ios): assert transition math deterministically * fix(ci): repair current-main Swift integration * fix(ci): return closed workspace restore result * test(simulator): cover final review regressions * fix(simulator): close final lifecycle gaps * test(simulator): cover review lifecycle findings * fix(simulator): resolve review lifecycle findings * test(simulator): cover durable recovery journals * fix(simulator): persist mutation recovery journals * refactor(simulator): inject durable recovery paths * test(simulator): cover durable journal transitions * fix(simulator): make recovery transitions crash consistent * test(simulator): cover recovery compatibility gaps * fix(simulator): preserve recovery compatibility * test(simulator): cover recovery ownership handoff * fix(simulator): gate recovery ownership handoff * test(simulator): cover duplicate camera journals * fix(simulator): suppress stale durable camera journals * test(simulator): cover journal reconciliation races * fix(simulator): serialize journal reconciliation * test(simulator): cover identical journal paths * fix(simulator): normalize camera journal paths * test(simulator): cover journal URL hints * fix(simulator): compare normalized journal paths * refactor(simulator): split legacy route fixture * test(simulator): observe journal lock contention | 2 个月前 | |
Run legacy Pi privacy regression in focused CI | 2 个月前 | |
Fix ssh PTY input loss and reordering at reconnect and backpressure seams (#7717) * test: regression tests for ssh PTY input loss at reconnect and backpressure seams Two deterministic reproductions of https://github.com/manaflow-ai/cmux/issues/7708 (garbled / out-of-order / lost keystrokes over cmux ssh). Both fail on main by design; the fix lands in the next commit. - TestWebSocketPTYReattachWritesAcceptedOldInputBeforeNew: input accepted by a superseded attachment must reach the PTY, in order, before input from the replacement attachment. On main the replaced-attachment check in writeInputChunk silently drops the queued bytes (times out reading OLDNEW). - "legacy input overflow pauses instead of closing and preserves order": input-window overflow in RemotePTYBridgeSession must backpressure the socket, not close the session. On main the session close(detach:)s and ~1MiB of accepted bytes are lost (delivered 4182004 of 5242880). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix: sequenced, acked ssh PTY input with seam quiesce and backpressure (#7708) Closes the four input-path holes behind garbled / out-of-order keystrokes over cmux ssh at reconnect and backpressure seams: - pty.write now carries an optional per-attachment monotonic seq (capability "pty.input.seq_ack", opt-in via pty.attach input_seq_ack). The daemon rejects gaps with the wire-pinned rpc error pty_input_seq_gap, which surfaces as a visible pty.error instead of silently writing whatever arrives. Cumulative, coalesced pty.input_ack events flow back after bytes hit the PTY fd. Writes stay async notifications, so the typing-latency win from 719a231c73 is kept. - Reattach seam is quiesced: superseding an attachment drains every already-accepted input chunk to the PTY through the single input-loop consumer (flush-barrier sentinel under inputEnqueueMu) before the replacement may enqueue, and the supersede slot is re-checked after the barrier so a concurrent attach for the same id is superseded too, never silently overwritten. Old and new bytes can no longer interleave or drop. - RemotePTYBridgeSession no longer close(detach:)s on input-window overflow: a queue-confined flow controller (RemotePTYBridgeInputFlow) pauses socket receives at the window and resumes on drain — acks in seq_ack mode, write completions in legacy mode — so accepted bytes are never dropped in either mode. - The reconnect input filter is bounded by a monotonic deadline (injectable clock, poll timeout capped by the remaining deadline) and flushes pending bytes on every pump exit (EOF, read error, poll failure), so it can never eat real ESC-prefixed keystrokes indefinitely; the fuzz test interleaves keys before/between/after probe replies, including a lone ESC. Mixed versions stay compatible: the capability is optional (never part of the required handshake set), old daemons ignore the attach param and seq, and old apps see no acks and no enforcement. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * review: harden seq validation, ack range checks, and EINTR deadline math Addresses PR #7717 review feedback (CodeRabbit): - pollStdinPump anchors its timeout to an absolute monotonic deadline so EINTR retries cannot extend the reconnect-filter window under repeated signal delivery. - pty.write with a present-but-malformed seq (non-integer or negative) is rejected with invalid_params instead of being treated as absent, which produced a misleading 'got 0' gap for seq-ack attachments and silently accepted malformed input for legacy ones. - RemotePTYBridgeInputFlow.acknowledge(upTo:) rejects acks for seqs that were never sent, making the session's protocol-violation teardown branch reachable instead of trusting a malformed daemon ack. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 2 个月前 | |
Fix remote PTY restore probe reply leak (#6070) * test: cover ssh pty queued terminal replies * fix: drop queued ssh pty probe replies on restore * fix: keep ssh pty reconnect filter out of long files * fix: avoid unchecked sendable in ssh pty filter * fix: pass through ambiguous ssh pty escape input * test: cover ssh pty reconnect filter boundaries * fix: keep reconnect probe filter active across reads * fix: buffer reconnect probe escape prefix * fix: flush bare escape after reconnect drain * fix: bound reconnect probe reply drain * fix: limit reconnect probe filter to terminal stdin * test: clean reconnect filter policy findings * fix: filter OSC 12 reconnect probe replies * fix: drain reconnect probes before relaying output * fix: keep reconnect probe filtering until bridge output * fix: stop reconnect input filtering after bridge output * chore: refresh swift file length budget * fix: signal reconnect filter stop without shared lock * fix: drain reconnect filter input before stopping * fix: wait for reconnect filter stop acknowledgement * fix: acknowledge reconnect filter natural completion * fix: preserve resize ordering in reconnect stdin pump * fix: avoid blocking reconnect output on filter stop * fix: bound reconnect filter handoff on first output * fix: disambiguate pending reconnect input before stop | 3 个月前 | |
Fix ssh PTY input loss and reordering at reconnect and backpressure seams (#7717) * test: regression tests for ssh PTY input loss at reconnect and backpressure seams Two deterministic reproductions of https://github.com/manaflow-ai/cmux/issues/7708 (garbled / out-of-order / lost keystrokes over cmux ssh). Both fail on main by design; the fix lands in the next commit. - TestWebSocketPTYReattachWritesAcceptedOldInputBeforeNew: input accepted by a superseded attachment must reach the PTY, in order, before input from the replacement attachment. On main the replaced-attachment check in writeInputChunk silently drops the queued bytes (times out reading OLDNEW). - "legacy input overflow pauses instead of closing and preserves order": input-window overflow in RemotePTYBridgeSession must backpressure the socket, not close the session. On main the session close(detach:)s and ~1MiB of accepted bytes are lost (delivered 4182004 of 5242880). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix: sequenced, acked ssh PTY input with seam quiesce and backpressure (#7708) Closes the four input-path holes behind garbled / out-of-order keystrokes over cmux ssh at reconnect and backpressure seams: - pty.write now carries an optional per-attachment monotonic seq (capability "pty.input.seq_ack", opt-in via pty.attach input_seq_ack). The daemon rejects gaps with the wire-pinned rpc error pty_input_seq_gap, which surfaces as a visible pty.error instead of silently writing whatever arrives. Cumulative, coalesced pty.input_ack events flow back after bytes hit the PTY fd. Writes stay async notifications, so the typing-latency win from 719a231c73 is kept. - Reattach seam is quiesced: superseding an attachment drains every already-accepted input chunk to the PTY through the single input-loop consumer (flush-barrier sentinel under inputEnqueueMu) before the replacement may enqueue, and the supersede slot is re-checked after the barrier so a concurrent attach for the same id is superseded too, never silently overwritten. Old and new bytes can no longer interleave or drop. - RemotePTYBridgeSession no longer close(detach:)s on input-window overflow: a queue-confined flow controller (RemotePTYBridgeInputFlow) pauses socket receives at the window and resumes on drain — acks in seq_ack mode, write completions in legacy mode — so accepted bytes are never dropped in either mode. - The reconnect input filter is bounded by a monotonic deadline (injectable clock, poll timeout capped by the remaining deadline) and flushes pending bytes on every pump exit (EOF, read error, poll failure), so it can never eat real ESC-prefixed keystrokes indefinitely; the fuzz test interleaves keys before/between/after probe replies, including a lone ESC. Mixed versions stay compatible: the capability is optional (never part of the required handshake set), old daemons ignore the attach param and seq, and old apps see no acks and no enforcement. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * review: harden seq validation, ack range checks, and EINTR deadline math Addresses PR #7717 review feedback (CodeRabbit): - pollStdinPump anchors its timeout to an absolute monotonic deadline so EINTR retries cannot extend the reconnect-filter window under repeated signal delivery. - pty.write with a present-but-malformed seq (non-integer or negative) is rejected with invalid_params instead of being treated as absent, which produced a misleading 'got 0' gap for seq-ack attachments and silently accepted malformed input for legacy ones. - RemotePTYBridgeInputFlow.acknowledge(upTo:) rejects acks for seqs that were never sent, making the session's protocol-violation teardown branch reachable instead of trusting a malformed daemon ack. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 2 个月前 | |
Fix remote PTY restore probe reply leak (#6070) * test: cover ssh pty queued terminal replies * fix: drop queued ssh pty probe replies on restore * fix: keep ssh pty reconnect filter out of long files * fix: avoid unchecked sendable in ssh pty filter * fix: pass through ambiguous ssh pty escape input * test: cover ssh pty reconnect filter boundaries * fix: keep reconnect probe filter active across reads * fix: buffer reconnect probe escape prefix * fix: flush bare escape after reconnect drain * fix: bound reconnect probe reply drain * fix: limit reconnect probe filter to terminal stdin * test: clean reconnect filter policy findings * fix: filter OSC 12 reconnect probe replies * fix: drain reconnect probes before relaying output * fix: keep reconnect probe filtering until bridge output * fix: stop reconnect input filtering after bridge output * chore: refresh swift file length budget * fix: signal reconnect filter stop without shared lock * fix: drain reconnect filter input before stopping * fix: wait for reconnect filter stop acknowledgement * fix: acknowledge reconnect filter natural completion * fix: preserve resize ordering in reconnect stdin pump * fix: avoid blocking reconnect output on filter stop * fix: bound reconnect filter handoff on first output * fix: disambiguate pending reconnect input before stop | 3 个月前 | |
Fix ssh PTY input loss and reordering at reconnect and backpressure seams (#7717) * test: regression tests for ssh PTY input loss at reconnect and backpressure seams Two deterministic reproductions of https://github.com/manaflow-ai/cmux/issues/7708 (garbled / out-of-order / lost keystrokes over cmux ssh). Both fail on main by design; the fix lands in the next commit. - TestWebSocketPTYReattachWritesAcceptedOldInputBeforeNew: input accepted by a superseded attachment must reach the PTY, in order, before input from the replacement attachment. On main the replaced-attachment check in writeInputChunk silently drops the queued bytes (times out reading OLDNEW). - "legacy input overflow pauses instead of closing and preserves order": input-window overflow in RemotePTYBridgeSession must backpressure the socket, not close the session. On main the session close(detach:)s and ~1MiB of accepted bytes are lost (delivered 4182004 of 5242880). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix: sequenced, acked ssh PTY input with seam quiesce and backpressure (#7708) Closes the four input-path holes behind garbled / out-of-order keystrokes over cmux ssh at reconnect and backpressure seams: - pty.write now carries an optional per-attachment monotonic seq (capability "pty.input.seq_ack", opt-in via pty.attach input_seq_ack). The daemon rejects gaps with the wire-pinned rpc error pty_input_seq_gap, which surfaces as a visible pty.error instead of silently writing whatever arrives. Cumulative, coalesced pty.input_ack events flow back after bytes hit the PTY fd. Writes stay async notifications, so the typing-latency win from 719a231c73 is kept. - Reattach seam is quiesced: superseding an attachment drains every already-accepted input chunk to the PTY through the single input-loop consumer (flush-barrier sentinel under inputEnqueueMu) before the replacement may enqueue, and the supersede slot is re-checked after the barrier so a concurrent attach for the same id is superseded too, never silently overwritten. Old and new bytes can no longer interleave or drop. - RemotePTYBridgeSession no longer close(detach:)s on input-window overflow: a queue-confined flow controller (RemotePTYBridgeInputFlow) pauses socket receives at the window and resumes on drain — acks in seq_ack mode, write completions in legacy mode — so accepted bytes are never dropped in either mode. - The reconnect input filter is bounded by a monotonic deadline (injectable clock, poll timeout capped by the remaining deadline) and flushes pending bytes on every pump exit (EOF, read error, poll failure), so it can never eat real ESC-prefixed keystrokes indefinitely; the fuzz test interleaves keys before/between/after probe replies, including a lone ESC. Mixed versions stay compatible: the capability is optional (never part of the required handshake set), old daemons ignore the attach param and seq, and old apps see no acks and no enforcement. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * review: harden seq validation, ack range checks, and EINTR deadline math Addresses PR #7717 review feedback (CodeRabbit): - pollStdinPump anchors its timeout to an absolute monotonic deadline so EINTR retries cannot extend the reconnect-filter window under repeated signal delivery. - pty.write with a present-but-malformed seq (non-integer or negative) is rejected with invalid_params instead of being treated as absent, which produced a misleading 'got 0' gap for seq-ack attachments and silently accepted malformed input for legacy ones. - RemotePTYBridgeInputFlow.acknowledge(upTo:) rejects acks for seqs that were never sent, making the session's protocol-violation teardown branch reachable instead of trusting a malformed daemon ack. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 2 个月前 | |
Fix stale cmux ssh pane resize: reconcile remote PTY size after arming SIGWINCH (#5989) * Reconcile remote PTY size after arming SIGWINCH (fix stale cmux ssh resize) `cmux ssh-pty-attach` captures the terminal size once for the bridge handshake and opens the remote PTY at that size, then arms its SIGWINCH DispatchSource only afterward. The window between the handshake-size capture and arming the source spans the entire remote `pty.attach` round-trip, so it is wide. Any SIGWINCH delivered in that window hits SIGWINCH's default disposition (ignore) and is lost, and nothing reconciles afterward — so when the surface's final grid size lands during attach/reattach (the common case, since SwiftUI lays the surface out after the helper spawns), the remote PTY stays frozen at the handshake size forever, corrupting full-screen TUIs (roborev, claude, htop, …). Only a later manual resize would fire SIGWINCH and correct it. Fix: after arming the SIGWINCH source, push the current size once to reconcile any resize missed during the attach window. Extract the send into a shared `sendSSHPTYResize` helper used by both the SIGWINCH handler and the reconcile so both read the freshest size and serialize on the same lock. The reconcile is a no-op on the daemon when the size already matches. Verified on macOS 15 / M4 Pro (the affected config): with the fix, a freshly opened remote workspace terminal reports the correct `stty size` immediately on attach and across reconnects, with no manual resize. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Sample terminal size inside socketLock in sendSSHPTYResize Address review: the ioctl(TIOCGWINSZ) was sampled before acquiring socketLock, so the SIGWINCH handler and the post-attach reconcile could sample different sizes and serialize only the sends — letting a stale sample win the lock last and overwrite a fresher size on the daemon, re-creating the frozen-PTY symptom. Move the sample inside the lock so it protects both the read and the send. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: split SSH PTY resize helper * test: expect initial SSH PTY resize * chore: keep SSH PTY resize sender local --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: austinpower1258 <austinwang115@gmail.com> | 3 个月前 | |
Fix stale SSH workspace connection status (#9085) * test: cover authoritative SSH terminal liveness * fix: derive SSH status from terminal liveness * fix: close SSH terminal lifecycle races * fix: authenticate SSH terminal readiness * fix: bind SSH liveness to terminal authority * fix: make Dock SSH readiness transactional * test: assert remote terminal end acceptance * test: reject retired PTY lifecycle readiness * fix: revalidate PTY lifecycle at readiness commit * test: cover remote readiness lifecycle races * fix: harden remote terminal lifecycle ownership * test: cover stale remote terminal generations * fix: authenticate remote terminal lifecycle callbacks * fix: bound remote lifecycle commit side effects * chore: document remote lifecycle ownership boundaries * test: cover reordered remote readiness callbacks * fix: order remote terminal lifecycle callbacks * test: cover remaining SSH lifecycle ordering gaps * fix: close remaining SSH lifecycle ordering gaps * test: cover lossy SSH liveness reconciliation * fix: make SSH liveness reconciliation resilient * test: cover remaining SSH liveness races * fix: close remaining SSH liveness races * test: cover Mosh and transient SSH readiness * fix: make terminal readiness authoritative * test: cover premature terminal readiness * fix: require proven terminal readiness * test: pass Dock readiness attempt generation * test: cover remote lifecycle review regressions * fix: preserve remote lifecycle routing * fix: retire orphaned remote lifecycles * test: cover raw SSH readiness gating * fix: decouple raw SSH readiness reporting * test: cover restored SSH lifecycle reporting * fix: restore SSH lifecycle authority * test: cover SSH lifecycle review regressions * fix: close SSH lifecycle review gaps * test: cover bounded SSH readiness lifecycle * fix: bound persistent SSH readiness retries * test: expose queued SSH readiness duplicates * fix: coalesce persistent SSH readiness delivery * fix: compile remote lifecycle app adapters * fix: satisfy ssh readiness closeout policy --------- Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> | 2 个月前 | |
Run cmux iOS over authenticated Iroh transport (#7908) * feat(iroh): bridge the production Swift endpoint * feat(iroh): run the mac host transport * test(iroh): reject local binding substitution * test(ios): cover pooled fallback route * fix(iroh): bind discovery to the local app instance * fix(ios): retain successful pooled route * test(iroh): require online-first host policy fallback * feat(iroh): start hosts from verified offline policy * feat(iroh): persist mac offline host policy * fix(iroh): reject partial online binding rotation * test(iroh): reject unvalidated private fallback * feat(iroh): own iOS endpoint and multistream sessions * fix(iroh): revalidate private fallback paths * fix(iroh): accept JSON media type parameters * ci(iroh): test full app on Intel Sonoma * ci(iroh): run transport tests on Intel Sonoma * test(iroh): cover abandoned relay reservations * fix(iroh): expire abandoned relay reservations * feat(iroh): expose admitted host multistream sessions * test(iroh): require bounded incoming streams * fix(iroh): bound peer-created QUIC streams * feat(iroh): defer iOS transport activation * feat(ios): prefer verified Iroh routes * test(iroh): preserve endpoint on preferred port collision * test(iroh): cover LAN rendezvous consistency * fix(iroh): fall back from occupied preferred port * feat(iroh): derive private rotating LAN aliases * fix(iroh): serialize LAN discovery with revocation * feat(iroh): make secure pairing the default * docs(iroh): record offline and LAN trust boundaries * feat(iroh): cache verified client policy offline * docs(iroh): add Apple and proxy launch caveats * docs(iroh): clarify Apple local network prompting * test(iroh): cover offline cache teardown races * fix(iroh): fence offline cache teardown * test(iroh): cover online admission leases * feat(iroh): gate online admission leases * feat(iroh): add authenticated Bonjour LAN fallback * feat(iroh): enforce online revocation leases * test(iroh): cover offline admission leases * test(iroh): cover canonical trust errors * fix(iroh): harden trust broker boundaries * fix(iroh): bound offline admission leases * test(iroh): cover policy refresh revision races * fix(iroh): fence admission policy refreshes * docs(iroh): narrow private network release scope * test(tailscale): reject unbound bearer routes * fix(mobile): state private network boundaries * test(tailscale): reject unbound bearer routes Cover numeric-only Tailscale bearer routes and reject authorization, DNS, and route substitution before transport writes. * docs(iroh): specify NAT authorization barrier * fix(tailscale): bind bearer writes to live tunnel * test(iroh): require acknowledged NAT admission barrier * test(tailscale): reject route-only transport bypass * fix(tailscale): close route-only transport bypass * fix(iroh): acknowledge NAT admission before app streams * test(iroh): hide database failure details * fix(iroh): defer reservation constraint validation * test(iroh): retain revocation monitor after handoff * fix(iroh): retain revocation monitor for connection * test(iroh): reject broker credential redirects * fix(iroh): block broker credential redirects * test(iroh): fail closed on terminal foreground policy * fix(iroh): fail closed on terminal policy refresh * test(iroh): prevent raw fallback after admission failure * fix(iroh): pin authenticated pairings to Iroh * test(auth): reject device registry redirects * test(iroh): lock registration identity and relay bootstrap * fix(iroh): preserve registration trust identity * fix(auth): reject credentialed API redirects * test(iroh): keep direct paths out of cloud storage * fix(iroh): keep direct paths device local * test(iroh): evict remotely closed client sessions * test(iroh): recover dead session on foreground * test(iroh): prevent server path-hint disclosure * fix(iroh): recover suspended client sessions * fix(iroh): keep private paths off server surfaces * test(iroh): reject overlapping LAN bootstrap routes * fix(iroh): reject ambiguous LAN interfaces * test(iroh): bound pending admissions per identity * fix(iroh): limit pending admissions per peer * test(iroh): require owned server event stream * test(auth): bound credentialed HTTP responses * test(iroh): reject concurrent control owners * fix(auth): cap credentialed HTTP responses * test(iroh): cover firewall dependency failures * fix(iroh): bound firewall availability checks * feat(iroh): deliver server events on owned stream * test(iroh): cap stalled firewall work * test(iroh): bound active sessions per binding * fix(iroh): cap stalled firewall work * fix(iroh): cap active sessions per binding * test(iroh): require firewall timeout recovery * fix(iroh): abort stalled firewall checks * fix(ci): isolate Iroh transport test suites * test(iroh): route revocation to broker delete * fix(iroh): send revocation to broker route * test(mobile): bound concurrent RPC work * fix(mobile): cap concurrent RPC work * test(mobile): bound decoded frame batches * fix(mobile): cap decoded frame batches * test(iroh): bound pending Bonjour resolves * test(iroh): gate reserved application lanes * test(iroh): retain failed binding revocations * fix(iroh): bound pending Bonjour resolves * fix(iroh): gate reserved application lanes * docs(iroh): narrow production multistream claims * build(iroh): pin attested Swift fork release * test(iroh): require retry-safe binding revocation * fix(iroh): make binding revocation retry-safe * fix(iroh): durably retry binding revocations * build(iroh): lock iOS Swift fork release * test(iroh): retain Bonjour observation lifetime * test(auth): prepare before raced sign-out clear * test(iroh): quarantine failed sign-out persistence * test(ios): quarantine failed Iroh sign-out * fix(iroh): quarantine incomplete sign-out teardown * fix(iroh): clear host network state in quarantine * fix(auth): quarantine Iroh before sign-out clear * fix(ios): quarantine incomplete Iroh sign-out * fix(mobile): type Iroh binding snapshot * fix(ios): wait for auth clear before Iroh recovery * build(iroh): lock app Swift fork release * fix(iroh): persist secrets in ad-hoc debug builds * test(iroh): require local-only HTTP minter opt-in * feat(iroh): add loopback relay minter runner * test(tailscale): require numeric registry targets * feat(iroh): gate local relay minter HTTP * fix(iroh): normalize local minter opt-in * test(ios): require tagged API origin bake * fix(ios): bake tagged API origin * fix(tailscale): pin MagicDNS remotes to peer IPs * fix(tailscale): reject inactive peer snapshots * build(iroh): pin hardened FFI release * test(auth): preserve auto-login during token reads * test(auth): preserve manual sign-in during token reads * test(iroh): require startup network event delivery * fix(iroh): establish endpoint observation before activation * fix(auth): preserve active session writers * test(iroh): accept existing binding registration responses * fix(iroh): accept existing binding relay status * test(iroh): keep host active after refresh throttling * fix(iroh): preserve host during broker throttling * test(iroh): preserve client during broker throttling * fix(iroh): retain verified policy during broker outages * fix(iroh): decode broker dates on older macOS * test(iroh): reject synthetic network change floods * fix(iroh): observe address changes without feedback loop * test(iroh): accept canonical UUID identity case * fix(iroh): canonicalize pinned device UUIDs * fix(iroh): harden compatibility and private routes * refactor(iroh): split runtime ownership boundaries * test(iroh): repair authorization suite split boundaries * test(iroh): link mobile RPC authorization tests * test(iroh): support compatibility compilers * test(iroh): cover uppercase UUID fallback paths * fix(iroh): canonicalize device UUID authority * test(iroh): support Intel Sonoma compiler * test(iroh): avoid non-Sendable fixture captures * fix(updater): handle Intel-only Sparkle reason * test(iroh): cover bearer and discovery overload * fix(iroh): close route and discovery gaps * fix(ci): close Iroh compatibility regressions * feat(iroh): integrate endpoint-bound relay fleet * fix(ci): wrap command timers for Intel Swift * fix(ios): expose relay deployment to Sendable factory * test(ci): cover private networking on Intel Sonoma * test(ci): support Intel Swift Testing macros * test(iroh): expose relay refresh expiry gap * fix(iroh): retry relay refresh before expiry * fix(ios): serialize Iroh quarantine recovery * refactor(auth): isolate lifecycle revision API * fix(ci): eliminate Iroh Swift 6 warnings * fix(ci): support Intel Xcode 16.2 * fix(ci): mark canvas clock sleep sendable * fix(ci): bridge canvas preferences to main actor * fix(ci): support sidebar git on Xcode 16.2 * fix(ci): mark RPC termination handler sendable * fix(ci): support CLI on Xcode 16.2 * fix(ci): support app target on Xcode 16.2 * fix(ci): finish Xcode 16.2 source compatibility * iroh: point the broker relay fleet at the 7 self-hosted relay.cmux.dev URLs Replaces the 4 hosted iroh.link relays with our self-hosted fleet in both allowlists (web MANAGED_RELAY_URLS + presence worker APPROVED_IROH_RELAY_URLS, kept in lockstep) and the tests that referenced hosted URLs. The self-hosted relays run iroh-relay 1.0.2 behind per-region MIG+L4-LB (zero-downtime upgrades), gated by the cmux EdDSA JWT that /api/relay/token (merged, #7879) mints. * fix(ci): support trailing closure on Xcode 16.2 * ci: allow Intel compatibility suite to finish * test(ci): avoid Xcode 16.2 require recursion * ci: focus Intel compatibility coverage * fix(ci): stabilize replay ownership and Intel budget * test(ios): isolate authoritative resync coverage * feat(iroh): add secure flexible relay policy * test(iroh): split relay runtime coverage * test(iroh): allow self-hosted broker without legacy minter * fix(iroh): make hosted relay minter optional * test(iroh): cover public firewall host fallback * fix(iroh): use public host for firewall checks * fix(iroh): keep accepts and sign-out responsive * test(iroh): reproduce lost online reachability * fix(iroh): republish endpoint online routes * test(iroh): reproduce coalesced route refresh * fix(iroh): replay coalesced route refreshes * refactor(iroh): split oversized runtime files * test(iroh): cover lifecycle refresh races * fix(iroh): fence lifecycle refresh work * test(ios): reproduce loopback dev auto-pair race * test(ios): cover redacted dev Iroh attach URLs * fix(ios): wait for redacted Iroh dev attach ticket * test(ios): reproduce Iroh cold-start attach race * fix(ios): await Iroh before dev auto-pair * feat(iroh): add server-driven relay preferences * feat(iroh): complete relay controls and multistream runtime * ci: rehearse staging migrations from dispatched branch * Make managed Iroh credentials server-driven * feat(iroh): expose redacted live path diagnostics * security(iroh): stage relay policy key rotation * fix(iroh): use instance-scoped host display name * test(iroh): require dev attach targets to prefer identity routes * fix(iroh): prefer identity routes for dev attach * fix(web): include shared relay catalog in Next root * test(web): keep relay catalog inside Next boundary * fix(web): generate relay catalog inside runtime boundaries * test(mobile): cover transport lifetime ownership * fix(mobile): retain Iroh transport lifetime * test(iroh): cover relay policy clock skew * fix(iroh): tolerate bounded relay policy clock skew * test(iroh): cover admitted session lifetime * fix(iroh): separate admission and session lifetimes * test(iroh): cover relay and route renewal stalls * fix(iroh): keep relay routes renewed through storage stalls * test(iroh): cover nonblocking binding persistence * fix(iroh): publish bindings before secure persistence * test(iroh): cover strict transport verification modes * feat(iroh): add strict transport verification modes * test(iroh): await nonblocking relay persistence * test(iroh): cover live peer connection quotas * fix(iroh): bound live sessions per endpoint * test(iroh): cover broker-aware route renewal backoff * fix(iroh): back off broker route renewal retries * test(mobile): cover superseded Iroh transport cleanup * fix(iroh): close unowned mobile sessions * test(iroh): reproduce stale reconnect sessions * fix(iroh): replace stale peer sessions on admission * feat(iroh): add debug transport mode menu * Add regression coverage for Iroh merge blockers * Fix Iroh relay and reconnect merge blockers --------- Co-authored-by: lawrencecchen <54008264+lawrencecchen@users.noreply.github.com> Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> Co-authored-by: Aziz Albahar <aziz@manaflow.ai> | 2 个月前 | |
fix: preserve claude-teams tmux routing (#9033) * test: preserve claude teams tmux launch context * fix: preserve claude teams tmux routing * fix: scope claude teams tmux routing * fix: harden claude teams launch routing * fix: close tmux compat review gaps * fix: require inherited tmux launch identity * fix: validate managed launcher context * fix: preserve non-launch management commands * fix: cover managed launcher aliases * fix: validate remote managed launch context * test: cover managed teams launch invariants * fix: keep managed teams shims authoritative * fix: preserve managed launcher compatibility * fix: harden managed launch classification * fix: reject ambiguous Claude debug filters * fix: require context for session hosts * fix: keep managed child identity coherent * test: migrate OMO plugin without a session * fix: preserve non-launch command compatibility * fix: align managed launch policy ownership * test: cover moved teams launch identity * fix: honor shell snapshot argument contract * fix: preserve managed launcher operator commands * fix: preserve managed launcher shell contracts * fix: close managed launcher review gaps * test: keep focused cmux sockets below AF_UNIX limits * fix: require launch context for ultrareview * fix: preserve managed launcher compatibility * fix: preserve Claude passthrough arguments * fix: preserve managed provider passthrough * test: cover managed launcher operator commands * fix: preserve managed launcher team operators * test: cover nested Codex Teams help * fix: pass nested Codex Teams help through * test: cover Claude Teams shell wrapper reentry * fix: harden managed Teams launch identity * test: consolidate managed Teams regressions * test: cover managed provider administrative help * fix: preserve managed provider administrative help * test: cover Claude forward subagent text flag * fix: recognize Claude forward subagent text flag * test: cover OMO subcommand global options * fix: preserve OMO subcommand global options * test: keep Claude import surface-bound * fix: require surface context for Claude import * test: cover Codex Teams help subcommand * fix: pass Codex Teams help through * fix: preserve managed wrapper root help * fix: apply retry binding predicate to both phases * test: handle teammate column equalization * test: model managed tmux focus changes * test: expect tmux-compatible pane IDs * fix: capture RPC session actor immutably | 2 个月前 | |
Add sidebar agent activity indicators Adds configurable sidebar indicators for active coding agents, including synced GPU-backed spinners and workspace loading controls. | 3 个月前 | |
Fix resumed Codex Teams subagent pane backfill (#9180) * test: cover resumed Codex subagent pane backfill * fix: open resumed Codex subagent panes * test: deduplicate Codex resume fixture tracking * fix: harden Codex Teams watcher diagnostics * test: pin Codex watcher diagnostic locale --------- Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> | 2 个月前 | |
Saved split layouts: capture, store, and reopen named workspace layouts (#7414) * Add saved split layouts: capture, store, and reopen named workspace layouts Users can save the current workspace's split layout (pane tree, split directions, divider ratios, and per-pane surface types: terminal with cwd, browser with URL, project) as a named template, then open new workspaces from it later. Layouts persist in ~/.config/cmux/layouts.json using the existing CmuxLayoutNode/CmuxWorkspaceDefinition schema, so a saved layout is copy-pasteable into cmux.json workspace commands and compatible with workspace.create --layout. Three entrypoints share one action path (TabManager.openWorkspace( fromSavedLayout:)): command palette ("Save Layout as Template…" plus one dynamic "New Workspace from Layout: <name>" entry per saved layout), a new cmux layout CLI namespace (save/list/get/open/delete), and layout.* debug socket verbs. Capture is the inverse of applyCustomLayout: a walk of the live bonsplit tree emitting the declarative schema, with unsupported panel kinds preserved as placeholder terminals. Implements the core of https://github.com/manaflow-ai/cmux/issues/1055; related: https://github.com/manaflow-ai/cmux/issues/3448. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Surface saved layouts: ⌘⇧S save shortcut + plus-button layout submenu Adds a saveLayoutTemplate keyboard shortcut (default cmd+shift+S, free slot; cmd+S stays with saveFilePreview) wired per shortcut policy: both ShortcutAction enums, Settings-visible, rebindable, automatic shortcuts.bindings.saveLayoutTemplate support in cmux.json, and a docs row in web/data/cmux-shortcuts.ts (EN+JA). Dispatch posts a window-scoped savedLayoutSaveRequested notification; the focused window's ContentView presents the existing save-name dialog, so the shortcut, palette command, and future callers share one path. The palette entry now shows the current binding as its shortcut hint. The tab-bar plus button's right-click menu gains a "New Workspace from Layout" submenu (one item per saved layout, hidden when none exist), modeled on the move-surface submenu pattern; items re-fetch the layout by name and call the shared TabManager.openWorkspace(fromSavedLayout:). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address review findings and file-length budget for saved layouts Review fixes: capture now throws on an unrecognized bonsplit orientation string instead of silently defaulting to horizontal, and counts unmapped tabs as unsupported placeholders; palette open handlers re-resolve the layout by name at invocation (no stale snapshots); the save command dismisses the palette before presenting its name prompt; the saved-layout store's mtime cache is shared across instances (keyed by file path); layout CLI subcommands reject unknown flags before consuming the name; layout.save/layout.list nil-context fallbacks return unavailable-style errors instead of misleading not-found/empty results; user-facing alerts no longer surface raw decoder or system error text (CLI/socket keep full detail); the e2e browser fixture uses about:blank instead of a live URL. Budget gate: cmux layout help text moved into CLI/cmux_layout.swift, the ControlLayoutContext test defaults into ControlLayoutContextTestStubs .swift, the shortcut alignment test into KeyboardShortcutSavedLayoutTemplateTests.swift, and the shortcut matcher body into AppDelegate+SavedLayoutMenu.swift, restoring those files to their existing budgets. Only Sources/AppDelegate.swift (+2) and Sources/KeyboardShortcutSettings.swift (+4) budgets grew, covering the compiler-enforced shortcut registry entries. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Widen two AppDelegate shortcut helpers to internal for the extension file Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Beep when saved-layout menu open returns nil, matching sibling failure paths Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Capture project pane paths so saved layouts can restore project surfaces The canonical review caught that .project surfaces were serialized with no cwd/url while the apply side rebuilds them from url ?? cwd, so any saved layout with a project pane reopened as an empty placeholder. Capture now stores ProjectPanel.projectURL.path in cwd (mirroring session persistence) and falls back to a counted placeholder terminal when the path is missing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Fix corrupt-file cache so deleting layouts.json recovers to empty state The canonical review caught that load() checked the corrupt short-circuit before file existence: a nil-mtime cache entry from a pre-corruption read matched the nil mtime after the user deleted the bad file, wedging the store on corruptFile until restart. Nonexistence now resets the corrupt state first, with a regression test covering the delete-to-recover path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Make saved layouts relocatable, move default binding off cmd+shift+S, reject unresolvable workspace refs Review findings from the canonical helper: terminal cwds and project paths under the workspace root now capture as relative paths so layout open --cwd re-roots them (apply-side project paths resolve via resolveCwd like terminals; paths outside the root stay absolute deliberately); the default saveLayoutTemplate binding moves to ctrl+cmd+S because cmd+shift+S is a common save-as shortcut inside browser panes (both enums, docs row, and alignment test updated); layout.save now errors with not_found when a workspace selector is present but unresolvable instead of silently capturing the focused workspace. Verified: socket package build + 195 tests, tagged build, e2e suite, and a live relocation proof (nested terminal saved from /tmp/laytest/a reopened rooted under --cwd /tmp/laytest/b). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Scope layout.save workspace lookup to an explicit window selector An explicit window_id must win over a workspace selector per the control routing precedence; previously a workspace in another window escaped the requested window's scope and could overwrite a saved layout with the wrong workspace contents. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Document the v1 tab-selection scope cut at the capture site Per-pane selected tabs are not representable in the declarative layout schema; extending it is tracked in https://github.com/manaflow-ai/cmux/issues/7444. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 3 个月前 | |
Fix Intel macOS 14 compatibility verification (#8272) * Fix Intel macOS 14 compatibility verification * ci: focus Intel compatibility verification * Revert "ci: focus Intel compatibility verification" This reverts commit 496bb8855a341ad1be92dc4d7bc4bed0ca6d52c4. * Fix Swift 6.0 type isolation compatibility * Reapply "ci: focus Intel compatibility verification" This reverts commit c17af42462d85bd1f83462666664c677e6edbd99. * Revert "Reapply "ci: focus Intel compatibility verification"" This reverts commit 1b3c2b474b551da6bd202ff00c58ed9aba229c2f. * Fix CryptoKit Sendable compatibility * ci: focus Intel compatibility verification * Revert "ci: focus Intel compatibility verification" This reverts commit 850170f7a57cca47a4612b558ca5ada71b5dcf73. * Fix Xcode 16 trailing argument syntax * ci: focus Intel compatibility verification * Revert "ci: focus Intel compatibility verification" This reverts commit 63c95213e912c232a42722d47c6855b6fbc17568. * Fix Xcode 16 extension isolation syntax * ci: focus Intel compatibility verification * Revert "ci: focus Intel compatibility verification" This reverts commit b0e1e084ee063ce2f93d882387f7d83a5b5660dd. * Fix Xcode 16 CLI call syntax * ci: focus Intel compatibility verification * Revert "ci: focus Intel compatibility verification" This reverts commit 1a9c4d414622ccef7081292e9b1972e35a8b4480. --------- Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> | 2 个月前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 2 个月前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 4 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 3 个月前 | ||
| 3 个月前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 4 个月前 | ||
| 2 个月前 | ||
| 5 个月前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 4 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 3 个月前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 5 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 2 个月前 |