@lattices/cli 0.4.2 → 0.4.5
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 +3 -0
- package/app/Info.plist +2 -2
- package/app/Lattices.app/Contents/Info.plist +2 -2
- package/app/Lattices.app/Contents/MacOS/Lattices +0 -0
- package/app/Package.swift +6 -0
- package/app/Sources/App.swift +10 -0
- package/app/Sources/AppDelegate.swift +90 -34
- package/app/Sources/AppShellView.swift +2 -0
- package/app/Sources/AppTypeClassifier.swift +36 -0
- package/app/Sources/AppUpdater.swift +92 -0
- package/app/Sources/CheatSheetHUD.swift +1 -0
- package/app/Sources/CliActionLauncher.swift +50 -0
- package/app/Sources/CommandModeView.swift +4 -24
- package/app/Sources/CompanionActivityLog.swift +70 -0
- package/app/Sources/CompanionKeyboardController.swift +141 -0
- package/app/Sources/DesktopModel.swift +4 -0
- package/app/Sources/HandsOffSession.swift +15 -4
- package/app/Sources/HomeDashboardView.swift +18 -10
- package/app/Sources/HotkeyStore.swift +8 -5
- package/app/Sources/IntentEngine.swift +7 -1
- package/app/Sources/LatticesApi.swift +125 -4
- package/app/Sources/LatticesCompanionBridgeServer.swift +438 -0
- package/app/Sources/LatticesCompanionCockpit.swift +555 -0
- package/app/Sources/LatticesCompanionSecurityCoordinator.swift +594 -0
- package/app/Sources/LatticesCompanionTrackpadController.swift +204 -0
- package/app/Sources/LatticesDeckHost.swift +1463 -0
- package/app/Sources/LatticesRuntime.swift +61 -0
- package/app/Sources/MainView.swift +351 -191
- package/app/Sources/MouseFinder.swift +335 -30
- package/app/Sources/MouseGestureConfig.swift +364 -0
- package/app/Sources/MouseGestureController.swift +1203 -0
- package/app/Sources/MouseInputDeviceStore.swift +98 -0
- package/app/Sources/MouseInputEventViewer.swift +272 -0
- package/app/Sources/MouseShortcutStore.swift +107 -0
- package/app/Sources/OmniSearchView.swift +136 -2
- package/app/Sources/OmniSearchWindow.swift +65 -5
- package/app/Sources/OnboardingView.swift +30 -16
- package/app/Sources/PaletteCommand.swift +26 -6
- package/app/Sources/PermissionChecker.swift +76 -2
- package/app/Sources/PiAuthNextStepCard.swift +148 -0
- package/app/Sources/PiAuthPromptCard.swift +90 -0
- package/app/Sources/PiChatDock.swift +137 -74
- package/app/Sources/PiChatSession.swift +608 -108
- package/app/Sources/PiInstallCallout.swift +86 -0
- package/app/Sources/PiProviderSetupCallout.swift +99 -0
- package/app/Sources/PiWorkspaceView.swift +174 -77
- package/app/Sources/Preferences.swift +78 -0
- package/app/Sources/ScreenMapState.swift +91 -31
- package/app/Sources/ScreenMapView.swift +510 -524
- package/app/Sources/ScreenMapWindowController.swift +12 -4
- package/app/Sources/SettingsView.swift +869 -152
- package/app/Sources/SystemTelemetryMonitor.swift +273 -0
- package/app/Sources/VoiceCommandWindow.swift +23 -2
- package/app/Sources/WindowDragSnapController.swift +628 -0
- package/app/Sources/WindowTiler.swift +328 -65
- package/app/Sources/WorkspaceManager.swift +288 -0
- package/bin/assistant-intelligence.ts +874 -0
- package/bin/handsoff-infer.ts +16 -209
- package/bin/handsoff-worker.ts +45 -258
- package/bin/lattices-app.ts +62 -0
- package/bin/lattices-dev +4 -0
- package/bin/lattices.ts +125 -14
- package/docs/agents.md +14 -0
- package/docs/api.md +55 -0
- package/docs/app.md +3 -0
- package/docs/companion-deck.md +180 -0
- package/docs/config.md +25 -0
- package/docs/tiling-reference.md +55 -0
- package/docs/voice-error-model.md +73 -0
- package/package.json +2 -1
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import AppKit
|
|
2
|
+
import DeckKit
|
|
3
|
+
import Foundation
|
|
4
|
+
|
|
5
|
+
final class LatticesCompanionTrackpadController {
|
|
6
|
+
static let shared = LatticesCompanionTrackpadController()
|
|
7
|
+
|
|
8
|
+
private init() {}
|
|
9
|
+
|
|
10
|
+
func state(isEnabled: Bool) -> DeckTrackpadState {
|
|
11
|
+
guard isEnabled else {
|
|
12
|
+
return DeckTrackpadState(
|
|
13
|
+
isEnabled: false,
|
|
14
|
+
isAvailable: false,
|
|
15
|
+
statusTitle: "Trackpad Off",
|
|
16
|
+
statusDetail: "Enable the companion trackpad from the Mac Shortcuts settings.",
|
|
17
|
+
pointerScale: 1.6,
|
|
18
|
+
scrollScale: 1.0,
|
|
19
|
+
supportsDragLock: true
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let trusted = AXIsProcessTrusted()
|
|
24
|
+
return DeckTrackpadState(
|
|
25
|
+
isEnabled: true,
|
|
26
|
+
isAvailable: trusted,
|
|
27
|
+
statusTitle: trusted ? "Trackpad Ready" : "Accessibility Needed",
|
|
28
|
+
statusDetail: trusted
|
|
29
|
+
? "Move, scroll, click, and drag on your Mac from the iPad surface."
|
|
30
|
+
: "Grant Accessibility permission to Lattices on your Mac to enable pointer control.",
|
|
31
|
+
pointerScale: 1.6,
|
|
32
|
+
scrollScale: 1.0,
|
|
33
|
+
supportsDragLock: true
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
func perform(_ request: DeckTrackpadEventRequest) -> DeckTrackpadEventResult {
|
|
38
|
+
guard AXIsProcessTrusted() else {
|
|
39
|
+
return DeckTrackpadEventResult(ok: false)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let ok: Bool
|
|
43
|
+
switch request.event {
|
|
44
|
+
case .move:
|
|
45
|
+
ok = performMouseMove(dx: request.dx, dy: request.dy)
|
|
46
|
+
case .click:
|
|
47
|
+
ok = performMouseClick(button: .left)
|
|
48
|
+
case .rightClick:
|
|
49
|
+
ok = performMouseClick(button: .right)
|
|
50
|
+
case .scroll:
|
|
51
|
+
ok = performMouseScroll(dx: request.dx, dy: request.dy)
|
|
52
|
+
case .mouseDown:
|
|
53
|
+
ok = performMouseButtonState(button: .left, isDown: true)
|
|
54
|
+
case .mouseUp:
|
|
55
|
+
ok = performMouseButtonState(button: .left, isDown: false)
|
|
56
|
+
case .drag:
|
|
57
|
+
ok = performMouseDrag(dx: request.dx, dy: request.dy)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return DeckTrackpadEventResult(ok: ok)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private extension LatticesCompanionTrackpadController {
|
|
65
|
+
func currentCursorPoint() -> CGPoint {
|
|
66
|
+
CGEvent(source: nil)?.location ?? .zero
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
func clamp(delta: Double) -> CGFloat {
|
|
70
|
+
CGFloat(max(-180, min(180, delta)))
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
func performMouseMove(dx: Double, dy: Double) -> Bool {
|
|
74
|
+
let current = currentCursorPoint()
|
|
75
|
+
let next = CGPoint(
|
|
76
|
+
x: current.x + clamp(delta: dx),
|
|
77
|
+
y: current.y + clamp(delta: dy)
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
// Disassociate so the synthesized warp isn't fought by the physical
|
|
81
|
+
// mouse's last reported position (which was pinning Y to the bottom).
|
|
82
|
+
CGAssociateMouseAndMouseCursorPosition(0)
|
|
83
|
+
CGWarpMouseCursorPosition(next)
|
|
84
|
+
|
|
85
|
+
guard let source = CGEventSource(stateID: .combinedSessionState),
|
|
86
|
+
let event = CGEvent(
|
|
87
|
+
mouseEventSource: source,
|
|
88
|
+
mouseType: .mouseMoved,
|
|
89
|
+
mouseCursorPosition: next,
|
|
90
|
+
mouseButton: .left
|
|
91
|
+
) else {
|
|
92
|
+
CGAssociateMouseAndMouseCursorPosition(1)
|
|
93
|
+
return false
|
|
94
|
+
}
|
|
95
|
+
event.setIntegerValueField(.mouseEventDeltaX, value: Int64(clamp(delta: dx)))
|
|
96
|
+
event.setIntegerValueField(.mouseEventDeltaY, value: Int64(clamp(delta: dy)))
|
|
97
|
+
event.post(tap: .cghidEventTap)
|
|
98
|
+
CGAssociateMouseAndMouseCursorPosition(1)
|
|
99
|
+
return true
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
func performMouseClick(button: CGMouseButton) -> Bool {
|
|
103
|
+
let pos = currentCursorPoint()
|
|
104
|
+
let downType: CGEventType = button == .left ? .leftMouseDown : .rightMouseDown
|
|
105
|
+
let upType: CGEventType = button == .left ? .leftMouseUp : .rightMouseUp
|
|
106
|
+
|
|
107
|
+
guard let source = CGEventSource(stateID: .combinedSessionState),
|
|
108
|
+
let down = CGEvent(
|
|
109
|
+
mouseEventSource: source,
|
|
110
|
+
mouseType: downType,
|
|
111
|
+
mouseCursorPosition: pos,
|
|
112
|
+
mouseButton: button
|
|
113
|
+
),
|
|
114
|
+
let up = CGEvent(
|
|
115
|
+
mouseEventSource: source,
|
|
116
|
+
mouseType: upType,
|
|
117
|
+
mouseCursorPosition: pos,
|
|
118
|
+
mouseButton: button
|
|
119
|
+
) else {
|
|
120
|
+
return false
|
|
121
|
+
}
|
|
122
|
+
down.post(tap: .cghidEventTap)
|
|
123
|
+
up.post(tap: .cghidEventTap)
|
|
124
|
+
return true
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
func performMouseButtonState(button: CGMouseButton, isDown: Bool) -> Bool {
|
|
128
|
+
let pos = currentCursorPoint()
|
|
129
|
+
let eventType: CGEventType
|
|
130
|
+
|
|
131
|
+
switch (button, isDown) {
|
|
132
|
+
case (.left, true):
|
|
133
|
+
eventType = .leftMouseDown
|
|
134
|
+
case (.left, false):
|
|
135
|
+
eventType = .leftMouseUp
|
|
136
|
+
case (.right, true):
|
|
137
|
+
eventType = .rightMouseDown
|
|
138
|
+
case (.right, false):
|
|
139
|
+
eventType = .rightMouseUp
|
|
140
|
+
default:
|
|
141
|
+
eventType = .leftMouseDown
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
guard let source = CGEventSource(stateID: .combinedSessionState),
|
|
145
|
+
let event = CGEvent(
|
|
146
|
+
mouseEventSource: source,
|
|
147
|
+
mouseType: eventType,
|
|
148
|
+
mouseCursorPosition: pos,
|
|
149
|
+
mouseButton: button
|
|
150
|
+
) else {
|
|
151
|
+
return false
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
event.post(tap: .cghidEventTap)
|
|
155
|
+
return true
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
func performMouseDrag(dx: Double, dy: Double) -> Bool {
|
|
159
|
+
let current = currentCursorPoint()
|
|
160
|
+
let next = CGPoint(
|
|
161
|
+
x: current.x + clamp(delta: dx),
|
|
162
|
+
y: current.y + clamp(delta: dy)
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
CGAssociateMouseAndMouseCursorPosition(0)
|
|
166
|
+
CGWarpMouseCursorPosition(next)
|
|
167
|
+
|
|
168
|
+
guard let source = CGEventSource(stateID: .combinedSessionState),
|
|
169
|
+
let event = CGEvent(
|
|
170
|
+
mouseEventSource: source,
|
|
171
|
+
mouseType: .leftMouseDragged,
|
|
172
|
+
mouseCursorPosition: next,
|
|
173
|
+
mouseButton: .left
|
|
174
|
+
) else {
|
|
175
|
+
CGAssociateMouseAndMouseCursorPosition(1)
|
|
176
|
+
return false
|
|
177
|
+
}
|
|
178
|
+
event.setIntegerValueField(.mouseEventDeltaX, value: Int64(clamp(delta: dx)))
|
|
179
|
+
event.setIntegerValueField(.mouseEventDeltaY, value: Int64(clamp(delta: dy)))
|
|
180
|
+
event.post(tap: .cghidEventTap)
|
|
181
|
+
CGAssociateMouseAndMouseCursorPosition(1)
|
|
182
|
+
return true
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
func performMouseScroll(dx: Double, dy: Double) -> Bool {
|
|
186
|
+
let horizontal = Int32(clamp(delta: dx).rounded())
|
|
187
|
+
let vertical = Int32((-clamp(delta: dy)).rounded())
|
|
188
|
+
|
|
189
|
+
guard let source = CGEventSource(stateID: .combinedSessionState),
|
|
190
|
+
let event = CGEvent(
|
|
191
|
+
scrollWheelEvent2Source: source,
|
|
192
|
+
units: .pixel,
|
|
193
|
+
wheelCount: 2,
|
|
194
|
+
wheel1: vertical,
|
|
195
|
+
wheel2: horizontal,
|
|
196
|
+
wheel3: 0
|
|
197
|
+
) else {
|
|
198
|
+
return false
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
event.post(tap: .cghidEventTap)
|
|
202
|
+
return true
|
|
203
|
+
}
|
|
204
|
+
}
|