@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.
- package/LICENSE +21 -0
- package/README.md +144 -69
- package/apps/mac/Info.plist +43 -0
- package/apps/mac/Lattices.app/Contents/Info.plist +43 -0
- package/apps/mac/Lattices.app/Contents/MacOS/Lattices +0 -0
- package/apps/mac/Lattices.app/Contents/Resources/AppIcon.icns +0 -0
- package/apps/mac/Lattices.app/Contents/Resources/docs/assistant-knowledge.md +130 -0
- package/apps/mac/Lattices.app/Contents/Resources/tap.wav +0 -0
- package/apps/mac/Lattices.app/Contents/_CodeSignature/CodeResources +150 -0
- package/apps/mac/Lattices.entitlements +21 -0
- package/apps/mac/Resources/Pets/assistant-spark/pet.json +62 -0
- package/apps/mac/Resources/Pets/assistant-spark/spritesheet.webp +0 -0
- package/apps/mac/Resources/Pets/scout-ranger/pet.json +6 -0
- package/apps/mac/Resources/Pets/scout-ranger/spritesheet.webp +0 -0
- package/apps/mac/Resources/tap.wav +0 -0
- package/assets/AppIcon.icns +0 -0
- package/bin/assistant-intelligence.ts +912 -0
- package/bin/cli/capture.ts +252 -0
- package/bin/cli/daemon.ts +22 -0
- package/bin/cli/helpers.ts +105 -0
- package/bin/cli/layer.ts +178 -0
- package/bin/cli/runs.ts +43 -0
- package/bin/cli/search.ts +141 -0
- package/bin/cli/session.ts +32 -0
- package/bin/client.ts +17 -0
- package/bin/cua.ts +26 -0
- package/bin/{daemon-client.js → daemon-client.ts} +49 -30
- package/bin/handsoff-infer.ts +96 -0
- package/bin/handsoff-worker.ts +531 -0
- package/bin/infer.ts +424 -0
- package/bin/keychain.ts +75 -0
- package/bin/lattices-app.ts +655 -0
- package/bin/lattices-build +125 -0
- package/bin/lattices-build-env.ts +77 -0
- package/bin/lattices-dev +362 -0
- package/bin/lattices.ts +3260 -0
- 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 +233 -0
- package/docs/ai-chat-ux-review.md +416 -0
- package/docs/api.md +1041 -47
- package/docs/app.md +96 -13
- package/docs/assistant-knowledge.md +130 -0
- package/docs/companion-deck.md +209 -0
- package/docs/component-extraction-roadmap.md +392 -0
- package/docs/concepts.md +13 -12
- package/docs/config.md +83 -10
- package/docs/gesture-customization-proposal.md +520 -0
- package/docs/handsoff-test-scenarios.md +84 -0
- package/docs/hyperspace-grid-snappiness.md +210 -0
- package/docs/layers.md +176 -28
- package/docs/mouse-gestures.md +244 -0
- package/docs/ocr.md +21 -9
- package/docs/overview.md +42 -23
- package/docs/presentation-execution-review.md +491 -0
- package/docs/prompts/hands-off-system.md +382 -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/proposals/LAT-001-gesture-visual-customization.md +522 -0
- package/docs/proposals/LAT-002-shared-overlay-canvas.md +353 -0
- package/docs/proposals/LAT-003-menu-bar-controller-architecture.md +291 -0
- package/docs/proposals/LAT-004-interactive-overlay-actors.md +534 -0
- package/docs/proposals/LAT-005-action-runtime-product-spine.md +914 -0
- package/docs/proposals/LAT-006-followup-gaps.md +103 -0
- package/docs/proposals/LAT-006-runs-and-capture-in-lattices.md +566 -0
- package/docs/proposals/LAT-007-unified-app-shell.md +128 -0
- package/docs/quickstart.md +8 -12
- package/docs/reference/dewey.config.ts +74 -0
- package/docs/reference/install-agent.md +79 -0
- package/docs/release.md +172 -0
- package/docs/repo-structure.md +100 -0
- package/docs/terminal-kit.md +87 -0
- package/docs/tiling-reference.md +224 -0
- package/docs/twins.md +138 -0
- package/docs/voice-command-protocol.md +278 -0
- package/docs/voice-error-model.md +73 -0
- package/docs/voice.md +221 -0
- package/package.json +69 -16
- package/packages/npm/sdk/cua.d.mts +1 -0
- package/packages/npm/sdk/cua.d.ts +188 -0
- package/packages/npm/sdk/cua.mjs +376 -0
- package/app/Lattices.app/Contents/Info.plist +0 -24
- package/app/Package.swift +0 -13
- package/app/Sources/ActionRow.swift +0 -61
- package/app/Sources/App.swift +0 -10
- package/app/Sources/AppDelegate.swift +0 -234
- package/app/Sources/AppShellView.swift +0 -62
- package/app/Sources/AppTypeClassifier.swift +0 -70
- package/app/Sources/AppWindowShell.swift +0 -63
- package/app/Sources/CheatSheetHUD.swift +0 -332
- package/app/Sources/CommandModeState.swift +0 -1362
- package/app/Sources/CommandModeView.swift +0 -1405
- package/app/Sources/CommandModeWindow.swift +0 -192
- package/app/Sources/CommandPaletteView.swift +0 -307
- package/app/Sources/CommandPaletteWindow.swift +0 -134
- package/app/Sources/DaemonProtocol.swift +0 -101
- package/app/Sources/DaemonServer.swift +0 -414
- package/app/Sources/DesktopModel.swift +0 -121
- package/app/Sources/DesktopModelTypes.swift +0 -71
- package/app/Sources/DiagnosticLog.swift +0 -271
- package/app/Sources/EventBus.swift +0 -30
- package/app/Sources/HotkeyManager.swift +0 -250
- package/app/Sources/HotkeyStore.swift +0 -338
- package/app/Sources/InventoryManager.swift +0 -35
- package/app/Sources/InventoryPath.swift +0 -43
- package/app/Sources/KeyRecorderView.swift +0 -210
- package/app/Sources/LatticesApi.swift +0 -1125
- package/app/Sources/MainView.swift +0 -467
- package/app/Sources/MainWindow.swift +0 -83
- package/app/Sources/OcrModel.swift +0 -309
- package/app/Sources/OcrStore.swift +0 -295
- package/app/Sources/OmniSearchState.swift +0 -283
- package/app/Sources/OmniSearchView.swift +0 -288
- package/app/Sources/OmniSearchWindow.swift +0 -105
- package/app/Sources/OrphanRow.swift +0 -129
- package/app/Sources/PaletteCommand.swift +0 -419
- package/app/Sources/PermissionChecker.swift +0 -125
- package/app/Sources/Preferences.swift +0 -92
- package/app/Sources/ProcessModel.swift +0 -199
- package/app/Sources/ProcessQuery.swift +0 -151
- package/app/Sources/Project.swift +0 -28
- package/app/Sources/ProjectRow.swift +0 -368
- package/app/Sources/ProjectScanner.swift +0 -121
- package/app/Sources/ScreenMapState.swift +0 -2387
- package/app/Sources/ScreenMapView.swift +0 -2820
- package/app/Sources/ScreenMapWindowController.swift +0 -89
- package/app/Sources/SessionManager.swift +0 -72
- package/app/Sources/SettingsView.swift +0 -1053
- package/app/Sources/SettingsWindow.swift +0 -20
- package/app/Sources/TabGroupRow.swift +0 -178
- package/app/Sources/Terminal.swift +0 -259
- package/app/Sources/TerminalQuery.swift +0 -156
- package/app/Sources/TerminalSynthesizer.swift +0 -200
- package/app/Sources/Theme.swift +0 -163
- package/app/Sources/TilePickerView.swift +0 -209
- package/app/Sources/TmuxModel.swift +0 -53
- package/app/Sources/TmuxQuery.swift +0 -81
- package/app/Sources/WindowTiler.swift +0 -1755
- package/app/Sources/WorkspaceManager.swift +0 -434
- package/bin/lattices-app.js +0 -221
- 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
|