@arach/lattices 0.2.0 → 0.6.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 (143) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +172 -86
  3. package/apps/mac/Info.plist +43 -0
  4. package/apps/mac/Lattices.app/Contents/Info.plist +43 -0
  5. package/apps/mac/Lattices.app/Contents/MacOS/Lattices +0 -0
  6. package/apps/mac/Lattices.app/Contents/Resources/AppIcon.icns +0 -0
  7. package/apps/mac/Lattices.app/Contents/Resources/docs/assistant-knowledge.md +130 -0
  8. package/apps/mac/Lattices.app/Contents/Resources/tap.wav +0 -0
  9. package/apps/mac/Lattices.app/Contents/_CodeSignature/CodeResources +150 -0
  10. package/apps/mac/Lattices.entitlements +21 -0
  11. package/apps/mac/Resources/Pets/assistant-spark/pet.json +62 -0
  12. package/apps/mac/Resources/Pets/assistant-spark/spritesheet.webp +0 -0
  13. package/apps/mac/Resources/Pets/scout-ranger/pet.json +6 -0
  14. package/apps/mac/Resources/Pets/scout-ranger/spritesheet.webp +0 -0
  15. package/apps/mac/Resources/tap.wav +0 -0
  16. package/assets/AppIcon.icns +0 -0
  17. package/bin/assistant-intelligence.ts +912 -0
  18. package/bin/cli/capture.ts +252 -0
  19. package/bin/cli/daemon.ts +22 -0
  20. package/bin/cli/helpers.ts +105 -0
  21. package/bin/cli/layer.ts +178 -0
  22. package/bin/cli/runs.ts +43 -0
  23. package/bin/cli/search.ts +141 -0
  24. package/bin/cli/session.ts +32 -0
  25. package/bin/client.ts +17 -0
  26. package/bin/cua.ts +26 -0
  27. package/bin/{daemon-client.js → daemon-client.ts} +49 -30
  28. package/bin/handsoff-infer.ts +96 -0
  29. package/bin/handsoff-worker.ts +531 -0
  30. package/bin/infer.ts +424 -0
  31. package/bin/keychain.ts +75 -0
  32. package/bin/lattices-app.ts +655 -0
  33. package/bin/lattices-build +125 -0
  34. package/bin/lattices-build-env.ts +77 -0
  35. package/bin/lattices-dev +362 -0
  36. package/bin/lattices.ts +3260 -0
  37. package/bin/project-twin.ts +645 -0
  38. package/docs/agent-execution-plan.md +562 -0
  39. package/docs/agent-layer-guide.md +207 -0
  40. package/docs/agents.md +233 -0
  41. package/docs/ai-chat-ux-review.md +416 -0
  42. package/docs/api.md +1041 -47
  43. package/docs/app.md +96 -13
  44. package/docs/assistant-knowledge.md +130 -0
  45. package/docs/companion-deck.md +209 -0
  46. package/docs/component-extraction-roadmap.md +392 -0
  47. package/docs/concepts.md +13 -12
  48. package/docs/config.md +83 -10
  49. package/docs/gesture-customization-proposal.md +520 -0
  50. package/docs/handsoff-test-scenarios.md +84 -0
  51. package/docs/hyperspace-grid-snappiness.md +210 -0
  52. package/docs/layers.md +176 -28
  53. package/docs/mouse-gestures.md +244 -0
  54. package/docs/ocr.md +21 -9
  55. package/docs/overview.md +42 -23
  56. package/docs/presentation-execution-review.md +491 -0
  57. package/docs/prompts/hands-off-system.md +382 -0
  58. package/docs/prompts/hands-off-turn.md +30 -0
  59. package/docs/prompts/voice-advisor.md +31 -0
  60. package/docs/prompts/voice-fallback.md +23 -0
  61. package/docs/proposals/LAT-001-gesture-visual-customization.md +522 -0
  62. package/docs/proposals/LAT-002-shared-overlay-canvas.md +353 -0
  63. package/docs/proposals/LAT-003-menu-bar-controller-architecture.md +291 -0
  64. package/docs/proposals/LAT-004-interactive-overlay-actors.md +534 -0
  65. package/docs/proposals/LAT-005-action-runtime-product-spine.md +914 -0
  66. package/docs/proposals/LAT-006-followup-gaps.md +103 -0
  67. package/docs/proposals/LAT-006-runs-and-capture-in-lattices.md +566 -0
  68. package/docs/proposals/LAT-007-unified-app-shell.md +128 -0
  69. package/docs/quickstart.md +8 -12
  70. package/docs/reference/dewey.config.ts +74 -0
  71. package/docs/reference/install-agent.md +79 -0
  72. package/docs/release.md +172 -0
  73. package/docs/repo-structure.md +100 -0
  74. package/docs/terminal-kit.md +87 -0
  75. package/docs/tiling-reference.md +224 -0
  76. package/docs/twins.md +138 -0
  77. package/docs/voice-command-protocol.md +278 -0
  78. package/docs/voice-error-model.md +73 -0
  79. package/docs/voice.md +221 -0
  80. package/package.json +69 -16
  81. package/packages/npm/sdk/cua.d.mts +1 -0
  82. package/packages/npm/sdk/cua.d.ts +188 -0
  83. package/packages/npm/sdk/cua.mjs +376 -0
  84. package/app/Lattices.app/Contents/Info.plist +0 -24
  85. package/app/Package.swift +0 -13
  86. package/app/Sources/ActionRow.swift +0 -61
  87. package/app/Sources/App.swift +0 -10
  88. package/app/Sources/AppDelegate.swift +0 -234
  89. package/app/Sources/AppShellView.swift +0 -62
  90. package/app/Sources/AppTypeClassifier.swift +0 -70
  91. package/app/Sources/AppWindowShell.swift +0 -63
  92. package/app/Sources/CheatSheetHUD.swift +0 -332
  93. package/app/Sources/CommandModeState.swift +0 -1362
  94. package/app/Sources/CommandModeView.swift +0 -1405
  95. package/app/Sources/CommandModeWindow.swift +0 -192
  96. package/app/Sources/CommandPaletteView.swift +0 -307
  97. package/app/Sources/CommandPaletteWindow.swift +0 -134
  98. package/app/Sources/DaemonProtocol.swift +0 -101
  99. package/app/Sources/DaemonServer.swift +0 -414
  100. package/app/Sources/DesktopModel.swift +0 -121
  101. package/app/Sources/DesktopModelTypes.swift +0 -71
  102. package/app/Sources/DiagnosticLog.swift +0 -271
  103. package/app/Sources/EventBus.swift +0 -30
  104. package/app/Sources/HotkeyManager.swift +0 -250
  105. package/app/Sources/HotkeyStore.swift +0 -338
  106. package/app/Sources/InventoryManager.swift +0 -35
  107. package/app/Sources/InventoryPath.swift +0 -43
  108. package/app/Sources/KeyRecorderView.swift +0 -210
  109. package/app/Sources/LatticesApi.swift +0 -1125
  110. package/app/Sources/MainView.swift +0 -467
  111. package/app/Sources/MainWindow.swift +0 -83
  112. package/app/Sources/OcrModel.swift +0 -309
  113. package/app/Sources/OcrStore.swift +0 -295
  114. package/app/Sources/OmniSearchState.swift +0 -283
  115. package/app/Sources/OmniSearchView.swift +0 -288
  116. package/app/Sources/OmniSearchWindow.swift +0 -105
  117. package/app/Sources/OrphanRow.swift +0 -129
  118. package/app/Sources/PaletteCommand.swift +0 -419
  119. package/app/Sources/PermissionChecker.swift +0 -125
  120. package/app/Sources/Preferences.swift +0 -92
  121. package/app/Sources/ProcessModel.swift +0 -199
  122. package/app/Sources/ProcessQuery.swift +0 -151
  123. package/app/Sources/Project.swift +0 -28
  124. package/app/Sources/ProjectRow.swift +0 -368
  125. package/app/Sources/ProjectScanner.swift +0 -121
  126. package/app/Sources/ScreenMapState.swift +0 -2387
  127. package/app/Sources/ScreenMapView.swift +0 -2820
  128. package/app/Sources/ScreenMapWindowController.swift +0 -89
  129. package/app/Sources/SessionManager.swift +0 -72
  130. package/app/Sources/SettingsView.swift +0 -1053
  131. package/app/Sources/SettingsWindow.swift +0 -20
  132. package/app/Sources/TabGroupRow.swift +0 -178
  133. package/app/Sources/Terminal.swift +0 -259
  134. package/app/Sources/TerminalQuery.swift +0 -156
  135. package/app/Sources/TerminalSynthesizer.swift +0 -200
  136. package/app/Sources/Theme.swift +0 -163
  137. package/app/Sources/TilePickerView.swift +0 -209
  138. package/app/Sources/TmuxModel.swift +0 -53
  139. package/app/Sources/TmuxQuery.swift +0 -81
  140. package/app/Sources/WindowTiler.swift +0 -1755
  141. package/app/Sources/WorkspaceManager.swift +0 -434
  142. package/bin/lattices-app.js +0 -221
  143. package/bin/lattices.js +0 -1418
package/docs/app.md CHANGED
@@ -11,6 +11,7 @@ workspace from there.
11
11
 
12
12
  ```bash
13
13
  lattices app # Build (or download) and launch
14
+ lattices app update # Download the latest release and relaunch
14
15
  lattices app build # Rebuild from source
15
16
  lattices app restart # Quit, rebuild, relaunch
16
17
  lattices app quit # Stop the app
@@ -73,10 +74,32 @@ Available when `layers` are configured in `~/.lattices/workspace.json`
73
74
  | Command | Description |
74
75
  |-------------------|------------------------------------------|
75
76
  | Settings | Open preferences (terminal, scan root) |
77
+ | Update Lattices | Download the latest release and relaunch |
76
78
  | Diagnostics | View logs and debug info |
77
79
  | Refresh Projects | Re-scan for .lattices.json configs |
78
80
  | Quit Lattices | Exit the menu bar app |
79
81
 
82
+ ## Overlay actors and HUDs
83
+
84
+ Persistent overlay actors can be hidden or restored with **Hyper+B**. Apps can
85
+ publish a static hover dashboard by exposing:
86
+
87
+ ```txt
88
+ .lattices/hud/manifest.json
89
+ ```
90
+
91
+ Register and publish one:
92
+
93
+ ```bash
94
+ lattices hud register .lattices/hud/manifest.json --publish
95
+ ```
96
+
97
+ The manifest points to a local `index.html`, optional icon, app activation
98
+ target, HUD dimensions, and optional app-owned `sources` metadata for logs or
99
+ state files. Lattices hosts the actor and loads the dashboard through a
100
+ transparent `WKWebView`; the app owns the renderer and writes its own logs in
101
+ the places it already uses.
102
+
80
103
  ## Project discovery
81
104
 
82
105
  The app scans a configurable root directory (up to 3 levels deep)
@@ -93,7 +116,7 @@ For each project found, the app reads:
93
116
  ## Session management
94
117
 
95
118
  The app calls the lattices CLI for session operations. Launch runs
96
- `lattices` in the project directory, Sync runs `lattices sync` to
119
+ `lattices start` in the project directory, Sync runs `lattices sync` to
97
120
  reconcile panes, and Restart runs `lattices restart <pane>` to kill
98
121
  and re-run a pane's process. Detach and Kill call `tmux detach-client`
99
122
  and `tmux kill-session` directly.
@@ -143,10 +166,22 @@ highlight around it for ~1 second so you can spot it immediately.
143
166
  Grant Screen Recording and Accessibility permissions in System
144
167
  Settings > Privacy & Security for all three paths to work.
145
168
 
169
+ ## Voice commands
170
+
171
+ > See [Voice Commands](/docs/voice) for the full guide.
172
+
173
+ Press **Hyper+D** to open the voice command window. Hold **Option** to
174
+ speak, release to stop. Lattices transcribes via Vox, matches to an
175
+ intent, and executes. Built-in commands: find, show, open, tile, kill, scan.
176
+
177
+ The provider-backed assistant can run in parallel, offering follow-up
178
+ suggestions in the AI corner. Configure the provider and credentials in
179
+ Settings > AI.
180
+
146
181
  ## Settings
147
182
 
148
183
  Open via the command palette or the gear icon in the main view.
149
- The settings window has three tabs:
184
+ The settings window has five tabs:
150
185
 
151
186
  ### General
152
187
 
@@ -155,6 +190,8 @@ The settings window has three tabs:
155
190
  | Terminal | Which terminal to use (auto-detected from installed) |
156
191
  | Mode | `learning` or `auto` (see below) |
157
192
  | Scan Root | Directory to scan for .lattices.json configs (type a path or click Browse) |
193
+ | Updates | Download the latest release and relaunch the app |
194
+ | Keyboard Remaps | Optional Caps Lock layer that maps hold to Hyper and tap to Escape |
158
195
 
159
196
  **Mode** controls how the app handles session interaction:
160
197
 
@@ -162,6 +199,44 @@ The settings window has three tabs:
162
199
  (helpful while getting used to tmux)
163
200
  - **Auto** — detaches sessions automatically (fewer prompts)
164
201
 
202
+ ### Keyboard Remaps
203
+
204
+ **Keyboard remaps** are enabled by default for the laptop-friendly rule:
205
+
206
+ - hold Caps Lock -> Hyper (`Control` + `Option` + `Shift` + `Command`)
207
+ - tap Caps Lock -> Escape
208
+
209
+ Rules live in `~/.lattices/keyboard-remaps.json`, and the Settings toggle
210
+ can turn the layer off. Keyboard remaps require Accessibility permission
211
+ because they use a local event tap.
212
+
213
+ ### Companion
214
+
215
+ Shows the secure local bridge status, Mac bridge fingerprint, supported
216
+ capability grants, and paired iPad or iPhone devices. The paired-device
217
+ list shows each device fingerprint, last-seen time, and granted
218
+ capabilities. You can refresh the list, revoke an individual device, or
219
+ forget all trusted companions.
220
+
221
+ The local companion bridge and trackpad proxy are off by default for
222
+ privacy. Turn the bridge on in Settings > Companion, or open
223
+ `lattices://companion/enable` to enable the bridge and jump straight to
224
+ Companion settings. `lattices://companion/disable` turns it off again.
225
+
226
+ The trackpad proxy toggle lives here. Paired devices still need the
227
+ `input.trackpad` grant before they can send pointer events.
228
+
229
+ ### AI
230
+
231
+ | Setting | Default | Description |
232
+ |----------------------|----------------|------------------------------------------|
233
+ | Assistant provider | OpenAI Codex | Provider used by in-app chat and provider-backed voice advice |
234
+ | Pi runtime | Auto-detected | Runtime install/refresh controls for provider chat |
235
+ | Provider credentials | Not set | OAuth sign-in or local API-key storage for the selected provider |
236
+
237
+ Shows assistant readiness, runtime availability, and selected-provider
238
+ authentication state.
239
+
165
240
  ### Shortcuts
166
241
 
167
242
  Shows keyboard shortcut reference:
@@ -169,6 +244,14 @@ Shows keyboard shortcut reference:
169
244
  | Shortcut | Action |
170
245
  |-------------------|----------------------|
171
246
  | Cmd+Shift+M | Open command palette |
247
+ | Hyper+1 | Screen map |
248
+ | Hyper+2 | Window bezel |
249
+ | Hyper+3 | HUD |
250
+ | Hyper+D | Voice commands |
251
+ | Hyper+G | Desktop inventory |
252
+ | Hyper+5 | Omni search |
253
+ | Hyper+6 | Cheat sheet |
254
+ | Hyper+B | Hide/show persistent overlay actors |
172
255
  | Cmd+Option+1/2/3 | Switch workspace layer |
173
256
  | Ctrl+B D | Detach from session |
174
257
  | Ctrl+B X | Kill current pane |
@@ -216,13 +299,13 @@ Agents can use this to "see" what's on screen.
216
299
 
217
300
  ### Desktop Inventory integration
218
301
 
219
- The Desktop Inventory view (Hyper+4) uses OCR to make windows searchable
302
+ The Desktop Inventory view (Hyper+G) uses OCR to make windows searchable
220
303
  by their content — not just by title or app name. When you type a search
221
304
  query, windows matching by OCR content show contextual snippets.
222
305
 
223
306
  ### API access
224
307
 
225
- Agents can query OCR data through four daemon endpoints:
308
+ Agents can query OCR data through four API methods:
226
309
 
227
310
  | Method | Description |
228
311
  |----------------|------------------------------------------------|
@@ -232,7 +315,7 @@ Agents can query OCR data through four daemon endpoints:
232
315
  | `ocr.scan` | Trigger an immediate scan (bypasses timer) |
233
316
 
234
317
  ```js
235
- import { daemonCall } from '@arach/lattices/daemon-client'
318
+ import { daemonCall } from '@lattices/cli'
236
319
 
237
320
  // Find windows showing error messages
238
321
  const errors = await daemonCall('ocr.search', { query: 'error OR failed' })
@@ -241,16 +324,16 @@ const errors = await daemonCall('ocr.search', { query: 'error OR failed' })
241
324
  const snapshot = await daemonCall('ocr.snapshot')
242
325
  ```
243
326
 
244
- More in the [Daemon API reference](/docs/api#ocrsnapshot).
327
+ More in the [Agent API reference](/docs/api#ocrsnapshot).
245
328
 
246
329
  ### Requirements
247
330
 
248
331
  - **Screen Recording** permission — required to capture window images
249
332
  - Granted via System Settings > Privacy & Security > Screen Recording
250
333
 
251
- ## Daemon
334
+ ## Agent API server
252
335
 
253
- The menu bar app runs a WebSocket daemon on `ws://127.0.0.1:9399`.
336
+ The menu bar app runs a WebSocket server on `ws://127.0.0.1:9399`.
254
337
  It starts automatically when the app launches and stops when the app
255
338
  quits.
256
339
 
@@ -263,7 +346,7 @@ lattices daemon status
263
346
  Or programmatically:
264
347
 
265
348
  ```js
266
- import { isDaemonRunning, daemonCall } from '@arach/lattices/daemon-client'
349
+ import { isDaemonRunning, daemonCall } from '@lattices/cli'
267
350
 
268
351
  if (await isDaemonRunning()) {
269
352
  const status = await daemonCall('daemon.status')
@@ -273,7 +356,7 @@ if (await isDaemonRunning()) {
273
356
 
274
357
  ### What it provides
275
358
 
276
- - 30 RPC methods for reading windows, sessions, projects, spaces, layers,
359
+ - 35+ RPC methods for reading windows, sessions, projects, spaces, layers,
277
360
  processes, terminals, and OCR. Also launching/killing sessions, tiling
278
361
  windows, switching layers, and managing tab groups.
279
362
  - 5 real-time events (`windows.changed`, `tmux.changed`, `processes.changed`,
@@ -284,11 +367,11 @@ if (await isDaemonRunning()) {
284
367
 
285
368
  ### Security
286
369
 
287
- The daemon binds to localhost only (`127.0.0.1:9399`). Not accessible
370
+ The server binds to localhost only (`127.0.0.1:9399`). Not accessible
288
371
  from the network. No authentication, so any local process can connect.
289
- This is intentional. It's for local automation, not remote access.
372
+ This is intentional — it's for local automation, not remote access.
290
373
 
291
- Full method list in the [Daemon API reference](/docs/api).
374
+ Full method list in the [Agent API reference](/docs/api).
292
375
 
293
376
  ## Diagnostics
294
377
 
@@ -0,0 +1,130 @@
1
+ ---
2
+ type: Assistant Knowledge Base
3
+ title: Lattices — Assistant Knowledge
4
+ description: Orientation + capability map the in-app Workspace Assistant uses to explain Lattices and point to the right feature or doc
5
+ audience: assistant
6
+ ---
7
+
8
+ > You are reading the Workspace Assistant's knowledge base. It summarizes what
9
+ > Lattices can do and links to the deeper docs. Treat the **structured context**
10
+ > in your prompt (current settings, file paths, CLI commands) as ground truth for
11
+ > *this user's* configuration; treat this file as ground truth for *how Lattices
12
+ > works*. When a question goes deeper than this summary, name the relevant doc
13
+ > (see [References](#references)) instead of guessing.
14
+
15
+ ## What Lattices is
16
+
17
+ Lattices is an **agentic window manager for macOS** — a programmable workspace
18
+ that pairs a native menu bar app with managed tmux sessions and a scriptable
19
+ agent API. Three layers, one product:
20
+
21
+ 1. **Programmable workspace** — a CLI and a WebSocket agent API (`ws://127.0.0.1:9399`,
22
+ 35+ methods, real-time events) that let scripts and AI agents observe and drive
23
+ the desktop the same way a person does.
24
+ 2. **Smart layout manager** — the menu bar app tracks every window across all
25
+ monitors: tiling, switchable layers, snap zones, and screen-text indexing.
26
+ 3. **Managed tmux sessions** — declare a dev environment in `.lattices.json`;
27
+ Lattices builds it, runs it, and keeps it alive across reboots.
28
+
29
+ Requirements: macOS 26+, Node 18+; tmux only for session management.
30
+ See [Overview](/docs/overview) and [Concepts](/docs/concepts).
31
+
32
+ ## Capability map
33
+
34
+ Each area below is a one-paragraph summary plus the doc to cite for detail.
35
+
36
+ ### Window tiling & placement
37
+ Snap windows to preset positions — halves, quarters, thirds, maximize, center —
38
+ from the command palette or `lattices tile <position>`. There is also a grid
39
+ placement primitive: compact `CxR:c,r` starts at 1 for command entry, while
40
+ canonical `grid:CxR:c,r` starts at 0 for APIs. → [Tiling reference](/docs/tiling-reference), positions in [Configuration](/docs/config).
41
+
42
+ ### Workspace layers & tab groups
43
+ Group projects into named **layers** you can switch between, and tab-group related
44
+ windows. `workspace.json` layers launch/focus/tile projects. Studio layers are
45
+ rule-backed live window sets persisted in `~/.lattices/layers.json`; their clauses
46
+ support app/title/session exact, substring, regex, Space, visibility, and exclusion
47
+ matches. → [Layers](/docs/layers).
48
+
49
+ ### Command palette & menu bar app
50
+ The palette (**Cmd+Shift+M**) is the app's primary surface: launch projects, tile,
51
+ sync, restart, open settings — all searchable. → [Menu Bar App](/docs/app).
52
+
53
+ ### tmux sessions (`.lattices.json`)
54
+ Declare panes, commands, and layout per project. `lattices start` builds/attaches a
55
+ persistent session named `<basename>-<hash>`; `lattices sync` reconciles a running
56
+ session to its config. **Ensure** re-runs exited commands on reattach; **prefill**
57
+ types them and waits. → [Concepts](/docs/concepts), [Configuration](/docs/config).
58
+
59
+ ### Screen OCR & search
60
+ The app reads on-screen text via the Accessibility API (~60s) and Apple Vision OCR
61
+ on background windows (~2h), indexing everything with FTS5. Search across titles,
62
+ app names, session tags, and OCR with `lattices search <query>` (add `--deep` or
63
+ `--all` to inspect terminal tabs by cwd). → [Screen OCR & Search](/docs/ocr).
64
+
65
+ ### Voice commands
66
+ Natural-language voice control for window management ("put the browser on the
67
+ right", "switch to the backend layer"). → [Voice Commands](/docs/voice).
68
+
69
+ ### Mouse gestures
70
+ Hold a mouse button, draw a direction or shape, release — runs the matched action.
71
+ Configured via `mouseGestures.enabled` plus `~/.lattices/mouse-shortcuts.json`.
72
+ → [Mouse Gestures](/docs/mouse-gestures).
73
+
74
+ ### Agent API & CLI
75
+ Agents connect over WebSocket and get the same control as a person: list
76
+ windows/projects, launch sessions, tile, switch layers, read screen text, and
77
+ subscribe to events (`windows.changed`, `tmux.changed`, `layer.switched`).
78
+ → [Agent Guide](/docs/agents), [Agent API](/docs/api).
79
+
80
+ ### Project twins
81
+ Pi-backed project "twins" for mediated, persistent agent execution scoped to a
82
+ project. → [Project Twins](/docs/twins).
83
+
84
+ ## Key shortcuts
85
+
86
+ | Shortcut | Action |
87
+ |----------|--------|
88
+ | **Cmd+Shift+M** | Open the command palette |
89
+ | `lattices tile <position>` | Tile the focused window (CLI) |
90
+ | `lattices layer [name\|index]` | Switch workspace layer (CLI) |
91
+ | **Ctrl+B** then `D` / `Z` / arrows | tmux: detach / zoom / move pane (inside a session) |
92
+
93
+ Tiling and grid hotkeys are user-configurable — for the live set, point the user to
94
+ Settings or the [Tiling reference](/docs/tiling-reference) rather than asserting one.
95
+
96
+ ## CLI quick reference
97
+
98
+ `lattices` · `lattices init` · `lattices sync` · `lattices start` ·
99
+ `lattices restart [pane]` · `lattices tile <position>` · `lattices group [id]` ·
100
+ `lattices layer [name|index]` · `lattices windows --json` ·
101
+ `lattices search <query> [--deep|--all] [--json] [--wid]` · `lattices place <query> [position]` ·
102
+ `lattices app restart`. Full flags: [Configuration](/docs/config).
103
+
104
+ ## Config & file locations
105
+
106
+ - **Per project:** `.lattices.json` in the project root (panes, commands, layout, ensure/prefill).
107
+ - **User config (`~/.lattices/`):** `workspace.json`, `layers.json`, `mouse-shortcuts.json`,
108
+ `snap-zones.json`, `clusters.json`, `ocr.db`, `lattices.log`.
109
+ - **Defaults domain:** `dev.lattices.app` (read/write app settings via `defaults`).
110
+
111
+ The exact current values and paths for *this* machine arrive in your structured
112
+ context — prefer those over the generic paths above when answering.
113
+
114
+ ## References
115
+
116
+ | Topic | Doc |
117
+ |-------|-----|
118
+ | What it is / who it's for | [Overview](/docs/overview) |
119
+ | Install & first run | [Quickstart](/docs/quickstart) |
120
+ | Architecture, glossary, internals | [Concepts](/docs/concepts) |
121
+ | `.lattices.json`, CLI, tile positions | [Configuration](/docs/config) |
122
+ | Command palette, tiling, sessions | [Menu Bar App](/docs/app) |
123
+ | Tiling & grid placement | [Tiling reference](/docs/tiling-reference) |
124
+ | Layers & tab groups | [Layers](/docs/layers) |
125
+ | Screen OCR & full-text search | [Screen OCR & Search](/docs/ocr) |
126
+ | Voice control | [Voice Commands](/docs/voice) |
127
+ | Mouse gestures | [Mouse Gestures](/docs/mouse-gestures) |
128
+ | Agent contracts (voice/CLI/daemon) | [Agent Guide](/docs/agents) |
129
+ | WebSocket RPC method reference | [Agent API](/docs/api) |
130
+ | Project twins | [Project Twins](/docs/twins) |
@@ -0,0 +1,209 @@
1
+ # Companion Deck
2
+
3
+ This document defines the first extraction boundary for the Lattices
4
+ companion deck work.
5
+
6
+ ## Goals
7
+
8
+ - Build the deck architecture in `lattices` first, without modifying
9
+ `talkie`.
10
+ - Treat `talkie` as the donor and reference implementation, not the
11
+ place where the first shared abstraction is born.
12
+ - Let `lattices` own Mac functionality.
13
+ - Let `talkie` continue to own Talkie-specific flows.
14
+ - Keep the transport and UI shell generic enough that both products can
15
+ embed the same deck later.
16
+
17
+ ## Product Ownership
18
+
19
+ ### Lattices owns
20
+
21
+ - Voice agent control
22
+ - Layout and screen state
23
+ - Application, window, tab, and task switching
24
+ - Session and layer switching
25
+ - Desktop questions and agent follow-up
26
+ - Action history and undo-oriented playback
27
+
28
+ ### Talkie owns
29
+
30
+ - Dictation
31
+ - Memo recording
32
+ - Scratchpad and compose flows
33
+ - Capture-specific flows
34
+ - Talkie-branded deck pages and follow-up actions
35
+
36
+ ### Shared deck kit owns
37
+
38
+ - Page model
39
+ - Action model
40
+ - Runtime snapshot model
41
+ - Security mode model
42
+ - App and task switcher model
43
+ - History feed model
44
+ - Generic host protocol
45
+
46
+ ## Security Modes
47
+
48
+ The deck must support two security modes.
49
+
50
+ ### Standalone
51
+
52
+ Used by a future standalone `Lattices Companion`.
53
+
54
+ - Bonjour discovery
55
+ - Local network only
56
+ - No Tailscale or external relay dependency
57
+ - QR or code-based pairing on top of the local network path
58
+ - Per-device keypairs
59
+ - Signed requests with nonce and timestamp protection
60
+ - Local companion gateway with a reduced action surface
61
+
62
+ ### Embedded
63
+
64
+ Used when the deck is embedded inside `talkie`.
65
+
66
+ - Pairing, trust, transport, and signing are delegated to Talkie
67
+ - Lattices focuses only on local functionality and state
68
+ - The Lattices deck host does not need to own remote security in this mode
69
+
70
+ ## First Lattices Companion Scope
71
+
72
+ The first iPad/iPhone companion for Lattices should focus on these pages:
73
+
74
+ 1. Voice
75
+ 2. Layout
76
+ 3. Switch
77
+ 4. History
78
+
79
+ These pages cover the highest-value mobile control loops without pulling
80
+ Talkie-specific concepts into the new product.
81
+
82
+ ## Module Plan
83
+
84
+ ### `swift/DeckKit`
85
+
86
+ Cross-product contract incubated in the Lattices repo first.
87
+
88
+ - Shared deck schema
89
+ - Security mode model
90
+ - Runtime snapshot model
91
+ - Host protocol
92
+
93
+ ### `LatticesDeckHost`
94
+
95
+ Mac-side adapter owned by Lattices.
96
+
97
+ - Publishes deck pages and runtime state
98
+ - Maps deck actions to the existing Lattices desktop APIs
99
+ - Uses the existing desktop model, layout engine, switcher logic, and
100
+ voice agent surfaces
101
+
102
+ ### `Lattices Companion`
103
+
104
+ Future iOS or iPadOS app that consumes `DeckKit` and the Lattices
105
+ companion gateway.
106
+
107
+ ### `TalkieDeckHost`
108
+
109
+ Future Talkie-side adapter that adds Talkie-only pages on top of the
110
+ shared deck shell.
111
+
112
+ ## Current Lattices Milestone
113
+
114
+ The first host-side integration now lives in the Lattices macOS app.
115
+
116
+ - `swift/DeckKit` continues to own the shared manifest, snapshot,
117
+ action, and security contract.
118
+ - `apps/mac/Sources/LatticesDeckHost.swift` is the first concrete Mac host.
119
+ - The menu bar app daemon now exposes:
120
+ - `deck.manifest`
121
+ - `deck.snapshot`
122
+ - `deck.perform`
123
+
124
+ That gives the future iPhone/iPad companion a stable local contract
125
+ before transport and pairing are finalized.
126
+
127
+ The current transport now runs as a local network bridge in the macOS
128
+ app with Bonjour discovery on port `5287` (`LATS` on a phone keypad).
129
+ Standalone mode now uses:
130
+
131
+ - local Mac approval for first-time device pairing
132
+ - per-device key agreement
133
+ - signed requests with nonce and timestamp checks
134
+ - encrypted deck payloads for snapshots, actions, and trackpad events
135
+ - pairing-time capability grants, enforced again on every protected route
136
+
137
+ The bridge still keeps `/health`, `/deck/manifest`, and pairing
138
+ bootstrap lightweight so a new companion can connect and establish trust
139
+ without an external relay or Tailscale dependency.
140
+
141
+ ## Reference Security Pattern
142
+
143
+ The standalone bridge is the reference pattern we should share back to
144
+ Talkie and Scout:
145
+
146
+ 1. Bonjour is discovery only. The TXT record exposes protocol version,
147
+ fingerprint, security mode, and coarse capabilities, but no project
148
+ names, sessions, commands, or tokens.
149
+ 2. Local-network control is opt-in. The bridge is disabled by default;
150
+ users enable it from Companion settings or the local
151
+ `lattices://companion/enable` deep link.
152
+ 3. Pairing is explicit Mac approval. A cryptographic handshake or public
153
+ key exchange proves key possession; it does not automatically grant
154
+ control.
155
+ 4. Trust is scoped. Pairing records store granted capabilities such as
156
+ `deck.read`, `deck.perform`, and `input.trackpad`.
157
+ 5. Every protected request is signed with a timestamp and nonce, then
158
+ checked for replay before the route runs.
159
+ 6. Sensitive payloads are encrypted with per-device key agreement and
160
+ route-bound additional authenticated data.
161
+ 7. Authorization happens after authentication. A trusted device still
162
+ needs the route's required capability before it can read state,
163
+ perform actions, or proxy input.
164
+
165
+ That gives the family of apps one ergonomic model: discover nearby,
166
+ pair once, reconnect quietly, and keep control surfaces capability
167
+ scoped.
168
+
169
+ ## Initial Action Surface
170
+
171
+ The first deck action IDs are intentionally small and map to existing
172
+ desktop behavior:
173
+
174
+ - `voice.toggle`
175
+ - `voice.cancel`
176
+ - `layout.activateLayer`
177
+ - `layout.optimize`
178
+ - `layout.placeFrontmost`
179
+ - `switch.focusItem`
180
+ - `history.undoLast`
181
+
182
+ This keeps the first bridge focused on real Mac control loops instead
183
+ of inventing a second execution stack.
184
+
185
+ ## Rollout Sequence
186
+
187
+ 1. Leave Talkie untouched and use it as the donor reference.
188
+ 2. Incubate `DeckKit` in `lattices`.
189
+ 3. Build a clean Lattices companion around `Voice`, `Layout`,
190
+ `Switch`, and `History`.
191
+ 4. Prove standalone local pairing and strong security for Lattices.
192
+ 5. Harden the deck contract.
193
+ 6. Retrofit the stabilized deck kit back into Talkie.
194
+
195
+ Embedded mode remains a first-class constraint throughout the rollout.
196
+ The standalone bridge must not leak into the shared deck contract in a
197
+ way that would make Talkie embedding awkward later.
198
+
199
+ ## Vox
200
+
201
+ Vox is the preferred voice dependency for the Lattices companion path.
202
+
203
+ - Prefer direct embedding through `VoxCore` and `VoxEngine` for
204
+ in-process ASR and TTS inside Apple apps.
205
+ - Keep `VoxBridge` available as an optional daemon-style path when a
206
+ shared runtime is more appropriate than direct embedding.
207
+ - Keep the first contract in `DeckKit` voice-agnostic.
208
+ - Let `LatticesDeckHost` decide whether voice is served by embedded Vox
209
+ or another local service surface.