Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 4 additions & 11 deletions CLI/cmux.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24881,16 +24881,14 @@ struct CMUXCLI {
client: client,
workspaceId: workspaceId,
surfaceId: cleanupSurfaceId,
sessionId: consumedSession.sessionId,
sessionDidEnd: true
sessionId: consumedSession.sessionId
)
if cleanupSurfaceId != consumedSession.surfaceId {
clearAgentSurfaceResumeBinding(
client: client,
workspaceId: consumedSession.workspaceId,
surfaceId: consumedSession.surfaceId,
sessionId: consumedSession.sessionId,
sessionDidEnd: true
sessionId: consumedSession.sessionId
)
}
sendClaudeFeedTelemetry(workspaceId: workspaceId, surfaceId: cleanupSurfaceId)
Expand Down Expand Up @@ -28022,8 +28020,7 @@ struct CMUXCLI {
client: SocketClient,
workspaceId: String,
surfaceId: String,
sessionId: String?,
sessionDidEnd: Bool = false
sessionId: String?
) {
let normalizedSessionId = normalizedHookValue(sessionId)
var params: [String: Any] = [
Expand All @@ -28033,9 +28030,6 @@ struct CMUXCLI {
if let normalizedSessionId {
params["checkpoint_id"] = normalizedSessionId
}
if sessionDidEnd, normalizedSessionId != nil {
params["agent_session_ended"] = true
}
_ = try? client.sendV2(method: "surface.resume.clear", params: params)
}

Expand Down Expand Up @@ -30551,8 +30545,7 @@ export default CMUXSessionRestore;
client: client,
workspaceId: consumed.workspaceId,
surfaceId: consumed.surfaceId,
sessionId: consumed.sessionId,
sessionDidEnd: true
sessionId: consumed.sessionId
)
_ = try? sendV1Command(
"clear_agent_pid \(pidKey) --tab=\(consumed.workspaceId)\(socketPanelOption(consumed.surfaceId)) --clear-status",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,38 +113,17 @@ extension ControlCommandCoordinator {
guard context?.controlSurfaceRoutingResolvesTabManager(routing: routing) ?? false else {
return .err(code: "unavailable", message: Self.surfaceWindowUnavailableMessage, data: nil)
}
let agentSessionEnded: Bool
switch params["agent_session_ended"] {
case .none:
agentSessionEnded = false
case .some(.bool(let value)):
agentSessionEnded = value
case .some:
return .err(
code: "invalid_params",
message: surfaceResumeStrings().agentSessionEndedMustBeBoolean,
data: nil
)
}
let resolution = context?.controlSurfaceResumeClear(
routing: routing,
explicitTargetID: surfaceResumeExplicitTargetID(params),
hasResolvedWindowID: uuid(params, "window_id") != nil,
expectedCheckpointID: optionalTrimmedRawString(params, "checkpoint_id")
?? optionalTrimmedRawString(params, "checkpointId"),
expectedSource: optionalTrimmedRawString(params, "source"),
agentSessionEnded: agentSessionEnded
expectedSource: optionalTrimmedRawString(params, "source")
) ?? .surfaceNotFound
return surfaceResumeResult(resolution)
}

/// The localized surface-resume strings supplied by the app bundle.
private func surfaceResumeStrings() -> ControlSurfaceResumeStrings {
context?.controlSurfaceResumeStrings() ?? ControlSurfaceResumeStrings(
agentSessionEndedMustBeBoolean: ""
)
}

/// Shapes the shared `surface.resume.*` result.
private func surfaceResumeResult(_ resolution: ControlSurfaceResumeResolution) -> ControlCallResult {
switch resolution {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,6 @@ public protocol ControlSurfaceContext: AnyObject {

// MARK: - resume.set / get / clear

/// The app-bundle-resolved localized validation strings for
/// `surface.resume.*` commands.
///
/// - Returns: The surface-resume strings.
func controlSurfaceResumeStrings() -> ControlSurfaceResumeStrings

/// Sets a resume binding for `surface.resume.set`. The app resolves the
/// target, runs the (possibly blocking, app-bundle-localized) approval flow,
/// and stores the binding.
Expand Down Expand Up @@ -267,16 +261,13 @@ public protocol ControlSurfaceContext: AnyObject {
/// - routing: The routing selectors (with the surface-resume precedence).
/// - expectedCheckpointID: The optional expected checkpoint guard.
/// - expectedSource: The optional expected source guard.
/// - agentSessionEnded: Whether a managed hook is clearing the binding as
/// part of authoritative session teardown.
/// - Returns: The resume resolution.
func controlSurfaceResumeClear(
routing: ControlRoutingSelectors,
explicitTargetID: UUID?,
hasResolvedWindowID: Bool,
expectedCheckpointID: String?,
expectedSource: String?,
agentSessionEnded: Bool
expectedSource: String?
) -> ControlSurfaceResumeResolution

// MARK: - report_tty / report_pwd / report_shell_state / ports_kick
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -445,10 +445,6 @@ extension ControlSurfaceContext {
ControlSurfaceInputStrings(inputQueueFull: "", surfaceUnavailable: "", processExited: "")
}

func controlSurfaceResumeStrings() -> ControlSurfaceResumeStrings {
ControlSurfaceResumeStrings(agentSessionEndedMustBeBoolean: "")
}

func controlSurfaceSendText(
routing: ControlRoutingSelectors,
surfaceID: UUID?,
Expand Down Expand Up @@ -481,8 +477,7 @@ extension ControlSurfaceContext {
explicitTargetID: UUID?,
hasResolvedWindowID: Bool,
expectedCheckpointID: String?,
expectedSource: String?,
agentSessionEnded: Bool
expectedSource: String?
) -> ControlSurfaceResumeResolution { .surfaceNotFound }

nonisolated func controlSurfaceParseShellActivityState(_ rawState: String) -> String? { nil }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,50 +211,6 @@ struct ControlCommandCoordinatorSurfaceTests {
))
}

@Test func surfaceResumeClearForwardsManagedSessionEndProvenance() {
let context = FakeSurfaceControlCommandContext()
let coordinator = ControlCommandCoordinator(context: context)

_ = coordinator.handle(ControlRequest(
id: .int(1),
method: "surface.resume.clear",
params: ["agent_session_ended": .bool(true)]
))
#expect(context.resumeClearAgentSessionEnded == true)

_ = coordinator.handle(ControlRequest(
id: .int(2),
method: "surface.resume.clear",
params: [:]
))
#expect(context.resumeClearAgentSessionEnded == false)
}

@Test(
"surface resume clear rejects malformed session-end provenance",
arguments: [JSONValue.null, .int(1), .string("true")]
)
func surfaceResumeClearRejectsMalformedSessionEndProvenance(value: JSONValue) {
let context = FakeSurfaceControlCommandContext()
context.resumeStrings = ControlSurfaceResumeStrings(
agentSessionEndedMustBeBoolean: "localized boolean validation"
)
let coordinator = ControlCommandCoordinator(context: context)

let result = coordinator.handle(ControlRequest(
id: .int(1),
method: "surface.resume.clear",
params: ["agent_session_ended": value]
))

#expect(result == .err(
code: "invalid_params",
message: "localized boolean validation",
data: nil
))
#expect(context.resumeClearAgentSessionEnded == nil)
}

@Test func paneCreateDockUnsupportedTypeReturnsInvalidParams() throws {
let context = FakeSurfaceControlCommandContext()
context.paneCreateResolution = .dockUnsupportedType(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ final class FakeSurfaceControlCommandContext: ControlCommandContext {
var createResolution: ControlSurfaceCreateResolution = .tabManagerUnavailable
var surfaceListSnapshot: ControlSurfaceListSnapshot?
var resumeResolution: ControlSurfaceResumeResolution = .surfaceNotFound
var resumeClearAgentSessionEnded: Bool?
var resumeStrings = ControlSurfaceResumeStrings(
agentSessionEndedMustBeBoolean: "agent_session_ended must be a boolean"
)
var reportPWDResolution: ControlSurfaceReportPWDResolution = .recorded(surfaceID: UUID())
var reportedPWD: (workspaceID: UUID, requestedSurfaceID: UUID?, path: String)?
var reportGitResolution: ControlSurfaceReportGitBranchResolution = .recorded(surfaceID: UUID())
Expand Down Expand Up @@ -57,22 +53,6 @@ final class FakeSurfaceControlCommandContext: ControlCommandContext {
resumeResolution
}

func controlSurfaceResumeStrings() -> ControlSurfaceResumeStrings {
resumeStrings
}

func controlSurfaceResumeClear(
routing: ControlRoutingSelectors,
explicitTargetID: UUID?,
hasResolvedWindowID: Bool,
expectedCheckpointID: String?,
expectedSource: String?,
agentSessionEnded: Bool
) -> ControlSurfaceResumeResolution {
resumeClearAgentSessionEnded = agentSessionEnded
return resumeResolution
}

func controlSurfaceReportPWD(
workspaceID: UUID,
requestedSurfaceID: UUID?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,6 @@ public struct TerminalCatalogSection: SettingCatalogSection {
userDefaultsKey: "terminal.autoResumeAgentSessions"
)

/// Whether failed active agent sessions automatically resume with bounded retries.
public let autoRetryAgentSessions = DefaultsKey<Bool>(
id: "terminal.autoRetryAgentSessions",
defaultValue: false,
userDefaultsKey: "terminal.autoRetryAgentSessions"
)

public let agentHibernationEnabled = DefaultsKey<Bool>(
id: "terminal.agentHibernation.enabled",
defaultValue: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,6 @@ public protocol SettingsHostActions: AnyObject {
/// catalog-backed setting.
func resetAllSettingsSideEffects()

/// Publishes the committed auto-retry setting to live workspace coordinators.
func agentSessionAutoRetrySettingDidChange()

/// Invalidates host-owned shortcut caches after Settings persists a shortcut change.
func notifyShortcutSettingsDidChange()

Expand All @@ -214,9 +211,6 @@ public extension SettingsHostActions {
/// Default no-op for hosts with no app-owned reset side effects.
func resetAllSettingsSideEffects() {}

/// Default no-op for previews and tests without agent retry coordination.
func agentSessionAutoRetrySettingDidChange() {}

/// Default no-op for hosts with no app-owned shortcut caches.
func notifyShortcutSettingsDidChange() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,6 @@ extension Array where Element == CuratedSettingEntry {
),
.init(section: .terminal, id: "copy-on-select", title: "Copy on Selection", synonyms: "terminal.copyOnSelect copy on selection select clipboard mouse double click triple click iterm"),
.init(section: .terminal, id: "agent-auto-resume", title: "Resume Agent Sessions on Reopen", synonyms: "terminal.autoResumeAgentSessions auto resume restore reopen relaunch quit sessions agents claude code codex opencode rovo dev rovodev toggle"),
.init(
section: .terminal,
id: "agent-auto-retry",
title: String(localized: "settings.terminal.agentAutoRetry", defaultValue: "Retry Failed Agent Sessions"),
synonyms: String(
localized: "settings.search.alias.setting.terminal.agent-auto-retry",
defaultValue: "terminal.autoRetryAgentSessions auto retry resume error failure transport api rate limit overloaded agents claude codex"
)
),
.init(section: .terminal, id: "agent-hibernation", title: "Agent Hibernation", synonyms: "terminal.agentHibernation.enabled idle hibernate suspend background agents claude code codex opencode live terminals"),
.init(section: .terminal, id: "agent-hibernation-idle", title: "Hibernate After Idle Seconds", synonyms: "terminal.agentHibernation.idleSeconds idle seconds timeout delay hibernate suspend"),
.init(section: .terminal, id: "agent-hibernation-max", title: "Max Live Agent Terminals", synonyms: "terminal.agentHibernation.maxLiveTerminals max live agent terminals limit count hibernate"),
Expand Down

This file was deleted.

Loading