projmux 0.4.9 → 0.5.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 +1 -3
- package/README.md +1 -4
- package/docs/agent-workflow.md +3 -3
- package/docs/architecture.md +4 -5
- package/docs/cli.md +22 -27
- package/docs/configuration.md +77 -2
- package/docs/hooks.md +190 -48
- package/docs/install.md +14 -3
- package/docs/keybindings.md +46 -7
- package/docs/native-picker-no-fzf-poc.md +16 -24
- package/docs/native-picker-parity.md +29 -27
- package/docs/picker-ui-plan.md +23 -43
- package/docs/repo-layout.md +6 -3
- package/docs/roadmap.md +23 -9
- package/docs/statusbar.md +33 -16
- package/docs/testing.md +5 -7
- package/docs/usage-tracking.md +13 -0
- package/package.json +5 -5
package/docs/keybindings.md
CHANGED
|
@@ -8,9 +8,10 @@ The recommended path when a key does not fire:
|
|
|
8
8
|
|
|
9
9
|
1. Press the key inside `projmux shell` and see what works on your terminal
|
|
10
10
|
out of the box ([Quick start](#quick-start-no-setup)).
|
|
11
|
-
2. If something is swallowed,
|
|
12
|
-
|
|
13
|
-
which the terminal is
|
|
11
|
+
2. If something is swallowed, open Settings > Labs > Diagnose keybindings, or
|
|
12
|
+
run [`projmux setup`](#diagnose-projmux-setup) outside tmux. Both paths tell
|
|
13
|
+
you exactly which sequences reach the process and which the terminal is
|
|
14
|
+
eating.
|
|
14
15
|
3. For terminals projmux knows how to configure, run
|
|
15
16
|
[`projmux init [terminal]`](#auto-config-projmux-init) as the fallback:
|
|
16
17
|
preview first, then add `--apply` to merge the right bindings into your
|
|
@@ -19,6 +20,24 @@ The recommended path when a key does not fire:
|
|
|
19
20
|
hand), use the [Manual fallback / advanced (CSI-u)](#manual-fallback--advanced-csi-u)
|
|
20
21
|
section.
|
|
21
22
|
|
|
23
|
+
To change projmux's tmux-level chords, open Settings > Keybindings. The
|
|
24
|
+
in-app editor writes `~/.config/projmux/keymap.toml`, regenerates
|
|
25
|
+
`~/.config/projmux/tmux.conf`, and hot-reloads the live tmux config when
|
|
26
|
+
Settings is running inside tmux. Terminal fallback mappings are separate:
|
|
27
|
+
after changing fallback keys, rerun `projmux init` and restart the terminal
|
|
28
|
+
where applicable.
|
|
29
|
+
|
|
30
|
+
Settings > Labs > Diagnose keybindings reuses the same probe and terminal
|
|
31
|
+
fallback engines from `projmux setup` and `projmux init`. It lists the
|
|
32
|
+
keybinding catalog, lets you press one action key at a time from inside the
|
|
33
|
+
app, distinguishes plain / CSI-u / unexpected / timeout outcomes, and exposes
|
|
34
|
+
preview/apply rows for supported terminal fallbacks. When an unexpected
|
|
35
|
+
sequence can be safely read as a tmux plain chord, the Lab shows an explicit
|
|
36
|
+
`Save as plain override` row with the suggested chord; it never overwrites
|
|
37
|
+
`keymap.toml` from an unexpected sequence unless you select that confirmation
|
|
38
|
+
row. The Lab also shows whether the detected terminal can reload config after
|
|
39
|
+
fallback apply or needs a restart/manual reload.
|
|
40
|
+
|
|
22
41
|
> 한국어 요약: 대부분의 터미널은 `projmux shell` 만으로 아래 키가 바로 동작합니다.
|
|
23
42
|
> 동작하지 않으면 `projmux setup` 으로 어떤 키가 막혔는지 진단하고,
|
|
24
43
|
> `projmux init [terminal]` 으로 자동 설정하세요. 자동 설정이 없는 터미널은
|
|
@@ -106,6 +125,10 @@ which projmux keys actually reach the process. The command auto-detects your
|
|
|
106
125
|
terminal, then asks you to press each shortcut in turn and classifies the
|
|
107
126
|
result:
|
|
108
127
|
|
|
128
|
+
The same diagnostic is available in-app at Settings > Labs > Diagnose
|
|
129
|
+
keybindings. The Lab flow reads the controlling TTY directly, so it can probe a
|
|
130
|
+
key while Settings itself is running inside tmux.
|
|
131
|
+
|
|
109
132
|
| Status | Meaning |
|
|
110
133
|
| --- | --- |
|
|
111
134
|
| `OK plain` | The terminal forwarded the bare escape (e.g. `\x1b1` for `Alt-1`); tmux's plain bind handles it. |
|
|
@@ -118,6 +141,9 @@ tailored to the detected terminal (Ghostty, WezTerm, kitty, iTerm2,
|
|
|
118
141
|
Alacritty, Windows Terminal, foot, VS Code, …). When projmux ships an init
|
|
119
142
|
adapter for the terminal, the summary gives both the dry-run preview and the
|
|
120
143
|
exact apply command, e.g. `projmux init ghostty --apply`.
|
|
144
|
+
Settings > Labs also includes a concise after-apply hint: Ghostty/WezTerm/kitty
|
|
145
|
+
can reload config, Windows Terminal and iTerm2 generally need a restarted tab
|
|
146
|
+
or session, and unknown terminals are marked manual.
|
|
121
147
|
|
|
122
148
|
Useful flags:
|
|
123
149
|
|
|
@@ -160,6 +186,11 @@ already mapped to a *different* action are left untouched and reported as
|
|
|
160
186
|
mappings. Re-running `projmux init --apply` after editing the file refreshes
|
|
161
187
|
just the projmux-owned region.
|
|
162
188
|
|
|
189
|
+
`projmux init` always uses the built-in terminal fallback map. To override the
|
|
190
|
+
tmux chords rendered by `projmux tmux print-config`, `projmux tmux install`,
|
|
191
|
+
or `projmux shell`, use Settings > Keybindings or edit
|
|
192
|
+
`~/.config/projmux/keymap.toml`; see [Configuration](configuration.md#keymap-file).
|
|
193
|
+
|
|
163
194
|
### Supported terminals
|
|
164
195
|
|
|
165
196
|
#### Ghostty
|
|
@@ -253,12 +284,16 @@ action fires.
|
|
|
253
284
|
| `ESC [ 9006 u` | `User5` | AI split picker |
|
|
254
285
|
| `ESC [ 9007 u` | `User6` | Settings |
|
|
255
286
|
| `ESC [ 9008 u` | `User7` | New tmux window in the current pane directory |
|
|
256
|
-
| `ESC [ 9009 u` | `User8` | Previous tmux window |
|
|
257
|
-
| `ESC [ 9010 u` | `User9` | Next tmux window |
|
|
258
287
|
| `ESC [ 9011 u` | `User10` | Rename the current tmux window |
|
|
259
288
|
| `ESC [ 9012 u` | `User11` | Rename the current tmux pane label |
|
|
260
289
|
| `ESC [ 9013 u` | `User12` | Project switcher popup |
|
|
261
290
|
|
|
291
|
+
> Previous/Next window (Alt-Shift-Left/Right) intentionally **do not** use a
|
|
292
|
+
> CSI-u detour — both projmux and modern terminals already agree on the
|
|
293
|
+
> xterm-standard modifier sequence (`\x1b[1;4D` / `\x1b[1;4C`), so tmux binds
|
|
294
|
+
> directly to `M-S-Left` / `M-S-Right`. This keeps the popup-side chord
|
|
295
|
+
> handler and the tmux root binding consuming the same sequence.
|
|
296
|
+
|
|
262
297
|
### Ghostty (manual)
|
|
263
298
|
|
|
264
299
|
`projmux init ghostty` is the maintained path. The block below is what the
|
|
@@ -281,10 +316,14 @@ keybind = ctrl+shift+l=csi:9002u
|
|
|
281
316
|
keybind = ctrl+shift+n=csi:9008u
|
|
282
317
|
keybind = ctrl+m=csi:9011u
|
|
283
318
|
keybind = ctrl+shift+m=csi:9012u
|
|
284
|
-
keybind = alt+shift+left=csi:9009u
|
|
285
|
-
keybind = alt+shift+right=csi:9010u
|
|
286
319
|
```
|
|
287
320
|
|
|
321
|
+
`Alt-Shift-Left` and `Alt-Shift-Right` are intentionally absent: Ghostty
|
|
322
|
+
already emits the xterm-standard `\x1b[1;4D` / `\x1b[1;4C` sequences for
|
|
323
|
+
those chords, which tmux now binds directly. Adding a `csi:9009u` /
|
|
324
|
+
`csi:9010u` override would re-introduce the detour that hid the chord from
|
|
325
|
+
projmux popup handlers.
|
|
326
|
+
|
|
288
327
|
Reload Ghostty or restart the terminal after changing the config.
|
|
289
328
|
|
|
290
329
|
### Windows Terminal (manual)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# Native Picker Engine
|
|
2
2
|
|
|
3
|
-
This note tracks the native picker engine. Native is the
|
|
4
|
-
while the `internal/ui/fzf` backend remains available as an explicit fallback.
|
|
3
|
+
This note tracks the native picker engine. Native is the only picker backend.
|
|
5
4
|
|
|
6
5
|
The fzf compatibility surface for the native engine is tracked in
|
|
7
6
|
[native-picker-parity.md](native-picker-parity.md).
|
|
@@ -16,21 +15,14 @@ The fzf compatibility surface for the native engine is tracked in
|
|
|
16
15
|
responsible for backend routing, keyboard input, filtering, preview command
|
|
17
16
|
execution, and result contracts, while moving visual composition into
|
|
18
17
|
`projmuxpicker` so projmux can evolve a native picker design without coupling
|
|
19
|
-
every visual tweak to the
|
|
20
|
-
- `internal/ui/
|
|
21
|
-
shape and the backend-neutral `picker.Options`
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
|
|
27
|
-
picker engines while keeping fzf available.
|
|
28
|
-
- Settings > Labs > Picker Engine stores the backend selection in
|
|
29
|
-
`~/.config/projmux/picker-backend` and updates the live tmux environment so
|
|
30
|
-
new picker popups can switch between `fzf` and `native` without restarting
|
|
31
|
-
the app server.
|
|
32
|
-
- Native is the default backend. `PROJMUX_PICKER_BACKEND=fzf` remains an
|
|
33
|
-
explicit environment override and takes priority over the saved Labs setting.
|
|
18
|
+
every visual tweak to the compatibility option/result shape.
|
|
19
|
+
- `internal/ui/pickercompat` remains an internal compatibility mapper between
|
|
20
|
+
the old option/result shape and the backend-neutral `picker.Options`
|
|
21
|
+
contract. It is not a runtime backend. App code should
|
|
22
|
+
describe picker intent as rows, actions, preview commands, and initial focus,
|
|
23
|
+
then route through the native picker.
|
|
24
|
+
- Settings > Labs remains available for experimental settings, but picker
|
|
25
|
+
backend selection has been retired.
|
|
34
26
|
- Picker flows covered by the native path include AI picker/settings, shell
|
|
35
27
|
update prompt, settings hub sections, switch settings/add-pin, the main
|
|
36
28
|
project switcher list, recent sessions, and notify sidebar.
|
|
@@ -41,9 +33,10 @@ The fzf compatibility surface for the native engine is tracked in
|
|
|
41
33
|
expect keys such as notify `Ctrl-X`, `start:pos(N)` initial focus, preview
|
|
42
34
|
command output, preview cycle command bindings, and sidebar focus command
|
|
43
35
|
bindings.
|
|
44
|
-
- FZF-style movement keys are supported for native selection: `Ctrl-N`
|
|
45
|
-
down, while `Ctrl-P` and `Ctrl-K` move up unless the app claims
|
|
46
|
-
custom action.
|
|
36
|
+
- FZF-style movement keys are supported for native selection: `Ctrl-N` and
|
|
37
|
+
`Ctrl-J` move down, while `Ctrl-P` and `Ctrl-K` move up unless the app claims
|
|
38
|
+
the key as a custom action. Up/down-family movement wraps at list boundaries;
|
|
39
|
+
PageUp/PageDown and Home/End remain clamped or explicit jumps.
|
|
47
40
|
- Typed-query prompts support cursor-aware insertion/deletion with a visible
|
|
48
41
|
prompt cursor, Left/Right, Ctrl-A/E, Delete, Backspace, Ctrl-U, and Ctrl-W
|
|
49
42
|
for settings path entry.
|
|
@@ -135,7 +128,8 @@ The fzf compatibility surface for the native engine is tracked in
|
|
|
135
128
|
## Experimental Boundaries
|
|
136
129
|
|
|
137
130
|
- The `projmuxpicker` package is intended as a foundation that can be carried
|
|
138
|
-
forward, along with the
|
|
131
|
+
forward, along with the compatibility option/result mapping in
|
|
132
|
+
`internal/ui/pickercompat`.
|
|
139
133
|
Its frame, row, preview, theme, ANSI, and redraw modules are foundation code;
|
|
140
134
|
Docker sandbox scripts and dependency-policy notes remain support
|
|
141
135
|
scaffolding.
|
|
@@ -151,9 +145,7 @@ The fzf compatibility surface for the native engine is tracked in
|
|
|
151
145
|
switch and sessions popup flows type a filtered query, send `Right` and
|
|
152
146
|
`Alt-Down`, and assert the stored preview window/pane cursor for the selected
|
|
153
147
|
session.
|
|
154
|
-
- Public doctor dependency policy
|
|
155
|
-
selection. Native is the default picker backend, and fzf remains available as
|
|
156
|
-
an explicit fallback.
|
|
148
|
+
- Public doctor dependency policy no longer includes an external picker binary.
|
|
157
149
|
|
|
158
150
|
## Interactive No-fzf Sandbox
|
|
159
151
|
|
|
@@ -14,8 +14,8 @@ native picker engine and is not a public dependency-policy change.
|
|
|
14
14
|
| `--header` | AI, settings, shell update, notify | Covered | `renderNativeInteractive`, `renderNative`; settings native tests |
|
|
15
15
|
| `--footer` / `--footer-border line` | AI, settings, shell update, switch, sessions, notify | Covered for interactive native screens | `renderNativeInteractive` reserves bottom footer space and renders a separator line; `TestNativeInteractiveRendersFooterAtBottom` |
|
|
16
16
|
| `--ansi` | colored row labels from render package | Covered | native writes row labels directly, strips ANSI escapes from default search text, restores selected-row styling after embedded ANSI resets, and measures rendered cell width for Korean/CJK text, emoji, and combining marks; `TestFilterItemsIgnoresANSIEscapeSequences`; `TestNativeInteractiveUsesCurrentStyleForSimpleSelection`; `TestVisibleLenUsesTerminalCellWidth`; Docker e2e shows ANSI rows |
|
|
17
|
-
| hidden value after tab delimiter | all picker selections and default fzf matching | Covered by `picker.Item.Value` and default search text | `
|
|
18
|
-
| plain fzf candidates without structured entries |
|
|
17
|
+
| hidden value after tab delimiter | all picker selections and default fzf matching | Covered by `picker.Item.Value` and default search text | `pickercompat.PickerOptions`; `TestNativeRunnerFiltersAndSelectsByNumber`; `TestFilterItemsSearchesHiddenValueWhenNoSearchKey` |
|
|
18
|
+
| plain fzf candidates without structured entries | compat option call shape | Covered | `pickercompat.PickerOptions`; `TestPickerOptionsFromCompatPickerMapsCandidatesWhenEntriesAreEmpty` |
|
|
19
19
|
| search key filtering (`--nth`/reload filter file) | switch/sessions/notify entries | Covered by `Item.SearchText` with fzf reload order preservation | `FilterItems`; `TestFilterItemsUsesSearchTextNotMetadata`; `TestFilterItemsPreservesSearchKeyOrder` |
|
|
20
20
|
| default `--smart-case` matching | all searchable picker rows | Covered | native filter keeps lower-case queries case-insensitive and uppercase queries case-sensitive; `TestFilterItemsUsesFZFSmartCase` |
|
|
21
21
|
| fzf match highlighting | searchable simple picker rows | Covered for non-search-key simple rows | native highlights matched visible label runes while preserving embedded ANSI style; search-key reload lists intentionally keep fzf disabled-filter rendering without match highlights; `TestNativeInteractiveHighlightsSimpleQueryMatches`; `TestNativeInteractiveDoesNotHighlightSearchKeyReloadLists` |
|
|
@@ -26,14 +26,14 @@ native picker engine and is not a public dependency-policy change.
|
|
|
26
26
|
| `--gap --gap-line ─` | switch, sessions, notify multi-line rows | Covered for app multiline rows | `nativeGapLine`, row-budgeted range; `TestNativeInteractiveRendersMultilineGapLine`, `TestNativeVisibleRangeCountsMultilineRenderedRows` |
|
|
27
27
|
| selected multi-line marker | selected switch/session/notify cards | Covered for app multiline rows | native uses the same compact pointer-width red `▌` gutter as the first selected project line, and metadata lines align to the project-name column without the old deeper indent; `nativeContinuation`; `TestNativeInteractiveRendersSelectedMultilineContinuationMarker`; `TestInteractiveRowLinesUsesCompactSelectedMetaIndent`; `TestInteractiveRowLinesAlignsUnselectedMetaWithProjectName` |
|
|
28
28
|
| fzf current row colors | simple and multi-line rows | Covered for app rows | `nativeCurrentStart`, `nativePointer`; pointer/continuation gutter tokens carry the current-row background; `TestNativeSelectedContentKeepsCurrentStyleAfterReset`; `TestNativeInteractiveUsesCurrentStyleForSimpleSelection` |
|
|
29
|
-
| `--expect` keys | Enter/Ctrl-X/Alt-P/notify keys | Covered | `
|
|
29
|
+
| `--expect` keys | Enter/Ctrl-X/Alt-P/notify keys | Covered | `pickercompat.PickerOptions`; `TestNativeInteractiveSupportsCustomExpectKeys` |
|
|
30
30
|
| printable expect keys | notify sidebar `x` ack | Covered | `TestNativeInteractiveSupportsPrintableExpectKeys`; Docker no-fzf e2e |
|
|
31
31
|
| control expect keys | notify sidebar `Ctrl-X`, settings `Ctrl-Alt-S` close | Covered | `TestNativeInteractiveSupportsControlExpectKeys`; `TestNativeInteractiveSupportsControlAltCloseKeys` |
|
|
32
32
|
| close `--bind key:abort` | Esc, Ctrl-C, Alt-N, Ctrl-Alt-S variants | Covered | `CloseActions`; `TestNativeRunnerUsesSharedCloseActions` |
|
|
33
33
|
| terminal CSI-u key encoding | app keybind probe sequences, Ghostty/kitty-style modified keys | Covered | native handles app-specific Alt keys, generic modified letters/digits, and non-text keys such as Enter/Esc/Backspace/Tab; `TestNativeInteractiveSupportsCSIuAppKeyBindings` |
|
|
34
|
-
| `execute-silent(...)+refresh-preview` | switch/session preview cycling | Covered for command execution and rerender loop | `
|
|
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
35
|
| `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
|
-
| `start:pos(N)` | switch sidebar initial row | Covered | `
|
|
36
|
+
| `start:pos(N)` | switch sidebar initial row | Covered | `pickercompat.PickerOptions`/`pickercompat.OptionsFromPicker`; `TestPickerOptionsFromCompatPickerMapsStartPosToInitialIndex`; `TestPickerOptionsMapsCompatBindingsToContractActions` |
|
|
37
37
|
| `--preview` | switch, sessions | Covered by command output | `nativePreviewLines`; `TestNativeInteractiveRendersSelectedPreview` |
|
|
38
38
|
| `--preview-window right,60%,border-left` | switch popup, sessions popup | Covered for projmux option shape | `renderNativeSplitPreview` renders a single-column left border without a synthetic title row, uses fzf-measured percent sizing, normalizes preview tabs/control bytes before clipping, and pads both panes to fixed row widths so long preview rows do not wrap into extra vertical rows; `TestNativeInteractiveRendersWidePreviewBesideList`; `TestNativePreviewWidthUsesPreviewWindowPercent`; `TestRenderSplitPreviewRowsPadsBothPanes`; `TestRenderSplitPreviewRowsNormalizesPreviewTabsBeforeTruncating` |
|
|
39
39
|
| `--preview-window down,25%,border-top` | switch sidebar | Covered for projmux option shape | `renderNativeDownPreview` renders an immediate top border without a synthetic title row, uses fzf-measured percent sizing, and pads preview rows to the surface width; `TestNativeInteractiveRendersDownPreviewBelowList`; `TestNativePreviewHeightUsesPreviewWindowPercent`; `TestRenderDownPreviewPadsPreviewRows` |
|
|
@@ -41,9 +41,9 @@ native picker engine and is not a public dependency-policy change.
|
|
|
41
41
|
| `--query` | typed settings path defaults | Covered | `Options.InitialQuery`; settings tests |
|
|
42
42
|
| `--print-query` accept-query mode | typed settings path prompts | Covered | `Options.AcceptQuery`; `TestNativeRunnerAcceptsTypedQuery` |
|
|
43
43
|
| query cursor editing | typed settings path prompts | Covered | Left/Right, Ctrl-A/E, Delete, Backspace, Ctrl-U/W query editing plus visible prompt cursor; `TestNativeInteractiveEditsTypedQueryAtCursor`; `TestNativeInteractiveSupportsQueryLineEditingKeys`; `TestNativeInteractiveCtrlUDeletesBeforeCursor`; `TestNativePromptLineRendersQueryCursor` |
|
|
44
|
-
| terminal arrow key variants | interactive selection in tmux/docker | Covered | CSI, SS3/application cursor, modified CSI tests; app TTY `/dev/tty` fallback; raw TTY EOF polling keeps split ESC sequences from leaking into the query |
|
|
44
|
+
| terminal arrow key variants | interactive selection in tmux/docker | Covered | CSI, SS3/application cursor, modified CSI tests; up/down movement wraps at list boundaries while PageUp/PageDown and Home/End remain clamped or explicit jumps; app TTY `/dev/tty` fallback; raw TTY EOF polling keeps split ESC sequences from leaking into the query; `TestNativeInteractiveWrapsPreviousNavigationKeys`; `TestNativeInteractiveWrapsNextNavigationKeys`; `TestNativeInteractiveJumpNavigationRemainsClamped` |
|
|
45
45
|
| mouse support | optional fzf mouse picker interaction | Partially covered | native enables SGR mouse reporting in interactive alternate-screen mode, primary mouse down focuses the clicked row, primary mouse up applies it, and wheel input moves selection; drag gestures remain outside this POC; `TestNativeInteractiveSelectsOnMouseRelease`; `TestNativeInteractiveMouseDownOnlyFocuses`; `TestNativeInteractiveIgnoresMouseReleaseBeforeDown`; `TestNativeInteractiveSupportsMouseWheelSelection`; Docker no-fzf e2e clicks the AI settings row under a PTY |
|
|
46
|
-
| fzf navigation keys | interactive selection in searchable lists | Covered | native maps CSI-u `Ctrl-J` plus `Ctrl-N` to down and `Ctrl-P`/`Ctrl-K` to up when not claimed by a custom action; raw LF remains Enter for PTY compatibility; `TestNativeInteractiveSupportsFZFNavigationKeys` |
|
|
46
|
+
| fzf navigation keys | interactive selection in searchable lists | Covered | native maps CSI-u `Ctrl-J` plus `Ctrl-N` to down and `Ctrl-P`/`Ctrl-K` to up when not claimed by a custom action; up/down-family movement is safe on empty lists; raw LF remains Enter for PTY compatibility; `TestNativeInteractiveSupportsFZFNavigationKeys`; `TestNativeInteractiveNavigationKeysAreNoopForEmptyList` |
|
|
47
47
|
| 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
48
|
| frame content width | fzf border inner width | Covered | `ContentLayout` uses the frame inner width so separators and rows reach the right border; `TestRendererContentLayoutUsesFrameInnerWidth` |
|
|
49
49
|
| 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` |
|
|
@@ -52,36 +52,39 @@ native picker engine and is not a public dependency-policy change.
|
|
|
52
52
|
|
|
53
53
|
## Native Surface Architecture
|
|
54
54
|
|
|
55
|
-
- `internal/ui/picker` remains the backend-neutral contract and owns
|
|
55
|
+
- `internal/ui/picker` remains the backend-neutral contract and owns native
|
|
56
56
|
routing, keyboard input, fuzzy filtering, action dispatch, preview command
|
|
57
57
|
execution, and result handling.
|
|
58
58
|
- `internal/ui/projmuxpicker` owns projmux-native visual composition: frame,
|
|
59
59
|
redraw updates, ANSI width/truncation, theme tokens, prompt/footer/list
|
|
60
60
|
rendering, selected row styling, scrollbars/gap rows, and preview pane
|
|
61
61
|
geometry/rendering.
|
|
62
|
-
- `internal/ui/
|
|
63
|
-
`picker.Options`
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
-
|
|
68
|
-
|
|
69
|
-
a narrower boundary without deleting the existing fzf runner.
|
|
70
|
-
- Settings > Labs > Picker Engine persists the selected backend in
|
|
71
|
-
`~/.config/projmux/picker-backend` and updates the live tmux server
|
|
72
|
-
environment through `PROJMUX_PICKER_BACKEND`, while direct environment
|
|
73
|
-
overrides still win over saved config. Native is the default when no saved
|
|
74
|
-
backend or override exists; `fzf` remains available as an explicit fallback.
|
|
62
|
+
- `internal/ui/pickercompat` remains as the internal compatibility option/result
|
|
63
|
+
mapper from older app option shapes to `picker.Options` for the native
|
|
64
|
+
backend. It is not a runtime backend. This keeps app code closer to a
|
|
65
|
+
DI-style picker contract instead of embedding binding strings at each call
|
|
66
|
+
site.
|
|
67
|
+
- Settings > Labs remains available, but picker backend selection has been
|
|
68
|
+
retired. Deprecated saved/env backend values normalize to native.
|
|
75
69
|
- The split lets projmux grow a first-party picker design independently from
|
|
76
|
-
the
|
|
70
|
+
the compatibility option/result mapper.
|
|
71
|
+
|
|
72
|
+
## Frame Chrome ANSI
|
|
73
|
+
|
|
74
|
+
Native picker frame chrome is normalized in `internal/ui/projmuxpicker`.
|
|
75
|
+
Titlebars restore the titlebar style after embedded ANSI resets, search prompt
|
|
76
|
+
and footer separators fill the available frame width, and header, row, footer,
|
|
77
|
+
and preview lines close any active SGR style before padding or frame borders can
|
|
78
|
+
inherit it. This phase does not add popup modes or change the `popup-toggle`
|
|
79
|
+
contract; native popups still rely on the existing borderless tmux popup path.
|
|
77
80
|
|
|
78
81
|
## Verified Flows
|
|
79
82
|
|
|
80
83
|
- `ai` picker/settings: native backend routing covered by app tests. Docker
|
|
81
84
|
no-fzf e2e also types `Codex` into `projmux ai settings` and verifies the
|
|
82
85
|
native simple picker writes the `codex` mode without fzf.
|
|
83
|
-
- `shell` update prompt: native backend routing covered by shared
|
|
84
|
-
|
|
86
|
+
- `shell` update prompt: native backend routing covered by shared compat-to-native
|
|
87
|
+
bridge and settings-style typed prompt tests.
|
|
85
88
|
- `settings`: native backend exercised in unit tests and Docker no-fzf e2e
|
|
86
89
|
using Enter plus arrow-key navigation under a PTY. The Docker e2e also fails
|
|
87
90
|
if the Settings flows write tmux no-server noise to stderr while running
|
|
@@ -121,9 +124,8 @@ native picker engine and is not a public dependency-policy change.
|
|
|
121
124
|
- Mouse support is intentionally narrow in this POC: primary mouse down focuses
|
|
122
125
|
the clicked row, primary mouse up applies it, and wheel input moves selection.
|
|
123
126
|
Drag gestures and the full fzf mouse grammar are follow-up work.
|
|
124
|
-
- The public doctor/docs dependency policy
|
|
125
|
-
|
|
126
|
-
explicit fallback.
|
|
127
|
+
- The public doctor/docs dependency policy no longer includes an external
|
|
128
|
+
picker binary.
|
|
127
129
|
- Draft PR: https://github.com/crevissepartners/projmux/pull/98.
|
|
128
130
|
|
|
129
131
|
## Commands
|
package/docs/picker-ui-plan.md
CHANGED
|
@@ -2,42 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
## Goal
|
|
4
4
|
|
|
5
|
-
The project switcher needs a
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
The project switcher needs a rich native picker surface. The target interaction
|
|
6
|
+
is a card-like list where each item can show a title plus small contextual lines
|
|
7
|
+
such as session state, window/pane summary, branch, or path. Search should stay
|
|
8
|
+
focused on stable identity text, especially the project or session title,
|
|
9
|
+
instead of matching every contextual preview line.
|
|
10
10
|
|
|
11
11
|
## Current Contract
|
|
12
12
|
|
|
13
13
|
The picker contract is split in two layers:
|
|
14
14
|
|
|
15
15
|
- `internal/ui/picker` owns backend-neutral items, actions, preview metadata,
|
|
16
|
-
|
|
17
|
-
- `internal/ui/
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
```text
|
|
22
|
-
<visible label>\t<selection value>
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
fzf is configured with:
|
|
26
|
-
|
|
27
|
-
- `--delimiter "\t"`
|
|
28
|
-
- `--with-nth 1`
|
|
29
|
-
- `--exit-0`
|
|
30
|
-
- optional `--preview` and `--preview-window`
|
|
31
|
-
|
|
32
|
-
The app depends on fzf returning the selected row and then extracts the hidden
|
|
33
|
-
value after the first tab. This contract is simple and stable, but it limits each
|
|
34
|
-
row to one visible line.
|
|
16
|
+
title-focused filtering, and the native runner.
|
|
17
|
+
- `internal/ui/pickercompat` is an internal compatibility option/result shape
|
|
18
|
+
for older app call sites. It is not a runtime backend, and product flows do
|
|
19
|
+
not execute the external fzf binary.
|
|
35
20
|
|
|
36
21
|
## fzf Capability Check
|
|
37
22
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
23
|
+
This section is historical context. Earlier design work evaluated fzf because it
|
|
24
|
+
supported multi-line items with `--read0`, where a single item can contain
|
|
25
|
+
newline characters when input records are NUL-delimited.
|
|
41
26
|
|
|
42
27
|
The simple fzf option path is not enough for the desired search behavior:
|
|
43
28
|
|
|
@@ -59,7 +44,7 @@ Use `--read0` and NUL-delimited multi-line entries. This is the smallest change,
|
|
|
59
44
|
but contextual card text will participate in search unless the visible card is
|
|
60
45
|
kept title-only. This does not meet the intended search model.
|
|
61
46
|
|
|
62
|
-
This path is
|
|
47
|
+
This path is retired and is not supported.
|
|
63
48
|
|
|
64
49
|
### 2. fzf custom filtering
|
|
65
50
|
|
|
@@ -73,13 +58,12 @@ Tradeoffs:
|
|
|
73
58
|
- More edge cases around selection identity and tracking.
|
|
74
59
|
- Still constrained by fzf's list layout and event model.
|
|
75
60
|
|
|
76
|
-
This
|
|
61
|
+
This bridge path is retired and is not supported.
|
|
77
62
|
|
|
78
63
|
### 3. Native picker TUI
|
|
79
64
|
|
|
80
65
|
Introduce a picker abstraction and implement a native terminal UI for card rows,
|
|
81
|
-
title-focused search, stable selection identity, and app-owned key handling.
|
|
82
|
-
remains the default backend until parity is reached.
|
|
66
|
+
title-focused search, stable selection identity, and app-owned key handling.
|
|
83
67
|
|
|
84
68
|
This best matches the desired product direction:
|
|
85
69
|
|
|
@@ -90,9 +74,9 @@ This best matches the desired product direction:
|
|
|
90
74
|
|
|
91
75
|
## Implemented Direction
|
|
92
76
|
|
|
93
|
-
Do not extend the
|
|
94
|
-
|
|
95
|
-
|
|
77
|
+
Do not extend the retired fzf row format again. The previous hidden-field attempt
|
|
78
|
+
showed that small fzf encoding changes can break selection and navigation in
|
|
79
|
+
subtle ways.
|
|
96
80
|
|
|
97
81
|
Current implementation:
|
|
98
82
|
|
|
@@ -100,12 +84,8 @@ Current implementation:
|
|
|
100
84
|
`SearchText`, `MetaLines`, `Badges`, and `PreviewTarget`.
|
|
101
85
|
- `picker.Options` carries backend-neutral actions, preview metadata, prompt,
|
|
102
86
|
footer, initial query, and multiline intent.
|
|
103
|
-
- Native is the
|
|
104
|
-
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
parity, including native preview panes, raw-key navigation, and sidebar focus
|
|
109
|
-
tracking.
|
|
110
|
-
|
|
111
|
-
fzf can stay as the stable fallback while the native picker continues to mature.
|
|
87
|
+
- Native is the picker backend and renders the popup/sidebar surfaces.
|
|
88
|
+
- Native supports multiline item rendering, title-focused search via
|
|
89
|
+
`SearchText`, numeric selection, and shared close actions.
|
|
90
|
+
- Switcher popup/sidebar use native preview panes, raw-key navigation, and
|
|
91
|
+
sidebar focus tracking.
|
package/docs/repo-layout.md
CHANGED
|
@@ -21,7 +21,9 @@ projmux/
|
|
|
21
21
|
tmux/
|
|
22
22
|
state/
|
|
23
23
|
ui/
|
|
24
|
-
|
|
24
|
+
picker/
|
|
25
|
+
pickercompat/
|
|
26
|
+
projmuxpicker/
|
|
25
27
|
render/
|
|
26
28
|
version/
|
|
27
29
|
docs/
|
|
@@ -36,7 +38,8 @@ projmux/
|
|
|
36
38
|
- `cmd/projmux` contains only CLI wiring.
|
|
37
39
|
- `internal/core` contains product behavior that should be testable without tmux.
|
|
38
40
|
- `internal/integrations/tmux` should be the only place that knows tmux command strings and output formats.
|
|
39
|
-
- `internal/ui/
|
|
41
|
+
- `internal/ui/picker` and `internal/ui/projmuxpicker` own native picker behavior.
|
|
42
|
+
- `internal/ui/pickercompat` is an internal compatibility option/result shape for older app call sites. It is not a runtime backend; product code should route through the native picker.
|
|
40
43
|
- `scripts/` is for development tooling only, not product logic.
|
|
41
44
|
|
|
42
45
|
## Early implementation order
|
|
@@ -46,5 +49,5 @@ projmux/
|
|
|
46
49
|
3. `internal/core/pins`
|
|
47
50
|
4. `internal/state`
|
|
48
51
|
5. `internal/integrations/tmux`
|
|
49
|
-
6. `internal/ui/
|
|
52
|
+
6. `internal/ui/picker`
|
|
50
53
|
7. CLI command wiring
|
package/docs/roadmap.md
CHANGED
|
@@ -19,7 +19,7 @@ core that 0.3 had landed.
|
|
|
19
19
|
### Diagnostics
|
|
20
20
|
|
|
21
21
|
- `projmux doctor` — runtime dependency report. Enforces minimum tmux
|
|
22
|
-
3.4 and
|
|
22
|
+
3.4 and checks workflow dependencies such as `git` and `stty`.
|
|
23
23
|
|
|
24
24
|
### Focus
|
|
25
25
|
|
|
@@ -52,7 +52,7 @@ core that 0.3 had landed.
|
|
|
52
52
|
|
|
53
53
|
- Two-line clickable status bar: row 0 is the existing
|
|
54
54
|
session/window/path/git/kube row, row 1 splits notify (left) and
|
|
55
|
-
usage (right).
|
|
55
|
+
usage (right), with a row-0 settings click fallback.
|
|
56
56
|
- `projmux statusbar click` — single dispatcher for both mouse clicks
|
|
57
57
|
and the `prefix s {u,n,g,k,p,s}` keyboard chord. Window-list clicks
|
|
58
58
|
on tabs short-circuit to native `select-window`.
|
|
@@ -71,20 +71,34 @@ v0.4 shipped.
|
|
|
71
71
|
|
|
72
72
|
### Picker UI
|
|
73
73
|
|
|
74
|
-
- Picker-domain model separate from
|
|
75
|
-
|
|
74
|
+
- Picker-domain model separate from row rendering. Done in the 0.5 picker
|
|
75
|
+
contract slice.
|
|
76
76
|
- Native picker backend for multi-line card rows and title-focused search.
|
|
77
|
-
Done in the 0.5 picker contract slice, later promoted to the
|
|
78
|
-
backend
|
|
77
|
+
Done in the 0.5 picker contract slice, later promoted to the only picker
|
|
78
|
+
backend.
|
|
79
79
|
- Port switcher popup/sidebar surfaces after parity tests cover
|
|
80
80
|
selection, preview, and key actions.
|
|
81
81
|
|
|
82
82
|
### Picker dismissal
|
|
83
83
|
|
|
84
84
|
- Picker-agnostic popup close/toggle handling so AI picker dismissal
|
|
85
|
-
does not depend on
|
|
86
|
-
contract slice;
|
|
87
|
-
|
|
85
|
+
does not depend on backend-specific key bindings. Done in the 0.5 picker
|
|
86
|
+
contract slice; the native runner consumes shared close action keys.
|
|
87
|
+
|
|
88
|
+
### Keybindings
|
|
89
|
+
|
|
90
|
+
- In-app Settings editor for tmux keymap entries. Done in the 0.5 keybinding
|
|
91
|
+
M4 slice: Settings > Keybindings lists actions, opens action detail rows,
|
|
92
|
+
accepts typed `plain`/`prefix` tmux chord strings, supports disable/reset,
|
|
93
|
+
writes `~/.config/projmux/keymap.toml`, regenerates the app tmux config, and
|
|
94
|
+
hot-reloads the live tmux config when Settings is running inside tmux.
|
|
95
|
+
- M6 progress: Settings > Labs now exposes a Keybinding Lab that reuses the
|
|
96
|
+
setup probe and init merge engines for per-action diagnostics, single-key
|
|
97
|
+
plain/CSI-u/unknown/timeout outcomes, and supported terminal fallback
|
|
98
|
+
preview/apply actions.
|
|
99
|
+
- Still outstanding for later milestones: broader terminal-specific fallback
|
|
100
|
+
remediation for changed/custom fallback mappings beyond the supported init
|
|
101
|
+
adapters.
|
|
88
102
|
|
|
89
103
|
### Docker install and E2E harness
|
|
90
104
|
|
package/docs/statusbar.md
CHANGED
|
@@ -27,7 +27,10 @@ row 1 #[range=user|notify] <notify HUD pill> #[norange]
|
|
|
27
27
|
`isWindowListRangeToken` fallback is now defense-in-depth only.
|
|
28
28
|
The session, pwd, kube, and git segments on this row are wrapped
|
|
29
29
|
in `#[range=user|<id>]` ranges and dispatched through the projmux
|
|
30
|
-
handler. The
|
|
30
|
+
handler. The standalone config also wraps the right-side `projmux`
|
|
31
|
+
badge as the `settings` range; the app config renders a compact
|
|
32
|
+
`⚙` settings chip after the clock. The git segment shows the current
|
|
33
|
+
branch or detached commit,
|
|
31
34
|
then compact state indicators when available: `*` for local changes,
|
|
32
35
|
`+N` for staged entries, and `↑N`/`↓N` for ahead/behind counts. Each
|
|
33
36
|
state token gets its own compact foreground color while preserving the
|
|
@@ -46,7 +49,7 @@ A single tmux bind handles both lines:
|
|
|
46
49
|
```tmux
|
|
47
50
|
bind-key -n MouseDown1Status if-shell -F "#{==:#{mouse_status_range},window}" \
|
|
48
51
|
{ select-window -t = } \
|
|
49
|
-
{ run-shell "'<projmux>' statusbar click \"#{mouse_status_range}\" --mouse-window \"#{mouse_window}\"" }
|
|
52
|
+
{ run-shell "'<projmux>' statusbar click \"#{mouse_status_range}\" --client \"#{client_tty}\" --mouse-window \"#{mouse_window}\"" }
|
|
50
53
|
```
|
|
51
54
|
|
|
52
55
|
`MouseDown1Status` fires from any line of a multi-line status bar with
|
|
@@ -57,10 +60,11 @@ bind-key -n MouseDown1Status if-shell -F "#{==:#{mouse_status_range},window}" \
|
|
|
57
60
|
| Range id | Row | Click action | Keyboard |
|
|
58
61
|
| -------- | --- | ----------------------------------------- | ------------- |
|
|
59
62
|
| `session` | 0 | `projmux tmux popup-toggle sessionizer-sidebar` | `prefix s s` |
|
|
60
|
-
| `pwd` | 0 |
|
|
63
|
+
| `pwd` | 0 | show a native-framed current-path popup; no clipboard or tmux buffer copy | `prefix s p` |
|
|
61
64
|
| `kube` | 0 | `projmux tmux popup-toggle sessionizer` | `prefix s k` |
|
|
62
65
|
| `git` | 0 | `projmux tmux popup-toggle sessionizer` | `prefix s g` |
|
|
63
|
-
| `
|
|
66
|
+
| `settings` | 0 | `projmux tmux popup-toggle --client <tty> ai-split-settings` | mouse only; `prefix s s` remains `session` |
|
|
67
|
+
| `usage` | 1 | show a native-framed usage HUD popup from cached usage state | `prefix s u` |
|
|
64
68
|
| `notify` | 1 | `projmux focus --target <newest> --source status-bar --kind segment-click`, then ack on focus success | `prefix s n` |
|
|
65
69
|
|
|
66
70
|
`notify` reads the pending queue only. For a live pane-state view that is
|
|
@@ -70,13 +74,23 @@ The notify segment renders the newest queued item as a single notification
|
|
|
70
74
|
block: project, state (`NEED`/`INFO`/`WARN`/`CRIT`), optional agent, text,
|
|
71
75
|
age, and `+N` for older pending entries. Window/pane ids are not shown in the
|
|
72
76
|
compact status segment.
|
|
73
|
-
`usage`
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
`usage` opens a native-framed detail HUD for the compact usage bar. It reads
|
|
78
|
+
the cached usage state in-process, keeps the existing `projmux usage` CLI
|
|
79
|
+
output shape unchanged for external consumers, aligns model/window rows with
|
|
80
|
+
right-aligned numeric values, dims unavailable values, and colors rows at the
|
|
81
|
+
same alert thresholds as the popup: amber at 80% and red at 95%.
|
|
82
|
+
|
|
83
|
+
The path popup uses the native picker frame chrome, a one-line title,
|
|
84
|
+
the full wrapped current path, cheap project/git metadata when available, and
|
|
85
|
+
an `Enter closes this popup` prompt. The click is display-only: it does not
|
|
86
|
+
invoke system clipboard tools and does not write a tmux paste buffer. The
|
|
87
|
+
popup command prints one quoted payload and waits for a plain Enter read so it
|
|
88
|
+
does not leave terminal key state behind. The usage popup uses the same
|
|
89
|
+
single-payload print and plain Enter-close pattern. It shows the authoritative
|
|
90
|
+
last collect timestamp when present, falls back to the cache file mtime when
|
|
91
|
+
needed, and colors that sync line amber once it is more than 60 seconds old.
|
|
92
|
+
The notification HUD detail surface
|
|
93
|
+
(`Alt-2` / `User2`) opens the
|
|
80
94
|
right-side notification popup with newest-first rows. The popup itself is
|
|
81
95
|
untitled; when decoration mode is `symbol` or `emoji`, the bell appears before
|
|
82
96
|
the fzf header text instead. Selecting a row still focuses and acknowledges
|
|
@@ -100,7 +114,9 @@ bind-key -T projmux-status s run-shell '#{q:projmux} statusbar click session'
|
|
|
100
114
|
```
|
|
101
115
|
|
|
102
116
|
The chord routes through the same dispatcher as the mouse click, so
|
|
103
|
-
keyboard and mouse paths are functionally identical.
|
|
117
|
+
keyboard and mouse paths are functionally identical for keyed ranges.
|
|
118
|
+
There is intentionally no `prefix s s` settings fallback because that chord
|
|
119
|
+
already opens the session/sidebar range.
|
|
104
120
|
|
|
105
121
|
## Click failure handling
|
|
106
122
|
|
|
@@ -115,10 +131,11 @@ them as `display-message` toasts:
|
|
|
115
131
|
<reason>`.
|
|
116
132
|
- `session`, `kube`, or `git` popup launch failure: toast
|
|
117
133
|
`statusbar <range>: popup failed`.
|
|
118
|
-
- `
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
134
|
+
- `settings` popup launch failure: toast `statusbar settings: popup failed`.
|
|
135
|
+
- `pwd` path popup failure: fall back to a short `display-message`
|
|
136
|
+
containing the current path.
|
|
137
|
+
- `usage` popup failure: fall back to a compact usage summary
|
|
138
|
+
`display-message`.
|
|
122
139
|
|
|
123
140
|
`MouseX` / `MouseY` are accepted but not consumed today; the fields
|
|
124
141
|
are wired through so click telemetry can land without changing the
|
package/docs/testing.md
CHANGED
|
@@ -7,9 +7,8 @@ and humans run the same entrypoints.
|
|
|
7
7
|
|
|
8
8
|
- `make test` runs the fast Go unit suite. These tests avoid tmux, TTY, GUI,
|
|
9
9
|
and host shell dependencies.
|
|
10
|
-
- Picker unit coverage includes the backend-neutral item/action contract,
|
|
11
|
-
|
|
12
|
-
shared close actions.
|
|
10
|
+
- Picker unit coverage includes the backend-neutral item/action contract,
|
|
11
|
+
native title-focused filtering, numeric selection, and shared close actions.
|
|
13
12
|
- `make test-integration` builds `test/docker/Dockerfile` and runs
|
|
14
13
|
`test/integration/linux-smoke.sh` in Docker. It validates Linux dependency
|
|
15
14
|
discovery, tmux config generation/install, app config reload against a real
|
|
@@ -29,7 +28,7 @@ The Docker suites are intended to cover portable Linux behavior that can be
|
|
|
29
28
|
made deterministic in a container:
|
|
30
29
|
|
|
31
30
|
- binary build and source install into an isolated prefix
|
|
32
|
-
- `doctor` dependency checks for `tmux`, `
|
|
31
|
+
- `doctor` dependency checks for `tmux`, `git`, and `stty`
|
|
33
32
|
- tmux config print/install/apply paths
|
|
34
33
|
- notify queue push/list/ack/reconcile state transitions
|
|
35
34
|
- focus fallback behavior when a tmux server has sessions but no attached
|
|
@@ -37,9 +36,8 @@ made deterministic in a container:
|
|
|
37
36
|
- status rendering that only depends on tmux state and local files
|
|
38
37
|
|
|
39
38
|
The test container disables networking during `docker run`. The image build may
|
|
40
|
-
use the network to fetch the pinned base image
|
|
41
|
-
|
|
42
|
-
built.
|
|
39
|
+
use the network to fetch the pinned base image and apt packages, but suite
|
|
40
|
+
execution should not need network access after the image is built.
|
|
43
41
|
|
|
44
42
|
## Host-Only Checks
|
|
45
43
|
|