Address ssh stack review follow-ups

This commit is contained in:
Lawrence Chen 2026-03-13 04:28:24 -07:00
parent 601e5a92e4
commit 4fffe3be3d
5 changed files with 48 additions and 30 deletions

View file

@ -27684,6 +27684,23 @@
}
}
},
"dialog.closeTab.cancel": {
"extractionState": "manual",
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Cancel"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "キャンセル"
}
}
}
},
"dialog.closeTab.message": {
"extractionState": "manual",
"localizations": {

View file

@ -9758,11 +9758,6 @@ private struct TabItemView: View, Equatable {
private var remoteWorkspaceSection: some View {
if sidebarShowSSH, let remoteWorkspaceSidebarText {
VStack(alignment: .leading, spacing: 2) {
Text(String(localized: "sidebar.remote.badge", defaultValue: "SSH"))
.font(.system(size: 9, weight: .semibold))
.foregroundColor(activeSecondaryColor(0.62))
.textCase(.uppercase)
HStack(spacing: 6) {
Text(remoteWorkspaceSidebarText)
.font(.system(size: 10, design: .monospaced))

View file

@ -1506,8 +1506,8 @@ class TabManager: ObservableObject {
alert.messageText = title
alert.informativeText = message
alert.alertStyle = .warning
alert.addButton(withTitle: "Close")
alert.addButton(withTitle: "Cancel")
alert.addButton(withTitle: String(localized: "dialog.closeTab.close", defaultValue: "Close"))
alert.addButton(withTitle: String(localized: "dialog.closeTab.cancel", defaultValue: "Cancel"))
// macOS convention: Cmd+D = confirm destructive close (e.g. "Don't Save").
// We only opt into this for the "close last workspace => close window" path to avoid

View file

@ -3117,7 +3117,7 @@ class TerminalController {
guard let windowId = v2UUID(params, "window_id") else {
return .err(code: "invalid_params", message: "Missing or invalid window_id", data: nil)
}
let focus = v2Bool(params, "focus") ?? true
let focus = v2FocusAllowed(requested: v2Bool(params, "focus") ?? false)
var result: V2CallResult = .err(code: "internal_error", message: "Failed to move workspace", data: nil)
v2MainSync {
@ -4149,14 +4149,6 @@ class TerminalController {
result = .err(code: "not_found", message: "Workspace not found", data: nil)
return
}
if let windowId = v2ResolveWindowId(tabManager: tabManager) {
_ = AppDelegate.shared?.focusMainWindow(windowId: windowId)
setActiveTabManager(tabManager)
}
if tabManager.selectedTabId != ws.id {
tabManager.selectWorkspace(ws)
}
let targetSurfaceId: UUID? = v2UUID(params, "surface_id") ?? ws.focusedPanelId
guard let targetSurfaceId else {
result = .err(code: "not_found", message: "No focused surface", data: nil)
@ -4167,6 +4159,9 @@ class TerminalController {
return
}
v2MaybeFocusWindow(for: tabManager)
v2MaybeSelectWorkspace(tabManager, workspace: ws)
if let newId = tabManager.newSplit(tabId: ws.id, surfaceId: targetSurfaceId, direction: direction) {
let paneUUID = ws.paneId(forPanelId: newId)?.id
let windowId = v2ResolveWindowId(tabManager: tabManager)
@ -4340,7 +4335,7 @@ class TerminalController {
let beforeSurfaceId = v2UUID(params, "before_surface_id")
let afterSurfaceId = v2UUID(params, "after_surface_id")
let explicitIndex = v2Int(params, "index")
let focus = v2Bool(params, "focus") ?? true
let focus = v2FocusAllowed(requested: v2Bool(params, "focus") ?? false)
let anchorCount = (beforeSurfaceId != nil ? 1 : 0) + (afterSurfaceId != nil ? 1 : 0)
if anchorCount > 1 {
@ -4451,7 +4446,7 @@ class TerminalController {
?? sourceWorkspace.bonsplitController.focusedPaneId
?? sourceWorkspace.bonsplitController.allPaneIds.first
if let rollbackPane {
_ = sourceWorkspace.attachDetachedSurface(transfer, inPane: rollbackPane, atIndex: sourceIndex, focus: true)
_ = sourceWorkspace.attachDetachedSurface(transfer, inPane: rollbackPane, atIndex: sourceIndex, focus: focus)
}
result = .err(code: "internal_error", message: "Failed to attach surface to destination", data: nil)
return
@ -4919,15 +4914,6 @@ class TerminalController {
return
}
// Ensure the flash is visible in the active UI.
if let windowId = v2ResolveWindowId(tabManager: tabManager) {
_ = AppDelegate.shared?.focusMainWindow(windowId: windowId)
setActiveTabManager(tabManager)
}
if tabManager.selectedTabId != ws.id {
tabManager.selectWorkspace(ws)
}
let surfaceId = v2UUID(params, "surface_id") ?? ws.focusedPanelId
guard let surfaceId else {
result = .err(code: "not_found", message: "No focused surface", data: nil)
@ -4938,6 +4924,9 @@ class TerminalController {
return
}
v2MaybeFocusWindow(for: tabManager)
v2MaybeSelectWorkspace(tabManager, workspace: ws)
ws.triggerFocusFlash(panelId: surfaceId)
result = .ok(["workspace_id": ws.id.uuidString, "workspace_ref": v2Ref(kind: .workspace, uuid: ws.id), "surface_id": surfaceId.uuidString, "surface_ref": v2Ref(kind: .surface, uuid: surfaceId), "window_id": v2OrNull(v2ResolveWindowId(tabManager: tabManager)?.uuidString), "window_ref": v2Ref(kind: .window, uuid: v2ResolveWindowId(tabManager: tabManager))])
}
@ -11017,6 +11006,7 @@ class TerminalController {
guard let windowId = UUID(uuidString: parts[1]) else { return "ERROR: Invalid window id" }
var ok = false
let focus = socketCommandAllowsInAppFocusMutations()
v2MainSync {
guard let srcTM = AppDelegate.shared?.tabManagerFor(tabId: wsId),
let dstTM = AppDelegate.shared?.tabManagerFor(windowId: windowId),
@ -11024,9 +11014,11 @@ class TerminalController {
ok = false
return
}
dstTM.attachWorkspace(ws, select: true)
_ = AppDelegate.shared?.focusMainWindow(windowId: windowId)
setActiveTabManager(dstTM)
dstTM.attachWorkspace(ws, select: focus)
if focus {
_ = AppDelegate.shared?.focusMainWindow(windowId: windowId)
setActiveTabManager(dstTM)
}
ok = true
}

View file

@ -102,6 +102,20 @@ final class TerminalControllerSocketSecurityTests: XCTestCase {
XCTAssertTrue(focusV2.insideSuppressed)
XCTAssertTrue(focusV2.insideAllowsFocus)
XCTAssertFalse(focusV2.outsideSuppressed)
let moveWorkspace = TerminalController.debugSocketCommandPolicySnapshot(
commandKey: "workspace.move_to_window",
isV2: true
)
XCTAssertTrue(moveWorkspace.insideSuppressed)
XCTAssertFalse(moveWorkspace.insideAllowsFocus)
let triggerFlash = TerminalController.debugSocketCommandPolicySnapshot(
commandKey: "surface.trigger_flash",
isV2: true
)
XCTAssertTrue(triggerFlash.insideSuppressed)
XCTAssertFalse(triggerFlash.insideAllowsFocus)
#else
throw XCTSkip("Socket command policy snapshot helper is debug-only.")
#endif