@arach/lattices 0.2.1 → 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 +144 -69
  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
@@ -0,0 +1,103 @@
1
+ # LAT-006 Follow-up: Next Use Cases & Gaps (Load / Voice / Type / Click)
2
+
3
+ Assessment date: 2026-06-17. Scope: current working tree on `main` (uncommitted LAT-006
4
+ runs/capture/computer-use slice). Focus: root-cause product/API shape, not workarounds.
5
+
6
+ ## What exists today (grounded)
7
+
8
+ A real **observe → act → capture → trace** layer landed (LAT-006 Phase 2 + a computer-use
9
+ extension), wired end to end:
10
+
11
+ - **Daemon** (`apps/mac/Sources/Core/Daemon/LatticesApi.swift`):
12
+ - `runs.create | runs.list | runs.get | runs.artifacts`
13
+ - `capture.screenshotWindow`
14
+ - `computer.prepare | computer.focusWindow | computer.typeText | computer.showCursor | computer.demoTerminal`
15
+ - `settings.cursorAppearance.get | .set`
16
+ - **Controllers**: `Core/Actions/ComputerUseController.swift`, `Core/Capture/CaptureController.swift`,
17
+ `Core/Runs/RunStore.swift` + `RunModels.swift` (persists to `~/Library/Application Support/Lattices/Runs/`, `runs.json` index).
18
+ - **CLI** (`bin/lattices.ts`): `lattices computer|capture|runs|terminals`.
19
+ - **Palette** (`PaletteCommand.swift`): "Screenshot Current Window", "Review Runs" under a new `.run` category → `ScreenMapWindowController.showPage(.runs)` + `RunsReviewView.swift`.
20
+ - **Safety model**: `ComputerTreatment` = observe/stage/present/execute. Typing only targets
21
+ scored *safe* terminals (avoids claude/codex/vim, requires idle shell for Enter), with a transport
22
+ ladder: tmux `send-keys` → iTerm session `write text` → pasteboard/key-events (active tab only).
23
+
24
+ This is a strong foundation. The gaps below are about **shape**, not patching.
25
+
26
+ ## Gaps by focus area (root-cause)
27
+
28
+ ### 1. Loading apps — not a first-class, composable operation
29
+ App/project launch lives only inside the voice `launch` intent → `session.launch`
30
+ (`Intents/LaunchIntent.swift`), with a brittle fallback (capitalize first letter, `NSWorkspace`
31
+ name match; no bundle-id resolution). Root cause: **there is no `apps.launch` daemon verb and no
32
+ "wait until window exists" precondition.** So launching can't be wrapped as a Run, can't be composed
33
+ with capture/type/click, and the computer-use layer can't open a target app before acting on it.
34
+ → Add `apps.launch` (name/bundleId/project) returning a `RunSession` with surfaces, plus a shared
35
+ `waitForWindow` primitive that `computer.focusWindow/typeText/click` reuse as a precondition.
36
+
37
+ ### 2. Voice/talk flows — the new capabilities are invisible to voice
38
+ `IntentEngine.swift` vocabulary stops at workspace control: tile_window, focus, launch,
39
+ switch_layer, search, list_*, distribute, create_layer, kill, scan, swap, hide, highlight,
40
+ move_to_display, find_mouse, summon_mouse, undo. Root cause: **none of `computer.*`, `capture.*`,
41
+ or `runs.*` is registered as an intent.** Voice can move/observe windows but cannot drive the proof
42
+ loop (screenshot, type, review a run). The slot/dispatch plumbing already exists, so this is additive.
43
+ → Register `screenshot` → `capture.screenshotWindow`; `type` → `computer.typeText` (default
44
+ `treatment=stage`, require explicit confirm before execute — matches the HandsOff "don't act on
45
+ questions" preference); `show_cursor`/`click` → cursor/click methods; `review_run` → runs page.
46
+
47
+ ### 3. Typing — solid, but terminal-only
48
+ Strongest area. The transport ladder + safety scoring is the right shape. Root-cause limits:
49
+ - Typing targets **terminals exclusively** (`TerminalCandidate` / `ProcessModel.synthesizeTerminals`).
50
+ There is no "type into the focused text field of app X" (browser URL bar, native field).
51
+ - The pasteboard path saves/restores the clipboard but requires the tab already active; iTerm is
52
+ explicitly excluded from the keyboard transport, so non-tmux iTerm has no fallback.
53
+ → Add an AX-based `computer.typeInto` that resolves the focused element / a target text field, keeping
54
+ the terminal path as the specialized *safe* case. This generalizes typing without weakening the
55
+ terminal safety model.
56
+
57
+ ### 4. Clicking around — the verb does not exist
58
+ **There is no click action.** `computer.showCursor` only renders a visual marker; it posts no mouse
59
+ event. The only `CGEvent` mouse code (`Core/Input/MouseGestureController.swift`) *recognizes* gestures
60
+ — it does not synthesize targeted clicks. So the "act" half of the loop for non-terminal targets
61
+ (buttons, links, menu items) is entirely missing. This is the single biggest missing primitive.
62
+ → Add `computer.click` (+ `computer.moveCursor`) that resolves a target (coordinate, AX element, or
63
+ window+role) and posts left/right down/up via `CGEvent`, wrapped in a Run with before/after capture,
64
+ gated by the same treatment model (observe/stage/present/execute).
65
+
66
+ ### 5. Cross-cutting: the proof loop is open at both ends
67
+ - **Recording not implemented.** Proposal lists `capture.recordWindow/recordRegion` + an AppKit
68
+ `--recording-probe` (Phase 3); only screenshots exist (`WindowCapture` uses `SCStream` for stills).
69
+ Also missing: `runs.start`, `runs.stop`.
70
+ - **No verify step.** `typeText` captures before/after screenshots but never asserts the text landed.
71
+ An OCR/AX diff (reusing the existing `ocr.search`) would close observe → act → **verify** and feed
72
+ LAT-005 receipts.
73
+
74
+ ## Suggested implementation order (highest leverage first)
75
+
76
+ 1. **`computer.click` + `computer.moveCursor`** — fills the only missing computer-use verb; reuse
77
+ treatment model + Run wrapper + before/after capture.
78
+ 2. **Voice intents over existing `computer.*`/`capture.*`/`runs.*`** — additive, low risk; stage-by-default
79
+ for any execute, explicit confirm gate.
80
+ 3. **`apps.launch` (Run-wrapped) + `waitForWindow` precondition** — unblocks "load app, then act".
81
+ 4. **`computer.typeInto` (AX focused-element)** — generalize typing beyond terminals.
82
+ 5. **LAT-006 Phase 3 recording probe + `runs.stop`**, then an **OCR/AX verify** step on type/click runs.
83
+
84
+ ## Testing steps
85
+
86
+ - CLI dogfood (per project convention — test via `lattices`, not raw daemon):
87
+ `lattices computer prepare`, `lattices computer type --text "ls" --dry-run`, `lattices capture window`,
88
+ `lattices runs list`, `lattices runs <id> --json`.
89
+ - Treatment matrix: observe/stage/present/execute each produce a Run with correct artifacts and never
90
+ over-act (stage/observe must not focus or type).
91
+ - Safety regression: `computer.typeText` refuses claude/codex/vim targets; refuses Enter on non-idle shells.
92
+ - Click (new): coordinate click + AX-element click on a known button → before/after artifacts in the run
93
+ dir; assert no click when `treatment != execute`.
94
+ - Voice: "screenshot this window" / "type ls in my terminal" resolve to the right daemon method; execute
95
+ paths require confirm.
96
+ - Persistence: confirm `~/Library/Application Support/Lattices/Runs/` + `runs.json` survive an app restart.
97
+
98
+ ## Owner / next move
99
+
100
+ This is an answer, not a handoff — no other agent needs waking. The clearest single next step that
101
+ unblocks the most use cases is **`computer.click`** (closes the "act" gap for non-terminal targets),
102
+ immediately followed by **exposing the existing computer/capture/run methods to voice**. Both are owned
103
+ by the Lattices macOS app. Recording + verify are the right Phase-3 follow-ups once click + voice land.
@@ -0,0 +1,566 @@
1
+ # LAT-006: Runs and Capture in Lattices
2
+
3
+ ## Status
4
+
5
+ Accepted direction; initial screenshot slice in progress.
6
+
7
+ ## Summary
8
+
9
+ The Action/Mira experiment should stop being a separate product the user has to
10
+ remember. The useful runtime loop should become plain Lattices functionality:
11
+
12
+ ```text
13
+ observe -> act -> capture -> trace -> artifact -> review
14
+ ```
15
+
16
+ The user-facing concepts should be:
17
+
18
+ ```text
19
+ Lattices = workspace control plane
20
+ Actions = executable workspace operations
21
+ Runs = executions with trace and artifacts
22
+ Capture = screenshots and recordings
23
+ Review = inspect output
24
+ Actors = optional on-screen presences
25
+ ```
26
+
27
+ This retires Mira as a feature name or product brand. Actors, pets, and
28
+ on-screen presences remain useful Lattices primitives, but no specific actor
29
+ should become the identity of the capture/review system.
30
+
31
+ The desired user experience is one macOS app, one daemon surface, one
32
+ permission assistant, one command palette, and one place to find runs and
33
+ artifacts.
34
+
35
+ Internally, Lattices can still keep specialized helper processes. The important
36
+ distinction is that helpers are implementation details. The product the user
37
+ grants permissions to, launches, trusts, and remembers should be Lattices.
38
+
39
+ ## Why This Belongs Here
40
+
41
+ Lattices and Action converged on the same operating model from opposite
42
+ directions:
43
+
44
+ - Lattices already knows about workspaces, projects, windows, Spaces, layers,
45
+ overlays, command surfaces, and local daemon control.
46
+ - Action already knows about observing surfaces, resolving targets, running
47
+ deterministic actions, recording what happened, and saving reviewable
48
+ artifacts.
49
+
50
+ LAT-005 proposes the shared action loop:
51
+
52
+ ```text
53
+ input -> canonical action -> plan -> execute -> verify -> receipt -> history
54
+ ```
55
+
56
+ Action supplies the missing proof loop:
57
+
58
+ ```text
59
+ run -> observe -> act -> capture -> trace -> artifact -> review
60
+ ```
61
+
62
+ Together, they make one product: a local macOS workspace runtime that can both
63
+ control the desktop and prove what happened.
64
+
65
+ ## Problem
66
+
67
+ Keeping Action/Mira as a separate product creates exactly the kind of operational
68
+ friction Lattices is supposed to remove:
69
+
70
+ - another repo to remember
71
+ - another app name in the user's head
72
+ - another daemon port
73
+ - another CLI
74
+ - another permission story
75
+ - another place where recordings, traces, and review artifacts live
76
+ - another set of product concepts that overlap with Lattices actions,
77
+ overlays, diagnostics, and permissions
78
+
79
+ The permissions problem is especially important. Accessibility, Screen
80
+ Recording, Automation, and future capture-related capabilities are high-trust
81
+ macOS permissions. Asking the user to manage those separately for Lattices and
82
+ Action/Mira makes the system feel fragmented even when the architecture is
83
+ sound.
84
+
85
+ ## Product Decision
86
+
87
+ Runs and capture should become a Lattices feature area, not a second app.
88
+
89
+ Recommended naming:
90
+
91
+ | Concept | Product Name |
92
+ | --- | --- |
93
+ | Individual execution | Run |
94
+ | Saved output | Artifact |
95
+ | Machine-readable event log | Trace |
96
+ | Human-facing result | Review |
97
+ | Visual desktop presence | Actor |
98
+
99
+ Examples of user-facing commands:
100
+
101
+ - `Record Current Window`
102
+ - `Capture Frontmost App`
103
+ - `Start Run`
104
+ - `Review Last Run`
105
+ - `Show Run Artifacts`
106
+ - `Rerun Scenario`
107
+
108
+ The user should not need to know whether a given operation used ScreenCaptureKit,
109
+ Accessibility, a browser adapter, a recording probe, or an embedded helper.
110
+ Those details belong in diagnostics and receipts.
111
+
112
+ ## Goals
113
+
114
+ 1. Make Lattices the single user-facing app for workspace control and
115
+ capture/review flows.
116
+ 2. Consolidate permission guidance into the existing Lattices Permissions
117
+ Assistant.
118
+ 3. Preserve Action's important native runtime lesson: AppKit-dependent work must
119
+ run inside a real app lifecycle.
120
+ 4. Add a first-class run/artifact model that extends LAT-005 receipts and
121
+ history.
122
+ 5. Route run/capture activity through the Lattices daemon instead of requiring users
123
+ or agents to remember a second public control plane.
124
+ 6. Keep actors as optional generic Lattices presences, not a required product identity.
125
+ 7. Migrate the useful protocol/runtime ideas without importing every demo,
126
+ composer, or release workflow at once.
127
+
128
+ ## Non-Goals
129
+
130
+ - Do not ship two visible apps as the normal experience.
131
+ - Do not push ScreenCaptureKit recording into a headless-only lifecycle.
132
+ - Do not make Lattices a general cross-platform automation product.
133
+ - Do not absorb Action's composer/export stack before the run/capture/review loop
134
+ is integrated.
135
+ - Do not remove the existing Action repo until Lattices can own the
136
+ important runtime paths.
137
+ - Do not ask users to manage Action.app permissions as part of normal Lattices
138
+ usage.
139
+
140
+ ## Target User Experience
141
+
142
+ The desired experience is:
143
+
144
+ 1. User launches Lattices.
145
+ 2. Lattices shows one permission checklist.
146
+ 3. User opens the palette and chooses `Record Current Window`.
147
+ 4. Lattices starts a run.
148
+ 5. Optional actors or overlays indicate recording or inspection state.
149
+ 6. The run writes media, screenshots, trace events, and receipts into the
150
+ Lattices run store.
151
+ 7. User opens `Review Last Run` from the same app.
152
+ 8. Agents can read the same run through daemon methods.
153
+
154
+ The user should not need to open a second project, remember the `action-dev`
155
+ CLI, or reason about `Action.app` unless they are intentionally working on the
156
+ old Action codebase.
157
+
158
+ ## Permission Model
159
+
160
+ Permissions should be owned by Lattices wherever possible.
161
+
162
+ Lattices already has a real permission assistant for:
163
+
164
+ - Accessibility
165
+ - Screen Recording
166
+ - Automation
167
+ - Input Monitoring
168
+
169
+ The Permissions Assistant should extend its existing capability model with
170
+ capture/review-specific explanations instead of introducing a second prompt
171
+ path.
172
+
173
+ ### TCC Identity
174
+
175
+ macOS privacy permissions are tied to process and bundle identity. That makes
176
+ the integration strategy important:
177
+
178
+ - Long-term recording should run through `Lattices.app` or a clearly bundled
179
+ Lattices helper identity.
180
+ - The old `Action.app` should not be required for normal user-facing capture.
181
+ - If a helper needs separate TCC visibility, the Permissions Assistant must say
182
+ exactly which binary appears in System Settings and why.
183
+ - Diagnostics should log bundle id, executable path, and permission state for
184
+ the component that actually needs access.
185
+
186
+ ### AppKit Lifecycle Boundary
187
+
188
+ Action's recording work found an important constraint: ScreenCaptureKit recording
189
+ is more reliable when the actual recording path runs inside a real AppKit app
190
+ lifecycle.
191
+
192
+ Preserve that constraint by moving the probe pattern, not by flattening it.
193
+
194
+ Recommended shape:
195
+
196
+ ```text
197
+ Lattices.app
198
+ normal mode
199
+ --recording-probe mode
200
+
201
+ Lattices daemon
202
+ accepts run/capture requests
203
+ records plans, receipts, and artifacts
204
+ launches probe mode for recording work when needed
205
+ ```
206
+
207
+ This keeps the lifecycle lesson without requiring a separate visible
208
+ `Action.app`.
209
+
210
+ ## Architecture
211
+
212
+ ### Current Shape
213
+
214
+ ```text
215
+ Lattices.app
216
+ daemon: ws://127.0.0.1:9399
217
+ permissions assistant
218
+ window/session/layer/overlay control
219
+
220
+ Action.app
221
+ agent: ws://127.0.0.1:4319
222
+ capture, recording probe, review loop
223
+ runtime/session/protocol packages
224
+ ```
225
+
226
+ ### Target Shape
227
+
228
+ ```text
229
+ Lattices.app
230
+ daemon: ws://127.0.0.1:9399
231
+ action runtime
232
+ permission assistant
233
+ run/capture/review UI
234
+ recording probe mode
235
+ overlay actor renderer
236
+
237
+ Optional internal helpers
238
+ capture helper
239
+ browser adapter
240
+ scenario/compiler tools
241
+ ```
242
+
243
+ The public API surface should be Lattices. Internal helpers can exist, but they
244
+ should not become another product for the user to operate.
245
+
246
+ ## Data Model
247
+
248
+ Add a run model that complements LAT-005 receipts.
249
+
250
+ ### `RunSession`
251
+
252
+ ```json
253
+ {
254
+ "id": "run_123",
255
+ "title": "Record current window",
256
+ "source": "palette",
257
+ "workspace": {
258
+ "projectPath": "/Users/art/dev/lattices",
259
+ "session": "lattices-abc123"
260
+ },
261
+ "state": "running",
262
+ "startedAt": "2026-05-30T12:00:00Z",
263
+ "completedAt": null,
264
+ "surfaces": [
265
+ {
266
+ "kind": "window",
267
+ "wid": 12345,
268
+ "app": "Lattices"
269
+ }
270
+ ],
271
+ "artifacts": [],
272
+ "receipts": []
273
+ }
274
+ ```
275
+
276
+ ### `RunArtifact`
277
+
278
+ ```json
279
+ {
280
+ "id": "art_123",
281
+ "runId": "run_123",
282
+ "kind": "recording",
283
+ "path": "~/Library/Application Support/Lattices/Runs/run_123/window.mov",
284
+ "mimeType": "video/quicktime",
285
+ "createdAt": "2026-05-30T12:01:00Z",
286
+ "metadata": {
287
+ "width": 1440,
288
+ "height": 900,
289
+ "durationMs": 12000
290
+ }
291
+ }
292
+ ```
293
+
294
+ ### `TraceEvent`
295
+
296
+ ```json
297
+ {
298
+ "id": "trace_123",
299
+ "runId": "run_123",
300
+ "time": "2026-05-30T12:00:03Z",
301
+ "kind": "capture.started",
302
+ "summary": "Started recording current window",
303
+ "data": {
304
+ "wid": 12345,
305
+ "probe": "Lattices.app --recording-probe"
306
+ }
307
+ }
308
+ ```
309
+
310
+ Run receipts should reference LAT-005 execution receipts when actions mutate
311
+ workspace state. For example, a run may include a `window.place` receipt before
312
+ recording begins.
313
+
314
+ ## Daemon API
315
+
316
+ Keep `ws://127.0.0.1:9399` as the user and agent-facing API.
317
+
318
+ Initial additions:
319
+
320
+ | Method | Purpose |
321
+ | --- | --- |
322
+ | `runs.create` | Create a run record and artifact directory |
323
+ | `runs.start` | Start a run from a scenario or direct capture request |
324
+ | `runs.stop` | Stop a running capture or scenario |
325
+ | `runs.list` | List recent runs |
326
+ | `runs.get` | Inspect one run, including receipts and artifacts |
327
+ | `runs.artifacts` | List artifacts for a run |
328
+ | `capture.screenshotWindow` | Capture a window as a run artifact |
329
+ | `capture.screenshotRegion` | Capture a region as a run artifact |
330
+ | `capture.recordWindow` | Record a window through probe mode |
331
+ | `capture.recordRegion` | Record a region through probe mode |
332
+
333
+ Development-only bridge methods may exist while migrating:
334
+
335
+ | Method | Purpose |
336
+ | --- | --- |
337
+ | `action.bridge.status` | Check whether the old Action agent is running |
338
+ | `action.bridge.call` | Proxy a small allowlist of old agent methods |
339
+
340
+ Those bridge methods should be treated as scaffolding, not the destination.
341
+
342
+ ## UI Integration
343
+
344
+ ### Home
345
+
346
+ Add a compact run status area only when relevant:
347
+
348
+ - last run
349
+ - active recording
350
+ - missing permissions
351
+ - recent artifact
352
+
353
+ This should not become a marketing panel. It is operational state.
354
+
355
+ ### Palette
356
+
357
+ Add commands over the same run API:
358
+
359
+ - `Record Current Window`
360
+ - `Screenshot Current Window`
361
+ - `Review Last Run`
362
+ - `Stop Run`
363
+ - `Open Run Artifacts`
364
+
365
+ ### Permissions Assistant
366
+
367
+ Add a capture capability section that explains why capture/review uses:
368
+
369
+ - Screen Recording for screenshots and recordings
370
+ - Accessibility for target resolution and window interaction
371
+ - Automation for app-specific control paths
372
+ - Input Monitoring only when a feature truly requires it
373
+
374
+ The assistant should report which exact component is missing permission.
375
+
376
+ ### Actors
377
+
378
+ Keep actors available as normal Lattices overlay actors.
379
+
380
+ Run/capture states can map onto LAT-004 actor states when a visible presence is
381
+ useful:
382
+
383
+ | Run State | Overlay State |
384
+ | --- | --- |
385
+ | idle | `idle` |
386
+ | observing | `active` |
387
+ | resolving | `thinking` |
388
+ | recording | `active` |
389
+ | waiting for permission | `warning` |
390
+ | failed | `failed` |
391
+ | completed | `success` |
392
+ | reviewing | `review` |
393
+
394
+ The actor should be optional and dismissible. The run/capture contract must not
395
+ depend on a decorative surface being visible.
396
+
397
+ ## Code Migration
398
+
399
+ Move concepts before moving everything.
400
+
401
+ ### Bring Into Lattices Early
402
+
403
+ - generic actor metadata and assets
404
+ - run/session lifecycle concepts
405
+ - artifact and trace event types
406
+ - capture request/response contracts
407
+ - screenshot capture path
408
+ - recording probe pattern
409
+ - review UI ideas
410
+
411
+ ### Bring Later
412
+
413
+ - scenario compiler
414
+ - browser companion
415
+ - composer packages
416
+ - demo rendering scripts
417
+ - release site assets
418
+ - MCP adapter
419
+
420
+ ### Rework Instead Of Copying Directly
421
+
422
+ - `Action.app` shell becomes Lattices run/capture mode
423
+ - old Action agent protocol becomes internal migration scaffolding
424
+ - old CLI commands become Lattices palette, CLI, or daemon commands
425
+ - old docs become migration references, not another documentation tree
426
+
427
+ ## File Ownership
428
+
429
+ Suggested Lattices locations:
430
+
431
+ ```text
432
+ apps/mac/Sources/Core/Runs/
433
+ RunStore.swift
434
+ RunModels.swift
435
+
436
+ apps/mac/Sources/Core/Capture/
437
+ CaptureController.swift
438
+ RecordingProbe.swift
439
+
440
+ apps/mac/Sources/Core/Overlays/Actors/
441
+ actor metadata and bundled assets
442
+
443
+ docs/proposals/
444
+ LAT-006-runs-and-capture-in-lattices.md
445
+
446
+ docs/runs.md
447
+ user-facing capture/review docs once implemented
448
+ ```
449
+
450
+ If TypeScript protocol packages remain useful, add them under a Lattices-owned
451
+ package namespace rather than keeping `action` as the product name.
452
+
453
+ ## Migration Plan
454
+
455
+ ### Phase 1: Product Decision And Bridge
456
+
457
+ - Add this proposal.
458
+ - Cross-link LAT-005 and LAT-006.
459
+ - Define `RunSession`, `RunArtifact`, and `TraceEvent`.
460
+ - Add a dev-only bridge to the old Action agent if useful for experiments.
461
+ - Do not present the bridge as the final user experience.
462
+
463
+ ### Phase 2: One-Permission Screenshot Slice
464
+
465
+ Implement the first real capture feature entirely inside Lattices:
466
+
467
+ ```text
468
+ Screenshot Current Window -> RunSession -> Artifact -> Review
469
+ ```
470
+
471
+ This proves the most important integration point: the user grants Lattices
472
+ permission and receives a run artifact without opening Action.app.
473
+
474
+ ### Phase 3: Recording Probe In Lattices
475
+
476
+ - Port the recording probe pattern.
477
+ - Launch `Lattices.app --recording-probe` for actual recording work.
478
+ - Preserve stop-file, finished-file, and debug-log behavior.
479
+ - Store outputs in the Lattices run directory.
480
+
481
+ ### Phase 4: Review UI
482
+
483
+ - Add a lightweight run library.
484
+ - Show screenshots, recordings, trace events, and action receipts.
485
+ - Link each artifact back to the workspace/window/session context.
486
+
487
+ ### Phase 5: Surface Adapters
488
+
489
+ - Bring over AX/browser/native surface adapter concepts.
490
+ - Let `actions.plan` and `runs.start` share target resolution confidence.
491
+ - Keep coordinate fallback visible in receipts.
492
+
493
+ ### Phase 6: Scenarios And Composer
494
+
495
+ - Bring scenario compilation only after manual capture and review feel solid.
496
+ - Keep composition/export optional and downstream from the run store.
497
+
498
+ ## Immediate Slice
499
+
500
+ The smallest meaningful integration is:
501
+
502
+ ```text
503
+ Record a screenshot of the current window as a run inside Lattices.
504
+ ```
505
+
506
+ Required pieces:
507
+
508
+ - `RunSession` model
509
+ - artifact directory under Lattices application support
510
+ - `capture.screenshotWindow`
511
+ - palette command
512
+ - permission receipt
513
+ - recent-run review surface
514
+ - optional actor state change
515
+
516
+ This avoids the two-app permission problem from the start and gives the product
517
+ a concrete user-facing capture feature before the heavier recording probe is
518
+ ported.
519
+
520
+ ## Open Questions
521
+
522
+ ### Should Actors Stay?
523
+
524
+ Recommendation: yes, as generic presences. Retire Mira as the product name, but
525
+ keep actors/pets available for agent, run, app, and task presence.
526
+
527
+ ### Should The Old Action Agent Port Stay?
528
+
529
+ Recommendation: temporarily. It can accelerate migration, but the stable public
530
+ surface should be the Lattices daemon on `9399`.
531
+
532
+ ### Should Lattices Ship A Separate Helper App?
533
+
534
+ Recommendation: avoid this unless needed. Prefer `Lattices.app` probe mode so
535
+ the user's permission story stays simple.
536
+
537
+ ### Where Should Runs Live?
538
+
539
+ Recommendation:
540
+
541
+ ```text
542
+ ~/Library/Application Support/Lattices/Runs/
543
+ ```
544
+
545
+ This keeps artifacts out of project repos unless the user explicitly exports
546
+ them.
547
+
548
+ ### Should Recording Be First?
549
+
550
+ Recommendation: no. Start with screenshots and run artifacts. Then port
551
+ recording once the run store and review loop exist.
552
+
553
+ ## Success Criteria
554
+
555
+ This proposal is successful when:
556
+
557
+ - the user sees runs and capture as part of Lattices, not as another app to remember
558
+ - the normal capture path asks for Lattices permissions, not Action.app
559
+ - a palette command can create a run artifact from the current window
560
+ - run artifacts are reviewable inside Lattices
561
+ - action receipts and run traces can reference each other
562
+ - actors can reflect run state without owning the run contract
563
+ - recording uses a real AppKit lifecycle without requiring a separate visible
564
+ product
565
+ - the old Action repo can eventually become a migration source, not an active
566
+ parallel product