@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.
- package/LICENSE +21 -0
- package/README.md +172 -86
- 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,914 @@
|
|
|
1
|
+
# LAT-005: Action Runtime and Product Spine
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Proposed.
|
|
6
|
+
|
|
7
|
+
## Summary
|
|
8
|
+
|
|
9
|
+
Lattices already has the pieces of a programmable workspace: a CLI,
|
|
10
|
+
native macOS app, daemon API, command palette, HUD, voice, hands-off mode,
|
|
11
|
+
screen search, overlays, session layers, tab groups, and a companion deck
|
|
12
|
+
contract.
|
|
13
|
+
|
|
14
|
+
What is missing is the product and execution spine that makes those pieces
|
|
15
|
+
feel like one system.
|
|
16
|
+
|
|
17
|
+
This proposal introduces an **Action Runtime** as the shared path for
|
|
18
|
+
planning, executing, explaining, and later undoing workspace mutations.
|
|
19
|
+
Every control surface should become a client of this runtime:
|
|
20
|
+
|
|
21
|
+
- CLI
|
|
22
|
+
- daemon RPC
|
|
23
|
+
- command palette
|
|
24
|
+
- hotkeys and HUD
|
|
25
|
+
- local voice
|
|
26
|
+
- hands-off voice
|
|
27
|
+
- companion deck
|
|
28
|
+
- future automations
|
|
29
|
+
|
|
30
|
+
The goal is not to add another large feature surface. The goal is to make
|
|
31
|
+
existing surfaces converge on the same action model:
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
input -> canonical action -> plan -> execute -> verify -> receipt -> history
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Collaboration Notes
|
|
38
|
+
|
|
39
|
+
This proposal was drafted from three Codex subagent review lanes:
|
|
40
|
+
|
|
41
|
+
- **Product/UX review**: shipped capabilities, missing product cohesion,
|
|
42
|
+
and user-facing priorities.
|
|
43
|
+
- **Architecture/API review**: action runtime, endpoint shape, module
|
|
44
|
+
boundaries, and migration risks.
|
|
45
|
+
- **Verification/release review**: test coverage, CI gaps, packaging,
|
|
46
|
+
docs truth, and operational readiness.
|
|
47
|
+
|
|
48
|
+
No Scout coordination was used.
|
|
49
|
+
|
|
50
|
+
## Current Strengths
|
|
51
|
+
|
|
52
|
+
Lattices does not need a new north star. The current product already has a
|
|
53
|
+
strong one: make the Mac workspace observable and controllable.
|
|
54
|
+
|
|
55
|
+
Important shipped strengths:
|
|
56
|
+
|
|
57
|
+
- Persistent tmux workspaces with config, sync, restart, tab groups, and
|
|
58
|
+
session naming shared by CLI and app.
|
|
59
|
+
- A native macOS app with project discovery, menu bar control, command
|
|
60
|
+
palette, settings, onboarding, permission guidance, and hotkeys.
|
|
61
|
+
- Window inventory, session title tags, Spaces support, tiling, drag snap,
|
|
62
|
+
screen map, OCR/search, and fallback paths through CG, AX, and AppleScript.
|
|
63
|
+
- A daemon with typed read and mutation endpoints, `api.schema`, and a
|
|
64
|
+
Node client for agents and scripts.
|
|
65
|
+
- Emerging canonical mutations: `window.place`, `layer.activate`, and
|
|
66
|
+
`space.optimize`.
|
|
67
|
+
- Overlay primitives for transient visual feedback and persistent actors.
|
|
68
|
+
- Voice and hands-off flows that can interpret natural language into
|
|
69
|
+
workspace actions.
|
|
70
|
+
- A companion deck contract and local bridge that can expose Lattices to
|
|
71
|
+
iPhone/iPad surfaces.
|
|
72
|
+
- Useful security instincts: explicit permissions, local-first daemon,
|
|
73
|
+
opt-in OCR, scoped companion pairing, and capability checks.
|
|
74
|
+
|
|
75
|
+
The product is broad enough for a serious beta. The next step is cohesion.
|
|
76
|
+
|
|
77
|
+
## Problem
|
|
78
|
+
|
|
79
|
+
The UX is ahead of the execution model.
|
|
80
|
+
|
|
81
|
+
Lattices has many capable surfaces, but they do not yet all share one
|
|
82
|
+
meaning for "do this workspace action." The result is a product that can
|
|
83
|
+
feel powerful but uneven:
|
|
84
|
+
|
|
85
|
+
- The command palette, HUD, voice, daemon, companion, and CLI can reach
|
|
86
|
+
similar outcomes through different code paths.
|
|
87
|
+
- `window.place`, `layer.activate`, and `space.optimize` exist, but the
|
|
88
|
+
deeper runtime behind them is still thin.
|
|
89
|
+
- Receipts often say the action was accepted or queued, but not always
|
|
90
|
+
what changed, what frame was computed, whether the move verified, or why
|
|
91
|
+
a target was chosen.
|
|
92
|
+
- Targeting is strong for explicit `wid` and lattices session tags, but
|
|
93
|
+
generic app/title matching still needs confidence, ambiguity handling,
|
|
94
|
+
previews, and user-facing explanation.
|
|
95
|
+
- Layers and groups exist, but saved workspace recipes, editable rules,
|
|
96
|
+
semantic layout strategies, drift recovery, and undo-ready history are
|
|
97
|
+
not yet first-class product objects.
|
|
98
|
+
- The docs describe a canonical model, but the implementation is not yet
|
|
99
|
+
fully centralized around it.
|
|
100
|
+
- Test and release workflows do not yet verify the full product contract.
|
|
101
|
+
|
|
102
|
+
In short: Lattices has enough surfaces. It needs one action spine.
|
|
103
|
+
|
|
104
|
+
## Goals
|
|
105
|
+
|
|
106
|
+
1. Make the daemon-backed action runtime the canonical mutation boundary.
|
|
107
|
+
2. Let all major surfaces compile into the same canonical action request.
|
|
108
|
+
3. Support dry-run planning before side effects.
|
|
109
|
+
4. Return structured receipts with target resolution, computed frames,
|
|
110
|
+
applied mutations, failures, and trace entries.
|
|
111
|
+
5. Record action history as the substrate for explanations, debugging, and
|
|
112
|
+
limited undo.
|
|
113
|
+
6. Add a shared target resolver with confidence and ambiguity policy.
|
|
114
|
+
7. Keep existing endpoint names working as compatibility wrappers.
|
|
115
|
+
8. Make product surfaces easier to explain: launcher, inventory, layout,
|
|
116
|
+
assistant, and companion should all feel like views over the same system.
|
|
117
|
+
9. Add verification and release gates that keep docs, API behavior, package
|
|
118
|
+
contents, and shipped app claims truthful.
|
|
119
|
+
|
|
120
|
+
## Non-Goals
|
|
121
|
+
|
|
122
|
+
- Do not build a fully autonomous desktop planner in the first version.
|
|
123
|
+
- Do not promise full undo for every side effect. Start with window geometry.
|
|
124
|
+
- Do not rewrite `WindowTiler` in one pass.
|
|
125
|
+
- Do not remove existing daemon endpoints or CLI commands.
|
|
126
|
+
- Do not replace command palette, HUD, voice, or companion UX. Make them
|
|
127
|
+
thinner clients of the shared runtime.
|
|
128
|
+
- Do not make OCR, AI, or companion control mandatory.
|
|
129
|
+
|
|
130
|
+
## Product Model
|
|
131
|
+
|
|
132
|
+
The product should be presented as a programmable workspace control plane,
|
|
133
|
+
not as a fully autonomous desktop agent.
|
|
134
|
+
|
|
135
|
+
The user-facing loop should be:
|
|
136
|
+
|
|
137
|
+
1. **Ask or act**
|
|
138
|
+
- A user presses a hotkey, chooses a palette command, speaks, uses the
|
|
139
|
+
companion, or calls the daemon.
|
|
140
|
+
2. **Plan**
|
|
141
|
+
- Lattices resolves targets, computes placements, finds missing projects
|
|
142
|
+
or windows, and explains ambiguity before mutation where possible.
|
|
143
|
+
3. **Execute**
|
|
144
|
+
- The runtime applies moves, launches sessions, focuses windows, or
|
|
145
|
+
activates layers through one executor.
|
|
146
|
+
4. **Receipt**
|
|
147
|
+
- The surface shows what happened, why it happened, and any failures.
|
|
148
|
+
5. **History**
|
|
149
|
+
- The action is inspectable and, when safe, undoable.
|
|
150
|
+
|
|
151
|
+
### Product Surfaces
|
|
152
|
+
|
|
153
|
+
The existing surfaces should have clearer roles:
|
|
154
|
+
|
|
155
|
+
| Surface | Role |
|
|
156
|
+
| --- | --- |
|
|
157
|
+
| Home | Status, health, active workspaces, suggested next action |
|
|
158
|
+
| Palette | Fast command launcher over canonical actions |
|
|
159
|
+
| Search / Inventory | Find windows, sessions, projects, text, and targets |
|
|
160
|
+
| Layout / Screen Map | Visual planning and editing for windows, layers, and recipes |
|
|
161
|
+
| HUD / Hotkeys | Fast tactile control for common actions |
|
|
162
|
+
| Voice / Hands-off | Natural-language action extraction and confirmation |
|
|
163
|
+
| Assistant | Planner, explainer, and recovery helper |
|
|
164
|
+
| Companion | Remote control surface over the same action contract |
|
|
165
|
+
| CLI / Daemon | Scriptable and agent-facing transports |
|
|
166
|
+
|
|
167
|
+
This keeps the app broad without making every surface invent its own rules.
|
|
168
|
+
|
|
169
|
+
## Proposed Action Runtime
|
|
170
|
+
|
|
171
|
+
Add a new runtime under:
|
|
172
|
+
|
|
173
|
+
```text
|
|
174
|
+
apps/mac/Sources/Core/Actions/Execution/
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Initial modules:
|
|
178
|
+
|
|
179
|
+
| Module | Responsibility |
|
|
180
|
+
| --- | --- |
|
|
181
|
+
| `ActionRegistry` | Canonical verbs, params, aliases, phrase hints, labels, and source support |
|
|
182
|
+
| `ActionPlanner` | Resolve targets and compute plans without side effects |
|
|
183
|
+
| `ActionExecutor` | Commit plans, verify outcomes, record receipts |
|
|
184
|
+
| `ActionHistoryStore` | Recent receipts, undo tokens, diagnostics, and inspection |
|
|
185
|
+
| `WindowTargetResolver` | Resolve `wid`, session, app/title, frontmost, selection, and query targets |
|
|
186
|
+
| `WindowPresenter` | Own move, resize, raise, activate, mark-interaction, and verification flow |
|
|
187
|
+
| `LayerActivationPlanner` | Extract planning from `WorkspaceManager.tileLayer` |
|
|
188
|
+
| `SpaceOptimizationPlanner` | Plan balanced/mosaic/grid arrangements before applying them |
|
|
189
|
+
|
|
190
|
+
`PlacementSpec` should remain the shared placement grammar. It is already
|
|
191
|
+
the right seed: named tiles, grids, and fractional placements all compile
|
|
192
|
+
into one typed model.
|
|
193
|
+
|
|
194
|
+
### Core Types
|
|
195
|
+
|
|
196
|
+
#### `ActionRequest`
|
|
197
|
+
|
|
198
|
+
```json
|
|
199
|
+
{
|
|
200
|
+
"requestId": "req_123",
|
|
201
|
+
"source": "voice",
|
|
202
|
+
"actions": [
|
|
203
|
+
{
|
|
204
|
+
"id": "act_123",
|
|
205
|
+
"type": "window.place",
|
|
206
|
+
"target": { "kind": "frontmost" },
|
|
207
|
+
"args": {
|
|
208
|
+
"placement": { "kind": "tile", "value": "top-right" },
|
|
209
|
+
"display": "current"
|
|
210
|
+
},
|
|
211
|
+
"policy": {
|
|
212
|
+
"ambiguity": "fail",
|
|
213
|
+
"verify": true
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
]
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
#### `ActionPlan`
|
|
221
|
+
|
|
222
|
+
```json
|
|
223
|
+
{
|
|
224
|
+
"planId": "plan_123",
|
|
225
|
+
"requestId": "req_123",
|
|
226
|
+
"status": "ready",
|
|
227
|
+
"resolvedTargets": [
|
|
228
|
+
{
|
|
229
|
+
"input": { "kind": "frontmost" },
|
|
230
|
+
"resolution": "wid",
|
|
231
|
+
"wid": 38192,
|
|
232
|
+
"app": "Google Chrome",
|
|
233
|
+
"title": "Docs",
|
|
234
|
+
"confidence": 1.0,
|
|
235
|
+
"reason": "frontmost window"
|
|
236
|
+
}
|
|
237
|
+
],
|
|
238
|
+
"computedFrames": [
|
|
239
|
+
{
|
|
240
|
+
"wid": 38192,
|
|
241
|
+
"placement": { "kind": "tile", "value": "top-right" },
|
|
242
|
+
"frame": { "x": 960, "y": 25, "w": 960, "h": 527 }
|
|
243
|
+
}
|
|
244
|
+
],
|
|
245
|
+
"steps": [
|
|
246
|
+
{ "kind": "placeWindow", "wid": 38192 }
|
|
247
|
+
],
|
|
248
|
+
"trace": [
|
|
249
|
+
{
|
|
250
|
+
"phase": "target.resolve",
|
|
251
|
+
"code": "frontmost",
|
|
252
|
+
"message": "Resolved target to the frontmost window"
|
|
253
|
+
}
|
|
254
|
+
]
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
#### `ExecutionReceipt`
|
|
259
|
+
|
|
260
|
+
```json
|
|
261
|
+
{
|
|
262
|
+
"receiptId": "exec_123",
|
|
263
|
+
"requestId": "req_123",
|
|
264
|
+
"planId": "plan_123",
|
|
265
|
+
"status": "ok",
|
|
266
|
+
"applied": [
|
|
267
|
+
{
|
|
268
|
+
"kind": "window.place",
|
|
269
|
+
"wid": 38192,
|
|
270
|
+
"before": { "x": 120, "y": 80, "w": 1280, "h": 900 },
|
|
271
|
+
"after": { "x": 960, "y": 25, "w": 960, "h": 527 },
|
|
272
|
+
"verified": true
|
|
273
|
+
}
|
|
274
|
+
],
|
|
275
|
+
"failures": [],
|
|
276
|
+
"trace": [
|
|
277
|
+
{
|
|
278
|
+
"phase": "execute.placeWindow",
|
|
279
|
+
"code": "ax.move.verified",
|
|
280
|
+
"message": "Moved and verified the target frame"
|
|
281
|
+
}
|
|
282
|
+
],
|
|
283
|
+
"undoToken": "undo_123"
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Trace entries should be structured objects, not only strings. They are
|
|
288
|
+
product data: users and agents should be able to ask why an action happened.
|
|
289
|
+
|
|
290
|
+
### Status Semantics
|
|
291
|
+
|
|
292
|
+
`actions.execute` should support four statuses:
|
|
293
|
+
|
|
294
|
+
| Status | Meaning |
|
|
295
|
+
| --- | --- |
|
|
296
|
+
| `ok` | All planned mutations applied and verified |
|
|
297
|
+
| `partial` | Some mutations applied, some failed or are pending |
|
|
298
|
+
| `failed` | No meaningful mutation applied |
|
|
299
|
+
| `accepted` | Long-running work was queued, such as launching missing projects |
|
|
300
|
+
|
|
301
|
+
Window placement can usually return `ok` or `failed` quickly. Layer
|
|
302
|
+
activation may need `accepted` or `partial` because project launches and
|
|
303
|
+
post-launch tiling are asynchronous.
|
|
304
|
+
|
|
305
|
+
## Proposed Daemon Endpoints
|
|
306
|
+
|
|
307
|
+
Add these endpoints while keeping existing names stable.
|
|
308
|
+
|
|
309
|
+
### `actions.catalog`
|
|
310
|
+
|
|
311
|
+
Returns canonical actions, params, target kinds, compatibility aliases,
|
|
312
|
+
surface labels, and phrase hints.
|
|
313
|
+
|
|
314
|
+
Uses:
|
|
315
|
+
|
|
316
|
+
- command palette generation
|
|
317
|
+
- voice/hands-off prompt assembly
|
|
318
|
+
- companion manifest alignment
|
|
319
|
+
- docs generation and API truth checks
|
|
320
|
+
|
|
321
|
+
### `actions.plan`
|
|
322
|
+
|
|
323
|
+
Dry-run action planning. No side effects.
|
|
324
|
+
|
|
325
|
+
Responsibilities:
|
|
326
|
+
|
|
327
|
+
- resolve targets
|
|
328
|
+
- compute frames
|
|
329
|
+
- expand layer and space actions into steps
|
|
330
|
+
- detect ambiguity
|
|
331
|
+
- report missing permissions
|
|
332
|
+
- return warnings and trace entries
|
|
333
|
+
|
|
334
|
+
### `actions.execute`
|
|
335
|
+
|
|
336
|
+
Primary mutation endpoint.
|
|
337
|
+
|
|
338
|
+
Responsibilities:
|
|
339
|
+
|
|
340
|
+
- accept one action or a batch
|
|
341
|
+
- optionally run `actions.plan` first
|
|
342
|
+
- apply side effects through the executor
|
|
343
|
+
- verify when feasible
|
|
344
|
+
- record an execution receipt
|
|
345
|
+
- return `ok`, `partial`, `failed`, or `accepted`
|
|
346
|
+
|
|
347
|
+
Important options:
|
|
348
|
+
|
|
349
|
+
```json
|
|
350
|
+
{
|
|
351
|
+
"dryRun": false,
|
|
352
|
+
"atomic": false,
|
|
353
|
+
"verify": true,
|
|
354
|
+
"timeoutMs": 1500,
|
|
355
|
+
"source": "daemon"
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### `actions.history`
|
|
360
|
+
|
|
361
|
+
Returns recent receipts filtered by:
|
|
362
|
+
|
|
363
|
+
- action type
|
|
364
|
+
- source
|
|
365
|
+
- window id
|
|
366
|
+
- session
|
|
367
|
+
- project
|
|
368
|
+
- status
|
|
369
|
+
|
|
370
|
+
This powers diagnostics, user explanation, and undo.
|
|
371
|
+
|
|
372
|
+
### `actions.undo`
|
|
373
|
+
|
|
374
|
+
Define the contract now, ship narrowly later.
|
|
375
|
+
|
|
376
|
+
Initial undo scope:
|
|
377
|
+
|
|
378
|
+
- restore window frames for `window.place`
|
|
379
|
+
- restore window frames for `space.optimize`
|
|
380
|
+
|
|
381
|
+
Deferred undo scope:
|
|
382
|
+
|
|
383
|
+
- launches
|
|
384
|
+
- kills
|
|
385
|
+
- app opens
|
|
386
|
+
- session mutation
|
|
387
|
+
- Space movement
|
|
388
|
+
- layer membership changes
|
|
389
|
+
|
|
390
|
+
## Compatibility Wrappers
|
|
391
|
+
|
|
392
|
+
Existing endpoints should stay, but route internally through the runtime.
|
|
393
|
+
|
|
394
|
+
| Existing endpoint | Runtime mapping |
|
|
395
|
+
| --- | --- |
|
|
396
|
+
| `window.place` | `actions.execute(type=window.place)` |
|
|
397
|
+
| `window.tile` | Compatibility wrapper for `window.place` |
|
|
398
|
+
| `window.focus` | `actions.execute(type=window.focus)` |
|
|
399
|
+
| `window.present` | `actions.execute(type=window.present)` |
|
|
400
|
+
| `space.optimize` | `actions.execute(type=space.optimize)` |
|
|
401
|
+
| `layout.distribute` | Compatibility wrapper for `space.optimize` |
|
|
402
|
+
| `layer.activate` | `actions.execute(type=layer.activate)` |
|
|
403
|
+
| `layer.switch` | Compatibility wrapper for `layer.activate` |
|
|
404
|
+
| `intents.execute` | Translator from old intent names to canonical action types |
|
|
405
|
+
| `deck.perform` | Companion action wrapper around runtime receipts |
|
|
406
|
+
|
|
407
|
+
CLI commands should prefer the daemon/runtime path when available and keep
|
|
408
|
+
direct AppleScript or local fallbacks only for daemon-unavailable scenarios.
|
|
409
|
+
|
|
410
|
+
## Target Resolution
|
|
411
|
+
|
|
412
|
+
Target resolution is the largest user-facing trust issue.
|
|
413
|
+
|
|
414
|
+
Create `WindowTargetResolver` as the single resolver for:
|
|
415
|
+
|
|
416
|
+
- `wid`
|
|
417
|
+
- lattices session name
|
|
418
|
+
- app name
|
|
419
|
+
- app plus title substring
|
|
420
|
+
- frontmost window
|
|
421
|
+
- current selection
|
|
422
|
+
- query result
|
|
423
|
+
- layer member
|
|
424
|
+
- project/session relation
|
|
425
|
+
|
|
426
|
+
Every resolution should return:
|
|
427
|
+
|
|
428
|
+
- resolved target
|
|
429
|
+
- confidence
|
|
430
|
+
- reason
|
|
431
|
+
- ambiguity candidates when applicable
|
|
432
|
+
- permissions or data sources used
|
|
433
|
+
|
|
434
|
+
Default policies:
|
|
435
|
+
|
|
436
|
+
| Source | Ambiguous app target policy |
|
|
437
|
+
| --- | --- |
|
|
438
|
+
| daemon/script/agent | fail with candidates |
|
|
439
|
+
| CLI interactive | choose top candidate only with clear output, or ask later |
|
|
440
|
+
| voice | prefer frontmost matching app, otherwise fail with prompt |
|
|
441
|
+
| HUD/hotkey | prefer current/frontmost context |
|
|
442
|
+
| companion | prefer explicit selected item |
|
|
443
|
+
|
|
444
|
+
The receipt must always say which policy was used.
|
|
445
|
+
|
|
446
|
+
## Layers, Rules, and Recipes
|
|
447
|
+
|
|
448
|
+
Layers and groups should become editable workspace recipes rather than only
|
|
449
|
+
config records or runtime snapshots.
|
|
450
|
+
|
|
451
|
+
First-class concepts:
|
|
452
|
+
|
|
453
|
+
- **Layer**: named workspace context with projects, apps, windows, rules, and
|
|
454
|
+
preferred layout.
|
|
455
|
+
- **Rule**: target matching plus intended placement or display.
|
|
456
|
+
- **Recipe**: saved arrangement that can be planned, applied, reconciled, and
|
|
457
|
+
inspected.
|
|
458
|
+
- **Drift**: current workspace differs from the recipe.
|
|
459
|
+
- **Reconcile**: plan and apply the smallest useful recovery.
|
|
460
|
+
|
|
461
|
+
This extends existing workspace layers and session layers rather than
|
|
462
|
+
replacing them.
|
|
463
|
+
|
|
464
|
+
Initial rule examples:
|
|
465
|
+
|
|
466
|
+
```json
|
|
467
|
+
{
|
|
468
|
+
"target": { "kind": "session", "name": "frontend-a1b2c3" },
|
|
469
|
+
"placement": { "kind": "tile", "value": "left" },
|
|
470
|
+
"display": 0
|
|
471
|
+
}
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
```json
|
|
475
|
+
{
|
|
476
|
+
"target": { "kind": "appTitle", "app": "Google Chrome", "title": "localhost" },
|
|
477
|
+
"placement": { "kind": "tile", "value": "right" },
|
|
478
|
+
"policy": { "ambiguity": "fail" }
|
|
479
|
+
}
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
`layer.activate` should produce a plan containing:
|
|
483
|
+
|
|
484
|
+
- running windows
|
|
485
|
+
- missing projects
|
|
486
|
+
- apps to launch
|
|
487
|
+
- windows to move
|
|
488
|
+
- placements to compute
|
|
489
|
+
- fallbacks
|
|
490
|
+
- post-launch pending steps
|
|
491
|
+
- failures
|
|
492
|
+
|
|
493
|
+
## Surface Migration
|
|
494
|
+
|
|
495
|
+
### CLI
|
|
496
|
+
|
|
497
|
+
Move these commands to the runtime path first:
|
|
498
|
+
|
|
499
|
+
- `lattices place`
|
|
500
|
+
- `lattices tile`
|
|
501
|
+
- `lattices distribute`
|
|
502
|
+
- `lattices layer`
|
|
503
|
+
|
|
504
|
+
Keep direct local tiling only as a fallback when the daemon is unavailable.
|
|
505
|
+
|
|
506
|
+
### Command Palette
|
|
507
|
+
|
|
508
|
+
Palette rows should become bindings of:
|
|
509
|
+
|
|
510
|
+
```text
|
|
511
|
+
ActionID + TargetRef + Args
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
Palette remains a fast launcher, but stops owning execution semantics.
|
|
515
|
+
|
|
516
|
+
### HUD and Hotkeys
|
|
517
|
+
|
|
518
|
+
HUD can keep its tactile cockpit behavior. The change is that key routing
|
|
519
|
+
should emit runtime actions instead of privately computing layouts.
|
|
520
|
+
|
|
521
|
+
HUD may still provide source-specific policy:
|
|
522
|
+
|
|
523
|
+
- target frontmost window
|
|
524
|
+
- use current display
|
|
525
|
+
- prefer low-latency execution
|
|
526
|
+
|
|
527
|
+
But placement, target resolution, receipt, and history should be shared.
|
|
528
|
+
|
|
529
|
+
### Voice and Hands-off
|
|
530
|
+
|
|
531
|
+
Voice should do interpretation, not execution policy.
|
|
532
|
+
|
|
533
|
+
Local voice:
|
|
534
|
+
|
|
535
|
+
- transcript cleanup
|
|
536
|
+
- intent/action extraction
|
|
537
|
+
- slot extraction
|
|
538
|
+
- confidence and confirmation UX
|
|
539
|
+
|
|
540
|
+
Runtime:
|
|
541
|
+
|
|
542
|
+
- target resolution
|
|
543
|
+
- planning
|
|
544
|
+
- execution
|
|
545
|
+
- receipt
|
|
546
|
+
- history
|
|
547
|
+
|
|
548
|
+
Hands-off worker output should be canonical actions, not a second grammar
|
|
549
|
+
that Swift reinterprets through another matcher.
|
|
550
|
+
|
|
551
|
+
### Companion Deck
|
|
552
|
+
|
|
553
|
+
`deck.perform` should include action receipts in its `ActionOutcome`.
|
|
554
|
+
|
|
555
|
+
The companion bridge should authorize action families, not blanket mutation
|
|
556
|
+
access. Example capability families:
|
|
557
|
+
|
|
558
|
+
- `actions.read`
|
|
559
|
+
- `actions.window`
|
|
560
|
+
- `actions.layer`
|
|
561
|
+
- `actions.session`
|
|
562
|
+
- `actions.input`
|
|
563
|
+
|
|
564
|
+
### Assistant
|
|
565
|
+
|
|
566
|
+
The assistant should become the planner/explainer surface:
|
|
567
|
+
|
|
568
|
+
- "What will happen if I do this?"
|
|
569
|
+
- "Why did that move?"
|
|
570
|
+
- "What failed?"
|
|
571
|
+
- "Can you restore the previous layout?"
|
|
572
|
+
|
|
573
|
+
It should call `actions.plan`, `actions.execute`, and `actions.history`
|
|
574
|
+
instead of inventing its own execution semantics.
|
|
575
|
+
|
|
576
|
+
## Migration Plan
|
|
577
|
+
|
|
578
|
+
### Phase 1: Action Runtime Skeleton
|
|
579
|
+
|
|
580
|
+
Deliverables:
|
|
581
|
+
|
|
582
|
+
- `ActionID`
|
|
583
|
+
- `ActionSource`
|
|
584
|
+
- `TargetRef`
|
|
585
|
+
- `ActionRequest`
|
|
586
|
+
- `ActionPlan`
|
|
587
|
+
- `ExecutionReceipt`
|
|
588
|
+
- `ActionTraceEntry`
|
|
589
|
+
- `ActionRegistry`
|
|
590
|
+
- `ActionHistoryStore`
|
|
591
|
+
- `actions.catalog`
|
|
592
|
+
- `actions.plan`
|
|
593
|
+
- `actions.execute`
|
|
594
|
+
|
|
595
|
+
Scope:
|
|
596
|
+
|
|
597
|
+
- support `window.place`
|
|
598
|
+
- support explicit `wid`, `session`, and `frontmost`
|
|
599
|
+
- support `PlacementSpec`
|
|
600
|
+
- record receipts
|
|
601
|
+
- verify window frame when feasible
|
|
602
|
+
|
|
603
|
+
This is the first vertical slice.
|
|
604
|
+
|
|
605
|
+
### Phase 2: Target Resolver and Wrappers
|
|
606
|
+
|
|
607
|
+
Deliverables:
|
|
608
|
+
|
|
609
|
+
- `WindowTargetResolver`
|
|
610
|
+
- ambiguity candidate shape
|
|
611
|
+
- confidence/reason fields
|
|
612
|
+
- `window.place` wrapper over `actions.execute`
|
|
613
|
+
- `window.tile` compatibility wrapper
|
|
614
|
+
- `IntentEngine.tile_window` using the same path for all target kinds
|
|
615
|
+
|
|
616
|
+
Scope:
|
|
617
|
+
|
|
618
|
+
- `wid`
|
|
619
|
+
- session
|
|
620
|
+
- app/title
|
|
621
|
+
- frontmost
|
|
622
|
+
- query-selected result
|
|
623
|
+
|
|
624
|
+
### Phase 3: Space Optimization
|
|
625
|
+
|
|
626
|
+
Deliverables:
|
|
627
|
+
|
|
628
|
+
- `SpaceOptimizationPlanner`
|
|
629
|
+
- real strategy names
|
|
630
|
+
- `space.optimize` wrapper over `actions.execute`
|
|
631
|
+
- `layout.distribute` compatibility wrapper
|
|
632
|
+
- structured receipts with affected windows and computed frames
|
|
633
|
+
|
|
634
|
+
Decision:
|
|
635
|
+
|
|
636
|
+
- Either make `mosaic` a distinct strategy or stop exposing it as distinct
|
|
637
|
+
while it uses the same smart-grid implementation as `balanced`.
|
|
638
|
+
|
|
639
|
+
### Phase 4: Layer Activation Planning
|
|
640
|
+
|
|
641
|
+
Deliverables:
|
|
642
|
+
|
|
643
|
+
- `LayerActivationPlanner`
|
|
644
|
+
- `layer.activate` wrapper over `actions.execute`
|
|
645
|
+
- pending steps for launches
|
|
646
|
+
- post-launch receipts or follow-up events
|
|
647
|
+
- drift/reconcile language for layer recipes
|
|
648
|
+
|
|
649
|
+
Scope:
|
|
650
|
+
|
|
651
|
+
- existing config layers
|
|
652
|
+
- session layers
|
|
653
|
+
- project launch/focus/retile behavior
|
|
654
|
+
- placement rules where already available
|
|
655
|
+
|
|
656
|
+
### Phase 5: Surface Convergence
|
|
657
|
+
|
|
658
|
+
Deliverables:
|
|
659
|
+
|
|
660
|
+
- CLI uses runtime by default.
|
|
661
|
+
- Palette emits action requests.
|
|
662
|
+
- HUD/hotkeys emit action requests.
|
|
663
|
+
- Local voice emits action requests.
|
|
664
|
+
- Hands-off worker emits action requests.
|
|
665
|
+
- Companion includes runtime receipts.
|
|
666
|
+
- Assistant reads `actions.history`.
|
|
667
|
+
|
|
668
|
+
The visible UX should remain familiar while the internals converge.
|
|
669
|
+
|
|
670
|
+
### Phase 6: Undo-ready History
|
|
671
|
+
|
|
672
|
+
Deliverables:
|
|
673
|
+
|
|
674
|
+
- `actions.history`
|
|
675
|
+
- limited `actions.undo`
|
|
676
|
+
- window geometry restore for placement and optimization
|
|
677
|
+
- UI affordance in HUD, palette, voice, companion, and assistant
|
|
678
|
+
|
|
679
|
+
Do not expand undo beyond geometry until receipts are reliable.
|
|
680
|
+
|
|
681
|
+
## Verification and Release Readiness
|
|
682
|
+
|
|
683
|
+
The action runtime should ship with a verification track, not as a pure
|
|
684
|
+
architecture refactor.
|
|
685
|
+
|
|
686
|
+
### Current Coverage Gaps
|
|
687
|
+
|
|
688
|
+
- Root checks typecheck TypeScript and build the Swift app, but do not run
|
|
689
|
+
Swift tests by default.
|
|
690
|
+
- Daemon E2E tests require a live local daemon and real desktop state.
|
|
691
|
+
- Voice phrase evals are useful but manually gated.
|
|
692
|
+
- Hands-off evals are useful but should be made clearer about pass/fail
|
|
693
|
+
semantics.
|
|
694
|
+
- Swift tests are mostly live Stage Manager/window experiments, not
|
|
695
|
+
deterministic CI units.
|
|
696
|
+
- `DeckKit` model tests exist but are not part of the root `check`.
|
|
697
|
+
- There is no headless fake desktop/window backend for CI.
|
|
698
|
+
- Docs can drift from API truth, including method counts and command lists.
|
|
699
|
+
|
|
700
|
+
### Proposed Test Tiers
|
|
701
|
+
|
|
702
|
+
#### Tier 1: Deterministic PR Checks
|
|
703
|
+
|
|
704
|
+
Run on every PR:
|
|
705
|
+
|
|
706
|
+
- TypeScript typecheck.
|
|
707
|
+
- Swift app build.
|
|
708
|
+
- `DeckKit` Swift tests.
|
|
709
|
+
- Placement parser tests.
|
|
710
|
+
- target resolver tests with fake windows.
|
|
711
|
+
- daemon schema contract tests.
|
|
712
|
+
- CLI command/help snapshot tests.
|
|
713
|
+
- docs agent artifact generation.
|
|
714
|
+
- site build.
|
|
715
|
+
|
|
716
|
+
#### Tier 2: Local Daemon Smoke
|
|
717
|
+
|
|
718
|
+
Run on release candidates or manual macOS runners:
|
|
719
|
+
|
|
720
|
+
- launch app
|
|
721
|
+
- confirm daemon health
|
|
722
|
+
- call `api.schema`
|
|
723
|
+
- call read endpoints
|
|
724
|
+
- execute dry-run plans
|
|
725
|
+
- run voice simulate evals
|
|
726
|
+
- verify package-installed CLI can talk to daemon
|
|
727
|
+
|
|
728
|
+
#### Tier 3: Live Desktop Acceptance
|
|
729
|
+
|
|
730
|
+
Document and run manually or on a controlled Mac:
|
|
731
|
+
|
|
732
|
+
- actual window placement
|
|
733
|
+
- Screen Recording and Accessibility fallback paths
|
|
734
|
+
- Stage Manager behavior
|
|
735
|
+
- Spaces movement
|
|
736
|
+
- OCR scan/search
|
|
737
|
+
- companion bridge pairing
|
|
738
|
+
- app update and relaunch
|
|
739
|
+
|
|
740
|
+
### CI and Release Hardening
|
|
741
|
+
|
|
742
|
+
Add a normal PR CI workflow:
|
|
743
|
+
|
|
744
|
+
```text
|
|
745
|
+
bun install --frozen-lockfile
|
|
746
|
+
bun run check:types
|
|
747
|
+
swift build --package-path apps/mac
|
|
748
|
+
swift test --package-path swift
|
|
749
|
+
bun run site:build
|
|
750
|
+
bun run docs:agent
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
Add package smoke:
|
|
754
|
+
|
|
755
|
+
- `npm pack`
|
|
756
|
+
- install into a temporary prefix
|
|
757
|
+
- run `lattices help`
|
|
758
|
+
- assert package files are present
|
|
759
|
+
- validate runtime requirement wording
|
|
760
|
+
|
|
761
|
+
Add docs truth checks:
|
|
762
|
+
|
|
763
|
+
- daemon method list generated from `api.schema` or source registry
|
|
764
|
+
- CLI command list generated or checked against `lattices help`
|
|
765
|
+
- install/runtime requirements checked against package reality
|
|
766
|
+
- canonical action list checked against `ActionRegistry`
|
|
767
|
+
|
|
768
|
+
Strengthen release candidate checks:
|
|
769
|
+
|
|
770
|
+
- root `check`
|
|
771
|
+
- Swift package tests
|
|
772
|
+
- package smoke
|
|
773
|
+
- site build
|
|
774
|
+
- docs artifacts
|
|
775
|
+
- unsigned DMG build
|
|
776
|
+
- iOS simulator build
|
|
777
|
+
- optional daemon smoke on a prepared Mac
|
|
778
|
+
|
|
779
|
+
Strengthen release publish checks:
|
|
780
|
+
|
|
781
|
+
- version/tag consistency
|
|
782
|
+
- package contents
|
|
783
|
+
- DMG mount/install smoke
|
|
784
|
+
- notarization and staple validation
|
|
785
|
+
- post-launch daemon health
|
|
786
|
+
- rollback/update notes
|
|
787
|
+
|
|
788
|
+
## Documentation Plan
|
|
789
|
+
|
|
790
|
+
After the runtime lands, update docs around one vocabulary:
|
|
791
|
+
|
|
792
|
+
- "dozens of RPC methods" unless a generated count is used.
|
|
793
|
+
- `window.place`, `layer.activate`, and `space.optimize` as stable
|
|
794
|
+
compatibility-level actions.
|
|
795
|
+
- `actions.plan`, `actions.execute`, and `actions.history` as the canonical
|
|
796
|
+
action runtime.
|
|
797
|
+
- OCR is local, opt-in, and retention-limited.
|
|
798
|
+
- Companion control is capability-scoped.
|
|
799
|
+
- Undo is initially geometry-only.
|
|
800
|
+
|
|
801
|
+
Docs to update:
|
|
802
|
+
|
|
803
|
+
- `docs/api.md`
|
|
804
|
+
- `docs/agents.md`
|
|
805
|
+
- `docs/tiling-reference.md`
|
|
806
|
+
- `docs/voice.md`
|
|
807
|
+
- `docs/layers.md`
|
|
808
|
+
- `README.md`
|
|
809
|
+
- agent docs artifacts generated by `apps/site/scripts/agent-docs.mjs`
|
|
810
|
+
|
|
811
|
+
## Risks and Decisions
|
|
812
|
+
|
|
813
|
+
### Verification Timing
|
|
814
|
+
|
|
815
|
+
Question: should `actions.execute` wait for verification?
|
|
816
|
+
|
|
817
|
+
Recommendation:
|
|
818
|
+
|
|
819
|
+
- wait for quick window operations
|
|
820
|
+
- return `accepted` for long-running launch/layer operations
|
|
821
|
+
- emit or record follow-up receipts for delayed steps
|
|
822
|
+
|
|
823
|
+
### Ambiguous Targets
|
|
824
|
+
|
|
825
|
+
Question: what should "Chrome right" mean with four Chrome windows?
|
|
826
|
+
|
|
827
|
+
Recommendation:
|
|
828
|
+
|
|
829
|
+
- daemon/agent default: fail with candidates
|
|
830
|
+
- voice default: use frontmost matching app only when clear
|
|
831
|
+
- HUD default: use current/frontmost context
|
|
832
|
+
- always record policy in the receipt
|
|
833
|
+
|
|
834
|
+
### Undo Scope
|
|
835
|
+
|
|
836
|
+
Question: how much undo should ship?
|
|
837
|
+
|
|
838
|
+
Recommendation:
|
|
839
|
+
|
|
840
|
+
- start with window geometry only
|
|
841
|
+
- defer launches, kills, session mutations, app opens, and Space moves
|
|
842
|
+
|
|
843
|
+
### Planner Location
|
|
844
|
+
|
|
845
|
+
Question: should planning live in TypeScript or Swift?
|
|
846
|
+
|
|
847
|
+
Recommendation:
|
|
848
|
+
|
|
849
|
+
- language interpretation can live in TypeScript
|
|
850
|
+
- desktop-state planning belongs in Swift, because Swift owns AX, CG,
|
|
851
|
+
SkyLight, permissions, and current window state
|
|
852
|
+
|
|
853
|
+
### Backward Compatibility
|
|
854
|
+
|
|
855
|
+
Question: should old endpoints disappear?
|
|
856
|
+
|
|
857
|
+
Recommendation:
|
|
858
|
+
|
|
859
|
+
- no
|
|
860
|
+
- keep old endpoint names as wrappers
|
|
861
|
+
- make the internal runtime and receipt shape better without breaking agents
|
|
862
|
+
|
|
863
|
+
### Companion Security
|
|
864
|
+
|
|
865
|
+
Question: how much can the companion invoke?
|
|
866
|
+
|
|
867
|
+
Recommendation:
|
|
868
|
+
|
|
869
|
+
- authorize by action family
|
|
870
|
+
- do not grant broad mutation access by default
|
|
871
|
+
- make receipts visible to the companion so remote actions stay inspectable
|
|
872
|
+
|
|
873
|
+
## Success Criteria
|
|
874
|
+
|
|
875
|
+
This proposal is successful when:
|
|
876
|
+
|
|
877
|
+
- `actions.plan` can describe what will happen for `window.place`.
|
|
878
|
+
- `actions.execute(window.place)` returns a verified receipt for a real move.
|
|
879
|
+
- `window.place` and `window.tile` route through the runtime.
|
|
880
|
+
- voice, CLI, and one native UI surface use the same runtime path for
|
|
881
|
+
placement.
|
|
882
|
+
- `actions.history` can answer "what just happened?"
|
|
883
|
+
- ambiguous app targets return useful candidates instead of silent guesses in
|
|
884
|
+
agent/script mode.
|
|
885
|
+
- `space.optimize` and `layer.activate` receipts include affected windows,
|
|
886
|
+
computed or intended frames, pending launches, and failures.
|
|
887
|
+
- docs no longer imply separate execution semantics per surface.
|
|
888
|
+
- CI has deterministic contract tests for placement, schema, and docs truth.
|
|
889
|
+
|
|
890
|
+
## Immediate Slice
|
|
891
|
+
|
|
892
|
+
Start with one vertical slice:
|
|
893
|
+
|
|
894
|
+
```text
|
|
895
|
+
actions.execute(window.place)
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
This forces the right abstractions without requiring the whole product to
|
|
899
|
+
move at once:
|
|
900
|
+
|
|
901
|
+
- target resolution
|
|
902
|
+
- placement parsing
|
|
903
|
+
- planning
|
|
904
|
+
- execution
|
|
905
|
+
- verification
|
|
906
|
+
- receipt
|
|
907
|
+
- history
|
|
908
|
+
- compatibility wrapper
|
|
909
|
+
- one or two migrated surfaces
|
|
910
|
+
|
|
911
|
+
Once this feels solid, migrate `space.optimize` and `layer.activate`.
|
|
912
|
+
|
|
913
|
+
That is the smallest path that ties the product together nicely without
|
|
914
|
+
turning the proposal into a rewrite.
|