projmux 0.8.4 → 0.10.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 +2 -2
- package/README.md +6 -5
- package/docs/agent-workflow.md +33 -18
- package/docs/ai-agent-shortcuts.md +25 -0
- package/docs/architecture.md +32 -10
- package/docs/cli.md +342 -78
- package/docs/configuration.md +69 -10
- package/docs/globalization.md +2 -2
- package/docs/hooks.md +68 -25
- package/docs/install.md +2 -2
- package/docs/keybindings.md +27 -17
- package/docs/native-picker.md +103 -0
- package/docs/notify-queue.md +4 -3
- package/docs/npm-distribution.md +2 -2
- package/docs/operational-diagnostics.md +121 -0
- package/docs/pr-guideline.md +1 -1
- package/docs/resource-attribution.md +189 -0
- package/docs/session-restore.md +31 -6
- package/docs/settings-ia.md +52 -12
- package/docs/statusbar.md +31 -4
- package/docs/testing.md +1 -1
- package/docs/tmux-surface-inventory.md +108 -775
- package/docs/upgrading.md +21 -0
- package/docs/usage-tracking.md +91 -28
- package/package.json +5 -5
- package/docs/native-picker-no-fzf-poc.md +0 -227
- package/docs/native-picker-parity.md +0 -153
- package/docs/picker-ui-plan.md +0 -91
package/docs/configuration.md
CHANGED
|
@@ -4,6 +4,24 @@ Most users can configure projmux from `projmux settings`. Environment variables
|
|
|
4
4
|
are available for repeatable shell setup, managed machines, or advanced
|
|
5
5
|
overrides.
|
|
6
6
|
|
|
7
|
+
## Operational diagnostics state
|
|
8
|
+
|
|
9
|
+
Projmux keeps a private bounded operational journal at:
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
${XDG_STATE_HOME:-$HOME/.local/state}/projmux/logs/operations.jsonl
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
There is no configuration switch for arbitrary fields or remote delivery. The
|
|
16
|
+
`projmux` state and `logs` directories are created/repaired to mode `0700`, and
|
|
17
|
+
the JSONL file is created/repaired to `0600` on POSIX systems. At more than
|
|
18
|
+
5 MiB, the writer atomically retains about the newest 2 MiB of complete valid
|
|
19
|
+
records. Lock ownership is maintained by the OS and acquisition waits no more
|
|
20
|
+
than 200 ms before the best-effort write is abandoned. See
|
|
21
|
+
[operational-diagnostics.md](operational-diagnostics.md) for safe field and
|
|
22
|
+
best-effort behavior. Existing `ai-ingest.log` and
|
|
23
|
+
`PROJMUX_*_DEBUG` settings remain separate and unchanged.
|
|
24
|
+
|
|
7
25
|
## Project Discovery
|
|
8
26
|
|
|
9
27
|
`projmux switch` combines pinned directories, live tmux sessions, and
|
|
@@ -97,8 +115,8 @@ keybinding as saved; failures identify the stage that failed.
|
|
|
97
115
|
Raw sequences that cannot be safely represented as a direct keybinding are not
|
|
98
116
|
persisted. Use Settings to save a custom key. When key delivery needs
|
|
99
117
|
terminal-layer remediation, first try the key in `projmux shell`, then run
|
|
100
|
-
`projmux setup` from the raw terminal, then use `projmux
|
|
101
|
-
terminal adapters.
|
|
118
|
+
`projmux setup` from the raw terminal, then use `projmux setup terminal` for
|
|
119
|
+
supported terminal adapters.
|
|
102
120
|
|
|
103
121
|
`~/.config/projmux/keymap.toml` can also be edited by hand. When the file is
|
|
104
122
|
absent, generated tmux config stays on the built-in defaults.
|
|
@@ -114,6 +132,9 @@ keys = ["C-t"]
|
|
|
114
132
|
|
|
115
133
|
[bindings."Sidebar:PinProject"]
|
|
116
134
|
keys = ["M-p", "p"]
|
|
135
|
+
|
|
136
|
+
[bindings."Resources:Open"]
|
|
137
|
+
keys = ["M-u"]
|
|
117
138
|
```
|
|
118
139
|
|
|
119
140
|
Each table is `[bindings.<action-id>]`. Supported keys are:
|
|
@@ -150,17 +171,23 @@ such as `ProjectSidebarToggle`, `NotifySidebarToggle`, `SessionPopupToggle`,
|
|
|
150
171
|
popup commands use `Surface:Action` IDs and have surface-local conflict
|
|
151
172
|
domains and remain visible in Settings when catalogued.
|
|
152
173
|
|
|
174
|
+
`Resources:Open` is a user-configurable direct popup action with no built-in
|
|
175
|
+
shortcut. Every configured alias renders the canonical client-scoped body
|
|
176
|
+
`projmux tmux popup-toggle --client #{client_tty} resource-inspector`; pressing
|
|
177
|
+
the same alias again closes only that client's popup. It remains available on
|
|
178
|
+
Linux/tmux even when the Labs live-resource status segment is off.
|
|
179
|
+
|
|
153
180
|
The Settings writer is deterministic and rewrites the supported saved subset
|
|
154
181
|
only. If the existing file has parse errors or unknown action IDs, Settings
|
|
155
182
|
shows the keymap error row and refuses to overwrite it until the file is fixed.
|
|
156
183
|
|
|
157
184
|
The file currently affects generated tmux config from `projmux tmux
|
|
158
185
|
print-config`, `projmux tmux install`, `projmux tmux print-app-config`,
|
|
159
|
-
`projmux tmux install-app`, and `projmux shell`. Terminal
|
|
186
|
+
`projmux tmux install-app`, and `projmux shell`. Terminal remediation adapters such as
|
|
160
187
|
Ghostty and Windows Terminal install built-in plain-byte mappings where needed;
|
|
161
188
|
they do not read `keymap.toml` or copy saved keys into terminal configs.
|
|
162
|
-
Changing terminal-layer mappings still requires rerunning `projmux
|
|
163
|
-
restarting the terminal where that terminal requires it.
|
|
189
|
+
Changing terminal-layer mappings still requires rerunning `projmux setup
|
|
190
|
+
terminal` and restarting the terminal where that terminal requires it.
|
|
164
191
|
|
|
165
192
|
When a chord is overridden, projmux emits unbinds for both the stale default
|
|
166
193
|
chord and the replacement before binding the merged action. Popup and floating
|
|
@@ -334,9 +361,9 @@ user/global preference in this release.
|
|
|
334
361
|
## AI Resume Picker
|
|
335
362
|
|
|
336
363
|
The AI resume picker (`projmux ai split --agent resume`) lists the most recent
|
|
337
|
-
deduplicated Claude/Codex resume sessions. The number of rows it
|
|
338
|
-
far below the current directory it scans are both configurable;
|
|
339
|
-
30 rows and depth 0 (the current directory only).
|
|
364
|
+
deduplicated Claude/Codex/Antigravity resume sessions. The number of rows it
|
|
365
|
+
shows and how far below the current directory it scans are both configurable;
|
|
366
|
+
the defaults are 30 rows and depth 0 (the current directory only).
|
|
340
367
|
|
|
341
368
|
Preferred interactive path:
|
|
342
369
|
|
|
@@ -375,6 +402,21 @@ column (`./`, `./web`, `./api`) so child-directory sessions are easy to tell
|
|
|
375
402
|
apart. A missing or zero depth is identical to the historical behavior. Settings
|
|
376
403
|
edits write the global config.
|
|
377
404
|
|
|
405
|
+
Antigravity uses the upstream v1.1.12 current-storage boundary before its
|
|
406
|
+
legacy history fallback. `cache/last_conversations.json` contributes the latest
|
|
407
|
+
UUID mapped to a matching workspace; `cache/conversation_metadata.json`
|
|
408
|
+
contributes only rows that carry a valid UUID, workspace URI/path, and summary.
|
|
409
|
+
Both require an exact regular `conversations/<uuid>.db` and use only its
|
|
410
|
+
existence/mtime. They do not open SQLite content and do not treat `.db-wal`,
|
|
411
|
+
`.db-shm`, symlinks, or arbitrary paths as conversations. The cache provides a
|
|
412
|
+
latest-session floor rather than complete history. Missing/malformed cache,
|
|
413
|
+
workspace-less metadata, and stale mappings degrade to legacy `history.jsonl`
|
|
414
|
+
without changing the shared exact/depth/sort/cap behavior.
|
|
415
|
+
Live hook/session-state resume metadata is a separate high-confidence lane and
|
|
416
|
+
is not a disk-picker candidate. When a disk picker selection creates a pane,
|
|
417
|
+
its source is persisted so Session State preview and doctor can report medium
|
|
418
|
+
confidence for DB-validated cache sources or low confidence for legacy history.
|
|
419
|
+
|
|
378
420
|
## Environment Variables
|
|
379
421
|
|
|
380
422
|
| Variable | Purpose |
|
|
@@ -397,7 +439,6 @@ edits write the global config.
|
|
|
397
439
|
| `PROJMUX_SESSIONSTATE_AUTOSAVE` | Session snapshot autosave override for the global fallback. Values such as `off`, `false`, or `0` disable autosave for projects that inherit the global setting; explicit project auto-save `on`/`off` still takes precedence. |
|
|
398
440
|
| `PROJMUX_SESSIONSTATE_DEBUG` | When non-empty, quiet autosave surfaces suppressed session-state errors to stderr. |
|
|
399
441
|
| `PROJMUX_FOCUS_DEBUG` | When non-empty, `projmux focus` prints one telemetry line to stderr. |
|
|
400
|
-
| `PROJMUX_PICKER_BACKEND` | Legacy picker backend override. Any value, including old `fzf` settings, now resolves to the native picker. |
|
|
401
442
|
| `PROJMUX_INSTALLER` | Installer source hint used by update flows. npm installs set this automatically; advanced release installs can set `github-release`. |
|
|
402
443
|
| `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. |
|
|
403
444
|
|
|
@@ -785,7 +826,25 @@ statistics and `hw.memsize`. Neither path launches `top`, `vm_stat`, `free`,
|
|
|
785
826
|
PowerShell, or another metrics process. On macOS, available memory is free plus
|
|
786
827
|
inactive pages, matching the reclaimable-memory intent of Linux
|
|
787
828
|
`MemAvailable`. In WSL the values describe the Linux guest/VM view, not total
|
|
788
|
-
Windows host utilization.
|
|
829
|
+
Windows host utilization. These are host-scoped values and do not attribute
|
|
830
|
+
usage to a pane, window, project, or session.
|
|
831
|
+
|
|
832
|
+
When enabled, the compact segment is also the clickable `resources` statusbar
|
|
833
|
+
range and opens the Resource Inspector. Turning the Lab off hides only this
|
|
834
|
+
segment; it does not disable `projmux resources` or a custom-bound
|
|
835
|
+
`Resources:Open` action. Inspector samples are memory-only for the popup
|
|
836
|
+
lifetime and are unrelated to the status segment's host CPU reference cache.
|
|
837
|
+
|
|
838
|
+
The display policy is fixed rather than configurable: CPU is normal below 70%,
|
|
839
|
+
warning at 70–89%, and critical at 90% or above; memory is normal below 75%,
|
|
840
|
+
warning at 75–89%, and critical at 90% or above. The two values are classified
|
|
841
|
+
and styled independently. Normal and unavailable (`--`) values use the
|
|
842
|
+
secondary status-text theme role, warnings use the warning role, and critical
|
|
843
|
+
values use the bold critical role. Visible severity words are omitted and each
|
|
844
|
+
percent uses a fixed four-column slot, including `%`, so metric transitions do
|
|
845
|
+
not resize the segment. No threshold values are stored in config.
|
|
846
|
+
|
|
847
|
+
The CPU delta cache is internal state at
|
|
789
848
|
`${XDG_STATE_HOME:-~/.local/state}/projmux/live-resources-sample.json`.
|
|
790
849
|
CPU reference samples older than 30 seconds are ignored and replaced on the
|
|
791
850
|
next refresh.
|
package/docs/globalization.md
CHANGED
|
@@ -87,7 +87,7 @@ Files:
|
|
|
87
87
|
|
|
88
88
|
- `internal/ui/projmuxpicker/*`
|
|
89
89
|
- `internal/ui/render/*`
|
|
90
|
-
- `docs/native-picker
|
|
90
|
+
- `docs/native-picker.md`
|
|
91
91
|
|
|
92
92
|
Classification:
|
|
93
93
|
|
|
@@ -124,7 +124,7 @@ Classification:
|
|
|
124
124
|
|
|
125
125
|
Do not translate these families:
|
|
126
126
|
|
|
127
|
-
- Product and agent names: `Codex`, `Claude`, `projmux`, `tmux`,
|
|
127
|
+
- Product and agent names: `Codex`, `Claude`, `projmux`, `tmux`,
|
|
128
128
|
`GitHub`, `npm`.
|
|
129
129
|
- Terminal and app names: `Windows Terminal`, `Ghostty`, `WezTerm`, `Kitty`,
|
|
130
130
|
`iTerm2`, `Alacritty`, `Foot`.
|
package/docs/hooks.md
CHANGED
|
@@ -207,8 +207,9 @@ If a `send-noti` hook itself calls `projmux notify push`, projmux sees
|
|
|
207
207
|
|
|
208
208
|
`Settings > Notifications > Delivery sources` surfaces the active Codex hooks,
|
|
209
209
|
Claude, and tmux AI notify diagnostics: status, conflicts, config paths, and
|
|
210
|
-
copyable CLI install/remove/dry-run commands. It
|
|
211
|
-
|
|
210
|
+
copyable CLI install/remove/dry-run commands. It also shows whether
|
|
211
|
+
`PROJMUX_NOTIFY_HOOK` overrides the built-in desktop sender. It does not install
|
|
212
|
+
or remove external Codex, Claude, or tmux settings.
|
|
212
213
|
|
|
213
214
|
`PROJMUX_NOTIFY_HOOK` is separate from `[hooks.send-noti]`: it replaces the
|
|
214
215
|
desktop sender and receives positional arguments
|
|
@@ -617,37 +618,79 @@ catalog `install` field for installed hook events.
|
|
|
617
618
|
|
|
618
619
|
## Antigravity Hook Ingest
|
|
619
620
|
|
|
620
|
-
`projmux ai ingest antigravity-hook < payload.json`
|
|
621
|
-
Antigravity CLI `agy` hook
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
621
|
+
`projmux ai ingest antigravity-hook --event <event> < payload.json` accepts
|
|
622
|
+
Antigravity CLI `agy` hook payloads. Antigravity v1.1.12 stdin does
|
|
623
|
+
not include the event name, so the command's `--event` value is authoritative.
|
|
624
|
+
Payload event aliases remain a compatibility fallback when `--event` is
|
|
625
|
+
omitted. `projmux ai integrate antigravity [--dry-run|--remove]` owns exactly
|
|
626
|
+
the named `projmux` entry in `~/.gemini/config/hooks.json` and separately owns
|
|
627
|
+
only `statusLine` in `~/.gemini/antigravity-cli/settings.json`. Other named hooks,
|
|
628
|
+
their fields, and unknown JSON values remain untouched. The generated commands
|
|
629
|
+
use the stable absolute projmux executable because Antigravity runs handlers
|
|
630
|
+
with the config directory as cwd. The command refuses unmanaged name/command
|
|
631
|
+
conflicts, malformed JSON, symlink paths, and permission failures with an
|
|
632
|
+
actionable diagnostic. Doctor/Settings distinguish installed, missing,
|
|
633
|
+
conflicting, and stale managed entries; stale covers executable, event/schema,
|
|
634
|
+
or stdout-fallback drift and is refreshed by the install command.
|
|
635
|
+
The statusline object uses the official v1.1.12 command shape with
|
|
636
|
+
`enabled=true` and `stack_with_default=true`. Its direct explicit `Statusline`
|
|
637
|
+
ingest command emits empty stdout, preserving the built-in line. Existing
|
|
638
|
+
custom statusline commands are conflicts and are never wrapped or chained.
|
|
639
|
+
|
|
640
|
+
The default Antigravity catalog records the five official v1.1.12 events and
|
|
641
|
+
installs four non-permission events:
|
|
630
642
|
|
|
631
643
|
| Event/signal | Behavior |
|
|
632
644
|
| --- | --- |
|
|
633
|
-
| `
|
|
634
|
-
| `
|
|
635
|
-
| `
|
|
636
|
-
| `
|
|
645
|
+
| `PreToolUse` | known permission-changing event; never installed and no permission decision is synthesized |
|
|
646
|
+
| `PreInvocation` | marks the matched pane hook-active and moves it to thinking/busy; no notify queue entry is pushed |
|
|
647
|
+
| `PostInvocation` | marks the matched pane hook-active and writes a quiet bookkeeping diagnostic; no notify queue entry is pushed |
|
|
648
|
+
| `PostToolUse` | marks the matched pane hook-active, retains tool error metadata in quiet diagnostics, and pushes no notify queue entry |
|
|
649
|
+
| `Stop` | pushes an info completion unless an explicit error signal requires a critical error row |
|
|
650
|
+
| `Statusline` with `tool_confirmation_pending=true` | pushes/replaces a deduped critical approval-required row outside the hook catalog |
|
|
651
|
+
| `Statusline` with `agent_state=thinking|working|tool_use` | moves the matched pane to thinking/busy without notifying, unless a terminal completion/approval state must be preserved from a late refresh; a new `PreInvocation` resets the next generation to busy |
|
|
652
|
+
| `Statusline` with `agent_state=idle` or `tool_confirmation_pending=false` | quiet update; does not clear completion/approval attention and creates no notification |
|
|
637
653
|
| unknown events | mark the matched pane hook-active and write quiet ingest diagnostics only |
|
|
638
654
|
|
|
639
|
-
Antigravity notify rows use `agent=antigravity` metadata.
|
|
640
|
-
|
|
641
|
-
`
|
|
642
|
-
`
|
|
655
|
+
Antigravity notify rows use `agent=antigravity` metadata. The v1.1.12 parser
|
|
656
|
+
retains common camelCase `conversationId`, `workspacePaths`, `transcriptPath`,
|
|
657
|
+
`artifactDirectoryPath`, and `modelName`; invocation `invocationNum` and
|
|
658
|
+
`initialNumSteps`; post-tool `toolCall`, `stepIdx`, and `error`; and Stop
|
|
659
|
+
`executionNum`, `terminationReason`, `error`, and `fullyIdle`. Existing aliases
|
|
660
|
+
such as `conversation_id`, `cwd`, `workspace.path`, `agent_state`, and nested
|
|
661
|
+
`statusline.tool_confirmation_pending` remain accepted. The first non-empty
|
|
662
|
+
`workspacePaths` value is only a cwd fallback candidate; empty/absent arrays do
|
|
663
|
+
not become the process cwd, and inherited `$TMUX_PANE` still wins attribution.
|
|
664
|
+
`NO_TOOL_CALL`, `MODEL_STOP`, and known normal reasons are info completions.
|
|
665
|
+
Non-empty `error`, explicit `ERROR`, and `MAX_STEPS_EXCEEDED` families are
|
|
666
|
+
critical; unknown reasons retain diagnostic metadata but default to info.
|
|
667
|
+
Explicit non-permission hook ingest writes valid hook stdout: `{}` for
|
|
668
|
+
invocation/post-tool events and `{"decision":"stop"}` for Stop. The latter
|
|
669
|
+
allows the requested stop to complete; projmux does not emit `continue` or a
|
|
670
|
+
`PreToolUse` permission decision.
|
|
671
|
+
Each managed command includes its explicit event selector and a valid stdout
|
|
672
|
+
fallback: `{}` for invocation/post-tool events and `{"decision":"stop"}` for
|
|
673
|
+
Stop. The fallback is non-blocking and never returns `continue`,
|
|
674
|
+
`allow`, `deny`, or `ask`.
|
|
675
|
+
|
|
676
|
+
The named entry in `hooks.json` remains the install source of truth. Use
|
|
677
|
+
`agy -p '/hooks' --output-format json` only as a read-only runtime diagnosis of
|
|
678
|
+
loaded sources/events; its result is never used to generate or rewrite config.
|
|
643
679
|
Antigravity ingest uses `conversationId` as pane thread metadata for matching
|
|
644
680
|
and as session-state resume metadata. Session restore uses
|
|
645
681
|
`agy --conversation <uuid>` only when that id is present and UUID-shaped;
|
|
646
|
-
otherwise preview and doctor render `resume unavailable`.
|
|
647
|
-
`
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
682
|
+
otherwise preview and doctor render `resume unavailable`. Official snake_case
|
|
683
|
+
`cwd`, `conversation_id`, `transcript_path`, `agent_state`,
|
|
684
|
+
`tool_confirmation_pending`, and structured `context_window.used_percentage`
|
|
685
|
+
plus token fields are parsed directly. The structured percentage is persisted
|
|
686
|
+
with conversation identity to the usage state dir; the legacy string percentage
|
|
687
|
+
remains a fallback so the usage HUD can surface it as the conversation-local
|
|
688
|
+
`context` row. The official top-level `quota` map is persisted independently:
|
|
689
|
+
valid `remaining_fraction` values become used percent, exact upstream bucket
|
|
690
|
+
IDs render as separate `quota/<bucket>` account rows, and `reset_time` plus
|
|
691
|
+
optional `reset_in_seconds` retain their independent meanings. Invalid,
|
|
692
|
+
disabled, missing, or empty quota shapes degrade without inventing a cadence or
|
|
693
|
+
reinterpreting context. Raw payloads or transcript contents are not stored.
|
|
651
694
|
|
|
652
695
|
## Ingest Debug Log
|
|
653
696
|
|
package/docs/install.md
CHANGED
|
@@ -18,8 +18,8 @@ After installing, run:
|
|
|
18
18
|
projmux doctor
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
`doctor`
|
|
22
|
-
|
|
21
|
+
`doctor` performs read-only diagnostics for runtime tools such as `tmux`,
|
|
22
|
+
`git`, and `stty`.
|
|
23
23
|
|
|
24
24
|
Start the tmux app with:
|
|
25
25
|
|
package/docs/keybindings.md
CHANGED
|
@@ -17,7 +17,7 @@ The recommended path when a key does not fire:
|
|
|
17
17
|
`projmux shell` key adapter, then retry the physical key.
|
|
18
18
|
3. Run `projmux setup` outside tmux to see which bytes reach the process.
|
|
19
19
|
4. For supported terminals outside the native macOS app socket, preview
|
|
20
|
-
`projmux
|
|
20
|
+
`projmux setup terminal [terminal]`; add `--apply`
|
|
21
21
|
only after reviewing the merge.
|
|
22
22
|
5. For unsupported terminals, configure plain Meta bytes or add a custom key in
|
|
23
23
|
Settings > Keybindings.
|
|
@@ -56,6 +56,13 @@ These shortcuts are the guaranteed launch defaults. They need no tmux prefix.
|
|
|
56
56
|
to the selected live tmux window using that window's current active pane; it is
|
|
57
57
|
separate from `last-pane` and from the existing-session popup.
|
|
58
58
|
|
|
59
|
+
`Resources:Open` is listed in Settings > Keybindings without a default key.
|
|
60
|
+
Adding a safe direct chord opens the Linux/tmux Resource Inspector through the
|
|
61
|
+
canonical client-scoped popup-toggle path; pressing the same custom chord again
|
|
62
|
+
closes it without touching another client's popup. The action remains usable
|
|
63
|
+
when Settings > Labs > Live system resources is off—the Lab controls only
|
|
64
|
+
statusbar visibility.
|
|
65
|
+
|
|
59
66
|
The tmux prefix remains the upstream default `Ctrl-b`. Inside a running
|
|
60
67
|
session, `Ctrl-b ?` lists the live tmux bindings.
|
|
61
68
|
|
|
@@ -142,11 +149,11 @@ Advanced typed entry remains available from Action detail for literal
|
|
|
142
149
|
risky/reserved key copy, and raw diagnostics. Advanced delivery is still owned
|
|
143
150
|
by the selected Projmux action. The native macOS app-socket adapter reads the
|
|
144
151
|
same safe chords directly; supported Ghostty and Windows Terminal mappings for
|
|
145
|
-
other paths are previewed/applied through `projmux
|
|
152
|
+
other paths are previewed/applied through `projmux setup terminal`, not by storing raw
|
|
146
153
|
sequences in the primary keymap. Options covers unbinding the action and
|
|
147
154
|
reset/use-default flows. Diagnostic/probe/init workflows are not first-class
|
|
148
155
|
Settings tabs; use `projmux setup` and, where the native adapter does not apply,
|
|
149
|
-
`projmux
|
|
156
|
+
`projmux setup terminal` from the terminal when key delivery needs remediation.
|
|
150
157
|
|
|
151
158
|
Optional direct keys can be added for actions such as:
|
|
152
159
|
|
|
@@ -187,7 +194,7 @@ Settings > Keybindings stays a discovery surface. It must continue to expose
|
|
|
187
194
|
launch toggles, sidebar keymap actions, picker-local actions, pane switching,
|
|
188
195
|
window switching, and rename actions. The basic Settings flow is not the
|
|
189
196
|
terminal remediation surface: key-role replacement, disable-default, typed
|
|
190
|
-
fallback
|
|
197
|
+
fallback and terminal mapping preview/apply rows stay out of
|
|
191
198
|
the action detail.
|
|
192
199
|
|
|
193
200
|
The product model does not support `UserN` or `CSI-u` as fallback guidance.
|
|
@@ -235,7 +242,10 @@ Settings is the default apply path for key edits: it writes the key list,
|
|
|
235
242
|
refreshes the generated config, and reloads the running tmux session when
|
|
236
243
|
possible. Use `projmux tmux apply` as a CLI recovery/sync command after editing
|
|
237
244
|
the keymap file by hand, after an outside-tmux Settings save, or after resolving
|
|
238
|
-
a reported generated-config or live-reload failure.
|
|
245
|
+
a reported generated-config or live-reload failure. Generated config first
|
|
246
|
+
unbinds the known retired `C-t` pane-label chord, then installs the current
|
|
247
|
+
keymap; an explicit current `C-t` assignment therefore wins without retaining
|
|
248
|
+
the retired command body. Apply does not rewrite `keymap.toml`.
|
|
239
249
|
|
|
240
250
|
## Keymap File
|
|
241
251
|
|
|
@@ -299,29 +309,29 @@ projmux setup --timeout 10s
|
|
|
299
309
|
projmux setup --non-interactive
|
|
300
310
|
```
|
|
301
311
|
|
|
302
|
-
##
|
|
312
|
+
## Terminal remediation: `projmux setup terminal`
|
|
303
313
|
|
|
304
|
-
`projmux
|
|
305
|
-
Default mode is
|
|
314
|
+
`projmux setup terminal` previews and optionally applies supported terminal
|
|
315
|
+
mappings. Default mode is a read-only preview; pass `--apply` to write changes with a timestamped
|
|
306
316
|
backup.
|
|
307
317
|
|
|
308
318
|
```sh
|
|
309
|
-
projmux
|
|
310
|
-
projmux
|
|
311
|
-
projmux
|
|
312
|
-
projmux
|
|
313
|
-
projmux
|
|
314
|
-
projmux
|
|
319
|
+
projmux setup terminal
|
|
320
|
+
projmux setup terminal ghostty
|
|
321
|
+
projmux setup terminal ghostty --apply
|
|
322
|
+
projmux setup terminal windows-terminal --apply
|
|
323
|
+
projmux setup terminal --config /path/to/file
|
|
324
|
+
projmux setup terminal --allow-symlink
|
|
315
325
|
```
|
|
316
326
|
|
|
317
327
|
The merge is idempotent: matching bindings are no-ops, missing bindings are
|
|
318
328
|
added, and keys already mapped to a different user action are skipped with a
|
|
319
|
-
warning. `projmux
|
|
329
|
+
warning. `projmux setup terminal` does not read `keymap.toml`; direct tmux keys still
|
|
320
330
|
belong in Settings > Keybindings or the keymap file.
|
|
321
331
|
|
|
322
332
|
### Ghostty
|
|
323
333
|
|
|
324
|
-
`projmux
|
|
334
|
+
`projmux setup terminal ghostty` emits plain Meta bytes for `Alt-1` through `Alt-5` in
|
|
325
335
|
the managed block:
|
|
326
336
|
|
|
327
337
|
```text
|
|
@@ -341,7 +351,7 @@ refused by default; pass `--allow-symlink` to write through the link.
|
|
|
341
351
|
|
|
342
352
|
### Windows Terminal
|
|
343
353
|
|
|
344
|
-
`projmux
|
|
354
|
+
`projmux setup terminal windows-terminal` merges `sendInput` actions identified by the
|
|
345
355
|
`User.projmux*` ID prefix. The generated inputs use plain Meta bytes, tmux
|
|
346
356
|
prefix sequences for split actions, and xterm modifier-arrow sequences for
|
|
347
357
|
previous/next window:
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Native Picker
|
|
2
|
+
|
|
3
|
+
The native picker is the product picker for every interactive selection flow.
|
|
4
|
+
There is no runtime backend selection, saved picker selector, or external
|
|
5
|
+
picker process. `internal/ui/picker` owns the interaction contract and
|
|
6
|
+
`internal/ui/projmuxpicker` owns its visual composition.
|
|
7
|
+
|
|
8
|
+
## Product Contract
|
|
9
|
+
|
|
10
|
+
| Area | Behavior | Primary evidence |
|
|
11
|
+
| --- | --- | --- |
|
|
12
|
+
| Items and results | Structured items keep display labels, stable values, optional search text, multi-line metadata, and action results separate. `internal/ui/pickercompat` maps older internal option/result shapes into this contract; it is not a runtime backend. | `TestPickerOptionsFromCompatPickerMapsCandidatesWhenEntriesAreEmpty`; `TestPickerOptionsFromCompatPickerPreservesTheme` |
|
|
13
|
+
| Search | Lower-case queries are case-insensitive, uppercase queries are case-sensitive, hidden values remain searchable when no explicit search key exists, explicit search-key lists preserve caller order, and simple rows receive fuzzy ranking and match highlighting. | `TestFilterItemsUsesSmartCase`; `TestFilterItemsSearchesHiddenValueWhenNoSearchKey`; `TestFilterItemsPreservesSearchKeyOrder`; `TestFilterItemsRanksBetterMatchesFirst` |
|
|
14
|
+
| Navigation | Up/Down, Ctrl-J/Ctrl-N, and Ctrl-K/Ctrl-P wrap selection; PageUp/PageDown and Home/End clamp or jump; empty lists remain safe. Ctrl-N and Ctrl-P remain real navigation keys unless a caller claims the key as a custom action. | `TestNativeInteractiveSupportsControlNavigationKeys`; `TestNativeInteractiveWrapsPreviousNavigationKeys`; `TestNativeInteractiveWrapsNextNavigationKeys`; `TestNativeInteractiveNavigationKeysAreNoopForEmptyList`; `TestNativeInteractiveJumpNavigationRemainsClamped` |
|
|
15
|
+
| Editing | Left/Right, Ctrl-A/E, Delete, Backspace, Ctrl-U/W, printable input, accept-query mode, and a visible query cursor are supported. | `TestNativeInteractiveEditsTypedQueryAtCursor`; `TestNativeInteractiveSupportsQueryLineEditingKeys`; `TestNativeInteractiveCtrlUDeletesBeforeCursor`; `TestNativeRunnerAcceptsTypedQuery` |
|
|
16
|
+
| Actions | Enter accepts, shared close actions abort, printable/control expect keys return stable action keys, command actions can refresh previews, and mutable actions can update items without restarting the picker. | `TestNativeRunnerUsesSharedCloseActions`; `TestNativeInteractiveSupportsPrintableExpectKeys`; `TestNativeInteractiveRunsCustomActionCommandAndRefreshes`; `TestNativeInteractiveCustomActionMutatesItemsAndRefreshes` |
|
|
17
|
+
| Deferred state | Deferred and event-triggered updates preserve query and selection by value, can repeat, and may explicitly choose a new focus value. | `TestNativeInteractiveDeferredUpdateTriggerRefreshesRepeatedly`; switch and notify sidebar mutable-refresh app tests |
|
|
18
|
+
| Preview | Popup previews use a right split, sidebar previews use a bottom split, control bytes and tabs are normalized before clipping, and preview scrolling/cycling rerenders in place. | `TestNativeInteractiveRendersWidePreviewBesideList`; `TestNativeInteractiveRendersDownPreviewBelowList`; `TestRenderSplitPreviewRowsNormalizesPreviewTabsBeforeTruncating`; `TestNativeInteractiveRendersPreviewOffset` |
|
|
19
|
+
| Mouse | SGR mouse input focuses on primary down, follows drag, accepts on matching release, and scrolls with the wheel. | `TestNativeInteractiveSelectsOnMouseRelease`; `TestNativeInteractiveMouseDragFollowsSelection`; `TestNativeInteractiveSupportsMouseWheelSelection` |
|
|
20
|
+
| Lifecycle | Interactive runs use the alternate screen, synchronized/coalesced frame updates, controlling-TTY fallback, and deterministic reader cleanup. | `TestNativeInteractiveUsesAlternateScreen`; `TestNativeInteractiveWrapsRedrawsInSynchronizedUpdates`; picker/setup lifecycle tests in `docs/agent-workflow.md` |
|
|
21
|
+
|
|
22
|
+
## Rendering And Popup Chrome
|
|
23
|
+
|
|
24
|
+
The renderer owns rounded frames, optional titlebars and chips, search/header
|
|
25
|
+
separators, footer placement, selected-row styling, proportional scrollbars,
|
|
26
|
+
multi-line gaps, preview geometry, ANSI restoration, and terminal-cell width for
|
|
27
|
+
CJK text, emoji, and combining marks. Frame-owned cells inherit the effective
|
|
28
|
+
theme's `surface` and `chrome_foreground` values, including padding after
|
|
29
|
+
embedded resets.
|
|
30
|
+
|
|
31
|
+
Picker popups are always borderless tmux popups (`display-popup -B`) so the
|
|
32
|
+
native renderer owns the visible frame. The popup body receives a per-command
|
|
33
|
+
style derived from the effective theme; no global popup, pane, window, shell,
|
|
34
|
+
or status style is mutated. Project sidebars use a `20%` width with a `40`
|
|
35
|
+
column minimum, notification sidebars use `24%` with a `64` column minimum,
|
|
36
|
+
and both reserve the two statusbar rows when client height is known.
|
|
37
|
+
|
|
38
|
+
Primary evidence includes `TestAppRunTmuxPopupToggleUsesBorderlessNativePopup`,
|
|
39
|
+
`TestAppRunTmuxPopupToggleUsesNativePopupBodyStyleFromGlobalTheme`,
|
|
40
|
+
`TestBuildPopupToggleAppliesNativeBodyStyle`,
|
|
41
|
+
`TestSessionizerSidebarWidthUsesCompactMinimum`,
|
|
42
|
+
`TestNotifySidebarWidthUsesProductContract`, and
|
|
43
|
+
`TestSidebarPopupHeightLeavesStatusbarRows`.
|
|
44
|
+
|
|
45
|
+
## Fuzzy Scoring Provenance
|
|
46
|
+
|
|
47
|
+
The native fuzzy scorer intentionally follows the fzf V2 dynamic-scoring
|
|
48
|
+
algorithm for the maintained reference cases in `internal/ui/picker/backend_test.go`.
|
|
49
|
+
`TestFuzzyScoreMatchesFZFV2ReferenceScores` and
|
|
50
|
+
`TestFuzzyScoreRejectsFZFV2ReferenceNonMatches` are provenance fixtures; keep
|
|
51
|
+
their expected scores stable when changing filtering internals.
|
|
52
|
+
|
|
53
|
+
## Retired Artifact Contract
|
|
54
|
+
|
|
55
|
+
The retired picker selector environment variable and saved selector filename
|
|
56
|
+
are not runtime inputs. Their presence must not cause lookup, file reads,
|
|
57
|
+
warnings, deletion, rewriting, propagation to child popups, or any change to
|
|
58
|
+
the native path. There is deliberately no alias, migration, or stale-value
|
|
59
|
+
cleanup behavior.
|
|
60
|
+
|
|
61
|
+
Coverage is split by boundary:
|
|
62
|
+
|
|
63
|
+
- `TestRunNativePickerOptionDoesNotObserveRetiredBackendArtifacts` guards the
|
|
64
|
+
direct picker path, fails if the retired env name is queried, and verifies a
|
|
65
|
+
stale file is neither deleted nor replaced.
|
|
66
|
+
- `TestAppRunSwitchUsesNativePickerWithoutBackendLookup` guards the ordinary
|
|
67
|
+
switch flow.
|
|
68
|
+
- `TestAppRunTmuxPopupToggleIgnoresRetiredBackendArtifacts` and
|
|
69
|
+
`TestBuildPopupTogglePropagatesNativePickerEnvironmentWithoutRetiredBackend`
|
|
70
|
+
guard popup chrome and child-environment construction.
|
|
71
|
+
- `test/e2e/linux-smoke.sh` launches the ordinary attached-client Settings
|
|
72
|
+
popup with stale env/file values, completes the recorder flow, verifies the
|
|
73
|
+
file inode/content are unchanged, and rejects visible compatibility output.
|
|
74
|
+
|
|
75
|
+
## Removed PoC Coverage Mapping
|
|
76
|
+
|
|
77
|
+
The retired standalone dependency sandbox and focused smoke duplicated product
|
|
78
|
+
coverage or tested a dependency policy that no longer exists. Its valid
|
|
79
|
+
behavior assertions remain covered as follows:
|
|
80
|
+
|
|
81
|
+
| Removed focused assertion | Maintained coverage |
|
|
82
|
+
| --- | --- |
|
|
83
|
+
| Settings and Labs render through the native picker | `TestSettingsUsesNativePicker`; `TestSettingsHubKeepsLabsSectionWithoutRetiredPickerChoices`; ordinary attached-client Settings recorder in `test/e2e/linux-smoke.sh` |
|
|
84
|
+
| Search chrome, smart-case filtering, native frame ownership, and full-height rendering | `TestNativeInteractiveSeparatesSearchHeaderFromList`; `TestFilterItemsUsesSmartCase`; `TestNativeInteractiveRendersBorderFrame`; `TestNativeInteractiveUsesAvailableHeightForSimpleLists` |
|
|
85
|
+
| AI Settings maps a typed selection to the saved mode | `TestAISettingsPickerSetsSelectedMode`; native picker option/result mapping tests |
|
|
86
|
+
| Switch popup/sidebar filtering, selection, preview cycling, and initial focus | `TestAppRunSwitchDefaultsToPopupAndOpensSelectedSession`; `TestSwitchCommandSupportsSidebarUI`; preview cycle and initial-position tests in `internal/app/switch_test.go` |
|
|
87
|
+
| Sessions popup filtering, selection, and preview cycling | `TestAppRunSessionsDefaultsToPopupAndOpensSelectedSession`; session popup preview/cycle tests in `internal/app/session_popup_test.go` |
|
|
88
|
+
| Notification sidebar navigation and mutable actions | `TestNotifySidebarUsesNativePicker`; notify sidebar ack/clear/deferred-refresh app tests |
|
|
89
|
+
| Launch-key close behavior and Ctrl-N/Ctrl-P navigation | `TestNativeInteractiveClosesOnMatchingLaunchCloseKey`; `TestNativeInteractiveSupportsControlNavigationKeys`; empty-list and wrap tests |
|
|
90
|
+
| Mouse selection and alternate-screen restoration | native mouse and lifecycle tests listed above |
|
|
91
|
+
| Generated shell config and the Alt-1 project-sidebar popup path | `TestShellWritesAppConfigAndRunsIsolatedTmux`; `TestAppRunTmuxPopupToggleOpensStandaloneSidebar`; popup frame/body-style tests listed above |
|
|
92
|
+
| Stale selector values do not affect the product | retained and strengthened in the unit/app/e2e negative coverage listed in the previous section |
|
|
93
|
+
|
|
94
|
+
The dependency-absence assertion is now a source-residue property rather than
|
|
95
|
+
a separate container scenario: production code contains no selector, resolver,
|
|
96
|
+
saved-selector access, propagation, or external picker launch path.
|
|
97
|
+
|
|
98
|
+
## Maintenance
|
|
99
|
+
|
|
100
|
+
Update this document and the maintained list in
|
|
101
|
+
[`docs/agent-workflow.md`](agent-workflow.md) whenever picker behavior changes
|
|
102
|
+
coverage level, gains a new product flow, or changes input/render/action
|
|
103
|
+
semantics.
|
package/docs/notify-queue.md
CHANGED
|
@@ -70,12 +70,13 @@ exit code 2.
|
|
|
70
70
|
routing/debug context such as `agent`, `thread_id`, `turn_id`, `cwd`,
|
|
71
71
|
`model`, and `client`; Claude hook rows also carry event-specific keys such as
|
|
72
72
|
`tool_name`, `tool_input.command`, `error_type`, `subagent_type`, and
|
|
73
|
-
`teammate_name`. Antigravity
|
|
73
|
+
`teammate_name`. Antigravity hook rows carry `agent=antigravity`,
|
|
74
74
|
`conversation_id`, `termination_reason`, `fully_idle`,
|
|
75
75
|
`tool_confirmation_pending`, `agent_state`, and `context_window` when present.
|
|
76
76
|
The same `conversation_id` can seed session-state restore via
|
|
77
|
-
`agy --conversation <uuid>` when it is UUID-shaped
|
|
78
|
-
remains
|
|
77
|
+
`agy --conversation <uuid>` when it is UUID-shaped. Antigravity
|
|
78
|
+
account quota remains outside notify attention semantics: `context_window` is a
|
|
79
|
+
separate conversation-local gauge and is never treated as quota data.
|
|
79
80
|
Tmux bell fallback rows carry `agent=bell`, `event=bell`, and tmux target
|
|
80
81
|
context such as pane title, command, session, window, pane, and socket.
|
|
81
82
|
`notify list --json` includes this metadata as the structured data channel
|
package/docs/npm-distribution.md
CHANGED
|
@@ -18,7 +18,7 @@ The shim sets `PROJMUX_INSTALLER=npm` before executing the real binary so
|
|
|
18
18
|
`projmux update status` and the Settings About screen can present
|
|
19
19
|
npm-specific guidance. npm is only an update/install source label here; the
|
|
20
20
|
keybinding flow remains `projmux shell` first, then `projmux setup` and
|
|
21
|
-
`projmux
|
|
21
|
+
`projmux setup terminal` only for terminals that swallow shortcuts.
|
|
22
22
|
|
|
23
23
|
## Local Packaging
|
|
24
24
|
|
|
@@ -116,5 +116,5 @@ completed update never leaves stale-path `run-shell` commands failing with
|
|
|
116
116
|
|
|
117
117
|
The npm installer must not install system dependencies, edit shell startup
|
|
118
118
|
files, or mutate tmux config. Those actions stay behind explicit
|
|
119
|
-
`projmux doctor`, `projmux
|
|
119
|
+
`projmux doctor`, `projmux setup terminal`, Settings About update actions, or future
|
|
120
120
|
opt-in install commands.
|