@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.
- package/README.md +85 -9
- package/app/Info.plist +30 -0
- package/app/Lattices.app/Contents/Info.plist +8 -2
- package/app/Lattices.app/Contents/MacOS/Lattices +0 -0
- package/app/Lattices.app/Contents/Resources/AppIcon.icns +0 -0
- package/app/Lattices.app/Contents/Resources/tap.wav +0 -0
- package/app/Lattices.app/Contents/_CodeSignature/CodeResources +139 -0
- package/app/Lattices.entitlements +15 -0
- package/app/Package.swift +8 -1
- package/app/Resources/tap.wav +0 -0
- package/app/Sources/AdvisorLearningStore.swift +90 -0
- package/app/Sources/AgentSession.swift +377 -0
- package/app/Sources/AppDelegate.swift +45 -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 +189 -6
- 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 +802 -0
- package/app/Sources/HomeDashboardView.swift +125 -0
- package/app/Sources/HotkeyManager.swift +2 -0
- package/app/Sources/HotkeyStore.swift +49 -9
- package/app/Sources/IntentEngine.swift +962 -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 +1275 -30
- package/app/Sources/LauncherHUD.swift +348 -0
- package/app/Sources/MainView.swift +147 -44
- package/app/Sources/MouseFinder.swift +222 -0
- 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 +58 -45
- 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/app/Tests/StageDragTests.swift +333 -0
- package/app/Tests/StageJoinTests.swift +313 -0
- package/app/Tests/StageManagerTests.swift +280 -0
- package/app/Tests/StageTileTests.swift +353 -0
- package/assets/AppIcon.icns +0 -0
- 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 +740 -0
- package/bin/lattices-app.ts +338 -0
- package/bin/lattices-dev +208 -0
- package/bin/{lattices.js → lattices.ts} +777 -140
- package/bin/project-twin.ts +645 -0
- package/docs/agent-execution-plan.md +562 -0
- package/docs/agent-layer-guide.md +207 -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 +29 -11
- package/bin/client.js +0 -4
- package/bin/lattices-app.js +0 -221
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import SwiftUI
|
|
2
|
+
|
|
3
|
+
// MARK: - HUDMinimap (expanded canvas-attached minimap)
|
|
4
|
+
|
|
5
|
+
struct HUDMinimap: View {
|
|
6
|
+
@ObservedObject var state: HUDState
|
|
7
|
+
@ObservedObject private var desktop = DesktopModel.shared
|
|
8
|
+
var onDismiss: () -> Void
|
|
9
|
+
let screenIndex: Int
|
|
10
|
+
|
|
11
|
+
var body: some View {
|
|
12
|
+
VStack(alignment: .leading, spacing: 0) {
|
|
13
|
+
// Header
|
|
14
|
+
HStack(spacing: 0) {
|
|
15
|
+
Image(systemName: screenIndex == 0 ? "display" : "rectangle.on.rectangle")
|
|
16
|
+
.font(.system(size: 10))
|
|
17
|
+
.foregroundColor(Palette.textMuted)
|
|
18
|
+
Text(screenIndex == 0 ? "Main" : "Display \(screenIndex + 1)")
|
|
19
|
+
.font(Typo.monoBold(10))
|
|
20
|
+
.foregroundColor(Palette.textMuted)
|
|
21
|
+
.padding(.leading, 4)
|
|
22
|
+
|
|
23
|
+
Spacer()
|
|
24
|
+
|
|
25
|
+
// Dock back into sidebar
|
|
26
|
+
Button {
|
|
27
|
+
state.minimapMode = .docked
|
|
28
|
+
} label: {
|
|
29
|
+
Image(systemName: "arrow.down.right.and.arrow.up.left")
|
|
30
|
+
.font(.system(size: 8, weight: .bold))
|
|
31
|
+
.foregroundColor(Palette.textMuted)
|
|
32
|
+
.frame(width: 20, height: 20)
|
|
33
|
+
.background(
|
|
34
|
+
RoundedRectangle(cornerRadius: 3)
|
|
35
|
+
.fill(Palette.surface)
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
.buttonStyle(.plain)
|
|
39
|
+
.help("Dock map (M)")
|
|
40
|
+
}
|
|
41
|
+
.padding(.horizontal, 12)
|
|
42
|
+
.padding(.top, 10)
|
|
43
|
+
.padding(.bottom, 6)
|
|
44
|
+
|
|
45
|
+
// Map canvas (larger in expanded mode)
|
|
46
|
+
mapCanvas
|
|
47
|
+
.padding(.horizontal, 10)
|
|
48
|
+
.padding(.bottom, 10)
|
|
49
|
+
}
|
|
50
|
+
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
51
|
+
.background(Palette.bg)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// MARK: - Map canvas
|
|
55
|
+
|
|
56
|
+
private var mapCanvas: some View {
|
|
57
|
+
GeometryReader { geo in
|
|
58
|
+
let screens = NSScreen.screens
|
|
59
|
+
let idx = clampedIndex
|
|
60
|
+
if idx < screens.count {
|
|
61
|
+
let screen = screens[idx]
|
|
62
|
+
let sw = screen.frame.width
|
|
63
|
+
let sh = screen.frame.height
|
|
64
|
+
let canvasW = geo.size.width
|
|
65
|
+
let canvasH = geo.size.height
|
|
66
|
+
|
|
67
|
+
let scaleX = canvasW / sw
|
|
68
|
+
let scaleY = canvasH / sh
|
|
69
|
+
let scale = min(scaleX, scaleY)
|
|
70
|
+
let drawW = sw * scale
|
|
71
|
+
let drawH = sh * scale
|
|
72
|
+
let offsetX = (canvasW - drawW) / 2
|
|
73
|
+
let offsetY = (canvasH - drawH) / 2
|
|
74
|
+
|
|
75
|
+
let origin = screenCGOrigin(screen)
|
|
76
|
+
let wins = windowsOnScreen(idx)
|
|
77
|
+
|
|
78
|
+
ZStack(alignment: .topLeading) {
|
|
79
|
+
// Screen background
|
|
80
|
+
RoundedRectangle(cornerRadius: 6)
|
|
81
|
+
.fill(Palette.surface.opacity(0.4))
|
|
82
|
+
.frame(width: drawW, height: drawH)
|
|
83
|
+
.offset(x: offsetX, y: offsetY)
|
|
84
|
+
|
|
85
|
+
// Windows (back-to-front)
|
|
86
|
+
ForEach(wins.reversed()) { win in
|
|
87
|
+
let rx = (CGFloat(win.frame.x) - origin.x) * scale + offsetX
|
|
88
|
+
let ry = (CGFloat(win.frame.y) - origin.y) * scale + offsetY
|
|
89
|
+
let rw = CGFloat(win.frame.w) * scale
|
|
90
|
+
let rh = CGFloat(win.frame.h) * scale
|
|
91
|
+
let isSelected = state.selectedItem == .window(win)
|
|
92
|
+
|
|
93
|
+
RoundedRectangle(cornerRadius: 2)
|
|
94
|
+
.fill(appColor(win.app).opacity(isSelected ? 0.5 : 0.15))
|
|
95
|
+
.overlay(
|
|
96
|
+
RoundedRectangle(cornerRadius: 2)
|
|
97
|
+
.strokeBorder(
|
|
98
|
+
isSelected ? Palette.running : appColor(win.app).opacity(0.35),
|
|
99
|
+
lineWidth: isSelected ? 1.5 : 0.5
|
|
100
|
+
)
|
|
101
|
+
)
|
|
102
|
+
.overlay(
|
|
103
|
+
Group {
|
|
104
|
+
if rw > 30 && rh > 18 {
|
|
105
|
+
VStack(spacing: 1) {
|
|
106
|
+
Text(String(win.app.prefix(1)))
|
|
107
|
+
.font(Typo.geistMonoBold(max(7, min(11, rh * 0.3))))
|
|
108
|
+
.foregroundColor(appColor(win.app).opacity(isSelected ? 1.0 : 0.5))
|
|
109
|
+
if rh > 30 && rw > 50 {
|
|
110
|
+
Text(win.title.prefix(12).description)
|
|
111
|
+
.font(Typo.mono(max(5, min(7, rh * 0.12))))
|
|
112
|
+
.foregroundColor(Palette.textDim.opacity(0.6))
|
|
113
|
+
.lineLimit(1)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
)
|
|
119
|
+
.frame(width: max(rw, 4), height: max(rh, 3))
|
|
120
|
+
.offset(x: rx, y: ry)
|
|
121
|
+
.onTapGesture {
|
|
122
|
+
state.selectedItem = .window(win)
|
|
123
|
+
state.focus = .list
|
|
124
|
+
if let flatIdx = state.flatItems.firstIndex(of: .window(win)) {
|
|
125
|
+
state.selectedIndex = flatIdx
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
.frame(width: canvasW, height: canvasH)
|
|
131
|
+
.clipShape(RoundedRectangle(cornerRadius: 6))
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// MARK: - Helpers
|
|
137
|
+
|
|
138
|
+
private var clampedIndex: Int {
|
|
139
|
+
min(screenIndex, NSScreen.screens.count - 1)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private func screenCGOrigin(_ screen: NSScreen) -> (x: CGFloat, y: CGFloat) {
|
|
143
|
+
let primaryH = NSScreen.screens.first?.frame.height ?? 900
|
|
144
|
+
return (screen.frame.origin.x, primaryH - screen.frame.origin.y - screen.frame.height)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
private func windowsOnScreen(_ screenIdx: Int) -> [WindowEntry] {
|
|
148
|
+
let screens = NSScreen.screens
|
|
149
|
+
guard screenIdx < screens.count else { return [] }
|
|
150
|
+
let screen = screens[screenIdx]
|
|
151
|
+
let origin = screenCGOrigin(screen)
|
|
152
|
+
let sw = Double(screen.frame.width)
|
|
153
|
+
let sh = Double(screen.frame.height)
|
|
154
|
+
|
|
155
|
+
return desktop.allWindows().filter { win in
|
|
156
|
+
let cx = win.frame.x + win.frame.w / 2
|
|
157
|
+
let cy = win.frame.y + win.frame.h / 2
|
|
158
|
+
return cx >= Double(origin.x) && cx < Double(origin.x) + sw &&
|
|
159
|
+
cy >= Double(origin.y) && cy < Double(origin.y) + sh &&
|
|
160
|
+
win.app != "Lattices"
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
private func appColor(_ app: String) -> Color {
|
|
165
|
+
if ["iTerm2", "Terminal", "WezTerm", "Alacritty", "kitty"].contains(app) {
|
|
166
|
+
return Palette.running
|
|
167
|
+
}
|
|
168
|
+
if ["Google Chrome", "Safari", "Arc", "Firefox", "Brave Browser"].contains(app) {
|
|
169
|
+
return Color.blue
|
|
170
|
+
}
|
|
171
|
+
if ["Xcode", "Visual Studio Code", "Cursor", "Zed"].contains(app) {
|
|
172
|
+
return Color.purple
|
|
173
|
+
}
|
|
174
|
+
if app.localizedCaseInsensitiveContains("Claude") || app.localizedCaseInsensitiveContains("Codex") {
|
|
175
|
+
return Color.orange
|
|
176
|
+
}
|
|
177
|
+
return Palette.textMuted
|
|
178
|
+
}
|
|
179
|
+
}
|