@arach/lattices 0.1.0
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/README.md +157 -0
- package/app/Lattices.app/Contents/Info.plist +24 -0
- package/app/Package.swift +13 -0
- package/app/Sources/App.swift +49 -0
- package/app/Sources/AppDelegate.swift +104 -0
- package/app/Sources/AppShellView.swift +62 -0
- package/app/Sources/AppTypeClassifier.swift +70 -0
- package/app/Sources/AppWindowShell.swift +63 -0
- package/app/Sources/CheatSheetHUD.swift +331 -0
- package/app/Sources/CommandModeState.swift +1341 -0
- package/app/Sources/CommandModeView.swift +1380 -0
- package/app/Sources/CommandModeWindow.swift +192 -0
- package/app/Sources/CommandPaletteView.swift +307 -0
- package/app/Sources/CommandPaletteWindow.swift +134 -0
- package/app/Sources/DaemonProtocol.swift +101 -0
- package/app/Sources/DaemonServer.swift +406 -0
- package/app/Sources/DesktopModel.swift +121 -0
- package/app/Sources/DesktopModelTypes.swift +71 -0
- package/app/Sources/DiagnosticLog.swift +253 -0
- package/app/Sources/EventBus.swift +29 -0
- package/app/Sources/HotkeyManager.swift +249 -0
- package/app/Sources/HotkeyStore.swift +330 -0
- package/app/Sources/InventoryManager.swift +35 -0
- package/app/Sources/InventoryPath.swift +43 -0
- package/app/Sources/KeyRecorderView.swift +210 -0
- package/app/Sources/LatticesApi.swift +915 -0
- package/app/Sources/MainView.swift +507 -0
- package/app/Sources/MainWindow.swift +70 -0
- package/app/Sources/OrphanRow.swift +129 -0
- package/app/Sources/PaletteCommand.swift +409 -0
- package/app/Sources/PermissionChecker.swift +115 -0
- package/app/Sources/Preferences.swift +48 -0
- package/app/Sources/ProcessModel.swift +199 -0
- package/app/Sources/ProcessQuery.swift +151 -0
- package/app/Sources/Project.swift +28 -0
- package/app/Sources/ProjectRow.swift +368 -0
- package/app/Sources/ProjectScanner.swift +121 -0
- package/app/Sources/ScreenMapState.swift +2397 -0
- package/app/Sources/ScreenMapView.swift +2817 -0
- package/app/Sources/ScreenMapWindowController.swift +89 -0
- package/app/Sources/SessionManager.swift +72 -0
- package/app/Sources/SettingsView.swift +641 -0
- package/app/Sources/SettingsWindow.swift +20 -0
- package/app/Sources/TabGroupRow.swift +178 -0
- package/app/Sources/Terminal.swift +259 -0
- package/app/Sources/TerminalQuery.swift +156 -0
- package/app/Sources/TerminalSynthesizer.swift +200 -0
- package/app/Sources/Theme.swift +124 -0
- package/app/Sources/TilePickerView.swift +209 -0
- package/app/Sources/TmuxModel.swift +53 -0
- package/app/Sources/TmuxQuery.swift +81 -0
- package/app/Sources/WindowTiler.swift +1752 -0
- package/app/Sources/WorkspaceManager.swift +434 -0
- package/bin/daemon-client.js +187 -0
- package/bin/lattices-app.js +205 -0
- package/bin/lattices.js +1295 -0
- package/docs/api.md +707 -0
- package/docs/app.md +250 -0
- package/docs/concepts.md +225 -0
- package/docs/config.md +234 -0
- package/docs/layers.md +317 -0
- package/docs/overview.md +74 -0
- package/docs/quickstart.md +82 -0
- package/package.json +38 -0
package/docs/config.md
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Configuration
|
|
3
|
+
description: CLI commands, .lattices.json format, and tile positions
|
|
4
|
+
order: 2
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Configuration
|
|
8
|
+
|
|
9
|
+
## .lattices.json
|
|
10
|
+
|
|
11
|
+
Place a `.lattices.json` file in your project root to define your
|
|
12
|
+
workspace layout. lattices reads this file when creating a session.
|
|
13
|
+
|
|
14
|
+
### Minimal example
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"panes": [
|
|
19
|
+
{ "name": "claude", "cmd": "claude" },
|
|
20
|
+
{ "name": "server", "cmd": "pnpm dev" }
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Full example
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"ensure": true,
|
|
30
|
+
"panes": [
|
|
31
|
+
{ "name": "claude", "cmd": "claude", "size": 60 },
|
|
32
|
+
{ "name": "server", "cmd": "pnpm dev" },
|
|
33
|
+
{ "name": "tests", "cmd": "pnpm test --watch" }
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Config fields
|
|
39
|
+
|
|
40
|
+
| Field | Type | Required | Description |
|
|
41
|
+
|----------|---------|----------|------------------------------------------------------|
|
|
42
|
+
| panes | array | no | List of pane definitions (see below) |
|
|
43
|
+
| ensure | boolean | no | Auto-restart exited commands on reattach |
|
|
44
|
+
| prefill | boolean | no | Type exited commands into idle panes on reattach (you hit Enter) |
|
|
45
|
+
|
|
46
|
+
`ensure` and `prefill` are mutually exclusive. If both are set,
|
|
47
|
+
`ensure` takes priority.
|
|
48
|
+
|
|
49
|
+
- **ensure** — when you reattach to an existing session, lattices checks
|
|
50
|
+
each pane. If a pane's process has exited and the shell is idle, lattices
|
|
51
|
+
automatically re-runs its declared command.
|
|
52
|
+
- **prefill** — same check, but the command is typed into the pane
|
|
53
|
+
without pressing Enter. You review and hit Enter yourself.
|
|
54
|
+
|
|
55
|
+
## Pane fields
|
|
56
|
+
|
|
57
|
+
| Field | Type | Required | Description |
|
|
58
|
+
|--------|--------|----------|-------------------------------------|
|
|
59
|
+
| name | string | no | Label for the pane (shown in app) |
|
|
60
|
+
| cmd | string | no | Command to run when pane opens |
|
|
61
|
+
| size | number | no | Width % for the first pane (1-99) |
|
|
62
|
+
|
|
63
|
+
- `size` only applies to the **first pane**. It sets the width of the
|
|
64
|
+
main pane as a percentage. Default is 60.
|
|
65
|
+
- `cmd` can be any shell command. If omitted, the pane opens a shell.
|
|
66
|
+
- `name` is used in the lattices app to show a summary of your layout,
|
|
67
|
+
and as a target for `lattices restart <name>`.
|
|
68
|
+
|
|
69
|
+
## Layouts
|
|
70
|
+
|
|
71
|
+
lattices picks a layout based on how many panes you define:
|
|
72
|
+
|
|
73
|
+
### 2 panes — side by side
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
┌──────────┬─────────┐
|
|
77
|
+
│ claude │ server │
|
|
78
|
+
│ (60%) │ (40%) │
|
|
79
|
+
└──────────┴─────────┘
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Horizontal split. First pane on the left, second on the right.
|
|
83
|
+
|
|
84
|
+
### 3+ panes — main-vertical
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
┌──────────┬─────────┐
|
|
88
|
+
│ claude │ server │
|
|
89
|
+
│ (60%) ├─────────┤
|
|
90
|
+
│ │ tests │
|
|
91
|
+
└──────────┴─────────┘
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
First pane takes the left side. Remaining panes stack vertically
|
|
95
|
+
on the right.
|
|
96
|
+
|
|
97
|
+
### 4 panes
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
┌──────────┬─────────┐
|
|
101
|
+
│ claude │ server │
|
|
102
|
+
│ (60%) ├─────────┤
|
|
103
|
+
│ │ tests │
|
|
104
|
+
│ ├─────────┤
|
|
105
|
+
│ │ logs │
|
|
106
|
+
└──────────┴─────────┘
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Auto-detection (no config)
|
|
110
|
+
|
|
111
|
+
If there's no `.lattices.json`, lattices still works. It will:
|
|
112
|
+
|
|
113
|
+
1. Create a 2-pane layout (60/40 split)
|
|
114
|
+
2. Run `claude` in the left pane
|
|
115
|
+
3. Auto-detect your dev command from package.json scripts:
|
|
116
|
+
- Looks for: `dev`, `start`, `serve`, `watch` (in that order)
|
|
117
|
+
- Detects package manager: pnpm > bun > yarn > npm
|
|
118
|
+
|
|
119
|
+
## Creating a config
|
|
120
|
+
|
|
121
|
+
Run `lattices init` in your project directory to generate a starter
|
|
122
|
+
`.lattices.json` based on your project. The generated config includes
|
|
123
|
+
`"ensure": true` by default.
|
|
124
|
+
|
|
125
|
+
## CLI commands
|
|
126
|
+
|
|
127
|
+
| Command | Description |
|
|
128
|
+
|----------------------------|--------------------------------------------------|
|
|
129
|
+
| `lattices` | Create or attach to session for current project |
|
|
130
|
+
| `lattices init` | Generate .lattices.json config for this project |
|
|
131
|
+
| `lattices ls` | List active tmux sessions |
|
|
132
|
+
| `lattices kill [name]` | Kill a session (defaults to current project) |
|
|
133
|
+
| `lattices sync` | Reconcile session to match declared config |
|
|
134
|
+
| `lattices restart [pane]` | Restart a pane's process (by name or index) |
|
|
135
|
+
| `lattices tile <position>` | Tile the frontmost window to a screen position |
|
|
136
|
+
| `lattices group [id]` | List tab groups or launch/attach a group |
|
|
137
|
+
| `lattices groups` | List all tab groups with status |
|
|
138
|
+
| `lattices tab <group> [tab]` | Switch tab within a group (by label or index) |
|
|
139
|
+
| `lattices app` | Launch the menu bar companion app |
|
|
140
|
+
| `lattices app build` | Rebuild the menu bar app from source |
|
|
141
|
+
| `lattices app restart` | Rebuild and relaunch the menu bar app |
|
|
142
|
+
| `lattices app quit` | Stop the menu bar app |
|
|
143
|
+
| `lattices help` | Show help |
|
|
144
|
+
|
|
145
|
+
Aliases: `ls`/`list`, `kill`/`rm`, `sync`/`reconcile`,
|
|
146
|
+
`restart`/`respawn`, `tile`/`t`.
|
|
147
|
+
|
|
148
|
+
## Machine-readable output
|
|
149
|
+
|
|
150
|
+
### `--json` flag
|
|
151
|
+
|
|
152
|
+
The `lattices windows` command supports a `--json` flag for structured
|
|
153
|
+
output:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
lattices windows --json
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Returns a JSON array of window objects to stdout — useful for piping
|
|
160
|
+
into `jq` or consuming from scripts.
|
|
161
|
+
|
|
162
|
+
### Daemon responses
|
|
163
|
+
|
|
164
|
+
All daemon API calls return JSON natively. If you need structured data
|
|
165
|
+
from lattices, the daemon is the best path — no flags needed, no stdout
|
|
166
|
+
parsing. See the [API reference](/docs/api).
|
|
167
|
+
|
|
168
|
+
### Exit codes
|
|
169
|
+
|
|
170
|
+
| Code | Meaning |
|
|
171
|
+
|------|---------------------------------------------|
|
|
172
|
+
| `0` | Success |
|
|
173
|
+
| `1` | General error (missing args, bad config) |
|
|
174
|
+
| `2` | Session not found |
|
|
175
|
+
|
|
176
|
+
## Recovery
|
|
177
|
+
|
|
178
|
+
### sync
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
lattices sync
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Reconciles a running session to match the declared config:
|
|
185
|
+
|
|
186
|
+
1. Counts actual panes vs declared panes
|
|
187
|
+
2. Recreates any missing panes
|
|
188
|
+
3. Re-applies the layout (main-vertical with correct width)
|
|
189
|
+
4. Restores pane labels
|
|
190
|
+
5. Re-runs declared commands in any idle panes
|
|
191
|
+
|
|
192
|
+
Use when a pane was killed and you want to get back to the declared
|
|
193
|
+
state without killing the whole session.
|
|
194
|
+
|
|
195
|
+
### restart
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
lattices restart [target]
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Kills the process in a specific pane and re-runs its declared command.
|
|
202
|
+
The target can be:
|
|
203
|
+
|
|
204
|
+
- A **pane name** (case-insensitive): `lattices restart server`
|
|
205
|
+
- A **0-based index**: `lattices restart 1`
|
|
206
|
+
- **Omitted** (defaults to pane 0): `lattices restart`
|
|
207
|
+
|
|
208
|
+
The restart sequence: send Ctrl-C, wait 0.5s, check if the process
|
|
209
|
+
stopped. If it's still running, escalate to SIGKILL on child
|
|
210
|
+
processes. Then send the declared command.
|
|
211
|
+
|
|
212
|
+
## Tile positions
|
|
213
|
+
|
|
214
|
+
The `lattices tile` command moves the frontmost window to a preset
|
|
215
|
+
screen position. Available positions:
|
|
216
|
+
|
|
217
|
+
| Position | Area |
|
|
218
|
+
|----------------|-----------------------------|
|
|
219
|
+
| `left` | Left half |
|
|
220
|
+
| `right` | Right half |
|
|
221
|
+
| `top` | Top half |
|
|
222
|
+
| `bottom` | Bottom half |
|
|
223
|
+
| `top-left` | Top-left quarter |
|
|
224
|
+
| `top-right` | Top-right quarter |
|
|
225
|
+
| `bottom-left` | Bottom-left quarter |
|
|
226
|
+
| `bottom-right` | Bottom-right quarter |
|
|
227
|
+
| `maximize` | Full screen (visible area) |
|
|
228
|
+
| `center` | 70% width, 80% height, centered |
|
|
229
|
+
|
|
230
|
+
Aliases: `left-half`/`left`, `right-half`/`right`, `top-half`/`top`,
|
|
231
|
+
`bottom-half`/`bottom`, `max`/`maximize`.
|
|
232
|
+
|
|
233
|
+
Tiling respects the menu bar and dock — it uses the visible desktop
|
|
234
|
+
area, not the full screen.
|
package/docs/layers.md
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Workspace Layers & Tab Groups
|
|
3
|
+
description: Group projects into switchable layers and tabbed groups
|
|
4
|
+
order: 4
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Workspace Layers & Tab Groups
|
|
8
|
+
|
|
9
|
+
Two ways to organize related projects in `~/.lattices/workspace.json`:
|
|
10
|
+
|
|
11
|
+
- **Layers** — switchable contexts that focus and tile windows
|
|
12
|
+
- **Tab groups** — related projects as tabs within a single terminal window
|
|
13
|
+
|
|
14
|
+
Both features are configured in the same workspace config and
|
|
15
|
+
work together.
|
|
16
|
+
|
|
17
|
+
## Tab Groups
|
|
18
|
+
|
|
19
|
+
Tab groups let you bundle related projects as tabs (tmux windows)
|
|
20
|
+
within a single tmux session. This is useful when you have a family
|
|
21
|
+
of projects — like an iOS app, macOS app, website, and API — that
|
|
22
|
+
you think of as one logical unit.
|
|
23
|
+
|
|
24
|
+
### Configuration
|
|
25
|
+
|
|
26
|
+
Add `groups` to `~/.lattices/workspace.json`:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"name": "my-setup",
|
|
31
|
+
"groups": [
|
|
32
|
+
{
|
|
33
|
+
"id": "talkie",
|
|
34
|
+
"label": "Talkie",
|
|
35
|
+
"tabs": [
|
|
36
|
+
{ "path": "/Users/you/dev/talkie-ios", "label": "iOS" },
|
|
37
|
+
{ "path": "/Users/you/dev/talkie-macos", "label": "macOS" },
|
|
38
|
+
{ "path": "/Users/you/dev/talkie-web", "label": "Website" },
|
|
39
|
+
{ "path": "/Users/you/dev/talkie-api", "label": "API" }
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Each tab's pane layout comes from its own `.lattices.json` — no changes
|
|
47
|
+
to per-project configs.
|
|
48
|
+
|
|
49
|
+
### How it works
|
|
50
|
+
|
|
51
|
+
- **Session naming**: `lattices-group-<id>` (e.g. `lattices-group-talkie`)
|
|
52
|
+
- **tmux mapping**: 1 group = 1 tmux session, each tab = 1 tmux window,
|
|
53
|
+
each window has its own panes from that project's `.lattices.json`
|
|
54
|
+
- **Independent launch still works**: `cd talkie-ios && lattices` creates
|
|
55
|
+
its own standalone session as before
|
|
56
|
+
|
|
57
|
+
### Tab group fields
|
|
58
|
+
|
|
59
|
+
| Field | Type | Description |
|
|
60
|
+
|----------------|----------|--------------------------------------|
|
|
61
|
+
| `id` | string | Unique identifier for the group |
|
|
62
|
+
| `label` | string | Display name shown in the UI |
|
|
63
|
+
| `tabs` | array | List of tab definitions |
|
|
64
|
+
| `tabs[].path` | string | Absolute path to project directory |
|
|
65
|
+
| `tabs[].label` | string? | Tab name (defaults to directory name) |
|
|
66
|
+
|
|
67
|
+
### CLI commands
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
lattices groups # List all groups with status
|
|
71
|
+
lattices group <id> # Launch or attach to a group
|
|
72
|
+
lattices tab <group> [tab] # Switch tab by label or index
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Examples:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
lattices group talkie # Launch all Talkie tabs
|
|
79
|
+
lattices tab talkie iOS # Switch to the iOS tab
|
|
80
|
+
lattices tab talkie 0 # Switch to first tab (by index)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Menu bar app
|
|
84
|
+
|
|
85
|
+
Tab groups appear above the project list in the menu bar panel.
|
|
86
|
+
Each group row shows:
|
|
87
|
+
|
|
88
|
+
- Status indicator (running/stopped)
|
|
89
|
+
- Tab count badge
|
|
90
|
+
- Expand/collapse to see individual tabs
|
|
91
|
+
- Launch/Attach and Kill buttons
|
|
92
|
+
- Per-tab "Go" buttons to switch and focus a specific tab
|
|
93
|
+
|
|
94
|
+
The command palette also includes group commands:
|
|
95
|
+
|
|
96
|
+
| Command | Description |
|
|
97
|
+
|----------------------------|----------------------------------------|
|
|
98
|
+
| Launch *group* | Start the group session |
|
|
99
|
+
| Attach *group* | Focus the running group session |
|
|
100
|
+
| *Group*: *Tab* | Switch to a specific tab in a group |
|
|
101
|
+
| Kill *group* Group | Terminate the group session |
|
|
102
|
+
|
|
103
|
+
## Layers
|
|
104
|
+
|
|
105
|
+
Layers let you group projects into switchable contexts. Instead of
|
|
106
|
+
juggling six terminal windows at once, define two or three layers and
|
|
107
|
+
switch between them instantly — the target layer's windows come to the
|
|
108
|
+
front and tile into position, while the previous layer's windows fall
|
|
109
|
+
behind.
|
|
110
|
+
|
|
111
|
+
All tmux sessions stay alive across switches. Nothing is detached or
|
|
112
|
+
killed — layers only control which windows are focused.
|
|
113
|
+
|
|
114
|
+
### Configuration
|
|
115
|
+
|
|
116
|
+
Add `layers` to `~/.lattices/workspace.json`:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"name": "my-setup",
|
|
121
|
+
"layers": [
|
|
122
|
+
{
|
|
123
|
+
"id": "web",
|
|
124
|
+
"label": "Web",
|
|
125
|
+
"projects": [
|
|
126
|
+
{ "path": "/Users/you/dev/frontend", "tile": "left" },
|
|
127
|
+
{ "path": "/Users/you/dev/api", "tile": "right" }
|
|
128
|
+
]
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"id": "mobile",
|
|
132
|
+
"label": "Mobile",
|
|
133
|
+
"projects": [
|
|
134
|
+
{ "path": "/Users/you/dev/ios-app", "tile": "left" },
|
|
135
|
+
{ "path": "/Users/you/dev/backend", "tile": "right" }
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
]
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Using groups in layers
|
|
143
|
+
|
|
144
|
+
Layer projects can reference a tab group instead of a single path.
|
|
145
|
+
This lets you tile a whole group into a screen position:
|
|
146
|
+
|
|
147
|
+
```json
|
|
148
|
+
{
|
|
149
|
+
"name": "my-setup",
|
|
150
|
+
"groups": [
|
|
151
|
+
{
|
|
152
|
+
"id": "talkie",
|
|
153
|
+
"label": "Talkie",
|
|
154
|
+
"tabs": [
|
|
155
|
+
{ "path": "/Users/you/dev/talkie-ios", "label": "iOS" },
|
|
156
|
+
{ "path": "/Users/you/dev/talkie-web", "label": "Website" }
|
|
157
|
+
]
|
|
158
|
+
}
|
|
159
|
+
],
|
|
160
|
+
"layers": [
|
|
161
|
+
{
|
|
162
|
+
"id": "main",
|
|
163
|
+
"label": "Main",
|
|
164
|
+
"projects": [
|
|
165
|
+
{ "group": "talkie", "tile": "top-left" },
|
|
166
|
+
{ "path": "/Users/you/dev/design-system", "tile": "right" }
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
]
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
When switching to this layer, lattices launches (or focuses) the
|
|
174
|
+
"talkie" group session and tiles it to the top-left quarter, alongside
|
|
175
|
+
the design-system project on the right.
|
|
176
|
+
|
|
177
|
+
### Layer fields
|
|
178
|
+
|
|
179
|
+
| Field | Type | Description |
|
|
180
|
+
|-------------------|----------|------------------------------------------|
|
|
181
|
+
| `name` | string | Workspace name (for your reference) |
|
|
182
|
+
| `layers` | array | List of layer definitions |
|
|
183
|
+
| `layers[].id` | string | Unique identifier (e.g. `"web"`) |
|
|
184
|
+
| `layers[].label` | string | Display name shown in the UI |
|
|
185
|
+
| `layers[].projects` | array | Projects in this layer |
|
|
186
|
+
| `projects[].path` | string? | Absolute path to project directory |
|
|
187
|
+
| `projects[].group`| string? | Group ID (alternative to `path`) |
|
|
188
|
+
| `projects[].tile` | string? | Tile position (optional, see below) |
|
|
189
|
+
|
|
190
|
+
Each project entry must have either `path` or `group`, not both.
|
|
191
|
+
|
|
192
|
+
### Tile values
|
|
193
|
+
|
|
194
|
+
Any tile position from the [config reference](/docs/config#tile-positions)
|
|
195
|
+
works: `left`, `right`, `top-left`, `top-right`, `bottom-left`,
|
|
196
|
+
`bottom-right`, `maximize`, `center`.
|
|
197
|
+
|
|
198
|
+
### Switching layers
|
|
199
|
+
|
|
200
|
+
Three ways to switch:
|
|
201
|
+
|
|
202
|
+
| Method | How |
|
|
203
|
+
|----------------------|------------------------------------------|
|
|
204
|
+
| **Hotkey** | Cmd+Option+1, Cmd+Option+2, Cmd+Option+3... |
|
|
205
|
+
| **Layer bar** | Click a layer pill in the menu bar panel |
|
|
206
|
+
| **Command palette** | Search "Switch to Layer" in Cmd+Shift+M |
|
|
207
|
+
|
|
208
|
+
When you switch to a layer:
|
|
209
|
+
|
|
210
|
+
1. Each project's terminal window is **raised and focused**
|
|
211
|
+
2. If a project isn't running yet, it gets **launched** automatically
|
|
212
|
+
3. Windows with a `tile` value are **tiled** to that position
|
|
213
|
+
4. The previous layer's windows stay open behind the new ones
|
|
214
|
+
|
|
215
|
+
The app remembers which layer was last active across restarts.
|
|
216
|
+
|
|
217
|
+
### Programmatic switching
|
|
218
|
+
|
|
219
|
+
Agents and scripts can switch layers via the daemon API:
|
|
220
|
+
|
|
221
|
+
```js
|
|
222
|
+
import { daemonCall } from 'lattices/daemon-client'
|
|
223
|
+
|
|
224
|
+
// List available layers
|
|
225
|
+
const { layers, active } = await daemonCall('layers.list')
|
|
226
|
+
console.log(`Active: ${layers[active].label}`)
|
|
227
|
+
|
|
228
|
+
// Switch to a layer by index
|
|
229
|
+
await daemonCall('layer.switch', { index: 0 })
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The `layer.switch` call focuses and tiles all windows in the target
|
|
233
|
+
layer, just like the hotkey or command palette. A `layer.switched`
|
|
234
|
+
event is broadcast to all connected clients.
|
|
235
|
+
|
|
236
|
+
See the [Daemon API reference](/docs/api) for more methods.
|
|
237
|
+
|
|
238
|
+
### Layer bar
|
|
239
|
+
|
|
240
|
+
When a workspace config is loaded, a layer bar appears between the
|
|
241
|
+
header and search field in the menu bar panel:
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
lattices 2 sessions [↔] [⟳]
|
|
245
|
+
┌────────────────────────────────────────┐
|
|
246
|
+
│ ● Web ○ Mobile │
|
|
247
|
+
│ ⌥1 ⌥2 │
|
|
248
|
+
└────────────────────────────────────────┘
|
|
249
|
+
Search projects...
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
- Active layer: filled green dot
|
|
253
|
+
- Inactive layers: dim outline dot
|
|
254
|
+
- Hotkey hints shown below each label
|
|
255
|
+
|
|
256
|
+
## Layout examples
|
|
257
|
+
|
|
258
|
+
### Single project
|
|
259
|
+
|
|
260
|
+
```json
|
|
261
|
+
{
|
|
262
|
+
"projects": [
|
|
263
|
+
{ "path": "/Users/you/dev/talkie" }
|
|
264
|
+
]
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
No `tile` — just focuses the window wherever it is.
|
|
269
|
+
|
|
270
|
+
### Two-project split
|
|
271
|
+
|
|
272
|
+
```json
|
|
273
|
+
{
|
|
274
|
+
"projects": [
|
|
275
|
+
{ "path": "/Users/you/dev/app", "tile": "left" },
|
|
276
|
+
{ "path": "/Users/you/dev/api", "tile": "right" }
|
|
277
|
+
]
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Group + project
|
|
282
|
+
|
|
283
|
+
```json
|
|
284
|
+
{
|
|
285
|
+
"projects": [
|
|
286
|
+
{ "group": "talkie", "tile": "left" },
|
|
287
|
+
{ "path": "/Users/you/dev/api", "tile": "right" }
|
|
288
|
+
]
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Four quadrants
|
|
293
|
+
|
|
294
|
+
```json
|
|
295
|
+
{
|
|
296
|
+
"projects": [
|
|
297
|
+
{ "path": "/Users/you/dev/frontend", "tile": "top-left" },
|
|
298
|
+
{ "path": "/Users/you/dev/backend", "tile": "top-right" },
|
|
299
|
+
{ "path": "/Users/you/dev/mobile", "tile": "bottom-left" },
|
|
300
|
+
{ "path": "/Users/you/dev/infra", "tile": "bottom-right" }
|
|
301
|
+
]
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## Tips
|
|
306
|
+
|
|
307
|
+
- Projects don't need a `.lattices.json` config to be in a layer — any
|
|
308
|
+
directory path works. If the project has a config, lattices uses it; if
|
|
309
|
+
not, it opens a plain terminal in that directory.
|
|
310
|
+
- You can have up to 9 layers (Cmd+Option+1 through Cmd+Option+9).
|
|
311
|
+
- Edit `workspace.json` by hand — the app re-reads it on launch. Use
|
|
312
|
+
the Refresh Projects button or restart the app to pick up changes.
|
|
313
|
+
- The `tile` field is optional. Omit it if you just want the window
|
|
314
|
+
focused without repositioning.
|
|
315
|
+
- Tab groups and standalone projects can coexist in the same workspace.
|
|
316
|
+
Use groups for related project families, standalone paths for
|
|
317
|
+
individual projects.
|
package/docs/overview.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Overview
|
|
3
|
+
description: What lattices is and who it's for
|
|
4
|
+
order: 0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Overview
|
|
8
|
+
|
|
9
|
+
lattices is a macOS developer workspace manager. It pairs tmux sessions
|
|
10
|
+
with a native menu bar app to give you — and your AI coding agents —
|
|
11
|
+
full control over terminal layouts, window tiling, and project navigation.
|
|
12
|
+
|
|
13
|
+
## The problem
|
|
14
|
+
|
|
15
|
+
Modern development means juggling multiple terminal windows: a coding
|
|
16
|
+
agent in one, a dev server in another, tests in a third. Setting this up
|
|
17
|
+
every morning is tedious. AI agents can't do it at all — they're trapped
|
|
18
|
+
inside a single shell with no way to manage windows or switch contexts.
|
|
19
|
+
|
|
20
|
+
## The solution
|
|
21
|
+
|
|
22
|
+
lattices solves both sides:
|
|
23
|
+
|
|
24
|
+
- **For you** — run `lattices` in any project to get a pre-configured
|
|
25
|
+
tmux session. Use the menu bar app to launch, tile, and navigate
|
|
26
|
+
sessions with a command palette.
|
|
27
|
+
- **For agents** — the daemon API exposes 20 RPC methods over WebSocket.
|
|
28
|
+
Agents can discover projects, launch sessions, tile windows, and
|
|
29
|
+
switch workspace layers programmatically.
|
|
30
|
+
|
|
31
|
+
## What's included
|
|
32
|
+
|
|
33
|
+
| Component | Description |
|
|
34
|
+
|-----------|-------------|
|
|
35
|
+
| **CLI** (`lattices`) | Create, manage, and tile tmux sessions from the terminal |
|
|
36
|
+
| **Menu bar app** | Native macOS companion with command palette, tiling, and project discovery |
|
|
37
|
+
| **Daemon API** | WebSocket server on `ws://127.0.0.1:9399` — 20 methods, 3 real-time events |
|
|
38
|
+
| **Node.js client** | Zero-dependency `daemonCall()` helper for scripting |
|
|
39
|
+
|
|
40
|
+
## Quick taste
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Launch a workspace (auto-detects your project)
|
|
44
|
+
cd ~/my-project && lattices
|
|
45
|
+
|
|
46
|
+
# Or give agents programmatic control
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
import { daemonCall } from 'lattices/daemon-client'
|
|
51
|
+
|
|
52
|
+
await daemonCall('session.launch', { path: '/Users/you/dev/frontend' })
|
|
53
|
+
await daemonCall('window.tile', { session: 'frontend-a1b2c3', position: 'left' })
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Who it's for
|
|
57
|
+
|
|
58
|
+
- **Developers** who use tmux and want faster project switching
|
|
59
|
+
- **AI agent builders** who need their agents to control the workspace
|
|
60
|
+
- **Power users** who manage multiple projects across macOS Spaces
|
|
61
|
+
|
|
62
|
+
## Requirements
|
|
63
|
+
|
|
64
|
+
- macOS 13.0+
|
|
65
|
+
- tmux (`brew install tmux`)
|
|
66
|
+
- Node.js 18+
|
|
67
|
+
- Swift 5.9+ (only needed to build the menu bar app from source)
|
|
68
|
+
|
|
69
|
+
## Next steps
|
|
70
|
+
|
|
71
|
+
- [Quickstart](/docs/quickstart) — install and run your first session in 2 minutes
|
|
72
|
+
- [Concepts](/docs/concepts) — architecture, glossary, and how it all works
|
|
73
|
+
- [Configuration](/docs/config) — `.lattices.json` format and CLI commands
|
|
74
|
+
- [Daemon API](/docs/api) — full RPC method reference for agents and scripts
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Quickstart
|
|
3
|
+
description: Install lattices and launch your first workspace in 2 minutes
|
|
4
|
+
order: 0.5
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Quickstart
|
|
8
|
+
|
|
9
|
+
Get from zero to a running workspace in five steps.
|
|
10
|
+
|
|
11
|
+
## 1. Install tmux
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
brew install tmux
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Skip if you already have it (`tmux -V` to check).
|
|
18
|
+
|
|
19
|
+
## 2. Install lattices
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Clone and link
|
|
23
|
+
git clone https://github.com/arach/lattices
|
|
24
|
+
cd lattices
|
|
25
|
+
bun link
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Verify: `lattices help` should print usage info.
|
|
29
|
+
|
|
30
|
+
## 3. Launch a workspace
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
cd ~/your-project
|
|
34
|
+
lattices
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This creates a tmux session with two panes side by side:
|
|
38
|
+
- Left pane (60%): `claude` (AI coding agent)
|
|
39
|
+
- Right pane (40%): your dev command (auto-detected from `package.json`)
|
|
40
|
+
|
|
41
|
+
No config file needed — lattices auto-detects your package manager
|
|
42
|
+
and dev script.
|
|
43
|
+
|
|
44
|
+
## 4. Customize with .lattices.json
|
|
45
|
+
|
|
46
|
+
For more control, add a config to your project:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
lattices init
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
This generates a `.lattices.json` like:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"ensure": true,
|
|
57
|
+
"panes": [
|
|
58
|
+
{ "name": "claude", "cmd": "claude", "size": 60 },
|
|
59
|
+
{ "name": "server", "cmd": "bun dev" }
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Edit it to match your workflow, then run `lattices` again to apply.
|
|
65
|
+
|
|
66
|
+
## 5. Launch the menu bar app
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
lattices app
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
This builds (or downloads) and launches the native macOS companion.
|
|
73
|
+
Open the command palette with **Cmd+Shift+M** to search and launch
|
|
74
|
+
any project, tile windows, or switch workspace layers.
|
|
75
|
+
|
|
76
|
+
## What's next
|
|
77
|
+
|
|
78
|
+
- [Concepts](/docs/concepts) — understand sessions, panes, and the architecture
|
|
79
|
+
- [Configuration](/docs/config) — full `.lattices.json` reference and CLI commands
|
|
80
|
+
- [Menu Bar App](/docs/app) — command palette, tiling, and settings
|
|
81
|
+
- [Daemon API](/docs/api) — programmatic control for agents and scripts
|
|
82
|
+
- [Layers & Groups](/docs/layers) — organize projects into switchable contexts
|