diff --git a/Sources/Surfaces/Workspace+CloudManualMirror.swift b/Sources/Surfaces/Workspace+CloudManualMirror.swift index 112f3d93ad71..1dababbf7796 100644 --- a/Sources/Surfaces/Workspace+CloudManualMirror.swift +++ b/Sources/Surfaces/Workspace+CloudManualMirror.swift @@ -267,8 +267,12 @@ extension Workspace { } /// The live workspace with `id` in any window, or nil once it was retired. + /// + /// Cloud pointer and input focus can call this on every event. Use each + /// manager's maintained id index so focus convergence stays constant time + /// as the workspace list grows. static func liveWorkspace(id: UUID) -> Workspace? { - AppDelegate.shared?.tabManagerFor(tabId: id)?.tabs.first { $0.id == id } + AppDelegate.shared?.tabManagerFor(tabId: id)?.workspacesById[id] } private static func pane(_ rawID: String, in workspace: Workspace) -> PaneID? { diff --git a/cmux.xcodeproj/project.pbxproj b/cmux.xcodeproj/project.pbxproj index ccaaa8a90f66..6de3fddc5b77 100644 --- a/cmux.xcodeproj/project.pbxproj +++ b/cmux.xcodeproj/project.pbxproj @@ -677,6 +677,7 @@ C11757000000000000000034 /* CLITmuxCompatStoreConcurrencyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1175700000000000000001B /* CLITmuxCompatStoreConcurrencyTests.swift */; }; 84ED8B0271A2FD801E8F280C /* CLIVMDevTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20A03BD3D5FCAFBEA0D8CA4C /* CLIVMDevTests.swift */; }; C78951D0E70B3BF25DFABD26 /* CLIVMLayoutEnvTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C52C82B48E0D40919A92FF1 /* CLIVMLayoutEnvTests.swift */; }; + 3319454512611C7069D420DE /* CLIVMReadyPollIntervalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDFFD7A7DDFCA73EF207C81D /* CLIVMReadyPollIntervalTests.swift */; }; A5D4120DA1B2C3D4E5F60F01 /* CLIVMTransferTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5D4120EA1B2C3D4E5F60F02 /* CLIVMTransferTests.swift */; }; 773600000000000000000001 /* CLIWindowCommandMockServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 773600000000000000000002 /* CLIWindowCommandMockServer.swift */; }; C11757000000000000000046 /* CLIWindowCommandMockServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 773600000000000000000002 /* CLIWindowCommandMockServer.swift */; }; @@ -5074,6 +5075,7 @@ C1175700000000000000001B /* CLITmuxCompatStoreConcurrencyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLITmuxCompatStoreConcurrencyTests.swift; sourceTree = ""; }; 20A03BD3D5FCAFBEA0D8CA4C /* CLIVMDevTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLIVMDevTests.swift; sourceTree = ""; }; 7C52C82B48E0D40919A92FF1 /* CLIVMLayoutEnvTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLIVMLayoutEnvTests.swift; sourceTree = ""; }; + BDFFD7A7DDFCA73EF207C81D /* CLIVMReadyPollIntervalTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLIVMReadyPollIntervalTests.swift; sourceTree = ""; }; A5D4120EA1B2C3D4E5F60F02 /* CLIVMTransferTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLIVMTransferTests.swift; sourceTree = ""; }; 773600000000000000000002 /* CLIWindowCommandMockServer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLIWindowCommandMockServer.swift; sourceTree = ""; }; C1175700000000000000001C /* CLIWindowHandleRoutingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLIWindowHandleRoutingTests.swift; sourceTree = ""; }; @@ -8783,6 +8785,7 @@ C11757000000000000000024 /* CodexTerminalErrorNotificationTests.swift */, C11757000000000000000025 /* KimiHookConfigLocationTests.swift */, A62542679E9A9BFDD99A7BC6 /* CodexAutoNamingArgumentsTests.swift */, + BDFFD7A7DDFCA73EF207C81D /* CLIVMReadyPollIntervalTests.swift */, ); path = cmuxCLITests; sourceTree = ""; @@ -13740,6 +13743,7 @@ C11757000000000000000045 /* CLITestBundleAnchor.swift in Sources */, C117570000000000000000B2 /* CLITmuxCompatBufferContentTests.swift in Sources */, C11757000000000000000034 /* CLITmuxCompatStoreConcurrencyTests.swift in Sources */, + 3319454512611C7069D420DE /* CLIVMReadyPollIntervalTests.swift in Sources */, C11757000000000000000046 /* CLIWindowCommandMockServer.swift in Sources */, C11757000000000000000035 /* CLIWindowHandleRoutingTests.swift in Sources */, C11757000000000000000047 /* CLIWorkspaceGroupSafetyMockServer.swift in Sources */, diff --git a/cmuxCLITests/CLIVMReadyPollIntervalTests.swift b/cmuxCLITests/CLIVMReadyPollIntervalTests.swift new file mode 100644 index 000000000000..b2867cdd9f0b --- /dev/null +++ b/cmuxCLITests/CLIVMReadyPollIntervalTests.swift @@ -0,0 +1,20 @@ +import Foundation +import Testing + +@testable import cmux_cli + +/// `vmReadyPollInterval` lives in the CLI target, so its pure override policy +/// is checked here rather than from the app-hosted `CLIVMTransferTests`, +/// where `CMUXCLI` names the app's routing type instead. +@Suite("cmux vm: ready poll interval") +struct CLIVMReadyPollIntervalTests { + @Test("Valid overrides are used; missing, malformed or out-of-range ones fall back to 3s", + arguments: [ + (nil, 3.0), ("0.05", 0.05), ("3", 3.0), ("3600", 3.0), + ("0", 3.0), ("-1", 3.0), ("nan", 3.0), ("fast", 3.0), + ] as [(String?, TimeInterval)]) + func pollInterval(override: String?, expected: TimeInterval) { + let environment = override.map { ["CMUX_VM_WAIT_POLL_SECONDS": $0] } ?? [:] + #expect(CMUXCLI.vmReadyPollInterval(environment: environment) == expected) + } +} diff --git a/cmuxTests/CLIVMTransferTests.swift b/cmuxTests/CLIVMTransferTests.swift index b8ff93990100..72fefc42f90f 100644 --- a/cmuxTests/CLIVMTransferTests.swift +++ b/cmuxTests/CLIVMTransferTests.swift @@ -726,11 +726,6 @@ extension CLINotifyProcessIntegrationRegressionTests { var environment = ProcessInfo.processInfo.environment environment["CMUX_SOCKET_PATH"] = socketPath environment["CMUX_CLI_SENTRY_DISABLED"] = "1" - XCTAssertEqual( - CMUXCLI.vmReadyPollInterval(environment: ["CMUX_VM_WAIT_POLL_SECONDS": "3600"]), - 3, - "oversized poll overrides must fall back to the command-safe cadence" - ) // The mock answers instantly, so keep the process-level check on a // valid short override rather than waiting out the production cadence. environment["CMUX_VM_WAIT_POLL_SECONDS"] = "0.05"