projmux 0.6.6 → 0.7.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-ko.md +36 -5
- package/README.md +40 -12
- package/docs/agent-workflow.md +24 -16
- package/docs/ai-agent-shortcuts.md +11 -6
- package/docs/architecture.md +4 -3
- package/docs/assets/projmux-ai-attention.gif +0 -0
- package/docs/assets/projmux-skill-workflow.gif +0 -0
- package/docs/cli.md +89 -41
- package/docs/configuration.md +51 -22
- package/docs/hooks.md +33 -0
- package/docs/install.md +8 -8
- package/docs/keybindings.md +59 -33
- package/docs/native-picker-no-fzf-poc.md +3 -2
- package/docs/native-picker-parity.md +6 -3
- package/docs/notify-queue.md +99 -26
- package/docs/session-restore.md +8 -4
- package/docs/settings-ia.md +17 -7
- package/docs/statusbar.md +34 -7
- package/docs/testing.md +10 -3
- package/docs/upgrading.md +10 -4
- package/docs/usage-tracking.md +42 -13
- package/package.json +5 -5
- package/docs/assets/projmux-shell-sidebar.gif +0 -0
- package/docs/readme-hero-gif-recording.md +0 -97
package/docs/configuration.md
CHANGED
|
@@ -87,14 +87,15 @@ language.
|
|
|
87
87
|
## Keymap File
|
|
88
88
|
|
|
89
89
|
Settings > Keybindings is the normal in-app editor for action keys. It lists
|
|
90
|
-
actions with current
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
90
|
+
actions with the current active keys and one state: Default, Custom, Available,
|
|
91
|
+
or Unbound. Open an action to see the action label, state, a flat Keys list,
|
|
92
|
+
Options, and a collapsed Troubleshooting row. Create flows start from
|
|
93
|
+
`+ Add key`, deletion lives under each key's detail, and action-level state
|
|
94
|
+
changes such as Unbind or Reset live under Options. Successful saves report the
|
|
95
|
+
keybinding as saved; failures identify the stage that failed.
|
|
96
|
+
|
|
97
|
+
Raw sequences that cannot be safely represented as a direct keybinding are not
|
|
98
|
+
persisted. Use Settings to save a custom key. When key delivery needs
|
|
98
99
|
terminal-layer remediation, first try the key in `projmux shell`, then run
|
|
99
100
|
`projmux setup` from the raw terminal, then use `projmux init` for supported
|
|
100
101
|
terminal adapters.
|
|
@@ -127,7 +128,13 @@ do not break. Settings preserves existing prefix entries when rewriting the
|
|
|
127
128
|
file, but does not create new prefix keys, and generated tmux config no longer
|
|
128
129
|
binds the old action prefix chords.
|
|
129
130
|
|
|
130
|
-
|
|
131
|
+
Settings > Keybindings names `AISplitPickerToggle` as the AI split popup
|
|
132
|
+
picker toggle. That action opens or closes the picker UI and is separate from
|
|
133
|
+
the direct AI pane actions, `ai-split-right` and `ai-split-down`. The direct
|
|
134
|
+
actions create a new managed AI pane each time they run, leaving existing AI
|
|
135
|
+
panes in place. `right` and `down` choose where the new pane is created.
|
|
136
|
+
|
|
137
|
+
Use an empty `keys` list to disable direct plain keys for the action when
|
|
131
138
|
editing the file by hand:
|
|
132
139
|
|
|
133
140
|
```toml
|
|
@@ -151,7 +158,7 @@ The file currently affects generated tmux config from `projmux tmux
|
|
|
151
158
|
print-config`, `projmux tmux install`, `projmux tmux print-app-config`,
|
|
152
159
|
`projmux tmux install-app`, and `projmux shell`. Terminal init adapters such as
|
|
153
160
|
Ghostty and Windows Terminal install built-in plain-byte mappings where needed;
|
|
154
|
-
they do not read `keymap.toml` or copy saved
|
|
161
|
+
they do not read `keymap.toml` or copy saved keys into terminal configs.
|
|
155
162
|
Changing terminal-layer mappings still requires rerunning `projmux init` and
|
|
156
163
|
restarting the terminal where that terminal requires it.
|
|
157
164
|
|
|
@@ -183,6 +190,14 @@ picker frames also apply the built-in fallback `background`/`foreground` tokens
|
|
|
183
190
|
so picker-owned padding, empty rows, footer rows, and preview gaps do not
|
|
184
191
|
inherit the terminal default background.
|
|
185
192
|
|
|
193
|
+
Native picker popups launched through `projmux tmux popup-toggle` also pass a
|
|
194
|
+
per-popup tmux 3.4 `display-popup -s` body style using the effective theme
|
|
195
|
+
`background`/`foreground` tmux tokens. This styles only the tmux popup body
|
|
196
|
+
before the native renderer draws. It does not set global `popup-style` or
|
|
197
|
+
`popup-border-style`, and it does not change shell pane backgrounds,
|
|
198
|
+
`default-style`, `window-style`, OSC terminal backgrounds, or the general
|
|
199
|
+
status/window palette.
|
|
200
|
+
|
|
186
201
|
Resolver schema shape:
|
|
187
202
|
|
|
188
203
|
```toml
|
|
@@ -273,11 +288,12 @@ user/global preference in this release.
|
|
|
273
288
|
| `PROJMUX_FOCUS_DEBUG` | When non-empty, `projmux focus` prints one telemetry line to stderr. |
|
|
274
289
|
| `PROJMUX_PICKER_BACKEND` | Legacy picker backend override. Any value, including old `fzf` settings, now resolves to the native picker. |
|
|
275
290
|
| `PROJMUX_INSTALLER` | Installer source hint used by update flows. npm installs set this automatically; advanced release installs can set `github-release`. |
|
|
291
|
+
| `PROJMUX_SHELL_UPDATE_CHECK_TIMEOUT_MS` | Timeout in milliseconds for the best-effort release check attempted by `projmux shell` when the update cache is missing or stale. Invalid, zero, or negative values use the default. |
|
|
276
292
|
|
|
277
293
|
## Welcome State
|
|
278
294
|
|
|
279
|
-
`projmux shell`
|
|
280
|
-
directory, normally:
|
|
295
|
+
`projmux shell` still reads and rewrites legacy per-version welcome state under
|
|
296
|
+
the projmux state directory for attach-popup compatibility, normally:
|
|
281
297
|
|
|
282
298
|
```text
|
|
283
299
|
${XDG_STATE_HOME:-$HOME/.local/state}/projmux/welcomed-v<version>.json
|
|
@@ -295,11 +311,21 @@ The current schema is:
|
|
|
295
311
|
}
|
|
296
312
|
```
|
|
297
313
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
314
|
+
This file no longer suppresses the shell-entry welcome. `skip_version` and
|
|
315
|
+
`last_welcomed_version` remain readable for legacy state and pending attach
|
|
316
|
+
popup compatibility, but the automatic shell prompt now uses release skip state
|
|
317
|
+
instead.
|
|
318
|
+
|
|
319
|
+
Update prompt skips are stored by latest release tag under the update cache
|
|
320
|
+
directory:
|
|
321
|
+
|
|
322
|
+
```text
|
|
323
|
+
${XDG_CACHE_HOME:-$HOME/.cache}/projmux/update-skip.json
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
When `tag_name` matches the fresh cached latest release tag, `projmux shell`
|
|
327
|
+
continues without offering the update actions. A newer latest tag makes the
|
|
328
|
+
prompt eligible again.
|
|
303
329
|
|
|
304
330
|
Example:
|
|
305
331
|
|
|
@@ -401,7 +427,9 @@ only a generic in-app queue/sidebar/statusbar row; it does not fire OS toast,
|
|
|
401
427
|
The OS-level dispatch carries three modes. The in-app notify queue, the
|
|
402
428
|
statusbar segment, and the attention badge stay live regardless of which
|
|
403
429
|
mode is active — only the toast / notify-send / auto-raise fan-out is
|
|
404
|
-
gated here.
|
|
430
|
+
gated here. The same mode also gates `projmux focus` post-switch osfocus
|
|
431
|
+
dispatch: only `raise` asks the host terminal to come forward after a
|
|
432
|
+
successful tmux focus.
|
|
405
433
|
|
|
406
434
|
| Mode | On push | On click |
|
|
407
435
|
| --- | --- | --- |
|
|
@@ -413,7 +441,8 @@ Click activation is wired only for `raise`. The `projmux://` URI handler is
|
|
|
413
441
|
registered on the first `raise` Notify of each tmux server (gated by the
|
|
414
442
|
`@projmux_uri_protocol_registered_v6` marker). The
|
|
415
443
|
mode only controls whether a toast fires at all and whether to follow it
|
|
416
|
-
up with an on-push auto-raise.
|
|
444
|
+
up with an on-push auto-raise. `off` / `none` and `notify` also suppress
|
|
445
|
+
the focus-triggered osfocus raise after `projmux focus`.
|
|
417
446
|
|
|
418
447
|
Resolution order (highest priority first):
|
|
419
448
|
|
|
@@ -551,8 +580,8 @@ while `on` and `off` take precedence. Auto-save only updates the latest
|
|
|
551
580
|
snapshot. Named snapshots are manual and are never updated by auto-save.
|
|
552
581
|
|
|
553
582
|
Project open from the Alt-1 sidebar defaults to opening a closed project as an
|
|
554
|
-
`Empty session`. The optional `Settings >
|
|
555
|
-
enables the native sidebar `Start project` step. Rows appear as `Latest
|
|
583
|
+
`Empty session`. The optional `Settings > Session State > Sidebar startup
|
|
584
|
+
picker` toggle enables the native sidebar `Start project` step. Rows appear as `Latest
|
|
556
585
|
snapshot`, named snapshot rows, `Empty session`, and `Back`. `Latest snapshot`
|
|
557
586
|
is the snapshot auto-save that changes as auto-save runs; named snapshots are
|
|
558
587
|
fixed snapshots. Rows include saved-at date/time metadata when projmux can
|
|
@@ -571,7 +600,7 @@ Default `projmux shell` no longer opens a startup picker or replays session-stat
|
|
|
571
600
|
snapshots before attach. It still derives the default app session identity and
|
|
572
601
|
startup directory from the current project context when available; otherwise it
|
|
573
602
|
uses the `home` target and home directory. Session-state restore selection is
|
|
574
|
-
limited to the
|
|
603
|
+
limited to the Session State sidebar startup picker.
|
|
575
604
|
|
|
576
605
|
Settings > Session State is global settings only: global auto-save, auto-save
|
|
577
606
|
interval, and storage/retention policy. Settings > Project > Session State
|
package/docs/hooks.md
CHANGED
|
@@ -606,6 +606,39 @@ Codex and are managed from `Settings > Notifications > Hook quiet policy`.
|
|
|
606
606
|
They only affect ingest delivery; `projmux ai integrate claude` still uses the
|
|
607
607
|
catalog `install` field for installed hook events.
|
|
608
608
|
|
|
609
|
+
## Antigravity Hook Ingest
|
|
610
|
+
|
|
611
|
+
`projmux ai ingest antigravity-hook < payload.json` is available for manual
|
|
612
|
+
Antigravity CLI `agy` hook/statusline payloads. Projmux does not provide
|
|
613
|
+
`projmux ai integrate antigravity`, does not install Antigravity hooks, and
|
|
614
|
+
does not mutate Antigravity user config. The Delivery sources diagnostic
|
|
615
|
+
therefore reports Antigravity as a read-only unsupported/manual row. If users
|
|
616
|
+
wire it by hand, use an absolute `projmux` command path or a known cwd because
|
|
617
|
+
relative command paths failed the Phase 0b smoke.
|
|
618
|
+
|
|
619
|
+
The default known Antigravity catalog records only observed Phase 0b signals
|
|
620
|
+
and marks them `install: false`:
|
|
621
|
+
|
|
622
|
+
| Event/signal | Behavior |
|
|
623
|
+
| --- | --- |
|
|
624
|
+
| `PostInvocation` | marks the matched pane hook-active and writes a quiet ingest diagnostic; no notify queue entry is pushed |
|
|
625
|
+
| `Stop` | pushes a completion row, or a critical error row when `error` is present or `terminationReason` is non-normal |
|
|
626
|
+
| `Statusline` with `tool_confirmation_pending=true` | pushes a critical approval row; this is only active when a statusline/manual status payload is wired to ingest |
|
|
627
|
+
| `Statusline` without `tool_confirmation_pending=true` | marks the matched pane hook-active and writes a quiet ingest diagnostic |
|
|
628
|
+
| unknown events | mark the matched pane hook-active and write quiet ingest diagnostics only |
|
|
629
|
+
|
|
630
|
+
Antigravity notify rows use `agent=antigravity` metadata. Accepted fields
|
|
631
|
+
include `conversationId`/`conversation_id`, `cwd`, `workspace.path`,
|
|
632
|
+
`transcriptPath`, `terminationReason`, `error`, `fullyIdle`, `agent_state`,
|
|
633
|
+
`context_window`, and nested `statusline.tool_confirmation_pending`.
|
|
634
|
+
Antigravity ingest uses `conversationId` as pane thread metadata for matching
|
|
635
|
+
and as session-state resume metadata. Session restore uses
|
|
636
|
+
`agy --conversation <uuid>` only when that id is present and UUID-shaped;
|
|
637
|
+
otherwise preview and doctor render `resume unavailable`. Antigravity usage
|
|
638
|
+
quota HUD support remains unsupported because the stable usage signal is
|
|
639
|
+
`context-window-only` statusline data, not 5-hour/weekly quota data. Raw
|
|
640
|
+
payloads or transcript contents are not stored.
|
|
641
|
+
|
|
609
642
|
## Ingest Debug Log
|
|
610
643
|
|
|
611
644
|
Every `projmux ai ingest ...` path appends compact JSONL diagnostics to
|
package/docs/install.md
CHANGED
|
@@ -28,14 +28,14 @@ projmux shell
|
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
Each `projmux shell` launch prints a short welcome with the current version,
|
|
31
|
-
detach/exit keys,
|
|
32
|
-
Press Enter to continue
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
detach/exit keys, a bootstrap reminder, and cached release status when
|
|
32
|
+
available. Press Enter to continue into the shell.
|
|
33
|
+
|
|
34
|
+
If an update is available, the same shell-entry prompt uses one action
|
|
35
|
+
vocabulary: Enter continues, `u` upgrades by invoking `projmux update apply`,
|
|
36
|
+
and `s` skips that latest release tag until a newer tag appears. For `source`
|
|
37
|
+
or unknown installer sources, `u` prints installer guidance and then continues
|
|
38
|
+
shell entry.
|
|
39
39
|
|
|
40
40
|
To revisit the guide later, run `projmux welcome`, or use Settings > About >
|
|
41
41
|
Welcome inside the app to open it in a visible viewer. Set `PROJMUX_WELCOME=off` before
|
package/docs/keybindings.md
CHANGED
|
@@ -4,7 +4,7 @@ projmux is keyboard-driven, but the guaranteed launch contract is small:
|
|
|
4
4
|
fresh installs bind `Alt-1` through `Alt-5` as plain Meta sequences
|
|
5
5
|
(`M-1`..`M-5`, bytes `\x1b1`..`\x1b5`). Other actions remain discoverable in
|
|
6
6
|
Settings > Keybindings. Transport-dependent actions keep their built-in
|
|
7
|
-
transport default key, and Settings can add separate safe tmux plain
|
|
7
|
+
transport default key, and Settings can add separate safe tmux plain keys to
|
|
8
8
|
the same action. They are not installed as terminal-specific User-key
|
|
9
9
|
fallbacks. `UserN` and `CSI-u` are legacy/removal/unsupported targets, not
|
|
10
10
|
supported fallback guidance.
|
|
@@ -15,14 +15,13 @@ The recommended path when a key does not fire:
|
|
|
15
15
|
2. Run `projmux setup` outside tmux to see which bytes reach the process.
|
|
16
16
|
3. For supported terminals, preview `projmux init [terminal]`; add `--apply`
|
|
17
17
|
only after reviewing the merge.
|
|
18
|
-
4. For unsupported terminals, configure plain Meta bytes or add a
|
|
18
|
+
4. For unsupported terminals, configure plain Meta bytes or add a custom key in
|
|
19
19
|
Settings > Keybindings.
|
|
20
20
|
|
|
21
|
-
Settings
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
and tmux User keys are rejected as aliases.
|
|
21
|
+
Settings saves safe tmux plain chords for actions. Successful saves use simple
|
|
22
|
+
confirmation copy; if saving, runtime config update, or active tmux reload
|
|
23
|
+
fails, the error names the failed stage. Raw escape payloads, Windows Terminal
|
|
24
|
+
`sendInput` strings, and tmux User keys are rejected as action keys.
|
|
26
25
|
|
|
27
26
|
## Quick Start
|
|
28
27
|
|
|
@@ -32,10 +31,14 @@ These shortcuts are the guaranteed launch defaults. They need no tmux prefix.
|
|
|
32
31
|
| --- | --- |
|
|
33
32
|
| `Alt-1` | Project sidebar |
|
|
34
33
|
| `Alt-2` | Notify sidebar |
|
|
35
|
-
| `Alt-3` |
|
|
36
|
-
| `Alt-4` | AI split picker |
|
|
34
|
+
| `Alt-3` | Recent Windows |
|
|
35
|
+
| `Alt-4` | AI split popup picker |
|
|
37
36
|
| `Alt-5` | Settings |
|
|
38
37
|
|
|
38
|
+
`RecentWindows:Open` opens the cross-project recent windows queue. It switches
|
|
39
|
+
to the selected live tmux window using that window's current active pane; it is
|
|
40
|
+
separate from `last-pane` and from the existing-session popup.
|
|
41
|
+
|
|
39
42
|
The tmux prefix remains the upstream default `Ctrl-b`. Inside a running
|
|
40
43
|
session, `Ctrl-b ?` lists the live tmux bindings.
|
|
41
44
|
|
|
@@ -43,43 +46,60 @@ session, `Ctrl-b ?` lists the live tmux bindings.
|
|
|
43
46
|
|
|
44
47
|
Settings > Keybindings lists the full action catalogue. In particular, sidebar
|
|
45
48
|
keymap actions, pane switching, window switching, and rename actions remain
|
|
46
|
-
visible.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
visible.
|
|
50
|
+
|
|
51
|
+
The Settings flow is intentionally simple: the root is one action list with a
|
|
52
|
+
key summary and state. The key summary uses the first key plus `+N`, or
|
|
53
|
+
`Not bound` when no key is active. State vocabulary is limited to Default,
|
|
54
|
+
Custom, Available, and Unbound. Each action detail shows the action label,
|
|
55
|
+
state, a flat Keys list with `+ Add key`, Options, and a collapsed
|
|
56
|
+
Troubleshooting row with Test key delivery and Advanced... entry points. Key
|
|
57
|
+
rows open key detail for Remove key and Test key. Add key opens Press a key by
|
|
58
|
+
default; Enter key name and raw diagnostics live under Advanced. Options covers
|
|
59
|
+
unbinding the action and reset/use-default flows. Diagnostic/probe/init
|
|
60
|
+
workflows are not first-class Settings tabs; use `projmux setup` and
|
|
61
|
+
`projmux init` from the terminal when key delivery needs remediation.
|
|
62
|
+
|
|
63
|
+
Optional direct keys can be added for actions such as:
|
|
56
64
|
|
|
57
65
|
| Canonical action | Meaning |
|
|
58
66
|
| --- | --- |
|
|
67
|
+
| `RecentWindows:Open` | Recent windows queue across projects |
|
|
59
68
|
| `ProjectSwitcherToggle` | Project switcher popup |
|
|
69
|
+
| `AISplitPickerToggle` | AI split popup picker; pressing again closes the picker popup |
|
|
70
|
+
| `ai-split-right` | Open a new direct AI split to the right |
|
|
71
|
+
| `ai-split-down` | Open a new direct AI split below |
|
|
60
72
|
| `new-window` | New tmux window in the current pane directory |
|
|
61
73
|
| `rename-window` | Rename the current tmux window |
|
|
62
74
|
|
|
75
|
+
`AISplitPickerToggle` is the `Alt-4` popup picker toggle. It opens or closes
|
|
76
|
+
the picker UI where the user chooses the AI split mode. It is separate from
|
|
77
|
+
the direct `ai-split-right` and `ai-split-down` actions.
|
|
78
|
+
|
|
79
|
+
The direct AI split actions create a new managed AI pane each time they run.
|
|
80
|
+
Existing AI panes are left in place; the requested direction controls where the
|
|
81
|
+
new pane is created.
|
|
82
|
+
|
|
63
83
|
Pane switching is catalogued as transport-dependent and the generated app tmux
|
|
64
84
|
config binds `M-Left`, `M-Right`, `M-Up`, and `M-Down` to `select-pane`
|
|
65
85
|
movement. Previous/next window remain transport-dependent and the generated app
|
|
66
86
|
tmux config binds `M-S-Left` / `M-S-Right` to the tmux window navigation
|
|
67
87
|
commands. These default transport keys are always rendered by projmux, because
|
|
68
88
|
delivery still depends on the terminal forwarding the modifier-arrow sequence.
|
|
69
|
-
Settings can add extra safe plain
|
|
70
|
-
`previous-window`; those
|
|
89
|
+
Settings can add extra safe plain keys, such as `M-[` for
|
|
90
|
+
`previous-window`; those keys are saved to `keymap.toml` as `keys = [...]`
|
|
71
91
|
without storing or replacing the transport default. Rename actions no longer
|
|
72
92
|
have a built-in terminal fallback; use tmux's prefix rename flow or configure
|
|
73
|
-
an explicit safe
|
|
93
|
+
an explicit safe key where the action is editable.
|
|
74
94
|
|
|
75
95
|
## Product Requirements
|
|
76
96
|
|
|
77
97
|
Settings > Keybindings stays a discovery surface. It must continue to expose
|
|
78
98
|
launch toggles, sidebar keymap actions, picker-local actions, pane switching,
|
|
79
|
-
window switching, and rename actions. The
|
|
80
|
-
terminal remediation surface:
|
|
81
|
-
terminal mapping preview/apply, and init execution rows stay out of
|
|
82
|
-
detail.
|
|
99
|
+
window switching, and rename actions. The basic Settings flow is not the
|
|
100
|
+
terminal remediation surface: key-role replacement, disable-default, typed
|
|
101
|
+
fallback, terminal mapping preview/apply, and init execution rows stay out of
|
|
102
|
+
the action detail.
|
|
83
103
|
|
|
84
104
|
The product model does not support `UserN` or `CSI-u` as fallback guidance.
|
|
85
105
|
Windows Terminal and Ghostty adapters use built-in plain Meta/control bytes or
|
|
@@ -99,10 +119,14 @@ by different picker surfaces, while conflicts inside one surface are rejected.
|
|
|
99
119
|
| `SessionPopup:KillSession` | Kill the focused session |
|
|
100
120
|
| `SessionPopup:CyclePreviewWindowPrev` / `SessionPopup:CyclePreviewWindowNext` | Preview windows |
|
|
101
121
|
| `SessionPopup:CyclePreviewPanePrev` / `SessionPopup:CyclePreviewPaneNext` | Preview panes |
|
|
102
|
-
| `NotifySidebar:Ack` / `NotifySidebar:ClearNonCritical` / `NotifySidebar:ClearAll` | Manage notifications |
|
|
122
|
+
| `NotifySidebar:Ack` / `NotifySidebar:AckGroup` / `NotifySidebar:ClearNonCritical` / `NotifySidebar:ClearAll` | Manage notifications |
|
|
123
|
+
|
|
124
|
+
Notify sidebar Right/Left child-row show/hide behavior is picker-local and is
|
|
125
|
+
not part of the Settings action catalog. `NotifySidebar:AckGroup` defaults to
|
|
126
|
+
uppercase `A`, distinct from `NotifySidebar:Ack` on lowercase `a`.
|
|
103
127
|
|
|
104
|
-
Runtime picker footers render key guides from the merged keymap,
|
|
105
|
-
|
|
128
|
+
Runtime picker footers render key guides from the merged keymap, using the
|
|
129
|
+
first active key as the representative key.
|
|
106
130
|
|
|
107
131
|
## Keymap File
|
|
108
132
|
|
|
@@ -132,12 +156,14 @@ Legacy popup IDs such as `sessionizer-sidebar`, `notify-sidebar`,
|
|
|
132
156
|
`session-popup`, `ai-split-picker-right`, `ai-split-settings`, and
|
|
133
157
|
`sessionizer` still read. Settings and new docs show the canonical toggle
|
|
134
158
|
names: `ProjectSidebarToggle`, `NotifySidebarToggle`, `SessionPopupToggle`,
|
|
135
|
-
`AISplitPickerToggle`, `SettingsToggle`, and `ProjectSwitcherToggle`.
|
|
159
|
+
`AISplitPickerToggle`, `SettingsToggle`, and `ProjectSwitcherToggle`. Direct
|
|
160
|
+
AI split actions keep their command IDs, `ai-split-right` and `ai-split-down`,
|
|
161
|
+
so Settings can distinguish them from the `Alt-4` popup picker toggle.
|
|
136
162
|
|
|
137
163
|
## Diagnose: `projmux setup`
|
|
138
164
|
|
|
139
165
|
Run `projmux setup` outside tmux to find out which projmux keys reach the raw
|
|
140
|
-
terminal. Settings > Keybindings remains the action
|
|
166
|
+
terminal. Settings > Keybindings remains the action-key editor; setup is the
|
|
141
167
|
terminal delivery diagnostic.
|
|
142
168
|
|
|
143
169
|
| Status | Meaning |
|
|
@@ -171,7 +197,7 @@ projmux init --allow-symlink
|
|
|
171
197
|
|
|
172
198
|
The merge is idempotent: matching bindings are no-ops, missing bindings are
|
|
173
199
|
added, and keys already mapped to a different user action are skipped with a
|
|
174
|
-
warning. `projmux init` does not read `keymap.toml`; direct tmux
|
|
200
|
+
warning. `projmux init` does not read `keymap.toml`; direct tmux keys still
|
|
175
201
|
belong in Settings > Keybindings or the keymap file.
|
|
176
202
|
|
|
177
203
|
### Ghostty
|
|
@@ -206,7 +232,7 @@ previous/next window:
|
|
|
206
232
|
"actions": [
|
|
207
233
|
{ "command": { "action": "sendInput", "input": "\u001b1" }, "id": "User.projmuxSidebar" },
|
|
208
234
|
{ "command": { "action": "sendInput", "input": "\u001b2" }, "id": "User.projmuxNotifySidebar" },
|
|
209
|
-
{ "command": { "action": "sendInput", "input": "\u001b3" }, "id": "User.
|
|
235
|
+
{ "command": { "action": "sendInput", "input": "\u001b3" }, "id": "User.projmuxRecentWindows" },
|
|
210
236
|
{ "command": { "action": "sendInput", "input": "\u001b4" }, "id": "User.projmuxAIPicker" },
|
|
211
237
|
{ "command": { "action": "sendInput", "input": "\u001b5" }, "id": "User.projmuxSettings" },
|
|
212
238
|
{ "command": { "action": "sendInput", "input": "\u0002r" }, "id": "User.projmuxAISplitRight" },
|
|
@@ -112,7 +112,7 @@ The fzf compatibility surface for the native engine is tracked in
|
|
|
112
112
|
the top border off screen.
|
|
113
113
|
- Native preview panes normalize tabs and control bytes before horizontal
|
|
114
114
|
clipping, preventing long preview rows from wrapping and consuming extra
|
|
115
|
-
vertical viewport rows in
|
|
115
|
+
vertical viewport rows in session popups.
|
|
116
116
|
- Native sidebar list scrollbars use the fixed list viewport as their track and
|
|
117
117
|
measure multi-line cards in rendered rows, so the thumb does not shrink or
|
|
118
118
|
jump when card heights vary.
|
|
@@ -179,8 +179,9 @@ Manual UX checks for the Docker sandbox:
|
|
|
179
179
|
- Alt-1 opens with the top border/title visible, not clipped.
|
|
180
180
|
- Vertical borders stay continuous while moving Up/Down.
|
|
181
181
|
- Alt-1 closes the sidebar immediately when pressed again.
|
|
182
|
-
- Alt-2, Alt-
|
|
182
|
+
- Alt-2, Alt-4, and Alt-5 open their matching native popups and close
|
|
183
183
|
on the same Alt key immediately.
|
|
184
|
+
- Alt-3 opens Recent Windows.
|
|
184
185
|
- Arrow keys move selection without leaking `^[[` text into the query.
|
|
185
186
|
|
|
186
187
|
`fzf` is intentionally not installed in the image.
|
|
@@ -32,6 +32,7 @@ native picker engine and is not a public dependency-policy change.
|
|
|
32
32
|
| close `--bind key:abort` | Esc, Ctrl-C, Alt-N, Ctrl-Alt-S variants | Covered | `CloseActions`; `TestNativeRunnerUsesSharedCloseActions` |
|
|
33
33
|
| terminal modified-key encoding | legacy parser fixtures, Ghostty/kitty-style modified keys | Covered | native handles app-specific parser fixtures, generic modified letters/digits, and non-text keys such as Enter/Esc/Backspace/Tab; this is backend parity, not product fallback guidance; `TestNativeInteractiveSupportsCSIuAppKeyBindings` |
|
|
34
34
|
| `execute-silent(...)+refresh-preview` | switch/session preview cycling | Covered for command execution and rerender loop | `pickercompat.PickerOptions`/`pickercompat.OptionsFromPicker`; `TestNativeInteractiveRunsCustomActionCommandAndRefreshes`; `TestPickerOptionsMapsCompatBindingsToContractActions`; Docker no-fzf e2e sends `Right` and `Alt-Down` before selection |
|
|
35
|
+
| action-local/event-backed mutable refresh | notify sidebar `a` ack and `x` non-critical clear; notify sidebar queue-write event refresh; switch sidebar `Ctrl-X` kill | Covered for in-session row/live-state refresh without picker restart | `picker.Action.Mutate` returns a `DeferredUpdate`, notify queue-write events trigger the same `DeferredUpdate` path after an event arrives, and both reuse the native frame diff renderer plus value-then-clamp selection preservation; `TestNativeInteractiveCustomActionMutatesItemsAndRefreshes`; `TestNativeInteractiveCustomActionRefreshPreservesSelectedValue`; `TestNativeInteractiveDeferredUpdateTriggerRefreshesRepeatedly`; notify sidebar app tests assert one picker invocation with refreshed rows/live state and event subscription; switch sidebar kill app tests assert one native picker invocation with refreshed rows/preview and previous-live-session guard preservation |
|
|
35
36
|
| `focus:execute-silent(...)` | switch sidebar focus | Covered | native renders the selection frame diff before running sidebar focus commands so movement stays visible before tmux focus side effects; `runNativeFocusAction`; `TestNativeInteractiveRunsFocusActionOnSelectionChange` |
|
|
36
37
|
| `start:pos(N)` | switch sidebar initial row | Covered | `pickercompat.PickerOptions`/`pickercompat.OptionsFromPicker`; `TestPickerOptionsFromCompatPickerMapsStartPosToInitialIndex`; `TestPickerOptionsMapsCompatBindingsToContractActions` |
|
|
37
38
|
| `--preview` | switch, sessions | Covered by command output | `nativePreviewLines`; `TestNativeInteractiveRendersSelectedPreview` |
|
|
@@ -47,7 +48,7 @@ native picker engine and is not a public dependency-policy change.
|
|
|
47
48
|
| alternate-screen lifecycle | fzf fullscreen picker screen restore | Covered | native frame updates and screen exit return to column 0 before terminal control sequences, screen exit resets styles plus clears the alternate buffer from the home cursor before restore, and real TTY restores get a short settle window before caller handoff; `nativeScreenEnter`; `TestNativeInteractiveUsesAlternateScreen`; `TestRenderFullFrameUpdateAlwaysHomesAndWritesFrame` |
|
|
48
49
|
| frame content width | fzf border inner width | Covered | `ContentLayout` uses the frame inner width so separators and rows reach the right border; `TestRendererContentLayoutUsesFrameInnerWidth` |
|
|
49
50
|
| picker-owned app background | native picker frame interior | Covered for renderer-owned cells | `ThemeFromEffective` applies built-in fallback and explicit effective background/foreground SGR to the native frame, and frame rows resume the app style after embedded resets so content padding, empty no-footer rows, footer rows, scrollbars, and preview gaps do not leak terminal default background; `TestThemeFromEffectiveFallbackPaintsFrameBackground`; `TestRendererFrameBackgroundResumesAfterContentResetBeforePadding`; `TestNativeInteractiveNoFooterBlankRowsUseThemeBackground`; `TestNativeInteractiveSplitPreviewGapsUseThemeBackground`; `TestNativeInteractiveSettingsAIBadgeStyleLongPreviewClampsFrameRows` |
|
|
50
|
-
| tmux popup frame interaction | native picker popups launched through `popup-toggle` | Covered for native backend popups | `popup-toggle` passes tmux `display-popup -B` when `PROJMUX_PICKER_BACKEND=native`, so the native picker owns the visible frame instead of double-drawing with the tmux popup border; native Alt-1 uses a compact native-only minimum while fzf keeps the previous project sidebar minimum; Alt-1/Alt-2 sidebar heights reserve two bottom statusbar rows; Alt-2 notify sidebar keeps the fzf-like `24%` / min `64` baseline; `TestAppRunTmuxPopupToggleUsesBorderlessPopupForNativeBackend`; `TestSessionizerSidebarWidthKeepsFZFMinimum`; `TestSidebarPopupHeightLeavesStatusbarRows`; `TestNotifySidebarWidthMatchesFZFBaseline`; `TestAppRunTmuxPopupToggleKeepsNotifySidebarFZFSizingForNative` |
|
|
51
|
+
| tmux popup frame interaction | native picker popups launched through `popup-toggle` | Covered for native backend popups | `popup-toggle` passes tmux `display-popup -B` when `PROJMUX_PICKER_BACKEND=native`, so the native picker owns the visible frame instead of double-drawing with the tmux popup border; tmux 3.4 per-command `display-popup -s` is used for the popup body style, setting `bg`/`fg` from the same effective theme tmux background/foreground tokens so tmux's blank/pre-draw popup body matches the native picker surface before the app renderer paints; no global `popup-style`, `popup-border-style`, shell pane background, `default-style`, `window-style`, OSC background, or status/window palette options are changed; native Alt-1 uses a compact native-only minimum while fzf keeps the previous project sidebar minimum; Alt-1/Alt-2 sidebar heights reserve two bottom statusbar rows; Alt-2 notify sidebar keeps the fzf-like `24%` / min `64` baseline; `TestAppRunTmuxPopupToggleUsesBorderlessPopupForNativeBackend`; `TestAppRunTmuxPopupToggleUsesNativePopupBodyStyleFromEffectiveTheme`; `TestBuildPopupToggleWithPickerBackendStylesNativeOnly`; `TestBuildDisplayPopupArgsAddsBodyStyle`; `TestSessionizerSidebarWidthKeepsFZFMinimum`; `TestSidebarPopupHeightLeavesStatusbarRows`; `TestNotifySidebarWidthMatchesFZFBaseline`; `TestAppRunTmuxPopupToggleKeepsNotifySidebarFZFSizingForNative` |
|
|
51
52
|
| optional native titlebar | native picker popup frame | Covered for empty-title compatibility and opt-in titles | `picker.Options.Title`; `RenderFrameWithTitle`; `ContentLayoutWithTitle`; empty titles keep the prior frame unchanged, non-empty titles render in a picker-owned section below the top border, titlebar text/divider/chip gaps inherit the frame background/foreground instead of a separate titlebar overlay ANSI layer, and the native Alt-1 project sidebar opts into `Projects`; `TestRendererRenderFrameWithTitleKeepsDefaultWhenTitleEmpty`; `TestRendererRenderFrameWithTitleUsesTitlebarRow`; `TestRendererContentLayoutWithTitleReservesTitlebarRow`; `TestNativeInteractiveRendersOptionalTitlebar`; `TestSwitchCommandNativeSidebarSetsTitle` |
|
|
52
53
|
| redraw flicker/top clipping | keyboard navigation in exact-height tmux popup | Partially covered | native redraws use synchronized updates plus coalesced row diffs after the first frame, skip unchanged frames, render frame diffs before sidebar focus commands, frame rendering avoids trailing bottom-border CRLF, and screen exit clears the alternate buffer before restore; `TestNativeInteractiveWrapsRedrawsInSynchronizedUpdates`; `TestFrameUpdateRendererSkipsUnchangedFrame`; `TestFrameUpdateRendererCoalescesEachFrameUpdate`; `TestRendererRenderFrameUsesCRLFRowsForRawTTY`; `TestNativeInteractiveUsesAlternateScreen` |
|
|
53
54
|
|
|
@@ -110,8 +111,10 @@ contract; native popups still rely on the existing borderless tmux popup path.
|
|
|
110
111
|
the right-side preview layout instead of inline preview, asserts the stored
|
|
111
112
|
preview cursor, selects `bravo-web`, and asserts tmux reports the selected
|
|
112
113
|
session's active target on the expected window with the expected pane path.
|
|
113
|
-
- `notify sidebar`: native routing is unit-covered;
|
|
114
|
-
|
|
114
|
+
- `notify sidebar`: native routing is unit-covered; app tests cover
|
|
115
|
+
queue-write event subscription and picker tests cover repeated
|
|
116
|
+
event-triggered deferred refresh. Docker no-fzf e2e pushes a notification,
|
|
117
|
+
presses printable expect key `a`, and verifies the row is acked.
|
|
115
118
|
|
|
116
119
|
## Experimental Boundaries
|
|
117
120
|
|