@lattices/cli 0.4.9 → 0.4.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +13 -13
  3. package/{app → apps/mac}/Lattices.app/Contents/Info.plist +10 -2
  4. package/{app → apps/mac}/Lattices.app/Contents/MacOS/Lattices +0 -0
  5. package/{app → apps/mac}/Package.swift +2 -1
  6. package/apps/mac/Resources/Pets/assistant-spark/pet.json +62 -0
  7. package/apps/mac/Resources/Pets/assistant-spark/spritesheet.webp +0 -0
  8. package/apps/mac/Resources/Pets/scout-ranger/pet.json +6 -0
  9. package/apps/mac/Resources/Pets/scout-ranger/spritesheet.webp +0 -0
  10. package/apps/mac/Sources/AppShell/AppActivationCoordinator.swift +27 -0
  11. package/apps/mac/Sources/AppShell/AppDelegate.swift +189 -0
  12. package/apps/mac/Sources/AppShell/AppServicesBootstrap.swift +25 -0
  13. package/{app → apps/mac}/Sources/AppShell/AppShellView.swift +18 -3
  14. package/{app → apps/mac}/Sources/AppShell/AppUpdater.swift +4 -3
  15. package/apps/mac/Sources/AppShell/HotkeyBootstrap.swift +87 -0
  16. package/{app → apps/mac}/Sources/AppShell/LatticesRuntime.swift +43 -0
  17. package/{app → apps/mac}/Sources/AppShell/MainView.swift +116 -63
  18. package/apps/mac/Sources/AppShell/MenuBarController.swift +177 -0
  19. package/{app → apps/mac}/Sources/AppShell/OnboardingView.swift +72 -60
  20. package/apps/mac/Sources/AppShell/PermissionsAssistantView.swift +366 -0
  21. package/apps/mac/Sources/AppShell/PermissionsAssistantWindow.swift +70 -0
  22. package/{app → apps/mac}/Sources/AppShell/Preferences.swift +37 -2
  23. package/{app → apps/mac}/Sources/AppShell/SettingsView.swift +815 -156
  24. package/{app → apps/mac}/Sources/AppShell/SettingsWindow.swift +10 -0
  25. package/apps/mac/Sources/AppShell/WorkspaceInspectorPresenter.swift +13 -0
  26. package/{app → apps/mac}/Sources/Core/Actions/HotkeyStore.swift +6 -1
  27. package/{app → apps/mac}/Sources/Core/Actions/IntentEngine.swift +2 -0
  28. package/{app → apps/mac}/Sources/Core/Daemon/DaemonServer.swift +5 -0
  29. package/{app → apps/mac}/Sources/Core/Daemon/LatticesApi.swift +365 -0
  30. package/{app → apps/mac}/Sources/Core/Desktop/DesktopModel.swift +1 -0
  31. package/{app → apps/mac}/Sources/Core/Desktop/OcrModel.swift +17 -13
  32. package/apps/mac/Sources/Core/Desktop/WindowCapture.swift +33 -0
  33. package/{app → apps/mac}/Sources/Core/Desktop/WindowDragSnapController.swift +18 -217
  34. package/{app → apps/mac}/Sources/Core/Desktop/WindowPreviewStore.swift +4 -5
  35. package/{app → apps/mac}/Sources/Core/Desktop/WindowTiler.swift +19 -13
  36. package/apps/mac/Sources/Core/Input/EventTapBreaker.swift +124 -0
  37. package/apps/mac/Sources/Core/Input/EventTapThread.swift +54 -0
  38. package/apps/mac/Sources/Core/Input/InputCaptureResetCenter.swift +20 -0
  39. package/apps/mac/Sources/Core/Input/KeyboardRemapController.swift +335 -0
  40. package/apps/mac/Sources/Core/Input/KeyboardRemapStore.swift +141 -0
  41. package/{app → apps/mac}/Sources/Core/Input/MouseGestureConfig.swift +155 -20
  42. package/apps/mac/Sources/Core/Input/MouseGestureController.swift +2259 -0
  43. package/apps/mac/Sources/Core/Input/MouseShortcutStore.swift +170 -0
  44. package/apps/mac/Sources/Core/Input/SecureEventInputMonitor.swift +39 -0
  45. package/apps/mac/Sources/Core/Input/ShapeRecognizer.swift +624 -0
  46. package/apps/mac/Sources/Core/Input/TapBudgetMeter.swift +56 -0
  47. package/{app → apps/mac}/Sources/Core/Overlays/ScreenMap/ScreenMapState.swift +46 -27
  48. package/{app → apps/mac}/Sources/Core/Overlays/ScreenMap/ScreenMapView.swift +580 -162
  49. package/apps/mac/Sources/Core/Overlays/ScreenOverlayCanvasController.swift +1240 -0
  50. package/{app → apps/mac}/Sources/Core/Overlays/Voice/VoiceCommandWindow.swift +11 -23
  51. package/{app → apps/mac}/Sources/Core/Pi/PiChatDock.swift +90 -43
  52. package/{app → apps/mac}/Sources/Core/Pi/PiChatSession.swift +676 -43
  53. package/{app → apps/mac}/Sources/Core/Pi/PiProviderSetupCallout.swift +5 -5
  54. package/{app → apps/mac}/Sources/Core/Pi/PiWorkspaceView.swift +93 -44
  55. package/apps/mac/Sources/Core/System/Capability.swift +79 -0
  56. package/{app → apps/mac}/Sources/Core/System/PermissionChecker.swift +43 -8
  57. package/{app → apps/mac}/Sources/Core/Voice/AudioProvider.swift +225 -56
  58. package/bin/handsoff-infer.ts +14 -5
  59. package/bin/handsoff-worker.ts +11 -7
  60. package/bin/infer.ts +406 -0
  61. package/bin/lattices-app.ts +57 -7
  62. package/bin/lattices-dev +40 -1
  63. package/bin/lattices.ts +1 -1
  64. package/docs/agent-execution-plan.md +9 -9
  65. package/docs/api.md +119 -0
  66. package/docs/app.md +1 -0
  67. package/docs/companion-deck.md +1 -1
  68. package/docs/gesture-customization-proposal.md +520 -0
  69. package/docs/mouse-gestures.md +79 -0
  70. package/docs/overview.md +2 -2
  71. package/docs/presentation-execution-review.md +9 -9
  72. package/docs/proposals/LAT-001-gesture-visual-customization.md +522 -0
  73. package/docs/proposals/LAT-002-shared-overlay-canvas.md +353 -0
  74. package/docs/proposals/LAT-003-menu-bar-controller-architecture.md +291 -0
  75. package/docs/proposals/LAT-004-interactive-overlay-actors.md +534 -0
  76. package/docs/reference/dewey.config.ts +74 -0
  77. package/docs/reference/install-agent.md +79 -0
  78. package/docs/repo-structure.md +100 -0
  79. package/docs/voice-error-model.md +7 -7
  80. package/docs/voice.md +18 -0
  81. package/package.json +23 -13
  82. package/swift/Package.swift +20 -0
  83. package/swift/Sources/DeckKit/DeckAction.swift +51 -0
  84. package/swift/Sources/DeckKit/DeckBridgeSecurity.swift +152 -0
  85. package/swift/Sources/DeckKit/DeckCockpit.swift +82 -0
  86. package/swift/Sources/DeckKit/DeckHost.swift +7 -0
  87. package/swift/Sources/DeckKit/DeckManifest.swift +145 -0
  88. package/swift/Sources/DeckKit/DeckRuntimeSnapshot.swift +533 -0
  89. package/swift/Sources/DeckKit/DeckTrackpad.swift +63 -0
  90. package/swift/Sources/DeckKit/DeckValue.swift +93 -0
  91. package/swift/Sources/DeckKit/DeckVoiceError.swift +88 -0
  92. package/swift/Tests/DeckKitTests/DeckKitTests.swift +286 -0
  93. package/app/Sources/AppShell/AppDelegate.swift +0 -408
  94. package/app/Sources/Core/Input/KeyboardRemapController.swift +0 -184
  95. package/app/Sources/Core/Input/KeyboardRemapStore.swift +0 -84
  96. package/app/Sources/Core/Input/MouseGestureController.swift +0 -1203
  97. package/app/Sources/Core/Input/MouseShortcutStore.swift +0 -107
  98. /package/{app → apps/mac}/Info.plist +0 -0
  99. /package/{app → apps/mac}/Lattices.app/Contents/Resources/AppIcon.icns +0 -0
  100. /package/{app → apps/mac}/Lattices.app/Contents/Resources/tap.wav +0 -0
  101. /package/{app → apps/mac}/Lattices.app/Contents/_CodeSignature/CodeResources +0 -0
  102. /package/{app → apps/mac}/Lattices.entitlements +0 -0
  103. /package/{app → apps/mac}/Resources/tap.wav +0 -0
  104. /package/{app → apps/mac}/Sources/AppShell/App.swift +0 -0
  105. /package/{app → apps/mac}/Sources/AppShell/CliActionLauncher.swift +0 -0
  106. /package/{app → apps/mac}/Sources/AppShell/HomeDashboardView.swift +0 -0
  107. /package/{app → apps/mac}/Sources/AppShell/KeyRecorderView.swift +0 -0
  108. /package/{app → apps/mac}/Sources/AppShell/MainWindow.swift +0 -0
  109. /package/{app → apps/mac}/Sources/Core/Actions/HotkeyManager.swift +0 -0
  110. /package/{app → apps/mac}/Sources/Core/Actions/IntentSchema.swift +0 -0
  111. /package/{app → apps/mac}/Sources/Core/Actions/Intents/CreateLayerIntent.swift +0 -0
  112. /package/{app → apps/mac}/Sources/Core/Actions/Intents/DistributeIntent.swift +0 -0
  113. /package/{app → apps/mac}/Sources/Core/Actions/Intents/FocusIntent.swift +0 -0
  114. /package/{app → apps/mac}/Sources/Core/Actions/Intents/HelpIntent.swift +0 -0
  115. /package/{app → apps/mac}/Sources/Core/Actions/Intents/KillIntent.swift +0 -0
  116. /package/{app → apps/mac}/Sources/Core/Actions/Intents/LatticeIntent.swift +0 -0
  117. /package/{app → apps/mac}/Sources/Core/Actions/Intents/LaunchIntent.swift +0 -0
  118. /package/{app → apps/mac}/Sources/Core/Actions/Intents/ListSessionsIntent.swift +0 -0
  119. /package/{app → apps/mac}/Sources/Core/Actions/Intents/ListWindowsIntent.swift +0 -0
  120. /package/{app → apps/mac}/Sources/Core/Actions/Intents/ScanIntent.swift +0 -0
  121. /package/{app → apps/mac}/Sources/Core/Actions/Intents/SearchIntent.swift +0 -0
  122. /package/{app → apps/mac}/Sources/Core/Actions/Intents/SwitchLayerIntent.swift +0 -0
  123. /package/{app → apps/mac}/Sources/Core/Actions/Intents/TileIntent.swift +0 -0
  124. /package/{app → apps/mac}/Sources/Core/Actions/PaletteCommand.swift +0 -0
  125. /package/{app → apps/mac}/Sources/Core/Actions/VoiceIntentResolver.swift +0 -0
  126. /package/{app → apps/mac}/Sources/Core/Companion/CompanionActivityLog.swift +0 -0
  127. /package/{app → apps/mac}/Sources/Core/Companion/CompanionKeyboardController.swift +0 -0
  128. /package/{app → apps/mac}/Sources/Core/Companion/LatticesCompanionBridgeServer.swift +0 -0
  129. /package/{app → apps/mac}/Sources/Core/Companion/LatticesCompanionCockpit.swift +0 -0
  130. /package/{app → apps/mac}/Sources/Core/Companion/LatticesCompanionSecurityCoordinator.swift +0 -0
  131. /package/{app → apps/mac}/Sources/Core/Companion/LatticesCompanionTrackpadController.swift +0 -0
  132. /package/{app → apps/mac}/Sources/Core/Companion/LatticesDeckHost.swift +0 -0
  133. /package/{app → apps/mac}/Sources/Core/Daemon/DaemonProtocol.swift +0 -0
  134. /package/{app → apps/mac}/Sources/Core/Desktop/AccessibilityTextExtractor.swift +0 -0
  135. /package/{app → apps/mac}/Sources/Core/Desktop/AppTypeClassifier.swift +0 -0
  136. /package/{app → apps/mac}/Sources/Core/Desktop/DesktopModelTypes.swift +0 -0
  137. /package/{app → apps/mac}/Sources/Core/Desktop/InventoryManager.swift +0 -0
  138. /package/{app → apps/mac}/Sources/Core/Desktop/InventoryPath.swift +0 -0
  139. /package/{app → apps/mac}/Sources/Core/Desktop/MouseFinder.swift +0 -0
  140. /package/{app → apps/mac}/Sources/Core/Desktop/OcrStore.swift +0 -0
  141. /package/{app → apps/mac}/Sources/Core/Desktop/PlacementSpec.swift +0 -0
  142. /package/{app → apps/mac}/Sources/Core/Desktop/SessionWindowLocator.swift +0 -0
  143. /package/{app → apps/mac}/Sources/Core/Desktop/TilePickerView.swift +0 -0
  144. /package/{app → apps/mac}/Sources/Core/Desktop/WindowPreviewCard.swift +0 -0
  145. /package/{app → apps/mac}/Sources/Core/Desktop/WindowSelectionStore.swift +0 -0
  146. /package/{app → apps/mac}/Sources/Core/Input/KeyboardRemapConfig.swift +0 -0
  147. /package/{app → apps/mac}/Sources/Core/Input/MouseInputDeviceStore.swift +0 -0
  148. /package/{app → apps/mac}/Sources/Core/Input/MouseInputEventViewer.swift +0 -0
  149. /package/{app → apps/mac}/Sources/Core/Overlays/AppWindowShell.swift +0 -0
  150. /package/{app → apps/mac}/Sources/Core/Overlays/CommandMode/CommandModeState.swift +0 -0
  151. /package/{app → apps/mac}/Sources/Core/Overlays/CommandMode/CommandModeView.swift +0 -0
  152. /package/{app → apps/mac}/Sources/Core/Overlays/CommandMode/CommandModeWindow.swift +0 -0
  153. /package/{app → apps/mac}/Sources/Core/Overlays/CommandPalette/CommandPaletteView.swift +0 -0
  154. /package/{app → apps/mac}/Sources/Core/Overlays/CommandPalette/CommandPaletteWindow.swift +0 -0
  155. /package/{app → apps/mac}/Sources/Core/Overlays/HUD/CheatSheetHUD.swift +0 -0
  156. /package/{app → apps/mac}/Sources/Core/Overlays/HUD/HUDBottomBar.swift +0 -0
  157. /package/{app → apps/mac}/Sources/Core/Overlays/HUD/HUDController.swift +0 -0
  158. /package/{app → apps/mac}/Sources/Core/Overlays/HUD/HUDLeftBar.swift +0 -0
  159. /package/{app → apps/mac}/Sources/Core/Overlays/HUD/HUDMinimap.swift +0 -0
  160. /package/{app → apps/mac}/Sources/Core/Overlays/HUD/HUDRightBar.swift +0 -0
  161. /package/{app → apps/mac}/Sources/Core/Overlays/HUD/HUDState.swift +0 -0
  162. /package/{app → apps/mac}/Sources/Core/Overlays/HUD/HUDTopBar.swift +0 -0
  163. /package/{app → apps/mac}/Sources/Core/Overlays/HUD/LauncherHUD.swift +0 -0
  164. /package/{app → apps/mac}/Sources/Core/Overlays/HUD/LayerBezel.swift +0 -0
  165. /package/{app → apps/mac}/Sources/Core/Overlays/OmniSearch/OmniSearchState.swift +0 -0
  166. /package/{app → apps/mac}/Sources/Core/Overlays/OmniSearch/OmniSearchView.swift +0 -0
  167. /package/{app → apps/mac}/Sources/Core/Overlays/OmniSearch/OmniSearchWindow.swift +0 -0
  168. /package/{app → apps/mac}/Sources/Core/Overlays/OverlayPanelShell.swift +0 -0
  169. /package/{app → apps/mac}/Sources/Core/Overlays/ScreenMap/ScreenMapWindowController.swift +0 -0
  170. /package/{app → apps/mac}/Sources/Core/Pi/PiAuthNextStepCard.swift +0 -0
  171. /package/{app → apps/mac}/Sources/Core/Pi/PiAuthPromptCard.swift +0 -0
  172. /package/{app → apps/mac}/Sources/Core/Pi/PiInstallCallout.swift +0 -0
  173. /package/{app → apps/mac}/Sources/Core/System/DiagnosticLog.swift +0 -0
  174. /package/{app → apps/mac}/Sources/Core/System/EventBus.swift +0 -0
  175. /package/{app → apps/mac}/Sources/Core/System/ProcessModel.swift +0 -0
  176. /package/{app → apps/mac}/Sources/Core/System/ProcessQuery.swift +0 -0
  177. /package/{app → apps/mac}/Sources/Core/System/SystemTelemetryMonitor.swift +0 -0
  178. /package/{app → apps/mac}/Sources/Core/Voice/AdvisorLearningStore.swift +0 -0
  179. /package/{app → apps/mac}/Sources/Core/Voice/AgentSession.swift +0 -0
  180. /package/{app → apps/mac}/Sources/Core/Voice/HandsOffSession.swift +0 -0
  181. /package/{app → apps/mac}/Sources/Core/Voice/VoiceChatView.swift +0 -0
  182. /package/{app → apps/mac}/Sources/Core/Voice/VoxClient.swift +0 -0
  183. /package/{app → apps/mac}/Sources/Core/Workspace/Project.swift +0 -0
  184. /package/{app → apps/mac}/Sources/Core/Workspace/ProjectScanner.swift +0 -0
  185. /package/{app → apps/mac}/Sources/Core/Workspace/SessionLayerStore.swift +0 -0
  186. /package/{app → apps/mac}/Sources/Core/Workspace/SessionManager.swift +0 -0
  187. /package/{app → apps/mac}/Sources/Core/Workspace/Terminal/Terminal.swift +0 -0
  188. /package/{app → apps/mac}/Sources/Core/Workspace/Terminal/TerminalQuery.swift +0 -0
  189. /package/{app → apps/mac}/Sources/Core/Workspace/Terminal/TerminalSynthesizer.swift +0 -0
  190. /package/{app → apps/mac}/Sources/Core/Workspace/Tmux/TmuxModel.swift +0 -0
  191. /package/{app → apps/mac}/Sources/Core/Workspace/Tmux/TmuxQuery.swift +0 -0
  192. /package/{app → apps/mac}/Sources/Core/Workspace/WorkspaceManager.swift +0 -0
  193. /package/{app → apps/mac}/Sources/UI/ActionRow.swift +0 -0
  194. /package/{app → apps/mac}/Sources/UI/OrphanRow.swift +0 -0
  195. /package/{app → apps/mac}/Sources/UI/ProjectRow.swift +0 -0
  196. /package/{app → apps/mac}/Sources/UI/TabGroupRow.swift +0 -0
  197. /package/{app → apps/mac}/Sources/UI/Theme.swift +0 -0
  198. /package/{app → apps/mac}/Tests/StageDragTests.swift +0 -0
  199. /package/{app → apps/mac}/Tests/StageJoinTests.swift +0 -0
  200. /package/{app → apps/mac}/Tests/StageManagerTests.swift +0 -0
  201. /package/{app → apps/mac}/Tests/StageTileTests.swift +0 -0
@@ -144,7 +144,7 @@ enum CanvasDragMode {
144
144
 
145
145
  final class ScreenMapEditorState: ObservableObject {
146
146
  @Published var windows: [ScreenMapWindowEntry]
147
- @Published var selectedLayers: Set<Int> = [0] // empty = show all
147
+ @Published var selectedLayers: Set<Int> = [] // empty = show all
148
148
  @Published var draggingWindowId: UInt32? = nil
149
149
  var canvasDragMode: CanvasDragMode = .move
150
150
  var currentCursorMode: CanvasDragMode = .move
@@ -153,7 +153,7 @@ final class ScreenMapEditorState: ObservableObject {
153
153
  @Published var zoomLevel: CGFloat = 1.0 // 1.0 = fit-all
154
154
  @Published var panOffset: CGPoint = .zero // canvas-local pixels
155
155
  @Published var focusedDisplayIndex: Int? = nil // nil = all-displays view
156
- @Published var activeViewportPreset: ScreenMapViewportPreset? = .main
156
+ @Published var activeViewportPreset: ScreenMapViewportPreset? = .overview
157
157
  @Published var windowSearchQuery: String = ""
158
158
  @Published var isTilingMode: Bool = false
159
159
  var isSearching: Bool { !windowSearchQuery.isEmpty }
@@ -380,10 +380,11 @@ final class ScreenMapEditorState: ObservableObject {
380
380
  return "L\(layer)"
381
381
  }
382
382
 
383
- /// Windows visible for the active layer filter
383
+ /// Windows visible on the current desktop for the active layer filter.
384
384
  var visibleWindows: [ScreenMapWindowEntry] {
385
- guard !selectedLayers.isEmpty else { return windows }
386
- return windows.filter { selectedLayers.contains($0.layer) }
385
+ let onscreen = windows.filter(\.isOnScreen)
386
+ guard !selectedLayers.isEmpty else { return onscreen }
387
+ return onscreen.filter { selectedLayers.contains($0.layer) }
387
388
  }
388
389
 
389
390
  private var worldScopedDisplays: [DisplayGeometry] {
@@ -398,7 +399,7 @@ final class ScreenMapEditorState: ObservableObject {
398
399
 
399
400
  var canvasWorldBounds: CGRect {
400
401
  var rects = worldScopedDisplays.map(\.cgRect)
401
- rects.append(contentsOf: worldScopedWindows.map(\.virtualFrame))
402
+ rects.append(contentsOf: worldScopedWindows.filter(\.hasEdits).map(\.virtualFrame))
402
403
 
403
404
  if rects.isEmpty {
404
405
  return CGRect(origin: bboxOrigin, size: screenSize)
@@ -409,7 +410,7 @@ final class ScreenMapEditorState: ObservableObject {
409
410
  union = union.union(rect)
410
411
  }
411
412
 
412
- let pad: CGFloat = focusedDisplayIndex == nil ? 120 : 80
413
+ let pad: CGFloat = focusedDisplayIndex == nil ? 180 : 120
413
414
  return union.insetBy(dx: -pad, dy: -pad)
414
415
  }
415
416
 
@@ -1424,7 +1425,7 @@ final class ScreenMapController: ObservableObject {
1424
1425
 
1425
1426
  private func finalizeDisplayFocusChange(flashLabel: Bool) {
1426
1427
  guard let ed = editor else { return }
1427
- focusViewportPreset(ed.activeViewportPreset ?? .main, flashView: false)
1428
+ focusViewportPreset(ed.activeViewportPreset ?? .overview, flashView: false)
1428
1429
  if flashLabel {
1429
1430
  flash(ed.focusedDisplay?.label ?? "All displays")
1430
1431
  }
@@ -1454,6 +1455,7 @@ final class ScreenMapController: ObservableObject {
1454
1455
  guard newZoom != ed.zoomLevel else { return }
1455
1456
  ed.activeViewportPreset = nil
1456
1457
  ed.zoomLevel = newZoom
1458
+ ed.scale = ed.fitScale * newZoom
1457
1459
  objectWillChange.send()
1458
1460
  }
1459
1461
 
@@ -1677,7 +1679,7 @@ final class ScreenMapController: ObservableObject {
1677
1679
  func enter() {
1678
1680
  let existingSets = windowSets
1679
1681
  guard let windowList = CGWindowListCopyWindowInfo(
1680
- [.optionAll, .excludeDesktopElements], kCGNullWindowID
1682
+ [.optionOnScreenOnly, .excludeDesktopElements], kCGNullWindowID
1681
1683
  ) as? [[String: Any]] else { return }
1682
1684
 
1683
1685
  struct CGWin {
@@ -1724,7 +1726,7 @@ final class ScreenMapController: ObservableObject {
1724
1726
  guard CGRectMakeWithDictionaryRepresentation(boundsDict, &rect) else { continue }
1725
1727
  guard rect.width >= 100 && rect.height >= 50 else { continue }
1726
1728
  let app = info[kCGWindowOwnerName as String] as? String ?? ""
1727
- if app == "Lattices" || app == "lattices" || app == "AutoFill" { continue }
1729
+ if app == "Lattices" || app == "lattices" || app == "AutoFill" || app == "Codex Computer Use" { continue }
1728
1730
  let pid = info[kCGWindowOwnerPID as String] as? Int32 ?? 0
1729
1731
  let title = info[kCGWindowName as String] as? String ?? ""
1730
1732
  let dIdx = displayIndex(for: rect)
@@ -1844,15 +1846,14 @@ final class ScreenMapController: ObservableObject {
1844
1846
  }
1845
1847
  }
1846
1848
 
1847
- // Auto-focus the display where the mouse cursor is
1848
- if screens.count > 1 {
1849
+ // Start monitor-first: focus the display under the cursor, or the first display.
1850
+ if !displayGeometries.isEmpty {
1849
1851
  let mouseLocation = NSEvent.mouseLocation
1850
1852
  let mouseCG = CGPoint(x: mouseLocation.x, y: primaryHeight - mouseLocation.y)
1851
- for disp in displayGeometries {
1852
- if disp.cgRect.contains(mouseCG) {
1853
- newEditor.focusedDisplayIndex = disp.index
1854
- break
1855
- }
1853
+ if let display = displayGeometries.first(where: { $0.cgRect.contains(mouseCG) }) {
1854
+ newEditor.focusedDisplayIndex = display.index
1855
+ } else {
1856
+ newEditor.focusedDisplayIndex = displayGeometries[0].index
1856
1857
  }
1857
1858
  }
1858
1859
 
@@ -1867,7 +1868,12 @@ final class ScreenMapController: ObservableObject {
1867
1868
  self.activeWindowSetID = nil
1868
1869
  }
1869
1870
  selectedWindowIds = []
1870
- focusViewportPreset(.main, flashView: false)
1871
+ focusViewportPreset(.overview, flashView: false)
1872
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.08) { [weak self] in
1873
+ guard let self,
1874
+ self.editor?.activeViewportPreset == .overview else { return }
1875
+ self.focusViewportPreset(.overview, flashView: false)
1876
+ }
1871
1877
  }
1872
1878
 
1873
1879
  /// Re-snapshot, preserving display/layer context
@@ -1914,10 +1920,15 @@ final class ScreenMapController: ObservableObject {
1914
1920
  ed.activeViewportPreset = preset
1915
1921
  let rect = ed.viewportRect(for: preset)
1916
1922
  DiagnosticLog.shared.info("[Canvas] preset → \(preset.title)")
1923
+ if preset == .overview {
1924
+ ed.zoomLevel = 1
1925
+ ed.scale = ed.fitScale
1926
+ ed.panOffset = .zero
1927
+ }
1917
1928
  queueCanvasNavigation(
1918
1929
  centeredOn: CGPoint(x: rect.midX, y: rect.midY),
1919
1930
  rect: rect,
1920
- zoomToFit: true
1931
+ zoomToFit: preset != .overview
1921
1932
  )
1922
1933
  if flashView {
1923
1934
  flash(preset.title)
@@ -1960,6 +1971,14 @@ final class ScreenMapController: ObservableObject {
1960
1971
  }
1961
1972
 
1962
1973
  setViewport(centeredOn: target.center, zoomLevel: targetZoom)
1974
+ if target.zoomToFit {
1975
+ ed.pendingCanvasNavigation = ScreenMapCanvasNavigationTarget(
1976
+ center: target.center,
1977
+ rect: nil,
1978
+ zoomToFit: false
1979
+ )
1980
+ ed.canvasNavigationRevision &+= 1
1981
+ }
1963
1982
  if shouldLogView {
1964
1983
  let viewport = ed.viewportWorldRect
1965
1984
  DiagnosticLog.shared.info(
@@ -2741,9 +2760,10 @@ final class ScreenMapController: ObservableObject {
2741
2760
 
2742
2761
  var captures: [UInt32: NSImage] = [:]
2743
2762
  for win in visible {
2744
- if let cgImage = CGWindowListCreateImage(
2745
- .null, .optionIncludingWindow, CGWindowID(win.id),
2746
- [.boundsIgnoreFraming, .bestResolution]
2763
+ if let cgImage = WindowCapture.image(
2764
+ listOption: .optionIncludingWindow,
2765
+ windowID: CGWindowID(win.id),
2766
+ imageOption: [.boundsIgnoreFraming, .bestResolution]
2747
2767
  ) {
2748
2768
  captures[win.id] = NSImage(cgImage: cgImage,
2749
2769
  size: NSSize(width: win.virtualFrame.width, height: win.virtualFrame.height))
@@ -2966,11 +2986,10 @@ final class WindowBezel {
2966
2986
 
2967
2987
  // Capture window content for screenshot tool compositing
2968
2988
  let windowSnapshot: NSImage? = {
2969
- guard let cgImage = CGWindowListCreateImage(
2970
- .null,
2971
- .optionIncludingWindow,
2972
- win.id,
2973
- [.bestResolution, .boundsIgnoreFraming]
2989
+ guard let cgImage = WindowCapture.image(
2990
+ listOption: .optionIncludingWindow,
2991
+ windowID: win.id,
2992
+ imageOption: [.bestResolution, .boundsIgnoreFraming]
2974
2993
  ) else { return nil }
2975
2994
  return NSImage(cgImage: cgImage, size: NSSize(width: cgFrame.width, height: cgFrame.height))
2976
2995
  }()