@lattices/cli 0.4.13 → 0.5.0

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 (180) hide show
  1. package/README.md +5 -7
  2. package/apps/mac/Info.plist +2 -2
  3. package/apps/mac/Lattices.app/Contents/Info.plist +4 -12
  4. package/apps/mac/Lattices.app/Contents/MacOS/Lattices +0 -0
  5. package/bin/lattices-app.ts +110 -17
  6. package/bin/lattices-build +125 -0
  7. package/bin/lattices-dev +89 -16
  8. package/bin/lattices.ts +977 -16
  9. package/docs/agents.md +81 -4
  10. package/docs/ai-chat-ux-review.md +416 -0
  11. package/docs/api.md +135 -3
  12. package/docs/app.md +30 -8
  13. package/docs/config.md +4 -0
  14. package/docs/mouse-gestures.md +191 -63
  15. package/docs/proposals/LAT-004-interactive-overlay-actors.md +1 -1
  16. package/docs/proposals/LAT-005-action-runtime-product-spine.md +914 -0
  17. package/docs/proposals/LAT-006-mira-in-lattices.md +553 -0
  18. package/docs/reference/dewey.config.ts +2 -2
  19. package/docs/release.md +171 -0
  20. package/docs/repo-structure.md +4 -5
  21. package/docs/voice.md +11 -27
  22. package/package.json +9 -10
  23. package/apps/mac/Package.swift +0 -27
  24. package/apps/mac/Sources/AppShell/App.swift +0 -26
  25. package/apps/mac/Sources/AppShell/AppActivationCoordinator.swift +0 -27
  26. package/apps/mac/Sources/AppShell/AppDelegate.swift +0 -189
  27. package/apps/mac/Sources/AppShell/AppServicesBootstrap.swift +0 -25
  28. package/apps/mac/Sources/AppShell/AppShellView.swift +0 -171
  29. package/apps/mac/Sources/AppShell/AppUpdater.swift +0 -305
  30. package/apps/mac/Sources/AppShell/CliActionLauncher.swift +0 -50
  31. package/apps/mac/Sources/AppShell/HomeDashboardView.swift +0 -133
  32. package/apps/mac/Sources/AppShell/HotkeyBootstrap.swift +0 -87
  33. package/apps/mac/Sources/AppShell/KeyRecorderView.swift +0 -210
  34. package/apps/mac/Sources/AppShell/LatticesRuntime.swift +0 -104
  35. package/apps/mac/Sources/AppShell/MainView.swift +0 -847
  36. package/apps/mac/Sources/AppShell/MainWindow.swift +0 -83
  37. package/apps/mac/Sources/AppShell/MenuBarController.swift +0 -177
  38. package/apps/mac/Sources/AppShell/OnboardingView.swift +0 -483
  39. package/apps/mac/Sources/AppShell/PermissionsAssistantView.swift +0 -366
  40. package/apps/mac/Sources/AppShell/PermissionsAssistantWindow.swift +0 -70
  41. package/apps/mac/Sources/AppShell/Preferences.swift +0 -297
  42. package/apps/mac/Sources/AppShell/SettingsView.swift +0 -3163
  43. package/apps/mac/Sources/AppShell/SettingsWindow.swift +0 -34
  44. package/apps/mac/Sources/AppShell/WorkspaceInspectorPresenter.swift +0 -13
  45. package/apps/mac/Sources/Core/Actions/HotkeyManager.swift +0 -256
  46. package/apps/mac/Sources/Core/Actions/HotkeyStore.swift +0 -399
  47. package/apps/mac/Sources/Core/Actions/IntentEngine.swift +0 -988
  48. package/apps/mac/Sources/Core/Actions/IntentSchema.swift +0 -94
  49. package/apps/mac/Sources/Core/Actions/Intents/CreateLayerIntent.swift +0 -54
  50. package/apps/mac/Sources/Core/Actions/Intents/DistributeIntent.swift +0 -56
  51. package/apps/mac/Sources/Core/Actions/Intents/FocusIntent.swift +0 -69
  52. package/apps/mac/Sources/Core/Actions/Intents/HelpIntent.swift +0 -41
  53. package/apps/mac/Sources/Core/Actions/Intents/KillIntent.swift +0 -47
  54. package/apps/mac/Sources/Core/Actions/Intents/LatticeIntent.swift +0 -53
  55. package/apps/mac/Sources/Core/Actions/Intents/LaunchIntent.swift +0 -67
  56. package/apps/mac/Sources/Core/Actions/Intents/ListSessionsIntent.swift +0 -32
  57. package/apps/mac/Sources/Core/Actions/Intents/ListWindowsIntent.swift +0 -30
  58. package/apps/mac/Sources/Core/Actions/Intents/ScanIntent.swift +0 -52
  59. package/apps/mac/Sources/Core/Actions/Intents/SearchIntent.swift +0 -190
  60. package/apps/mac/Sources/Core/Actions/Intents/SwitchLayerIntent.swift +0 -50
  61. package/apps/mac/Sources/Core/Actions/Intents/TileIntent.swift +0 -61
  62. package/apps/mac/Sources/Core/Actions/PaletteCommand.swift +0 -439
  63. package/apps/mac/Sources/Core/Actions/VoiceIntentResolver.swift +0 -713
  64. package/apps/mac/Sources/Core/Companion/CompanionActivityLog.swift +0 -70
  65. package/apps/mac/Sources/Core/Companion/CompanionKeyboardController.swift +0 -141
  66. package/apps/mac/Sources/Core/Companion/LatticesCompanionBridgeServer.swift +0 -454
  67. package/apps/mac/Sources/Core/Companion/LatticesCompanionCockpit.swift +0 -555
  68. package/apps/mac/Sources/Core/Companion/LatticesCompanionSecurityCoordinator.swift +0 -629
  69. package/apps/mac/Sources/Core/Companion/LatticesCompanionTrackpadController.swift +0 -204
  70. package/apps/mac/Sources/Core/Companion/LatticesDeckHost.swift +0 -1463
  71. package/apps/mac/Sources/Core/Daemon/DaemonProtocol.swift +0 -114
  72. package/apps/mac/Sources/Core/Daemon/DaemonServer.swift +0 -427
  73. package/apps/mac/Sources/Core/Daemon/LatticesApi.swift +0 -2965
  74. package/apps/mac/Sources/Core/Desktop/AccessibilityTextExtractor.swift +0 -111
  75. package/apps/mac/Sources/Core/Desktop/AppTypeClassifier.swift +0 -106
  76. package/apps/mac/Sources/Core/Desktop/DesktopModel.swift +0 -331
  77. package/apps/mac/Sources/Core/Desktop/DesktopModelTypes.swift +0 -73
  78. package/apps/mac/Sources/Core/Desktop/InventoryManager.swift +0 -35
  79. package/apps/mac/Sources/Core/Desktop/InventoryPath.swift +0 -43
  80. package/apps/mac/Sources/Core/Desktop/MouseFinder.swift +0 -527
  81. package/apps/mac/Sources/Core/Desktop/OcrModel.swift +0 -467
  82. package/apps/mac/Sources/Core/Desktop/OcrStore.swift +0 -329
  83. package/apps/mac/Sources/Core/Desktop/PlacementSpec.swift +0 -195
  84. package/apps/mac/Sources/Core/Desktop/SessionWindowLocator.swift +0 -139
  85. package/apps/mac/Sources/Core/Desktop/TilePickerView.swift +0 -209
  86. package/apps/mac/Sources/Core/Desktop/WindowCapture.swift +0 -33
  87. package/apps/mac/Sources/Core/Desktop/WindowDragSnapController.swift +0 -429
  88. package/apps/mac/Sources/Core/Desktop/WindowPreviewCard.swift +0 -100
  89. package/apps/mac/Sources/Core/Desktop/WindowPreviewStore.swift +0 -112
  90. package/apps/mac/Sources/Core/Desktop/WindowSelectionStore.swift +0 -76
  91. package/apps/mac/Sources/Core/Desktop/WindowTiler.swift +0 -2222
  92. package/apps/mac/Sources/Core/Input/EventTapBreaker.swift +0 -124
  93. package/apps/mac/Sources/Core/Input/EventTapThread.swift +0 -54
  94. package/apps/mac/Sources/Core/Input/InputCaptureResetCenter.swift +0 -20
  95. package/apps/mac/Sources/Core/Input/KeyboardRemapConfig.swift +0 -69
  96. package/apps/mac/Sources/Core/Input/KeyboardRemapController.swift +0 -346
  97. package/apps/mac/Sources/Core/Input/KeyboardRemapStore.swift +0 -141
  98. package/apps/mac/Sources/Core/Input/MouseGestureConfig.swift +0 -499
  99. package/apps/mac/Sources/Core/Input/MouseGestureController.swift +0 -2271
  100. package/apps/mac/Sources/Core/Input/MouseInputDeviceStore.swift +0 -98
  101. package/apps/mac/Sources/Core/Input/MouseInputEventViewer.swift +0 -272
  102. package/apps/mac/Sources/Core/Input/MouseShortcutStore.swift +0 -170
  103. package/apps/mac/Sources/Core/Input/SecureEventInputMonitor.swift +0 -39
  104. package/apps/mac/Sources/Core/Input/ShapeRecognizer.swift +0 -624
  105. package/apps/mac/Sources/Core/Input/TapBudgetMeter.swift +0 -56
  106. package/apps/mac/Sources/Core/Overlays/AppWindowShell.swift +0 -63
  107. package/apps/mac/Sources/Core/Overlays/CommandMode/CommandModeState.swift +0 -1566
  108. package/apps/mac/Sources/Core/Overlays/CommandMode/CommandModeView.swift +0 -1927
  109. package/apps/mac/Sources/Core/Overlays/CommandMode/CommandModeWindow.swift +0 -196
  110. package/apps/mac/Sources/Core/Overlays/CommandPalette/CommandPaletteView.swift +0 -307
  111. package/apps/mac/Sources/Core/Overlays/CommandPalette/CommandPaletteWindow.swift +0 -67
  112. package/apps/mac/Sources/Core/Overlays/HUD/CheatSheetHUD.swift +0 -576
  113. package/apps/mac/Sources/Core/Overlays/HUD/HUDBottomBar.swift +0 -279
  114. package/apps/mac/Sources/Core/Overlays/HUD/HUDController.swift +0 -1158
  115. package/apps/mac/Sources/Core/Overlays/HUD/HUDLeftBar.swift +0 -849
  116. package/apps/mac/Sources/Core/Overlays/HUD/HUDMinimap.swift +0 -179
  117. package/apps/mac/Sources/Core/Overlays/HUD/HUDRightBar.swift +0 -596
  118. package/apps/mac/Sources/Core/Overlays/HUD/HUDState.swift +0 -367
  119. package/apps/mac/Sources/Core/Overlays/HUD/HUDTopBar.swift +0 -243
  120. package/apps/mac/Sources/Core/Overlays/HUD/LauncherHUD.swift +0 -334
  121. package/apps/mac/Sources/Core/Overlays/HUD/LayerBezel.swift +0 -203
  122. package/apps/mac/Sources/Core/Overlays/OmniSearch/OmniSearchState.swift +0 -280
  123. package/apps/mac/Sources/Core/Overlays/OmniSearch/OmniSearchView.swift +0 -422
  124. package/apps/mac/Sources/Core/Overlays/OmniSearch/OmniSearchWindow.swift +0 -94
  125. package/apps/mac/Sources/Core/Overlays/OverlayPanelShell.swift +0 -241
  126. package/apps/mac/Sources/Core/Overlays/ScreenMap/ScreenMapState.swift +0 -3135
  127. package/apps/mac/Sources/Core/Overlays/ScreenMap/ScreenMapView.swift +0 -3977
  128. package/apps/mac/Sources/Core/Overlays/ScreenMap/ScreenMapWindowController.swift +0 -119
  129. package/apps/mac/Sources/Core/Overlays/ScreenOverlayCanvasController.swift +0 -1217
  130. package/apps/mac/Sources/Core/Overlays/Voice/VoiceCommandWindow.swift +0 -1575
  131. package/apps/mac/Sources/Core/Pi/PiAuthNextStepCard.swift +0 -148
  132. package/apps/mac/Sources/Core/Pi/PiAuthPromptCard.swift +0 -90
  133. package/apps/mac/Sources/Core/Pi/PiChatDock.swift +0 -564
  134. package/apps/mac/Sources/Core/Pi/PiChatSession.swift +0 -1948
  135. package/apps/mac/Sources/Core/Pi/PiInstallCallout.swift +0 -86
  136. package/apps/mac/Sources/Core/Pi/PiProviderSetupCallout.swift +0 -99
  137. package/apps/mac/Sources/Core/Pi/PiWorkspaceView.swift +0 -510
  138. package/apps/mac/Sources/Core/System/Capability.swift +0 -79
  139. package/apps/mac/Sources/Core/System/DiagnosticLog.swift +0 -373
  140. package/apps/mac/Sources/Core/System/EventBus.swift +0 -31
  141. package/apps/mac/Sources/Core/System/PermissionChecker.swift +0 -224
  142. package/apps/mac/Sources/Core/System/ProcessModel.swift +0 -199
  143. package/apps/mac/Sources/Core/System/ProcessQuery.swift +0 -151
  144. package/apps/mac/Sources/Core/System/SystemTelemetryMonitor.swift +0 -273
  145. package/apps/mac/Sources/Core/Voice/AdvisorLearningStore.swift +0 -90
  146. package/apps/mac/Sources/Core/Voice/AgentSession.swift +0 -377
  147. package/apps/mac/Sources/Core/Voice/AudioProvider.swift +0 -555
  148. package/apps/mac/Sources/Core/Voice/HandsOffSession.swift +0 -839
  149. package/apps/mac/Sources/Core/Voice/VoiceChatView.swift +0 -192
  150. package/apps/mac/Sources/Core/Voice/VoxClient.swift +0 -454
  151. package/apps/mac/Sources/Core/Workspace/Project.swift +0 -28
  152. package/apps/mac/Sources/Core/Workspace/ProjectScanner.swift +0 -141
  153. package/apps/mac/Sources/Core/Workspace/SessionLayerStore.swift +0 -285
  154. package/apps/mac/Sources/Core/Workspace/SessionManager.swift +0 -75
  155. package/apps/mac/Sources/Core/Workspace/Terminal/Terminal.swift +0 -259
  156. package/apps/mac/Sources/Core/Workspace/Terminal/TerminalQuery.swift +0 -156
  157. package/apps/mac/Sources/Core/Workspace/Terminal/TerminalSynthesizer.swift +0 -200
  158. package/apps/mac/Sources/Core/Workspace/Tmux/TmuxModel.swift +0 -60
  159. package/apps/mac/Sources/Core/Workspace/Tmux/TmuxQuery.swift +0 -105
  160. package/apps/mac/Sources/Core/Workspace/WorkspaceManager.swift +0 -1027
  161. package/apps/mac/Sources/UI/ActionRow.swift +0 -78
  162. package/apps/mac/Sources/UI/OrphanRow.swift +0 -129
  163. package/apps/mac/Sources/UI/ProjectRow.swift +0 -368
  164. package/apps/mac/Sources/UI/TabGroupRow.swift +0 -178
  165. package/apps/mac/Sources/UI/Theme.swift +0 -164
  166. package/apps/mac/Tests/StageDragTests.swift +0 -333
  167. package/apps/mac/Tests/StageJoinTests.swift +0 -313
  168. package/apps/mac/Tests/StageManagerTests.swift +0 -280
  169. package/apps/mac/Tests/StageTileTests.swift +0 -353
  170. package/swift/Package.swift +0 -20
  171. package/swift/Sources/DeckKit/DeckAction.swift +0 -51
  172. package/swift/Sources/DeckKit/DeckBridgeSecurity.swift +0 -152
  173. package/swift/Sources/DeckKit/DeckCockpit.swift +0 -82
  174. package/swift/Sources/DeckKit/DeckHost.swift +0 -7
  175. package/swift/Sources/DeckKit/DeckManifest.swift +0 -145
  176. package/swift/Sources/DeckKit/DeckRuntimeSnapshot.swift +0 -533
  177. package/swift/Sources/DeckKit/DeckTrackpad.swift +0 -63
  178. package/swift/Sources/DeckKit/DeckValue.swift +0 -93
  179. package/swift/Sources/DeckKit/DeckVoiceError.swift +0 -88
  180. package/swift/Tests/DeckKitTests/DeckKitTests.swift +0 -286
@@ -1,87 +0,0 @@
1
- import AppKit
2
-
3
- enum HotkeyBootstrap {
4
- static func registerHotkeys() {
5
- let scanner = ProjectScanner.shared
6
- CommandPaletteWindow.shared.configure(scanner: scanner)
7
-
8
- let store = HotkeyStore.shared
9
- store.register(action: .palette) { CommandPaletteWindow.shared.toggle() }
10
- store.register(action: .unifiedWindow) { ScreenMapWindowController.shared.toggle() }
11
- store.register(action: .bezel) { WorkspaceInspectorPresenter.show() }
12
- store.register(action: .cheatSheet) { SettingsWindowController.shared.show() }
13
- store.register(action: .desktopInventory) {
14
- DiagnosticLog.shared.info("Hotkey: desktopInventory triggered")
15
- ScreenMapWindowController.shared.showPage(.desktopInventory)
16
- }
17
- store.register(action: .voiceCommand) {
18
- DiagnosticLog.shared.info("Hotkey: voiceCommand triggered")
19
- VoiceCommandWindow.shared.toggle()
20
- }
21
- store.register(action: .handsOff) {
22
- DiagnosticLog.shared.info("Hotkey: handsOff triggered")
23
- HandsOffSession.shared.toggle()
24
- if HandsOffSession.shared.state != .idle {
25
- HUDController.shared.showVoiceBar()
26
- } else {
27
- HUDController.shared.hideVoiceBar()
28
- }
29
- }
30
- store.register(action: .hud) { HUDController.shared.toggle() }
31
- store.register(action: .mouseFinder) { MouseFinder.shared.find() }
32
- store.register(action: .overlayActors) { ScreenOverlayCanvasController.shared.toggleAgentActorsVisibility() }
33
- store.register(action: .omniSearch) { OmniSearchWindow.shared.toggle() }
34
-
35
- registerLayerHotkeys(store: store)
36
- registerTilingHotkeys(store: store)
37
- }
38
-
39
- private static func registerLayerHotkeys(store: HotkeyStore) {
40
- store.register(action: .layerNext) { SessionLayerStore.shared.cycleNext() }
41
- store.register(action: .layerPrev) { SessionLayerStore.shared.cyclePrev() }
42
- store.register(action: .layerTag) { SessionLayerStore.shared.tagFrontmostWindow() }
43
-
44
- let workspace = WorkspaceManager.shared
45
- let configLayerCount = (workspace.config?.layers ?? []).count
46
- let maxLayers = max(configLayerCount, 9)
47
- for (index, action) in HotkeyAction.layerActions.prefix(maxLayers).enumerated() {
48
- store.register(action: action) {
49
- let session = SessionLayerStore.shared
50
- if !session.layers.isEmpty && index < session.layers.count {
51
- session.switchTo(index: index)
52
- } else {
53
- workspace.focusLayer(index: index)
54
- }
55
- EventBus.shared.post(.layerSwitched(index: index))
56
- }
57
- }
58
- }
59
-
60
- private static func registerTilingHotkeys(store: HotkeyStore) {
61
- let tileMap: [(HotkeyAction, TilePosition)] = [
62
- (.tileLeft, .left), (.tileRight, .right),
63
- (.tileMaximize, .maximize), (.tileCenter, .center),
64
- (.tileTopLeft, .topLeft), (.tileTopRight, .topRight),
65
- (.tileBottomLeft, .bottomLeft), (.tileBottomRight, .bottomRight),
66
- (.tileTop, .top), (.tileBottom, .bottom),
67
- (.tileLeftThird, .leftThird), (.tileCenterThird, .centerThird),
68
- (.tileRightThird, .rightThird),
69
- ]
70
- for (action, position) in tileMap {
71
- store.register(action: action) {
72
- WindowTiler.tileFrontmostViaAX(to: position)
73
- }
74
- }
75
- store.register(action: .tileDistribute) {
76
- WindowTiler.distributeVisible(reactivateLattices: false)
77
- }
78
- store.register(action: .tileTypeGrid) {
79
- WindowTiler.distributeVisibleByFrontmostType(reactivateLattices: false)
80
- }
81
- store.register(action: .tileOrganize) {
82
- let appName = DesktopModel.shared.frontmostWindow()?.app
83
- ?? NSWorkspace.shared.frontmostApplication?.localizedName
84
- CommandModeWindow.shared.show(launchMode: .organize(appName: appName))
85
- }
86
- }
87
- }
@@ -1,210 +0,0 @@
1
- import SwiftUI
2
- import Carbon
3
-
4
- // MARK: - KeyRecorderView
5
-
6
- struct KeyRecorderView: View {
7
- let action: HotkeyAction
8
- @ObservedObject var store: HotkeyStore
9
-
10
- @State private var isCapturing = false
11
- @State private var conflictAction: HotkeyAction?
12
- @State private var pendingBinding: KeyBinding?
13
- @State private var showConflict = false
14
-
15
- private var binding: KeyBinding? { store.bindings[action] }
16
- private var isModified: Bool {
17
- binding != HotkeyStore.defaultBindings[action]
18
- }
19
-
20
- var body: some View {
21
- HStack(spacing: 8) {
22
- // Action label
23
- Text(action.label)
24
- .font(Typo.caption(11))
25
- .foregroundColor(Palette.textDim)
26
- .frame(minWidth: 60, idealWidth: 90, alignment: .trailing)
27
- .lineLimit(1)
28
-
29
- // Key badges or capture prompt
30
- if isCapturing {
31
- Text("Press shortcut...")
32
- .font(Typo.mono(11))
33
- .foregroundColor(Palette.running)
34
- .frame(minWidth: 80, alignment: .leading)
35
- } else if let binding = binding {
36
- HStack(spacing: 4) {
37
- ForEach(binding.compactDisplayParts, id: \.self) { part in
38
- keyBadge(part)
39
- }
40
- }
41
- .frame(minWidth: 80, alignment: .leading)
42
- }
43
-
44
- Spacer()
45
-
46
- // Edit button
47
- Button {
48
- if isCapturing {
49
- isCapturing = false
50
- } else {
51
- isCapturing = true
52
- }
53
- } label: {
54
- Text(isCapturing ? "Cancel" : "Edit")
55
- .font(Typo.caption(10))
56
- .foregroundColor(isCapturing ? Palette.kill : Palette.textDim)
57
- .padding(.horizontal, 8)
58
- .padding(.vertical, 3)
59
- .background(
60
- RoundedRectangle(cornerRadius: 3)
61
- .fill(Palette.surface)
62
- .overlay(
63
- RoundedRectangle(cornerRadius: 3)
64
- .strokeBorder(Palette.border, lineWidth: 0.5)
65
- )
66
- )
67
- }
68
- .buttonStyle(.plain)
69
-
70
- // Reset link (only when modified)
71
- if isModified {
72
- Button {
73
- store.resetBinding(for: action)
74
- } label: {
75
- Text("Reset")
76
- .font(Typo.caption(10))
77
- .foregroundColor(Palette.detach)
78
- }
79
- .buttonStyle(.plain)
80
- }
81
- }
82
- .padding(.vertical, 2)
83
- .background(
84
- isCapturing
85
- ? KeyCaptureOverlay(onCapture: handleCapture, onCancel: { isCapturing = false })
86
- : nil
87
- )
88
- .alert("Shortcut Conflict", isPresented: $showConflict) {
89
- Button("Replace") {
90
- if let pending = pendingBinding, let conflict = conflictAction {
91
- // Remove conflicting binding by resetting it
92
- store.resetBinding(for: conflict)
93
- store.updateBinding(for: action, to: pending)
94
- }
95
- pendingBinding = nil
96
- conflictAction = nil
97
- isCapturing = false
98
- }
99
- Button("Cancel", role: .cancel) {
100
- pendingBinding = nil
101
- conflictAction = nil
102
- }
103
- } message: {
104
- if let conflict = conflictAction {
105
- Text("This shortcut is already assigned to \"\(conflict.label)\". Replace it?")
106
- }
107
- }
108
- }
109
-
110
- private func handleCapture(_ binding: KeyBinding) {
111
- if let conflict = store.conflicts(for: action, with: binding) {
112
- pendingBinding = binding
113
- conflictAction = conflict
114
- showConflict = true
115
- } else {
116
- store.updateBinding(for: action, to: binding)
117
- isCapturing = false
118
- }
119
- }
120
-
121
- private func keyBadge(_ key: String) -> some View {
122
- Text(key)
123
- .font(Typo.geistMonoBold(10))
124
- .foregroundColor(Palette.text)
125
- .padding(.horizontal, 6)
126
- .padding(.vertical, 3)
127
- .background(
128
- RoundedRectangle(cornerRadius: 3)
129
- .fill(Palette.surface)
130
- .overlay(
131
- RoundedRectangle(cornerRadius: 3)
132
- .strokeBorder(Palette.border, lineWidth: 0.5)
133
- )
134
- )
135
- }
136
- }
137
-
138
- // MARK: - KeyCaptureOverlay (NSViewRepresentable bridge)
139
-
140
- struct KeyCaptureOverlay: NSViewRepresentable {
141
- let onCapture: (KeyBinding) -> Void
142
- let onCancel: () -> Void
143
-
144
- func makeNSView(context: Context) -> KeyCaptureNSView {
145
- let view = KeyCaptureNSView()
146
- view.onCapture = onCapture
147
- view.onCancel = onCancel
148
- return view
149
- }
150
-
151
- func updateNSView(_ nsView: KeyCaptureNSView, context: Context) {
152
- nsView.onCapture = onCapture
153
- nsView.onCancel = onCancel
154
- }
155
- }
156
-
157
- class KeyCaptureNSView: NSView {
158
- var onCapture: ((KeyBinding) -> Void)?
159
- var onCancel: (() -> Void)?
160
- private var monitor: Any?
161
-
162
- override func viewDidMoveToWindow() {
163
- super.viewDidMoveToWindow()
164
- if window != nil {
165
- startMonitoring()
166
- } else {
167
- stopMonitoring()
168
- }
169
- }
170
-
171
- private func startMonitoring() {
172
- stopMonitoring()
173
- monitor = NSEvent.addLocalMonitorForEvents(matching: .keyDown) { [weak self] event in
174
- guard let self = self else { return event }
175
-
176
- // Escape cancels
177
- if event.keyCode == 53 {
178
- self.onCancel?()
179
- return nil
180
- }
181
-
182
- // Require at least one modifier
183
- let mods = event.modifierFlags.intersection([.command, .shift, .option, .control])
184
- guard !mods.isEmpty else { return nil }
185
-
186
- let keyCode = UInt32(event.keyCode)
187
- let carbonMods = KeyBinding.carbonModifiers(from: mods)
188
- let parts = KeyBinding.displayParts(keyCode: keyCode, carbonModifiers: carbonMods)
189
-
190
- let binding = KeyBinding(
191
- keyCode: keyCode,
192
- carbonModifiers: carbonMods,
193
- displayParts: parts
194
- )
195
- self.onCapture?(binding)
196
- return nil // swallow the event
197
- }
198
- }
199
-
200
- private func stopMonitoring() {
201
- if let monitor = monitor {
202
- NSEvent.removeMonitor(monitor)
203
- self.monitor = nil
204
- }
205
- }
206
-
207
- deinit {
208
- stopMonitoring()
209
- }
210
- }
@@ -1,104 +0,0 @@
1
- import Foundation
2
-
3
- enum LatticesRuntime {
4
- static var cliRoot: String? {
5
- if let idx = CommandLine.arguments.firstIndex(of: "--lattices-cli-root"),
6
- CommandLine.arguments.indices.contains(idx + 1) {
7
- let root = CommandLine.arguments[idx + 1]
8
- if hasAppHelper(in: root) { return root }
9
- }
10
-
11
- let bundleDerivedRoot = Bundle.main.bundleURL
12
- .deletingLastPathComponent()
13
- .deletingLastPathComponent()
14
- .path
15
- if hasAppHelper(in: bundleDerivedRoot) {
16
- return bundleDerivedRoot
17
- }
18
-
19
- let devRoot = NSHomeDirectory() + "/dev/lattices"
20
- if hasAppHelper(in: devRoot) {
21
- return devRoot
22
- }
23
-
24
- return nil
25
- }
26
-
27
- static var appHelperScriptPath: String? {
28
- guard let cliRoot else { return nil }
29
- let path = cliRoot + "/bin/lattices-app.ts"
30
- return FileManager.default.fileExists(atPath: path) ? path : nil
31
- }
32
-
33
- static var bunPath: String? {
34
- let candidates = [
35
- NSHomeDirectory() + "/.bun/bin/bun",
36
- "/usr/local/bin/bun",
37
- "/opt/homebrew/bin/bun",
38
- ]
39
- if let path = candidates.first(where: { FileManager.default.isExecutableFile(atPath: $0) }) {
40
- return path
41
- }
42
-
43
- let resolved = ProcessQuery.shell(["/bin/zsh", "-lc", "command -v bun 2>/dev/null"])
44
- if !resolved.isEmpty, FileManager.default.isExecutableFile(atPath: resolved) {
45
- return resolved
46
- }
47
-
48
- return nil
49
- }
50
-
51
- static var appVersion: String {
52
- let info = Bundle.main.infoDictionary
53
- return (info?["CFBundleShortVersionString"] as? String)
54
- ?? (info?["CFBundleVersion"] as? String)
55
- ?? "unknown"
56
- }
57
-
58
- static var appDisplayVersion: String {
59
- let base = appVersion == "unknown" ? "unknown" : "v\(appVersion)"
60
- guard isDevBuild else { return base }
61
-
62
- let track = buildTrack ?? "latest"
63
- return "\(base)-dev.\(track)"
64
- }
65
-
66
- static var buildChannel: String {
67
- let raw = Bundle.main.infoDictionary?["LatticesBuildChannel"] as? String
68
- return raw?.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() ?? "release"
69
- }
70
-
71
- static var buildTrack: String? {
72
- normalizedInfoValue("LatticesBuildTrack")
73
- }
74
-
75
- static var buildRevision: String? {
76
- normalizedInfoValue("LatticesBuildRevision")
77
- }
78
-
79
- static var buildTimestamp: String? {
80
- normalizedInfoValue("LatticesBuildTimestamp")
81
- }
82
-
83
- static var isDevBuild: Bool {
84
- buildChannel == "dev"
85
- }
86
-
87
- static var buildStatusLabel: String {
88
- isDevBuild ? "Latest local dev build" : "Signed release build"
89
- }
90
-
91
- static var buildChannelLabel: String {
92
- isDevBuild ? "DEV" : "RELEASE"
93
- }
94
-
95
- private static func hasAppHelper(in root: String) -> Bool {
96
- FileManager.default.fileExists(atPath: root + "/bin/lattices-app.ts")
97
- }
98
-
99
- private static func normalizedInfoValue(_ key: String) -> String? {
100
- guard let raw = Bundle.main.infoDictionary?[key] as? String else { return nil }
101
- let value = raw.trimmingCharacters(in: .whitespacesAndNewlines)
102
- return value.isEmpty || value == "unknown" ? nil : value
103
- }
104
- }