@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.
Files changed (70) hide show
  1. package/README.md +3 -0
  2. package/app/Info.plist +2 -2
  3. package/app/Lattices.app/Contents/Info.plist +2 -2
  4. package/app/Lattices.app/Contents/MacOS/Lattices +0 -0
  5. package/app/Package.swift +6 -0
  6. package/app/Sources/App.swift +10 -0
  7. package/app/Sources/AppDelegate.swift +90 -34
  8. package/app/Sources/AppShellView.swift +2 -0
  9. package/app/Sources/AppTypeClassifier.swift +36 -0
  10. package/app/Sources/AppUpdater.swift +92 -0
  11. package/app/Sources/CheatSheetHUD.swift +1 -0
  12. package/app/Sources/CliActionLauncher.swift +50 -0
  13. package/app/Sources/CommandModeView.swift +4 -24
  14. package/app/Sources/CompanionActivityLog.swift +70 -0
  15. package/app/Sources/CompanionKeyboardController.swift +141 -0
  16. package/app/Sources/DesktopModel.swift +4 -0
  17. package/app/Sources/HandsOffSession.swift +15 -4
  18. package/app/Sources/HomeDashboardView.swift +18 -10
  19. package/app/Sources/HotkeyStore.swift +8 -5
  20. package/app/Sources/IntentEngine.swift +7 -1
  21. package/app/Sources/LatticesApi.swift +125 -4
  22. package/app/Sources/LatticesCompanionBridgeServer.swift +438 -0
  23. package/app/Sources/LatticesCompanionCockpit.swift +555 -0
  24. package/app/Sources/LatticesCompanionSecurityCoordinator.swift +594 -0
  25. package/app/Sources/LatticesCompanionTrackpadController.swift +204 -0
  26. package/app/Sources/LatticesDeckHost.swift +1463 -0
  27. package/app/Sources/LatticesRuntime.swift +61 -0
  28. package/app/Sources/MainView.swift +351 -191
  29. package/app/Sources/MouseFinder.swift +335 -30
  30. package/app/Sources/MouseGestureConfig.swift +364 -0
  31. package/app/Sources/MouseGestureController.swift +1203 -0
  32. package/app/Sources/MouseInputDeviceStore.swift +98 -0
  33. package/app/Sources/MouseInputEventViewer.swift +272 -0
  34. package/app/Sources/MouseShortcutStore.swift +107 -0
  35. package/app/Sources/OmniSearchView.swift +136 -2
  36. package/app/Sources/OmniSearchWindow.swift +65 -5
  37. package/app/Sources/OnboardingView.swift +30 -16
  38. package/app/Sources/PaletteCommand.swift +26 -6
  39. package/app/Sources/PermissionChecker.swift +76 -2
  40. package/app/Sources/PiAuthNextStepCard.swift +148 -0
  41. package/app/Sources/PiAuthPromptCard.swift +90 -0
  42. package/app/Sources/PiChatDock.swift +137 -74
  43. package/app/Sources/PiChatSession.swift +608 -108
  44. package/app/Sources/PiInstallCallout.swift +86 -0
  45. package/app/Sources/PiProviderSetupCallout.swift +99 -0
  46. package/app/Sources/PiWorkspaceView.swift +174 -77
  47. package/app/Sources/Preferences.swift +78 -0
  48. package/app/Sources/ScreenMapState.swift +91 -31
  49. package/app/Sources/ScreenMapView.swift +510 -524
  50. package/app/Sources/ScreenMapWindowController.swift +12 -4
  51. package/app/Sources/SettingsView.swift +869 -152
  52. package/app/Sources/SystemTelemetryMonitor.swift +273 -0
  53. package/app/Sources/VoiceCommandWindow.swift +23 -2
  54. package/app/Sources/WindowDragSnapController.swift +628 -0
  55. package/app/Sources/WindowTiler.swift +328 -65
  56. package/app/Sources/WorkspaceManager.swift +288 -0
  57. package/bin/assistant-intelligence.ts +874 -0
  58. package/bin/handsoff-infer.ts +16 -209
  59. package/bin/handsoff-worker.ts +45 -258
  60. package/bin/lattices-app.ts +62 -0
  61. package/bin/lattices-dev +4 -0
  62. package/bin/lattices.ts +125 -14
  63. package/docs/agents.md +14 -0
  64. package/docs/api.md +55 -0
  65. package/docs/app.md +3 -0
  66. package/docs/companion-deck.md +180 -0
  67. package/docs/config.md +25 -0
  68. package/docs/tiling-reference.md +55 -0
  69. package/docs/voice-error-model.md +73 -0
  70. 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
+ }