@lattices/cli 0.3.0 → 0.4.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.
- package/README.md +85 -9
- package/app/Package.swift +8 -1
- package/app/Sources/AdvisorLearningStore.swift +90 -0
- package/app/Sources/AgentSession.swift +377 -0
- package/app/Sources/AppDelegate.swift +44 -12
- package/app/Sources/AppShellView.swift +81 -8
- package/app/Sources/AudioProvider.swift +386 -0
- package/app/Sources/CheatSheetHUD.swift +261 -19
- package/app/Sources/DaemonProtocol.swift +13 -0
- package/app/Sources/DaemonServer.swift +8 -0
- package/app/Sources/DesktopModel.swift +164 -5
- package/app/Sources/DesktopModelTypes.swift +2 -0
- package/app/Sources/DiagnosticLog.swift +104 -2
- package/app/Sources/EventBus.swift +1 -0
- package/app/Sources/HUDBottomBar.swift +279 -0
- package/app/Sources/HUDController.swift +1158 -0
- package/app/Sources/HUDLeftBar.swift +849 -0
- package/app/Sources/HUDMinimap.swift +179 -0
- package/app/Sources/HUDRightBar.swift +774 -0
- package/app/Sources/HUDState.swift +367 -0
- package/app/Sources/HUDTopBar.swift +243 -0
- package/app/Sources/HandsOffSession.swift +733 -0
- package/app/Sources/HomeDashboardView.swift +125 -0
- package/app/Sources/HotkeyManager.swift +2 -0
- package/app/Sources/HotkeyStore.swift +45 -9
- package/app/Sources/IntentEngine.swift +925 -0
- package/app/Sources/Intents/CreateLayerIntent.swift +54 -0
- package/app/Sources/Intents/DistributeIntent.swift +56 -0
- package/app/Sources/Intents/FocusIntent.swift +69 -0
- package/app/Sources/Intents/HelpIntent.swift +41 -0
- package/app/Sources/Intents/KillIntent.swift +47 -0
- package/app/Sources/Intents/LatticeIntent.swift +78 -0
- package/app/Sources/Intents/LaunchIntent.swift +67 -0
- package/app/Sources/Intents/ListSessionsIntent.swift +32 -0
- package/app/Sources/Intents/ListWindowsIntent.swift +30 -0
- package/app/Sources/Intents/ScanIntent.swift +52 -0
- package/app/Sources/Intents/SearchIntent.swift +190 -0
- package/app/Sources/Intents/SwitchLayerIntent.swift +50 -0
- package/app/Sources/Intents/TileIntent.swift +61 -0
- package/app/Sources/LatticesApi.swift +1235 -30
- package/app/Sources/LauncherHUD.swift +348 -0
- package/app/Sources/MainView.swift +147 -44
- package/app/Sources/OcrModel.swift +34 -1
- package/app/Sources/OmniSearchState.swift +99 -102
- package/app/Sources/OnboardingView.swift +457 -0
- package/app/Sources/PermissionChecker.swift +2 -12
- package/app/Sources/PiChatDock.swift +454 -0
- package/app/Sources/PiChatSession.swift +815 -0
- package/app/Sources/PiWorkspaceView.swift +364 -0
- package/app/Sources/PlacementSpec.swift +195 -0
- package/app/Sources/Preferences.swift +59 -0
- package/app/Sources/ProjectScanner.swift +1 -1
- package/app/Sources/ScreenMapState.swift +701 -55
- package/app/Sources/ScreenMapView.swift +843 -103
- package/app/Sources/ScreenMapWindowController.swift +22 -0
- package/app/Sources/SessionLayerStore.swift +285 -0
- package/app/Sources/SessionManager.swift +4 -1
- package/app/Sources/SettingsView.swift +186 -3
- package/app/Sources/Theme.swift +9 -8
- package/app/Sources/TmuxModel.swift +7 -0
- package/app/Sources/TmuxQuery.swift +27 -3
- package/app/Sources/VoiceChatView.swift +192 -0
- package/app/Sources/VoiceCommandWindow.swift +1594 -0
- package/app/Sources/VoiceIntentResolver.swift +671 -0
- package/app/Sources/VoxClient.swift +454 -0
- package/app/Sources/WindowTiler.swift +348 -87
- package/app/Sources/WorkspaceManager.swift +127 -18
- package/bin/client.ts +16 -0
- package/bin/{daemon-client.js → daemon-client.ts} +49 -30
- package/bin/handsoff-infer.ts +280 -0
- package/bin/handsoff-worker.ts +731 -0
- package/bin/{lattices-app.js → lattices-app.ts} +67 -32
- package/bin/lattices-dev +160 -0
- package/bin/{lattices.js → lattices.ts} +600 -137
- package/bin/project-twin.ts +645 -0
- package/docs/agent-execution-plan.md +562 -0
- package/docs/agents.md +142 -0
- package/docs/api.md +153 -34
- package/docs/app.md +29 -1
- package/docs/config.md +5 -1
- package/docs/handsoff-test-scenarios.md +84 -0
- package/docs/layers.md +20 -20
- package/docs/ocr.md +14 -5
- package/docs/overview.md +5 -1
- package/docs/presentation-execution-review.md +491 -0
- package/docs/prompts/hands-off-system.md +374 -0
- package/docs/prompts/hands-off-turn.md +30 -0
- package/docs/prompts/voice-advisor.md +31 -0
- package/docs/prompts/voice-fallback.md +23 -0
- package/docs/tiling-reference.md +167 -0
- package/docs/twins.md +138 -0
- package/docs/voice-command-protocol.md +278 -0
- package/docs/voice.md +219 -0
- package/package.json +21 -10
- package/bin/client.js +0 -4
|
@@ -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,13 @@ 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
|
|
23
27
|
// Layers
|
|
24
28
|
case layer1, layer2, layer3, layer4, layer5, layer6, layer7, layer8, layer9
|
|
29
|
+
case layerNext, layerPrev, layerTag
|
|
25
30
|
// Tiling
|
|
26
31
|
case tileLeft, tileRight, tileMaximize, tileCenter
|
|
27
32
|
case tileTopLeft, tileTopRight, tileBottomLeft, tileBottomRight
|
|
@@ -36,6 +41,10 @@ enum HotkeyAction: String, CaseIterable, Codable {
|
|
|
36
41
|
case .cheatSheet: return "Cheat Sheet"
|
|
37
42
|
case .desktopInventory: return "Desktop Inventory"
|
|
38
43
|
case .omniSearch: return "Omni Search"
|
|
44
|
+
case .voiceCommand: return "Voice Command"
|
|
45
|
+
case .handsOff: return "Hands-Off Mode"
|
|
46
|
+
case .unifiedWindow: return "Unified Window"
|
|
47
|
+
case .hud: return "HUD"
|
|
39
48
|
case .layer1: return "Layer 1"
|
|
40
49
|
case .layer2: return "Layer 2"
|
|
41
50
|
case .layer3: return "Layer 3"
|
|
@@ -45,6 +54,9 @@ enum HotkeyAction: String, CaseIterable, Codable {
|
|
|
45
54
|
case .layer7: return "Layer 7"
|
|
46
55
|
case .layer8: return "Layer 8"
|
|
47
56
|
case .layer9: return "Layer 9"
|
|
57
|
+
case .layerNext: return "Next Layer"
|
|
58
|
+
case .layerPrev: return "Previous Layer"
|
|
59
|
+
case .layerTag: return "Tag Window"
|
|
48
60
|
case .tileLeft: return "Tile Left"
|
|
49
61
|
case .tileRight: return "Tile Right"
|
|
50
62
|
case .tileMaximize: return "Maximize"
|
|
@@ -64,9 +76,10 @@ enum HotkeyAction: String, CaseIterable, Codable {
|
|
|
64
76
|
|
|
65
77
|
var group: HotkeyGroup {
|
|
66
78
|
switch self {
|
|
67
|
-
case .palette, .screenMap, .bezel, .cheatSheet, .desktopInventory, .omniSearch: return .app
|
|
79
|
+
case .palette, .screenMap, .bezel, .cheatSheet, .desktopInventory, .omniSearch, .voiceCommand, .handsOff, .unifiedWindow, .hud: return .app
|
|
68
80
|
case .layer1, .layer2, .layer3, .layer4, .layer5,
|
|
69
|
-
.layer6, .layer7, .layer8, .layer9
|
|
81
|
+
.layer6, .layer7, .layer8, .layer9,
|
|
82
|
+
.layerNext, .layerPrev, .layerTag: return .layers
|
|
70
83
|
default: return .tiling
|
|
71
84
|
}
|
|
72
85
|
}
|
|
@@ -79,6 +92,10 @@ enum HotkeyAction: String, CaseIterable, Codable {
|
|
|
79
92
|
case .cheatSheet: return 202
|
|
80
93
|
case .desktopInventory: return 203
|
|
81
94
|
case .omniSearch: return 204
|
|
95
|
+
case .voiceCommand: return 205
|
|
96
|
+
case .handsOff: return 206
|
|
97
|
+
case .unifiedWindow: return 207
|
|
98
|
+
case .hud: return 208
|
|
82
99
|
case .layer1: return 101
|
|
83
100
|
case .layer2: return 102
|
|
84
101
|
case .layer3: return 103
|
|
@@ -88,6 +105,9 @@ enum HotkeyAction: String, CaseIterable, Codable {
|
|
|
88
105
|
case .layer7: return 107
|
|
89
106
|
case .layer8: return 108
|
|
90
107
|
case .layer9: return 109
|
|
108
|
+
case .layerNext: return 110
|
|
109
|
+
case .layerPrev: return 111
|
|
110
|
+
case .layerTag: return 112
|
|
91
111
|
case .tileLeft: return 300
|
|
92
112
|
case .tileRight: return 301
|
|
93
113
|
case .tileMaximize: return 302
|
|
@@ -178,6 +198,14 @@ class HotkeyStore: ObservableObject {
|
|
|
178
198
|
@Published var bindings: [HotkeyAction: KeyBinding]
|
|
179
199
|
private var callbacks: [HotkeyAction: () -> Void] = [:]
|
|
180
200
|
|
|
201
|
+
private func instrumentedCallback(for action: HotkeyAction, callback: @escaping () -> Void) -> () -> Void {
|
|
202
|
+
{
|
|
203
|
+
let timed = DiagnosticLog.shared.startTimed("Hotkey \(action.label)")
|
|
204
|
+
callback()
|
|
205
|
+
DiagnosticLog.shared.finish(timed)
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
181
209
|
static let defaultBindings: [HotkeyAction: KeyBinding] = {
|
|
182
210
|
var d = [HotkeyAction: KeyBinding]()
|
|
183
211
|
let hyper = UInt32(cmdKey | controlKey | optionKey | shiftKey)
|
|
@@ -195,11 +223,14 @@ class HotkeyStore: ObservableObject {
|
|
|
195
223
|
|
|
196
224
|
// App
|
|
197
225
|
bind(.palette, 46, cmdShift) // Cmd+Shift+M
|
|
198
|
-
bind(.
|
|
226
|
+
bind(.unifiedWindow, 18, hyper) // Hyper+1 (Screen Map + Desktop Inventory)
|
|
199
227
|
bind(.bezel, 19, hyper) // Hyper+2
|
|
200
|
-
bind(.
|
|
201
|
-
bind(.
|
|
228
|
+
bind(.hud, 20, hyper) // Hyper+3 (HUD overlay)
|
|
229
|
+
bind(.voiceCommand, 21, hyper) // Hyper+4 (moved from Hyper+3)
|
|
230
|
+
let cmdCtrl = UInt32(cmdKey | controlKey)
|
|
231
|
+
bind(.handsOff, 46, cmdCtrl) // Ctrl+Cmd+M
|
|
202
232
|
bind(.omniSearch, 23, hyper) // Hyper+5
|
|
233
|
+
bind(.cheatSheet, 22, hyper) // Hyper+6
|
|
203
234
|
|
|
204
235
|
// Layers: Cmd+Option+1-9
|
|
205
236
|
let layerKeyCodes: [UInt32] = [18, 19, 20, 21, 23, 22, 26, 28, 25]
|
|
@@ -207,6 +238,11 @@ class HotkeyStore: ObservableObject {
|
|
|
207
238
|
bind(action, layerKeyCodes[i], cmdOpt)
|
|
208
239
|
}
|
|
209
240
|
|
|
241
|
+
// Layer cycling: Cmd+Option+Arrow / Cmd+Option+T
|
|
242
|
+
bind(.layerNext, 124, cmdOpt) // Cmd+Opt+→
|
|
243
|
+
bind(.layerPrev, 123, cmdOpt) // Cmd+Opt+←
|
|
244
|
+
bind(.layerTag, 17, cmdOpt) // Cmd+Opt+T
|
|
245
|
+
|
|
210
246
|
// Tiling: Ctrl+Option for all
|
|
211
247
|
bind(.tileLeft, 123, ctrlOpt) // Ctrl+Opt+←
|
|
212
248
|
bind(.tileRight, 124, ctrlOpt) // Ctrl+Opt+→
|
|
@@ -263,7 +299,7 @@ class HotkeyStore: ObservableObject {
|
|
|
263
299
|
id: action.carbonID,
|
|
264
300
|
keyCode: binding.keyCode,
|
|
265
301
|
modifiers: binding.carbonModifiers,
|
|
266
|
-
callback: callback
|
|
302
|
+
callback: instrumentedCallback(for: action, callback: callback)
|
|
267
303
|
)
|
|
268
304
|
}
|
|
269
305
|
|
|
@@ -283,7 +319,7 @@ class HotkeyStore: ObservableObject {
|
|
|
283
319
|
id: action.carbonID,
|
|
284
320
|
keyCode: binding.keyCode,
|
|
285
321
|
modifiers: binding.carbonModifiers,
|
|
286
|
-
callback: callback
|
|
322
|
+
callback: instrumentedCallback(for: action, callback: callback)
|
|
287
323
|
)
|
|
288
324
|
}
|
|
289
325
|
}
|
|
@@ -300,7 +336,7 @@ class HotkeyStore: ObservableObject {
|
|
|
300
336
|
id: action.carbonID,
|
|
301
337
|
keyCode: defaultBinding.keyCode,
|
|
302
338
|
modifiers: defaultBinding.carbonModifiers,
|
|
303
|
-
callback: callback
|
|
339
|
+
callback: instrumentedCallback(for: action, callback: callback)
|
|
304
340
|
)
|
|
305
341
|
}
|
|
306
342
|
}
|
|
@@ -318,7 +354,7 @@ class HotkeyStore: ObservableObject {
|
|
|
318
354
|
id: action.carbonID,
|
|
319
355
|
keyCode: binding.keyCode,
|
|
320
356
|
modifiers: binding.carbonModifiers,
|
|
321
|
-
callback: callback
|
|
357
|
+
callback: instrumentedCallback(for: action, callback: callback)
|
|
322
358
|
)
|
|
323
359
|
}
|
|
324
360
|
}
|