@lattices/cli 0.3.0 → 0.4.1

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 (111) hide show
  1. package/README.md +85 -9
  2. package/app/Info.plist +30 -0
  3. package/app/Lattices.app/Contents/Info.plist +8 -2
  4. package/app/Lattices.app/Contents/MacOS/Lattices +0 -0
  5. package/app/Lattices.app/Contents/Resources/AppIcon.icns +0 -0
  6. package/app/Lattices.app/Contents/Resources/tap.wav +0 -0
  7. package/app/Lattices.app/Contents/_CodeSignature/CodeResources +139 -0
  8. package/app/Lattices.entitlements +15 -0
  9. package/app/Package.swift +8 -1
  10. package/app/Resources/tap.wav +0 -0
  11. package/app/Sources/AdvisorLearningStore.swift +90 -0
  12. package/app/Sources/AgentSession.swift +377 -0
  13. package/app/Sources/AppDelegate.swift +45 -12
  14. package/app/Sources/AppShellView.swift +81 -8
  15. package/app/Sources/AudioProvider.swift +386 -0
  16. package/app/Sources/CheatSheetHUD.swift +261 -19
  17. package/app/Sources/DaemonProtocol.swift +13 -0
  18. package/app/Sources/DaemonServer.swift +8 -0
  19. package/app/Sources/DesktopModel.swift +189 -6
  20. package/app/Sources/DesktopModelTypes.swift +2 -0
  21. package/app/Sources/DiagnosticLog.swift +104 -2
  22. package/app/Sources/EventBus.swift +1 -0
  23. package/app/Sources/HUDBottomBar.swift +279 -0
  24. package/app/Sources/HUDController.swift +1158 -0
  25. package/app/Sources/HUDLeftBar.swift +849 -0
  26. package/app/Sources/HUDMinimap.swift +179 -0
  27. package/app/Sources/HUDRightBar.swift +774 -0
  28. package/app/Sources/HUDState.swift +367 -0
  29. package/app/Sources/HUDTopBar.swift +243 -0
  30. package/app/Sources/HandsOffSession.swift +802 -0
  31. package/app/Sources/HomeDashboardView.swift +125 -0
  32. package/app/Sources/HotkeyManager.swift +2 -0
  33. package/app/Sources/HotkeyStore.swift +49 -9
  34. package/app/Sources/IntentEngine.swift +962 -0
  35. package/app/Sources/Intents/CreateLayerIntent.swift +54 -0
  36. package/app/Sources/Intents/DistributeIntent.swift +56 -0
  37. package/app/Sources/Intents/FocusIntent.swift +69 -0
  38. package/app/Sources/Intents/HelpIntent.swift +41 -0
  39. package/app/Sources/Intents/KillIntent.swift +47 -0
  40. package/app/Sources/Intents/LatticeIntent.swift +78 -0
  41. package/app/Sources/Intents/LaunchIntent.swift +67 -0
  42. package/app/Sources/Intents/ListSessionsIntent.swift +32 -0
  43. package/app/Sources/Intents/ListWindowsIntent.swift +30 -0
  44. package/app/Sources/Intents/ScanIntent.swift +52 -0
  45. package/app/Sources/Intents/SearchIntent.swift +190 -0
  46. package/app/Sources/Intents/SwitchLayerIntent.swift +50 -0
  47. package/app/Sources/Intents/TileIntent.swift +61 -0
  48. package/app/Sources/LatticesApi.swift +1275 -30
  49. package/app/Sources/LauncherHUD.swift +348 -0
  50. package/app/Sources/MainView.swift +147 -44
  51. package/app/Sources/MouseFinder.swift +222 -0
  52. package/app/Sources/OcrModel.swift +34 -1
  53. package/app/Sources/OmniSearchState.swift +99 -102
  54. package/app/Sources/OnboardingView.swift +457 -0
  55. package/app/Sources/PermissionChecker.swift +2 -12
  56. package/app/Sources/PiChatDock.swift +454 -0
  57. package/app/Sources/PiChatSession.swift +815 -0
  58. package/app/Sources/PiWorkspaceView.swift +364 -0
  59. package/app/Sources/PlacementSpec.swift +195 -0
  60. package/app/Sources/Preferences.swift +59 -0
  61. package/app/Sources/ProjectScanner.swift +58 -45
  62. package/app/Sources/ScreenMapState.swift +701 -55
  63. package/app/Sources/ScreenMapView.swift +843 -103
  64. package/app/Sources/ScreenMapWindowController.swift +22 -0
  65. package/app/Sources/SessionLayerStore.swift +285 -0
  66. package/app/Sources/SessionManager.swift +4 -1
  67. package/app/Sources/SettingsView.swift +186 -3
  68. package/app/Sources/Theme.swift +9 -8
  69. package/app/Sources/TmuxModel.swift +7 -0
  70. package/app/Sources/TmuxQuery.swift +27 -3
  71. package/app/Sources/VoiceChatView.swift +192 -0
  72. package/app/Sources/VoiceCommandWindow.swift +1594 -0
  73. package/app/Sources/VoiceIntentResolver.swift +671 -0
  74. package/app/Sources/VoxClient.swift +454 -0
  75. package/app/Sources/WindowTiler.swift +348 -87
  76. package/app/Sources/WorkspaceManager.swift +127 -18
  77. package/app/Tests/StageDragTests.swift +333 -0
  78. package/app/Tests/StageJoinTests.swift +313 -0
  79. package/app/Tests/StageManagerTests.swift +280 -0
  80. package/app/Tests/StageTileTests.swift +353 -0
  81. package/assets/AppIcon.icns +0 -0
  82. package/bin/client.ts +16 -0
  83. package/bin/{daemon-client.js → daemon-client.ts} +49 -30
  84. package/bin/handsoff-infer.ts +280 -0
  85. package/bin/handsoff-worker.ts +740 -0
  86. package/bin/lattices-app.ts +338 -0
  87. package/bin/lattices-dev +208 -0
  88. package/bin/{lattices.js → lattices.ts} +777 -140
  89. package/bin/project-twin.ts +645 -0
  90. package/docs/agent-execution-plan.md +562 -0
  91. package/docs/agent-layer-guide.md +207 -0
  92. package/docs/agents.md +142 -0
  93. package/docs/api.md +153 -34
  94. package/docs/app.md +29 -1
  95. package/docs/config.md +5 -1
  96. package/docs/handsoff-test-scenarios.md +84 -0
  97. package/docs/layers.md +20 -20
  98. package/docs/ocr.md +14 -5
  99. package/docs/overview.md +5 -1
  100. package/docs/presentation-execution-review.md +491 -0
  101. package/docs/prompts/hands-off-system.md +374 -0
  102. package/docs/prompts/hands-off-turn.md +30 -0
  103. package/docs/prompts/voice-advisor.md +31 -0
  104. package/docs/prompts/voice-fallback.md +23 -0
  105. package/docs/tiling-reference.md +167 -0
  106. package/docs/twins.md +138 -0
  107. package/docs/voice-command-protocol.md +278 -0
  108. package/docs/voice.md +219 -0
  109. package/package.json +29 -11
  110. package/bin/client.js +0 -4
  111. package/bin/lattices-app.js +0 -221
@@ -0,0 +1,125 @@
1
+ import SwiftUI
2
+
3
+ struct HomeDashboardView: View {
4
+ var onNavigate: ((AppPage) -> Void)? = nil
5
+
6
+ @ObservedObject private var scanner = ProjectScanner.shared
7
+
8
+ var body: some View {
9
+ VStack(spacing: 0) {
10
+ hero
11
+
12
+ Rectangle()
13
+ .fill(Palette.border)
14
+ .frame(height: 0.5)
15
+
16
+ MainView(scanner: scanner, layout: .embedded)
17
+ }
18
+ .background(Palette.bg)
19
+ }
20
+
21
+ private var hero: some View {
22
+ VStack(alignment: .leading, spacing: 18) {
23
+ HStack(alignment: .top) {
24
+ VStack(alignment: .leading, spacing: 8) {
25
+ Text("Lattices Home")
26
+ .font(Typo.heading(18))
27
+ .foregroundColor(Palette.text)
28
+
29
+ Text("Launch workspaces, jump into the screen map, or open a full Pi session from one place.")
30
+ .font(Typo.mono(11))
31
+ .foregroundColor(Palette.textDim)
32
+ .fixedSize(horizontal: false, vertical: true)
33
+ }
34
+
35
+ Spacer()
36
+ }
37
+
38
+ HStack(spacing: 10) {
39
+ homeActionCard(
40
+ title: "Screen Map",
41
+ subtitle: "Spatial window layout",
42
+ icon: "rectangle.3.group",
43
+ tint: Palette.running
44
+ ) {
45
+ onNavigate?(.screenMap)
46
+ }
47
+
48
+ homeActionCard(
49
+ title: "Desktop Inventory",
50
+ subtitle: "Enumerate displays and spaces",
51
+ icon: "macwindow.on.rectangle",
52
+ tint: Palette.detach
53
+ ) {
54
+ onNavigate?(.desktopInventory)
55
+ }
56
+
57
+ homeActionCard(
58
+ title: "Pi Workspace",
59
+ subtitle: "Standalone conversation surface",
60
+ icon: "terminal",
61
+ tint: Palette.text
62
+ ) {
63
+ onNavigate?(.pi)
64
+ }
65
+ }
66
+ }
67
+ .padding(.horizontal, 16)
68
+ .padding(.vertical, 16)
69
+ .background(
70
+ LinearGradient(
71
+ colors: [
72
+ Palette.running.opacity(0.08),
73
+ Color.black.opacity(0.18),
74
+ ],
75
+ startPoint: .topLeading,
76
+ endPoint: .bottomTrailing
77
+ )
78
+ )
79
+ }
80
+
81
+ private func homeActionCard(
82
+ title: String,
83
+ subtitle: String,
84
+ icon: String,
85
+ tint: Color,
86
+ action: @escaping () -> Void
87
+ ) -> some View {
88
+ Button(action: action) {
89
+ VStack(alignment: .leading, spacing: 10) {
90
+ HStack {
91
+ Image(systemName: icon)
92
+ .font(.system(size: 12, weight: .semibold))
93
+ .foregroundColor(tint)
94
+
95
+ Spacer()
96
+
97
+ Circle()
98
+ .fill(tint.opacity(0.85))
99
+ .frame(width: 6, height: 6)
100
+ }
101
+
102
+ Text(title)
103
+ .font(Typo.monoBold(12))
104
+ .foregroundColor(Palette.text)
105
+
106
+ Text(subtitle)
107
+ .font(Typo.mono(10))
108
+ .foregroundColor(Palette.textMuted)
109
+ .multilineTextAlignment(.leading)
110
+ .fixedSize(horizontal: false, vertical: true)
111
+ }
112
+ .frame(maxWidth: .infinity, alignment: .leading)
113
+ .padding(12)
114
+ .background(
115
+ RoundedRectangle(cornerRadius: 8)
116
+ .fill(Palette.surface.opacity(0.7))
117
+ .overlay(
118
+ RoundedRectangle(cornerRadius: 8)
119
+ .strokeBorder(tint.opacity(0.18), lineWidth: 0.5)
120
+ )
121
+ )
122
+ }
123
+ .buttonStyle(.plain)
124
+ }
125
+ }
@@ -35,6 +35,7 @@ class HotkeyManager {
35
35
  nil,
36
36
  &hotkeyID
37
37
  )
38
+ DiagnosticLog.shared.info("HotkeyManager: fired id=\(hotkeyID.id)")
38
39
  hotkeyCallbacks[hotkeyID.id]?()
39
40
  return noErr
40
41
  },
@@ -176,6 +177,7 @@ class HotkeyManager {
176
177
  )
177
178
  if let ref {
178
179
  hotKeyRefs[id] = ref
180
+ DiagnosticLog.shared.info("HotkeyManager: registered id=\(id) keyCode=\(keyCode) mods=\(modifiers)")
179
181
  } else {
180
182
  DiagnosticLog.shared.warn("HotkeyManager: failed to register id=\(id) keyCode=\(keyCode) mods=\(modifiers) status=\(status)")
181
183
  }
@@ -20,8 +20,14 @@ enum HotkeyAction: String, CaseIterable, Codable {
20
20
  case cheatSheet
21
21
  case desktopInventory
22
22
  case omniSearch
23
+ case voiceCommand
24
+ case handsOff
25
+ case unifiedWindow
26
+ case hud
27
+ case mouseFinder
23
28
  // Layers
24
29
  case layer1, layer2, layer3, layer4, layer5, layer6, layer7, layer8, layer9
30
+ case layerNext, layerPrev, layerTag
25
31
  // Tiling
26
32
  case tileLeft, tileRight, tileMaximize, tileCenter
27
33
  case tileTopLeft, tileTopRight, tileBottomLeft, tileBottomRight
@@ -36,6 +42,11 @@ enum HotkeyAction: String, CaseIterable, Codable {
36
42
  case .cheatSheet: return "Cheat Sheet"
37
43
  case .desktopInventory: return "Desktop Inventory"
38
44
  case .omniSearch: return "Omni Search"
45
+ case .voiceCommand: return "Voice Command"
46
+ case .handsOff: return "Hands-Off Mode"
47
+ case .unifiedWindow: return "Unified Window"
48
+ case .hud: return "HUD"
49
+ case .mouseFinder: return "Find Mouse"
39
50
  case .layer1: return "Layer 1"
40
51
  case .layer2: return "Layer 2"
41
52
  case .layer3: return "Layer 3"
@@ -45,6 +56,9 @@ enum HotkeyAction: String, CaseIterable, Codable {
45
56
  case .layer7: return "Layer 7"
46
57
  case .layer8: return "Layer 8"
47
58
  case .layer9: return "Layer 9"
59
+ case .layerNext: return "Next Layer"
60
+ case .layerPrev: return "Previous Layer"
61
+ case .layerTag: return "Tag Window"
48
62
  case .tileLeft: return "Tile Left"
49
63
  case .tileRight: return "Tile Right"
50
64
  case .tileMaximize: return "Maximize"
@@ -64,9 +78,10 @@ enum HotkeyAction: String, CaseIterable, Codable {
64
78
 
65
79
  var group: HotkeyGroup {
66
80
  switch self {
67
- case .palette, .screenMap, .bezel, .cheatSheet, .desktopInventory, .omniSearch: return .app
81
+ case .palette, .screenMap, .bezel, .cheatSheet, .desktopInventory, .omniSearch, .voiceCommand, .handsOff, .unifiedWindow, .hud, .mouseFinder: return .app
68
82
  case .layer1, .layer2, .layer3, .layer4, .layer5,
69
- .layer6, .layer7, .layer8, .layer9: return .layers
83
+ .layer6, .layer7, .layer8, .layer9,
84
+ .layerNext, .layerPrev, .layerTag: return .layers
70
85
  default: return .tiling
71
86
  }
72
87
  }
@@ -79,6 +94,11 @@ enum HotkeyAction: String, CaseIterable, Codable {
79
94
  case .cheatSheet: return 202
80
95
  case .desktopInventory: return 203
81
96
  case .omniSearch: return 204
97
+ case .voiceCommand: return 205
98
+ case .handsOff: return 206
99
+ case .unifiedWindow: return 207
100
+ case .hud: return 208
101
+ case .mouseFinder: return 209
82
102
  case .layer1: return 101
83
103
  case .layer2: return 102
84
104
  case .layer3: return 103
@@ -88,6 +108,9 @@ enum HotkeyAction: String, CaseIterable, Codable {
88
108
  case .layer7: return 107
89
109
  case .layer8: return 108
90
110
  case .layer9: return 109
111
+ case .layerNext: return 110
112
+ case .layerPrev: return 111
113
+ case .layerTag: return 112
91
114
  case .tileLeft: return 300
92
115
  case .tileRight: return 301
93
116
  case .tileMaximize: return 302
@@ -178,6 +201,14 @@ class HotkeyStore: ObservableObject {
178
201
  @Published var bindings: [HotkeyAction: KeyBinding]
179
202
  private var callbacks: [HotkeyAction: () -> Void] = [:]
180
203
 
204
+ private func instrumentedCallback(for action: HotkeyAction, callback: @escaping () -> Void) -> () -> Void {
205
+ {
206
+ let timed = DiagnosticLog.shared.startTimed("Hotkey \(action.label)")
207
+ callback()
208
+ DiagnosticLog.shared.finish(timed)
209
+ }
210
+ }
211
+
181
212
  static let defaultBindings: [HotkeyAction: KeyBinding] = {
182
213
  var d = [HotkeyAction: KeyBinding]()
183
214
  let hyper = UInt32(cmdKey | controlKey | optionKey | shiftKey)
@@ -195,11 +226,15 @@ class HotkeyStore: ObservableObject {
195
226
 
196
227
  // App
197
228
  bind(.palette, 46, cmdShift) // Cmd+Shift+M
198
- bind(.screenMap, 18, hyper) // Hyper+1
229
+ bind(.unifiedWindow, 18, hyper) // Hyper+1 (Screen Map + Desktop Inventory)
199
230
  bind(.bezel, 19, hyper) // Hyper+2
200
- bind(.cheatSheet, 20, hyper) // Hyper+3
201
- bind(.desktopInventory, 21, hyper) // Hyper+4
231
+ bind(.hud, 20, hyper) // Hyper+3 (HUD overlay)
232
+ bind(.voiceCommand, 21, hyper) // Hyper+4 (moved from Hyper+3)
233
+ let cmdCtrl = UInt32(cmdKey | controlKey)
234
+ bind(.handsOff, 46, cmdCtrl) // Ctrl+Cmd+M
202
235
  bind(.omniSearch, 23, hyper) // Hyper+5
236
+ bind(.cheatSheet, 22, hyper) // Hyper+6
237
+ bind(.mouseFinder, 26, hyper) // Hyper+7
203
238
 
204
239
  // Layers: Cmd+Option+1-9
205
240
  let layerKeyCodes: [UInt32] = [18, 19, 20, 21, 23, 22, 26, 28, 25]
@@ -207,6 +242,11 @@ class HotkeyStore: ObservableObject {
207
242
  bind(action, layerKeyCodes[i], cmdOpt)
208
243
  }
209
244
 
245
+ // Layer cycling: Cmd+Option+Arrow / Cmd+Option+T
246
+ bind(.layerNext, 124, cmdOpt) // Cmd+Opt+→
247
+ bind(.layerPrev, 123, cmdOpt) // Cmd+Opt+←
248
+ bind(.layerTag, 17, cmdOpt) // Cmd+Opt+T
249
+
210
250
  // Tiling: Ctrl+Option for all
211
251
  bind(.tileLeft, 123, ctrlOpt) // Ctrl+Opt+←
212
252
  bind(.tileRight, 124, ctrlOpt) // Ctrl+Opt+→
@@ -263,7 +303,7 @@ class HotkeyStore: ObservableObject {
263
303
  id: action.carbonID,
264
304
  keyCode: binding.keyCode,
265
305
  modifiers: binding.carbonModifiers,
266
- callback: callback
306
+ callback: instrumentedCallback(for: action, callback: callback)
267
307
  )
268
308
  }
269
309
 
@@ -283,7 +323,7 @@ class HotkeyStore: ObservableObject {
283
323
  id: action.carbonID,
284
324
  keyCode: binding.keyCode,
285
325
  modifiers: binding.carbonModifiers,
286
- callback: callback
326
+ callback: instrumentedCallback(for: action, callback: callback)
287
327
  )
288
328
  }
289
329
  }
@@ -300,7 +340,7 @@ class HotkeyStore: ObservableObject {
300
340
  id: action.carbonID,
301
341
  keyCode: defaultBinding.keyCode,
302
342
  modifiers: defaultBinding.carbonModifiers,
303
- callback: callback
343
+ callback: instrumentedCallback(for: action, callback: callback)
304
344
  )
305
345
  }
306
346
  }
@@ -318,7 +358,7 @@ class HotkeyStore: ObservableObject {
318
358
  id: action.carbonID,
319
359
  keyCode: binding.keyCode,
320
360
  modifiers: binding.carbonModifiers,
321
- callback: callback
361
+ callback: instrumentedCallback(for: action, callback: callback)
322
362
  )
323
363
  }
324
364
  }