Tabs: '+' opens brov-chat or term.macOS (max 6, split around the camera); real zsh terminals via SwiftTerm; per-tab chat history and claude session; hover 3 s to close with confirmation

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
maksarsanjeev
2026-10-07 15:27:02 +03:00
parent 0d40b78b26
commit 56367ef9cd
11 changed files with 452 additions and 35 deletions
@@ -206,7 +206,12 @@ final class IslandWindowController: NSWindowController {
self?.fsm.greetComplete()
}
fsm.isHeldOpen = { AppState.shared.pendingApproval != nil }
// Held open: a pending approval, or a chat/terminal tab on screen (typing with
// the pointer elsewhere must not fold it away; ⌃ in the header closes it).
fsm.isHeldOpen = {
let s = AppState.shared
return s.pendingApproval != nil || (s.mode == .expanded && s.view.isTall)
}
}
// MARK: - 60 Hz polling loop
@@ -498,6 +503,8 @@ final class IslandWindowController: NSWindowController {
if cmd, let n = digitCodes[event.keyCode] {
switchToPill(number: n); return true
}
// ⎋ Escape — belongs to the shell in a term.macOS tab (vim, claude, less…).
if event.keyCode == 53 && state.view == .terminal { return false }
// ⎋ Escape — focused views (.onExitCommand) have first crack; fall back to collapse
if event.keyCode == 53 && raw.isEmpty {
let consumed = NSApp.sendAction(Selector(("cancelOperation:")), to: nil, from: nil)
@@ -1021,7 +1028,7 @@ final class IslandWindowController: NSWindowController {
progress: s.uploadProgress, nw: notchW, nh: notchH)
// Chat view resizes dynamically — AppState.chatIslandHeight
let islandH: CGFloat
if s.mode == .expanded && s.view == .prompt {
if s.mode == .expanded && s.view.isTall {
islandH = s.chatIslandHeight
} else {
islandH = fixedH
@@ -1084,7 +1091,7 @@ final class IslandPanel: NSPanel {
let (w, fixedH) = islandSize(mode: s.mode, view: s.view,
progress: s.uploadProgress, nw: nw, nh: nh)
let h: CGFloat
if s.mode == .expanded && s.view == .prompt {
if s.mode == .expanded && s.view.isTall {
h = s.chatIslandHeight
} else {
h = fixedH
@@ -1151,7 +1158,7 @@ func islandSize(mode: IslandMode, view: IslandView,
case .expanded:
let layout = IslandConst.viewLayouts[view]!
// BroV: the chat has its own width (Settings → Чат).
if view == .prompt { return (AppState.shared.chatWidth, layout.height) }
if view.isTall { return (AppState.shared.chatWidth, layout.height) }
return (IslandConst.expandedWidth, layout.height)
}
}