peakypanes 0.0.4 → 0.0.6

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 CHANGED
@@ -6,12 +6,12 @@
6
6
  █ █████ █ █ █ ██ █ █ █ █ █ ██ █████ █████
7
7
  ```
8
8
 
9
- **Tmux layout manager with YAML-based configuration.**
9
+ **Terminal dashboard with YAML-based layouts, native live previews, and persistent native sessions.**
10
10
 
11
- ![Peaky Panes Preview](assets/peakypanes-preview.jpg)
11
+ ![Peaky Panes Preview](assets/preview-peakypanes-v2.jpg)
12
12
 
13
13
 
14
- Define your tmux layouts in YAML, share them with your team via git, and get consistent development environments everywhere.
14
+ Define your layouts in YAML, share them with your team via git, and get consistent development environments everywhere. Sessions are owned by a **native daemon** so they keep running after the UI exits.
15
15
 
16
16
  ## Features
17
17
 
@@ -21,9 +21,11 @@ Define your tmux layouts in YAML, share them with your team via git, and get con
21
21
  - 🏠 **Global config** - Define layouts once, use everywhere
22
22
  - 🔄 **Variable expansion** - Use `${EDITOR}`, `${PROJECT_PATH}`, etc.
23
23
  - 🎯 **Zero config** - Just run `peakypanes` in any directory
24
- - ⚙️ **Session-scoped tmux options** - Configure tmux per-session without affecting global config
25
- - 🪟 **Popup dashboard** - Open the UI as a tmux popup when available
26
- - **Command palette** - Quick actions, including renaming sessions/windows
24
+ - 🧠 **Native live previews** - Full TUI support (vim/htop) with live panes
25
+ - 🧭 **Persistent native daemon** - Sessions keep running after the UI exits
26
+ - 📜 **Scrollback + copy mode** - Navigate output and yank from native panes
27
+ - ⌘ **Command palette** - Quick actions, including renaming sessions/panes
28
+ - 🖱️ **Mouse support** - Click to select panes, double-click to focus a pane
27
29
 
28
30
  ## Quick Start
29
31
 
@@ -36,21 +38,31 @@ npm i -g peakypanes
36
38
  peakypanes
37
39
  ```
38
40
 
39
- > [!TIP]
40
- > Run `peakypanes setup` to check dependencies
41
-
42
41
  **Run once with npx**
43
42
 
44
43
  ```bash
45
44
  npx -y peakypanes
46
45
  ```
47
46
 
47
+ **Using Homebrew**
48
+
49
+ ```bash
50
+ brew tap regenrek/tap
51
+ brew install regenrek/tap/peakypanes
52
+ ```
53
+
48
54
  Using Go
49
55
 
50
56
  ```bash
51
57
  go install github.com/regenrek/peakypanes/cmd/peakypanes@latest
52
58
  ```
53
59
 
60
+ **Hot reload (from repo)**
61
+
62
+ ```bash
63
+ scripts/dev-watch -- --layout dev-3
64
+ ```
65
+
54
66
  ### Usage
55
67
 
56
68
  **Start a session (auto-detect layout):**
@@ -72,9 +84,14 @@ peakypanes init --local
72
84
  git add .peakypanes.yml # Share with team
73
85
  ```
74
86
 
87
+ **Run the daemon in the foreground (optional):**
88
+ ```bash
89
+ peakypanes daemon
90
+ ```
91
+
75
92
  ## Configuration
76
93
 
77
- > 📖 **[Layout Builder Guide](docs/layout-builder.md)** - Detailed documentation on creating custom layouts, pane arrangements, and tmux options.
94
+ > 📖 **[Layout Builder Guide](docs/layout-builder.md)** - Detailed documentation on creating custom layouts, pane arrangements, and configuration.
78
95
 
79
96
  ### Project-Local (`.peakypanes.yml`)
80
97
 
@@ -85,28 +102,22 @@ Create in your project root for team-shared layouts:
85
102
  session: my-project
86
103
 
87
104
  layout:
88
- windows:
89
- - name: dev
90
- panes:
91
- - title: editor
92
- cmd: "${EDITOR:-}"
93
- size: "60%"
94
- - title: server
95
- cmd: "npm run dev"
96
- split: horizontal
97
- - title: shell
98
- cmd: ""
99
- split: vertical
100
-
101
- - name: logs
102
- panes:
103
- - title: docker
104
- cmd: "docker compose logs -f"
105
+ panes:
106
+ - title: editor
107
+ cmd: "${EDITOR:-}"
108
+ size: "60%"
109
+ - title: server
110
+ cmd: "npm run dev"
111
+ split: horizontal
112
+ - title: shell
113
+ cmd: ""
114
+ split: vertical
115
+ - title: docker
116
+ cmd: "docker compose logs -f"
105
117
 
106
118
  # Or use exact grids
107
119
  # layout:
108
120
  # grid: 2x3
109
- # window: codex
110
121
  # commands:
111
122
  # - "${SHELL:-bash}"
112
123
  # - "codex"
@@ -121,6 +132,11 @@ layout:
121
132
  # - codex-3
122
133
  # - codex-4
123
134
  # - codex-5
135
+
136
+ # Optional per-project dashboard overrides
137
+ # dashboard:
138
+ # sidebar:
139
+ # hidden: true
124
140
  ```
125
141
 
126
142
  ### Global Config (`~/.config/peakypanes/config.yml`)
@@ -128,12 +144,6 @@ layout:
128
144
  For personal layouts and multi-project management:
129
145
 
130
146
  ```yaml
131
- # Global settings
132
- tmux:
133
- # Optional: source a custom tmux config when starting sessions.
134
- # (tmux already reads ~/.tmux.conf or ~/.config/tmux/tmux.conf by default)
135
- config: ~/.config/tmux/tmux.conf
136
-
137
147
  # Dashboard UI settings (optional)
138
148
  # dashboard:
139
149
  # project_roots:
@@ -143,13 +153,11 @@ tmux:
143
153
  # Custom layouts
144
154
  layouts:
145
155
  my-custom:
146
- windows:
147
- - name: main
148
- panes:
149
- - title: code
150
- cmd: nvim
151
- - title: term
152
- cmd: ""
156
+ panes:
157
+ - title: code
158
+ cmd: nvim
159
+ - title: term
160
+ cmd: ""
153
161
 
154
162
  # Projects for quick switching
155
163
  projects:
@@ -174,10 +182,8 @@ Use variables in your layouts:
174
182
  layout:
175
183
  vars:
176
184
  log_file: "${HOME}/logs/${PROJECT_NAME}.log"
177
- windows:
178
- - name: dev
179
- panes:
180
- - cmd: "tail -f ${log_file}"
185
+ panes:
186
+ - cmd: "tail -f ${log_file}"
181
187
  ```
182
188
 
183
189
  ## Commands
@@ -185,23 +191,39 @@ layout:
185
191
  ```bash
186
192
  peakypanes # Open dashboard (direct)
187
193
  peakypanes dashboard # Open dashboard (direct)
188
- peakypanes dashboard --tmux-session # Host dashboard in tmux session
189
- peakypanes dashboard --popup # Open dashboard as a tmux popup
190
- peakypanes popup # Open dashboard as a tmux popup
191
- peakypanes open # Start/attach session in current directory
194
+ peakypanes open # Start session and open dashboard
192
195
  peakypanes start # Same as open
193
196
  peakypanes start --layout X # Use specific layout
194
- peakypanes start --detach # Create session without attaching
195
- peakypanes kill [session] # Kill a tmux session
196
197
  peakypanes init # Create global config
197
198
  peakypanes init --local # Create .peakypanes.yml
198
199
  peakypanes layouts # List available layouts
199
200
  peakypanes layouts export X # Export layout YAML
200
201
  peakypanes clone user/repo # Clone from GitHub and start session
201
- peakypanes setup # Check external dependencies
202
202
  peakypanes version # Show version
203
203
  ```
204
204
 
205
+ ## Troubleshooting: daemon stuck / restart
206
+
207
+ The daemon owns sessions and PTYs. If it becomes unresponsive, the only recovery
208
+ today is a manual restart, which **will terminate all running sessions**.
209
+
210
+ **Manual restart (macOS default path):**
211
+ ```bash
212
+ kill "$(cat "$HOME/Library/Application Support/peakypanes/daemon.pid")"
213
+ ```
214
+
215
+ **Manual restart (Linux default path):**
216
+ ```bash
217
+ kill "$(cat "$HOME/.config/peakypanes/daemon.pid")"
218
+ ```
219
+
220
+ You can also set `PEAKYPANES_DAEMON_PID` to control the pid file location.
221
+
222
+ ### Proposed UX (future)
223
+ If the app detects a hung daemon, it should show a dialog like:
224
+ **“Restart daemon? This will stop all running sessions and close their PTYs.”**
225
+ This makes the data-loss tradeoff explicit before taking action.
226
+
205
227
  ## Built-in Layouts
206
228
 
207
229
  Core (general) layouts:
@@ -216,7 +238,7 @@ Core (general) layouts:
216
238
  Additional built-ins (specialized):
217
239
  - `dev-2`: editor + shell
218
240
  - `dev-3`: editor + server + shell (default fallback)
219
- - `fullstack`: dev + logs
241
+ - `fullstack`: editor + server + shell + logs
220
242
  - `go-dev`: code/run/test + git
221
243
  - `codex-grid`: 2x4 grid running codex in every pane
222
244
 
@@ -231,50 +253,47 @@ peakypanes layouts export codex-dev > .peakypanes.yml
231
253
  ## Dashboard UI
232
254
 
233
255
  Running `peakypanes` with no subcommand opens the dashboard UI in the current terminal.
234
- Use `peakypanes dashboard --tmux-session` to host the dashboard in a dedicated tmux session.
235
- Use `peakypanes popup` (or `peakypanes dashboard --popup`) from inside tmux for a popup dashboard.
236
- If popups are unsupported, PeakyPanes opens a `peakypanes-dashboard` window in the current tmux session.
237
256
 
238
257
  The dashboard shows:
239
258
  - Projects on top (tabs)
240
- - Sessions on the left (with window counts and expandable windows)
241
- - Live pane preview on the right (window bar at the bottom)
242
- - Lightweight session thumbnails at the bottom (last activity per session)
259
+ - Sessions on the left (with pane counts and expandable panes)
260
+ - Live pane preview on the right (native panes are fully interactive)
243
261
  - Quick reply bar (always visible) and target pane highlight for follow-ups
244
262
 
245
263
  Navigation (always visible):
246
- - `ctrl+a/ctrl+d` project, `ctrl+w/ctrl+s` session, `tab/⇧tab` pane (across windows), `ctrl+g` help
264
+ - `ctrl+a/ctrl+d` project, `ctrl+w/ctrl+s` session/panes, `alt+w/alt+s` session only, `tab/⇧tab` pane, `ctrl+g` help
247
265
 
248
266
  Key bindings (also shown in the help view):
249
267
  Keymap overrides are available in the global config (`~/.config/peakypanes/config.yml`).
250
268
 
251
269
  Project
252
270
  - `ctrl+o` open project picker (creates session detached; stay in dashboard)
253
- - `ctrl+b` close project (hides from tabs; sessions keep running; press k in the dialog to kill)
271
+ - `ctrl+b` toggle sidebar (show/hide sessions list)
272
+ - `alt+c` close project (hides from tabs; sessions keep running; press k in the dialog to kill)
254
273
 
255
274
  Session
256
275
  - `enter` attach/start session (when reply is empty)
257
276
  - `ctrl+n` new session (pick layout)
258
- - `ctrl+t` open in new terminal window
259
277
  - `ctrl+x` kill session
260
278
  - rename session via command palette (`ctrl+p`)
261
279
 
262
280
  Window
263
- - `ctrl+u` toggle window list
264
- - rename window via command palette (`ctrl+p`)
281
+ Pane list
282
+ - `ctrl+u` toggle pane list
265
283
 
266
284
  Pane
267
285
  - rename pane via command palette (`ctrl+p`)
268
286
  - `ctrl+y` peek selected pane in new terminal
269
-
270
- Tmux (inside session)
271
- - `prefix+g` open dashboard popup (tmux prefix is yours)
287
+ - `ctrl+\` toggle terminal focus (native only; configurable via `dashboard.keymap.terminal_focus`)
288
+ - mouse: single-click selects a pane; double-click toggles terminal focus (native only); `esc` exits focus
289
+ - `f7` scrollback mode (native only; configurable via `dashboard.keymap.scrollback`)
290
+ - `f8` copy mode (native only; configurable via `dashboard.keymap.copy_mode`)
272
291
 
273
292
  Other
274
293
  - `ctrl+p` command palette
275
294
  - `ctrl+r` refresh, `ctrl+e` edit config, `ctrl+f` filter, `ctrl+c` quit
276
295
 
277
- Quick reply details: the input is always active—type and press `enter` to send to the highlighted pane. Use `esc` to clear. `tab/⇧tab` still cycles panes while the input is focused.
296
+ Quick reply details: the input is always active—type and press `enter` to send to the highlighted pane. Use `esc` to clear. Toggle terminal focus to send raw keystrokes into the pane. Use scrollback (`f7`) to navigate output and copy mode (`f8`) to select/yank (`v` select, `y` yank, `esc/q` exit).
278
297
 
279
298
  ### Dashboard Config (optional)
280
299
 
@@ -283,20 +302,26 @@ dashboard:
283
302
  refresh_ms: 2000
284
303
  preview_lines: 12
285
304
  preview_compact: true
286
- thumbnail_lines: 1
287
305
  idle_seconds: 20
288
- show_thumbnails: true
289
306
  preview_mode: grid # grid | layout
290
- attach_behavior: new_terminal # current | new_terminal | detached
307
+ sidebar:
308
+ hidden: false
309
+ attach_behavior: current # current | detached
291
310
  keymap:
292
311
  project_left: ["ctrl+a"]
293
312
  project_right: ["ctrl+d"]
294
313
  session_up: ["ctrl+w"]
295
314
  session_down: ["ctrl+s"]
315
+ session_only_up: ["alt+w"]
316
+ session_only_down: ["alt+s"]
296
317
  pane_next: ["tab"]
297
318
  pane_prev: ["shift+tab"]
298
- peek_pane: ["ctrl+y"]
299
- toggle_windows: ["ctrl+u"]
319
+ terminal_focus: ["ctrl+\\"]
320
+ scrollback: ["f7"]
321
+ copy_mode: ["f8"]
322
+ toggle_panes: ["ctrl+u"]
323
+ toggle_sidebar: ["ctrl+b"]
324
+ close_project: ["alt+c"]
300
325
  command_palette: ["ctrl+p"]
301
326
  help: ["ctrl+g"]
302
327
  quit: ["ctrl+c"]
@@ -309,13 +334,13 @@ dashboard:
309
334
  claude: true
310
335
  ```
311
336
 
312
- `attach_behavior` controls what the “attach/start” action does (default `new_terminal`): `current` switches the terminal running PeakyPanes into the session, `new_terminal` opens a fresh terminal to attach, and `detached` only creates the session.
337
+ `attach_behavior` controls what the “attach/start” action does (default `current`): `current` focuses the selected session in the dashboard, and `detached` creates the session without switching focus.
313
338
 
314
339
  ### Agent Status Detection (Codex & Claude Code)
315
340
 
316
341
  PeakyPanes can read per-pane JSON state files to show accurate running/idle/done status for Codex CLI and Claude Code TUI sessions. This is **on by default** and falls back to regex/idle detection if no state file is present. You can disable it via `dashboard.agent_detection`.
317
342
 
318
- State files are written under `${XDG_RUNTIME_DIR:-/tmp}/peakypanes/agent-state` and keyed by `TMUX_PANE` (override with `PEAKYPANES_AGENT_STATE_DIR`).
343
+ State files are written under `${XDG_RUNTIME_DIR:-/tmp}/peakypanes/agent-state` and keyed by `PEAKYPANES_PANE_ID` (override with `PEAKYPANES_AGENT_STATE_DIR`).
319
344
 
320
345
  **Codex CLI (TUI)**
321
346
 
@@ -340,23 +365,6 @@ Example hook command (wire it to each event above in Claude Code):
340
365
  python3 /absolute/path/to/peakypanes/scripts/agent-state/claude-hook.py
341
366
  ```
342
367
 
343
- ### Tmux Config & Key Bindings
344
-
345
- - PeakyPanes **never edits** your tmux config file.
346
- - tmux already reads `~/.tmux.conf` or `~/.config/tmux/tmux.conf` by default.
347
- - If you use a **custom tmux config path**, set `tmux.config` in `~/.config/peakypanes/config.yml`.
348
- PeakyPanes will **source** that file when starting sessions (no overwrite).
349
- - Per-layout tmux options and key bindings are supported:
350
-
351
- ```yaml
352
- settings:
353
- tmux_options:
354
- remain-on-exit: "on"
355
- bind_keys:
356
- - key: g
357
- action: "run-shell \"peakypanes popup\""
358
- ```
359
-
360
368
  ## How Layout Detection Works
361
369
 
362
370
  1. `--layout` flag (highest priority)
@@ -379,20 +387,14 @@ Race tests:
379
387
  go test ./... -race
380
388
  ```
381
389
 
382
- Tmux integration tests (requires tmux; opt-in):
383
-
384
- ```bash
385
- PEAKYPANES_INTEGRATION=1 go test ./internal/tmuxctl -run Integration -count=1
386
- ```
387
-
388
390
  Manual npm smoke run (fresh HOME/XDG config):
389
391
 
390
392
  ```bash
391
393
  scripts/fresh-run
392
- scripts/fresh-run 0.0.2 --with-project
394
+ scripts/fresh-run 0.0.6 --with-project
393
395
  ```
394
396
 
395
- GitHub Actions runs gofmt checks, go vet, go test with coverage, race, and tmux integration tests on Linux.
397
+ GitHub Actions runs gofmt checks, go vet, go test with coverage, and race on Linux.
396
398
 
397
399
  ## Release
398
400
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "peakypanes",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "Tmux layout manager with YAML based configuration.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/regenrek/peakypanes",
@@ -12,10 +12,10 @@
12
12
  "peakypanes": "bin/peakypanes.js"
13
13
  },
14
14
  "optionalDependencies": {
15
- "peakypanes-darwin-x64": "0.0.4",
16
- "peakypanes-darwin-arm64": "0.0.4",
17
- "peakypanes-linux-x64": "0.0.4",
18
- "peakypanes-linux-arm64": "0.0.4"
15
+ "peakypanes-darwin-x64": "0.0.6",
16
+ "peakypanes-darwin-arm64": "0.0.6",
17
+ "peakypanes-linux-x64": "0.0.6",
18
+ "peakypanes-linux-arm64": "0.0.6"
19
19
  },
20
20
  "engines": {
21
21
  "node": ">=18"
@@ -70,7 +70,7 @@ def map_event_to_state(event: str, payload: dict) -> str:
70
70
 
71
71
 
72
72
  def main() -> int:
73
- pane_id = os.environ.get("TMUX_PANE", "").strip()
73
+ pane_id = os.environ.get("PEAKYPANES_PANE_ID", "").strip()
74
74
  if not pane_id:
75
75
  return 0
76
76
  try:
@@ -36,7 +36,7 @@ def write_state(pane_id: str, state: str, tool: str, payload: dict) -> None:
36
36
 
37
37
 
38
38
  def main() -> int:
39
- pane_id = os.environ.get("TMUX_PANE", "").strip()
39
+ pane_id = os.environ.get("PEAKYPANES_PANE_ID", "").strip()
40
40
  if not pane_id:
41
41
  return 0
42
42
  if len(sys.argv) < 2: