projmux 0.4.4 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README-ko.md +58 -269
- package/README.md +57 -259
- package/docs/agent-workflow.md +56 -0
- package/docs/architecture.md +199 -0
- package/docs/assets/projmux-icon.png +0 -0
- package/docs/assets/projmux-shell-sidebar.gif +0 -0
- package/docs/cli.md +429 -0
- package/docs/configuration.md +127 -0
- package/docs/hooks.md +118 -0
- package/docs/install.md +99 -0
- package/docs/keybindings.md +337 -0
- package/docs/migration-plan.md +82 -0
- package/docs/notify-queue.md +199 -0
- package/docs/npm-distribution.md +86 -0
- package/docs/picker-ui-plan.md +111 -0
- package/docs/pr-guideline.md +106 -0
- package/docs/repo-layout.md +50 -0
- package/docs/roadmap.md +95 -0
- package/docs/shell-autostart.md +33 -0
- package/docs/statusbar.md +151 -0
- package/docs/testing.md +57 -0
- package/docs/upgrading.md +100 -0
- package/docs/usage-tracking.md +153 -0
- package/package.json +7 -5
package/docs/install.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Install
|
|
2
|
+
|
|
3
|
+
The recommended install path is npm:
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npm install -g projmux
|
|
7
|
+
projmux version
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
The `projmux` npm package installs a small Node.js shim plus one
|
|
11
|
+
platform-specific Go binary package for Linux and macOS on x64 or arm64. The
|
|
12
|
+
shim sets `PROJMUX_INSTALLER=npm` so Settings > About and `projmux update`
|
|
13
|
+
can use npm-aware update guidance.
|
|
14
|
+
|
|
15
|
+
After installing, run:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
projmux doctor
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`doctor` checks that runtime tools such as `tmux` and the junegunn/fzf CLI are
|
|
22
|
+
available and new enough.
|
|
23
|
+
|
|
24
|
+
## Runtime Tools
|
|
25
|
+
|
|
26
|
+
Normal use needs:
|
|
27
|
+
|
|
28
|
+
- Node.js and npm for the npm install channel.
|
|
29
|
+
- tmux 3.4 or newer.
|
|
30
|
+
- fzf 0.65.0 or newer.
|
|
31
|
+
|
|
32
|
+
Useful optional tools:
|
|
33
|
+
|
|
34
|
+
- `git` for branch/status metadata.
|
|
35
|
+
- `kubectl` for the Kubernetes status segment.
|
|
36
|
+
- `notify-send` on Linux, or `powershell.exe` under WSL, for built-in desktop
|
|
37
|
+
notifications.
|
|
38
|
+
|
|
39
|
+
## Go Install
|
|
40
|
+
|
|
41
|
+
Use this only when npm is not the right fit for your machine or workflow:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
go install github.com/crevissepartners/projmux/cmd/projmux@latest
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
This requires Go 1.24 or newer. The binary is written to `$(go env GOBIN)` when
|
|
48
|
+
set, otherwise `$(go env GOPATH)/bin` (usually `~/go/bin`). Make sure that
|
|
49
|
+
directory is on `PATH`.
|
|
50
|
+
|
|
51
|
+
Go-managed installs can update through:
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
projmux upgrade
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
See [Upgrading](upgrading.md) for version pinning and installer-specific
|
|
58
|
+
update behavior.
|
|
59
|
+
|
|
60
|
+
## Source Checkout
|
|
61
|
+
|
|
62
|
+
Source installs are for contributors or users who intentionally track a local
|
|
63
|
+
checkout:
|
|
64
|
+
|
|
65
|
+
```sh
|
|
66
|
+
git clone https://github.com/crevissepartners/projmux.git
|
|
67
|
+
cd projmux
|
|
68
|
+
make install
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`make install` builds the binary, atomically replaces
|
|
72
|
+
`$(go env GOPATH)/bin/projmux`, runs `projmux tmux apply`, and reconciles the
|
|
73
|
+
notify queue. Override the destination with `INSTALL_DIR=/usr/local/bin`.
|
|
74
|
+
|
|
75
|
+
Update source checkouts with the repository workflow:
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
git pull --ff-only
|
|
79
|
+
make install
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## GitHub Release Binary
|
|
83
|
+
|
|
84
|
+
GitHub Release tarballs are supported by the updater when the install is
|
|
85
|
+
marked as release-managed:
|
|
86
|
+
|
|
87
|
+
```sh
|
|
88
|
+
export PROJMUX_INSTALLER=github-release
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
With that set, `projmux update apply` downloads the latest matching release
|
|
92
|
+
asset, replaces the current executable, and reapplies the live tmux config
|
|
93
|
+
unless `--no-apply` is used.
|
|
94
|
+
|
|
95
|
+
## npm Packaging Details
|
|
96
|
+
|
|
97
|
+
Repository packaging and publish details are maintained in
|
|
98
|
+
[npm Distribution](npm-distribution.md). That document is for maintainers; end
|
|
99
|
+
users should not need it for installation.
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
# Terminal Keybindings
|
|
2
|
+
|
|
3
|
+
projmux is keyboard-driven. `projmux shell` writes a tmux config that owns
|
|
4
|
+
every binding listed here, so the keys are live the moment the app starts —
|
|
5
|
+
no extra setup in most terminals.
|
|
6
|
+
|
|
7
|
+
The recommended path when a key does not fire:
|
|
8
|
+
|
|
9
|
+
1. Press the key inside `projmux shell` and see what works on your terminal
|
|
10
|
+
out of the box ([Quick start](#quick-start-no-setup)).
|
|
11
|
+
2. If something is swallowed, run [`projmux setup`](#diagnose-projmux-setup)
|
|
12
|
+
outside tmux — it tells you exactly which sequences reach the process and
|
|
13
|
+
which the terminal is eating.
|
|
14
|
+
3. For terminals projmux knows how to configure, run
|
|
15
|
+
[`projmux init [terminal]`](#auto-config-projmux-init) as the fallback:
|
|
16
|
+
preview first, then add `--apply` to merge the right bindings into your
|
|
17
|
+
terminal config with a timestamped backup.
|
|
18
|
+
4. If your terminal is not in the init list (or you prefer to edit configs by
|
|
19
|
+
hand), use the [Manual fallback / advanced (CSI-u)](#manual-fallback--advanced-csi-u)
|
|
20
|
+
section.
|
|
21
|
+
|
|
22
|
+
> 한국어 요약: 대부분의 터미널은 `projmux shell` 만으로 아래 키가 바로 동작합니다.
|
|
23
|
+
> 동작하지 않으면 `projmux setup` 으로 어떤 키가 막혔는지 진단하고,
|
|
24
|
+
> `projmux init [terminal]` 으로 자동 설정하세요. 자동 설정이 없는 터미널은
|
|
25
|
+
> 마지막 [Manual fallback / advanced (CSI-u)](#manual-fallback--advanced-csi-u)
|
|
26
|
+
> 섹션의 매핑표를 참고해 직접 설정하면 됩니다.
|
|
27
|
+
|
|
28
|
+
The tmux **prefix** is the upstream default `Ctrl-b`. Inside the running
|
|
29
|
+
session, `Ctrl-b ?` lists every binding live.
|
|
30
|
+
|
|
31
|
+
## Quick start (no setup)
|
|
32
|
+
|
|
33
|
+
These shortcuts are bound by projmux's generated tmux config. On terminals
|
|
34
|
+
that pass `Alt-*` and `Ctrl-*` chords through to the running process
|
|
35
|
+
unchanged (e.g. Linux gnome-terminal, foot, most stock Linux terminals),
|
|
36
|
+
they work the moment you launch `projmux shell` — no terminal config
|
|
37
|
+
required.
|
|
38
|
+
|
|
39
|
+
If a key does nothing, jump to
|
|
40
|
+
[Diagnose: `projmux setup`](#diagnose-projmux-setup) instead of guessing.
|
|
41
|
+
|
|
42
|
+
### Pickers
|
|
43
|
+
|
|
44
|
+
These open the projmux popups and the sidebar. No prefix needed.
|
|
45
|
+
|
|
46
|
+
| Shortcut | Action |
|
|
47
|
+
| --- | --- |
|
|
48
|
+
| `Alt-1` | Project sidebar |
|
|
49
|
+
| `Alt-2` | Notify sidebar |
|
|
50
|
+
| `Alt-3` | Existing session popup |
|
|
51
|
+
| `Alt-4` | AI split picker |
|
|
52
|
+
| `Alt-5` | Settings |
|
|
53
|
+
| `Alt-6` | Project switcher popup |
|
|
54
|
+
|
|
55
|
+
The same surfaces are also available from the prefix table:
|
|
56
|
+
|
|
57
|
+
| Shortcut | Action |
|
|
58
|
+
| --- | --- |
|
|
59
|
+
| `Prefix F` | Project sidebar |
|
|
60
|
+
| `Prefix b` | Existing session popup |
|
|
61
|
+
| `Prefix f` | Project switcher popup |
|
|
62
|
+
| `Prefix g` | Jump to the current pane's project session |
|
|
63
|
+
|
|
64
|
+
### Windows, panes, AI splits
|
|
65
|
+
|
|
66
|
+
| Shortcut | Action |
|
|
67
|
+
| --- | --- |
|
|
68
|
+
| `Ctrl-n` | New tmux window in the current pane's directory |
|
|
69
|
+
| `Alt-Shift-Left` / `Alt-Shift-Right` | Previous / next window |
|
|
70
|
+
| `Alt-Left` / `Right` / `Up` / `Down` | Move focus between panes |
|
|
71
|
+
| `Alt-r` | Rename the current window |
|
|
72
|
+
| `Prefix R` | Rename the current window |
|
|
73
|
+
| `Prefix r` | Open an AI split to the right |
|
|
74
|
+
| `Prefix l` | Open an AI split below |
|
|
75
|
+
|
|
76
|
+
When a pane closes, projmux re-spreads remaining panes so the surviving split
|
|
77
|
+
does not stretch lopsided.
|
|
78
|
+
|
|
79
|
+
### Inside the pickers
|
|
80
|
+
|
|
81
|
+
| Surface | Shortcut | Action |
|
|
82
|
+
| --- | --- | --- |
|
|
83
|
+
| Existing session popup | `Ctrl-X` | Kill the focused session and reopen the popup |
|
|
84
|
+
| Existing session popup | `Left/Right` | Preview previous/next window |
|
|
85
|
+
| Existing session popup | `Alt-Up/Alt-Down` | Preview previous/next pane |
|
|
86
|
+
| Project switcher | `Ctrl-X` | Kill the focused existing session and reopen the picker |
|
|
87
|
+
| Project switcher | `Alt-P` | Pin or unpin the focused directory |
|
|
88
|
+
|
|
89
|
+
### Conditional rename keys
|
|
90
|
+
|
|
91
|
+
These two only fire if your terminal forwards CSI-u sequences for `Ctrl-M`
|
|
92
|
+
and `Ctrl-Shift-M`. Without that wiring, plain `Ctrl-M` is just `Enter` and
|
|
93
|
+
`Ctrl-Shift-M` typically does nothing. `projmux init` configures this for
|
|
94
|
+
the terminals it supports; otherwise see
|
|
95
|
+
[Manual fallback / advanced (CSI-u)](#manual-fallback--advanced-csi-u).
|
|
96
|
+
|
|
97
|
+
| Shortcut | Action |
|
|
98
|
+
| --- | --- |
|
|
99
|
+
| `Ctrl-M` | Rename the current window (terminal must send `User10`) |
|
|
100
|
+
| `Ctrl-Shift-M` | Rename the current AI pane label / topic (terminal must send `User11`) |
|
|
101
|
+
|
|
102
|
+
## Diagnose: `projmux setup`
|
|
103
|
+
|
|
104
|
+
Run `projmux setup` *outside* tmux (in your raw terminal window) to find out
|
|
105
|
+
which projmux keys actually reach the process. The command auto-detects your
|
|
106
|
+
terminal, then asks you to press each shortcut in turn and classifies the
|
|
107
|
+
result:
|
|
108
|
+
|
|
109
|
+
| Status | Meaning |
|
|
110
|
+
| --- | --- |
|
|
111
|
+
| `OK plain` | The terminal forwarded the bare escape (e.g. `\x1b1` for `Alt-1`); tmux's plain bind handles it. |
|
|
112
|
+
| `OK csi-u` | The terminal already forwards a `ESC [ NNNNu` sequence routed to a tmux `User*` key. You are fully wired. |
|
|
113
|
+
| `MISS timeout` | No bytes arrived — the terminal swallowed the key for its own action. |
|
|
114
|
+
| `MISS unknown` | Something arrived, but it does not match either expected sequence — the terminal bound this combo to a different action. |
|
|
115
|
+
|
|
116
|
+
The summary at the end lists the failing keys and a remediation hint
|
|
117
|
+
tailored to the detected terminal (Ghostty, WezTerm, kitty, iTerm2,
|
|
118
|
+
Alacritty, Windows Terminal, foot, VS Code, …). When projmux ships an init
|
|
119
|
+
adapter for the terminal, the summary gives both the dry-run preview and the
|
|
120
|
+
exact apply command, e.g. `projmux init ghostty --apply`.
|
|
121
|
+
|
|
122
|
+
Useful flags:
|
|
123
|
+
|
|
124
|
+
```sh
|
|
125
|
+
projmux setup # interactive probe (default)
|
|
126
|
+
projmux setup --timeout 10s # wait longer per key
|
|
127
|
+
projmux setup --non-interactive # just print the expected key map and exit
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
`--non-interactive` is handy when you only want to see, on this machine and
|
|
131
|
+
shell, which `plain` and `csi-u` byte sequences projmux is listening for —
|
|
132
|
+
useful for hand-rolling a config in a terminal projmux does not yet know
|
|
133
|
+
about.
|
|
134
|
+
|
|
135
|
+
> 한국어 요약: `projmux setup` 을 tmux *밖에서* 실행하면, 진단 대상 키를 차례로
|
|
136
|
+
> 누르며 어떤 키가 plain/CSI-u 로 도달하는지, 어떤 키가 swallow 되는지 표로
|
|
137
|
+
> 알려줍니다. 끝에서 터미널별 다음 단계를 제안합니다.
|
|
138
|
+
|
|
139
|
+
## Auto-config: `projmux init`
|
|
140
|
+
|
|
141
|
+
`projmux init` is the supported fallback when `projmux setup` shows that a
|
|
142
|
+
terminal swallows shortcuts projmux already binds in tmux. It merges the
|
|
143
|
+
projmux CSI-u keybindings into a terminal emulator's config file. Default
|
|
144
|
+
mode is **dry-run** — nothing is written until you pass `--apply`. Applying
|
|
145
|
+
the merge always creates a timestamped backup of the previous file.
|
|
146
|
+
|
|
147
|
+
```sh
|
|
148
|
+
projmux init # auto-detect + dry-run preview
|
|
149
|
+
projmux init ghostty # explicit terminal, dry-run preview
|
|
150
|
+
projmux init ghostty --apply # write changes (with .bak.<ts> backup)
|
|
151
|
+
projmux init --config /path/to/file # bypass auto-detected paths
|
|
152
|
+
projmux init --allow-symlink # opt in to merging through a symlink
|
|
153
|
+
projmux init --dry-run # force dry-run even with no other flag
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The merge is idempotent: bindings already pointing at the desired action are
|
|
157
|
+
no-ops, missing bindings are appended in a managed block, and triggers
|
|
158
|
+
already mapped to a *different* action are left untouched and reported as
|
|
159
|
+
`skip-conflict` warnings — projmux never silently overwrites your custom
|
|
160
|
+
mappings. Re-running `projmux init --apply` after editing the file refreshes
|
|
161
|
+
just the projmux-owned region.
|
|
162
|
+
|
|
163
|
+
### Supported terminals
|
|
164
|
+
|
|
165
|
+
#### Ghostty
|
|
166
|
+
|
|
167
|
+
- Detection: `TERM_PROGRAM=ghostty` or `GHOSTTY_RESOURCES_DIR` set.
|
|
168
|
+
- Config candidates (resolved in this order):
|
|
169
|
+
1. `<config-dir>/ghostty/config` — canonical default
|
|
170
|
+
2. `<config-dir>/ghostty/config.ghostty` — common dotfiles convention
|
|
171
|
+
|
|
172
|
+
`<config-dir>` honours `$XDG_CONFIG_HOME` first, then `$HOME/.config`.
|
|
173
|
+
When both candidates exist, init refuses to guess and asks for
|
|
174
|
+
`--config <path>` to disambiguate.
|
|
175
|
+
- Idempotency marker: bindings live inside a managed block delimited by
|
|
176
|
+
|
|
177
|
+
```text
|
|
178
|
+
# >>> projmux managed keybindings (do not edit between markers)
|
|
179
|
+
...
|
|
180
|
+
# <<< projmux managed keybindings
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Edit anything *outside* those markers freely; init re-renders the inside
|
|
184
|
+
on every `--apply`.
|
|
185
|
+
- Symlink guard: if the resolved config path is a symlink (typical when
|
|
186
|
+
dotfiles users symlink the terminal config into a tracked repo), init
|
|
187
|
+
refuses by default to avoid silently mutating the symlink target. Pass
|
|
188
|
+
`--allow-symlink` to opt in, or `--config <path>` to point at a
|
|
189
|
+
non-symlinked file.
|
|
190
|
+
|
|
191
|
+
#### Windows Terminal (including WSL)
|
|
192
|
+
|
|
193
|
+
- Detection: `WT_SESSION` set (native Windows), or `WSL_DISTRO_NAME` /
|
|
194
|
+
`WSL_INTEROP` set (running from inside WSL where the host terminal is
|
|
195
|
+
Windows Terminal).
|
|
196
|
+
- Config resolution:
|
|
197
|
+
- Native Windows: `%LOCALAPPDATA%\Packages\Microsoft.WindowsTerminal_*\LocalState\settings.json`.
|
|
198
|
+
- WSL: resolves `%LOCALAPPDATA%` through `cmd.exe /c echo %LOCALAPPDATA%`
|
|
199
|
+
interop, then translates `C:\Users\...` into `/mnt/c/Users/...` so the
|
|
200
|
+
Linux side can read/write the file directly.
|
|
201
|
+
- Merge model: settings.json is JSONC (allows `//` and `/* */` comments,
|
|
202
|
+
trailing commas). Init parses, locates `actions[]` and `keybindings[]`,
|
|
203
|
+
and merges entries identified by the `User.projmux*` ID prefix. Anything
|
|
204
|
+
outside that prefix is preserved verbatim, including comments and
|
|
205
|
+
formatting where reasonable.
|
|
206
|
+
- Conflicts: a key already mapped to a non-projmux action is skipped with a
|
|
207
|
+
warning, same as Ghostty.
|
|
208
|
+
|
|
209
|
+
### Reading dry-run output
|
|
210
|
+
|
|
211
|
+
Each line of the dry-run plan prefixes the action with one of:
|
|
212
|
+
|
|
213
|
+
| Prefix | Meaning |
|
|
214
|
+
| --- | --- |
|
|
215
|
+
| `+` | New binding will be added. |
|
|
216
|
+
| `=` | Binding already matches; no change. |
|
|
217
|
+
| `!` | Trigger is already mapped to a *different* action; will be skipped. Resolve manually before applying. |
|
|
218
|
+
|
|
219
|
+
The trailing `note:` lines flag whether the config file does not yet exist
|
|
220
|
+
(it will be created), and the final line tells you whether you still need
|
|
221
|
+
`--apply` or whether the file is already up to date.
|
|
222
|
+
|
|
223
|
+
> 한국어 요약: `projmux init` 은 dry-run 이 기본이고 `--apply` 시 timestamped
|
|
224
|
+
> 백업 후 머지합니다. Ghostty 는 managed 블록 마커로 idempotent, 두 표준
|
|
225
|
+
> path 모두 인식하며 symlink 는 default 거절. Windows Terminal 은 WSL interop
|
|
226
|
+
> 으로 `/mnt/c/...` 경로까지 알아서 풀고, JSONC 형식의 `settings.json` 에
|
|
227
|
+
> `User.projmux*` prefix 로 머지합니다. 사용자가 같은 키를 다른 액션에 매핑한
|
|
228
|
+
> 경우 skip + warning.
|
|
229
|
+
|
|
230
|
+
## Manual fallback / advanced (CSI-u)
|
|
231
|
+
|
|
232
|
+
Use this section when:
|
|
233
|
+
|
|
234
|
+
- your terminal is not yet supported by `projmux init`, or
|
|
235
|
+
- you prefer to manage the config by hand, or
|
|
236
|
+
- `projmux setup` shows specific keys still being swallowed and you want to
|
|
237
|
+
redirect just those.
|
|
238
|
+
|
|
239
|
+
The fix is to map the swallowed keystroke to a CSI-u sequence the terminal
|
|
240
|
+
forwards to tmux unchanged. projmux binds CSI-u escapes to tmux's
|
|
241
|
+
`User0`–`User11` keys, so once the terminal forwards the sequence the
|
|
242
|
+
action fires.
|
|
243
|
+
|
|
244
|
+
### CSI-u Map
|
|
245
|
+
|
|
246
|
+
| CSI-u sequence | tmux key | Action |
|
|
247
|
+
| --- | --- | --- |
|
|
248
|
+
| `ESC [ 9001 u` | `User0` | Open AI split to the right |
|
|
249
|
+
| `ESC [ 9002 u` | `User1` | Open AI split below |
|
|
250
|
+
| `ESC [ 9003 u` | `User2` | Notify sidebar |
|
|
251
|
+
| `ESC [ 9004 u` | `User3` | Existing session popup |
|
|
252
|
+
| `ESC [ 9005 u` | `User4` | Project sidebar |
|
|
253
|
+
| `ESC [ 9006 u` | `User5` | AI split picker |
|
|
254
|
+
| `ESC [ 9007 u` | `User6` | Settings |
|
|
255
|
+
| `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
|
+
| `ESC [ 9011 u` | `User10` | Rename the current tmux window |
|
|
259
|
+
| `ESC [ 9012 u` | `User11` | Rename the current tmux pane label |
|
|
260
|
+
| `ESC [ 9013 u` | `User12` | Project switcher popup |
|
|
261
|
+
|
|
262
|
+
### Ghostty (manual)
|
|
263
|
+
|
|
264
|
+
`projmux init ghostty` is the maintained path. The block below is what the
|
|
265
|
+
managed region in `~/.config/ghostty/config` ends up looking like — useful
|
|
266
|
+
if you want to author it by hand or vet what init produces. Ghostty
|
|
267
|
+
keybinds use `keybind = trigger=action`; the `csi:` action sends a CSI
|
|
268
|
+
sequence without the leading `ESC [` bytes.
|
|
269
|
+
|
|
270
|
+
```text
|
|
271
|
+
keybind = alt+1=csi:9005u
|
|
272
|
+
keybind = alt+2=csi:9003u
|
|
273
|
+
keybind = alt+3=csi:9004u
|
|
274
|
+
keybind = alt+4=csi:9006u
|
|
275
|
+
keybind = alt+5=csi:9007u
|
|
276
|
+
keybind = alt+6=csi:9013u
|
|
277
|
+
|
|
278
|
+
keybind = ctrl+shift+r=csi:9001u
|
|
279
|
+
keybind = ctrl+shift+l=csi:9002u
|
|
280
|
+
|
|
281
|
+
keybind = ctrl+shift+n=csi:9008u
|
|
282
|
+
keybind = ctrl+m=csi:9011u
|
|
283
|
+
keybind = ctrl+shift+m=csi:9012u
|
|
284
|
+
keybind = alt+shift+left=csi:9009u
|
|
285
|
+
keybind = alt+shift+right=csi:9010u
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Reload Ghostty or restart the terminal after changing the config.
|
|
289
|
+
|
|
290
|
+
### Windows Terminal (manual)
|
|
291
|
+
|
|
292
|
+
`projmux init windows-terminal` (which also covers WSL) is the maintained
|
|
293
|
+
path. Use the snippet below to author `settings.json` by hand. Add
|
|
294
|
+
`sendInput` actions and bind them from `keybindings`. Windows Terminal
|
|
295
|
+
works well with plain tmux escape sequences for the default `Alt`
|
|
296
|
+
shortcuts, while the split actions can send tmux prefix sequences directly. Escape bytes should be written as `\u001b`.
|
|
297
|
+
|
|
298
|
+
```json
|
|
299
|
+
{
|
|
300
|
+
"actions": [
|
|
301
|
+
{ "command": { "action": "sendInput", "input": "\u001b1" }, "id": "User.projmuxSidebar" },
|
|
302
|
+
{ "command": { "action": "sendInput", "input": "\u001b2" }, "id": "User.projmuxNotifySidebar" },
|
|
303
|
+
{ "command": { "action": "sendInput", "input": "\u001b3" }, "id": "User.projmuxSessions" },
|
|
304
|
+
{ "command": { "action": "sendInput", "input": "\u001b4" }, "id": "User.projmuxAIPicker" },
|
|
305
|
+
{ "command": { "action": "sendInput", "input": "\u001b5" }, "id": "User.projmuxSettings" },
|
|
306
|
+
{ "command": { "action": "sendInput", "input": "\u001b6" }, "id": "User.projmuxSwitch" },
|
|
307
|
+
{ "command": { "action": "sendInput", "input": "\u0002r" }, "id": "User.projmuxAISplitRight" },
|
|
308
|
+
{ "command": { "action": "sendInput", "input": "\u0002l" }, "id": "User.projmuxAISplitDown" },
|
|
309
|
+
{ "command": { "action": "sendInput", "input": "\u000e" }, "id": "User.projmuxNewWindow" },
|
|
310
|
+
{ "command": { "action": "sendInput", "input": "\u001b[1;4D" }, "id": "User.projmuxPrevWindow" },
|
|
311
|
+
{ "command": { "action": "sendInput", "input": "\u001b[1;4C" }, "id": "User.projmuxNextWindow" },
|
|
312
|
+
{ "command": { "action": "sendInput", "input": "\u001b[9011u" }, "id": "User.projmuxRenameWindow" },
|
|
313
|
+
{ "command": { "action": "sendInput", "input": "\u001b[9012u" }, "id": "User.projmuxRenamePane" }
|
|
314
|
+
],
|
|
315
|
+
"keybindings": [
|
|
316
|
+
{ "id": "User.projmuxSidebar", "keys": "alt+1" },
|
|
317
|
+
{ "id": "User.projmuxNotifySidebar", "keys": "alt+2" },
|
|
318
|
+
{ "id": "User.projmuxSessions", "keys": "alt+3" },
|
|
319
|
+
{ "id": "User.projmuxAIPicker", "keys": "alt+4" },
|
|
320
|
+
{ "id": "User.projmuxSettings", "keys": "alt+5" },
|
|
321
|
+
{ "id": "User.projmuxSwitch", "keys": "alt+6" },
|
|
322
|
+
{ "id": "User.projmuxAISplitRight", "keys": "ctrl+shift+r" },
|
|
323
|
+
{ "id": "User.projmuxAISplitDown", "keys": "ctrl+shift+l" },
|
|
324
|
+
{ "id": "User.projmuxNewWindow", "keys": "ctrl+n" },
|
|
325
|
+
{ "id": "User.projmuxPrevWindow", "keys": "alt+shift+left" },
|
|
326
|
+
{ "id": "User.projmuxNextWindow", "keys": "alt+shift+right" },
|
|
327
|
+
{ "id": "User.projmuxRenameWindow", "keys": "ctrl+m" },
|
|
328
|
+
{ "id": "User.projmuxRenamePane", "keys": "ctrl+shift+m" }
|
|
329
|
+
]
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
This example matches the default projmux app shortcuts without depending on
|
|
334
|
+
CSI-u support from Windows Terminal for the `Alt` shortcuts. `Ctrl-M` and
|
|
335
|
+
`Ctrl-Shift-M` still use CSI-u so tmux can distinguish rename commands from
|
|
336
|
+
plain Enter. If a key is already bound by Windows Terminal, remove or change
|
|
337
|
+
the conflicting `keybindings` entry before adding the projmux binding.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Standalone Plan
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Keep session-management product logic inside `projmux`.
|
|
6
|
+
The current target is a standalone app that can generate the tmux bindings and popup entry policy it needs.
|
|
7
|
+
|
|
8
|
+
## What moves first
|
|
9
|
+
|
|
10
|
+
### Phase 1
|
|
11
|
+
- session naming rules
|
|
12
|
+
- preview selection state
|
|
13
|
+
- pin state
|
|
14
|
+
- current-directory session jump
|
|
15
|
+
- tagged kill fallback logic
|
|
16
|
+
|
|
17
|
+
### Phase 2
|
|
18
|
+
- candidate discovery
|
|
19
|
+
- sessionizer row building
|
|
20
|
+
- session popup row building
|
|
21
|
+
- preview rendering data model
|
|
22
|
+
- session create or switch orchestration
|
|
23
|
+
|
|
24
|
+
### Phase 3
|
|
25
|
+
- popup toggle orchestration
|
|
26
|
+
- auto-attach logic
|
|
27
|
+
- ephemeral prune logic
|
|
28
|
+
- kube session helpers
|
|
29
|
+
|
|
30
|
+
### Phase 4
|
|
31
|
+
- standalone tmux popup toggle entrypoints
|
|
32
|
+
- generated tmux binding snippet
|
|
33
|
+
- `projmux tmux install` include-file wiring
|
|
34
|
+
|
|
35
|
+
### Phase 5
|
|
36
|
+
- pane attention toggle/clear/window badge commands
|
|
37
|
+
- generated tmux window-status and pane-focus hooks backed by `projmux attention`
|
|
38
|
+
- AI pane status, Codex title watcher, and desktop notification commands
|
|
39
|
+
- status bar git/kube segments
|
|
40
|
+
|
|
41
|
+
## What stays outside standalone projmux
|
|
42
|
+
|
|
43
|
+
- shell startup hooks
|
|
44
|
+
- machine-specific install behavior
|
|
45
|
+
- optional OS or terminal integration scripts that are not session-management features
|
|
46
|
+
|
|
47
|
+
## Compatibility strategy
|
|
48
|
+
|
|
49
|
+
- preserve the user-facing keybindings and popup flows
|
|
50
|
+
- route those flows through `projmux` commands
|
|
51
|
+
- provide `projmux tmux print-config` and `projmux tmux install` for generated tmux bindings
|
|
52
|
+
- remove shell implementation only after the Go behavior is verified by the standalone path
|
|
53
|
+
|
|
54
|
+
## Expected first cut
|
|
55
|
+
|
|
56
|
+
The first useful milestone is not full parity.
|
|
57
|
+
It is:
|
|
58
|
+
- `projmux current`
|
|
59
|
+
- `projmux switch --ui=popup`
|
|
60
|
+
- `projmux sessions --ui=popup`
|
|
61
|
+
- pin persistence
|
|
62
|
+
- preview state persistence
|
|
63
|
+
|
|
64
|
+
## Standalone tmux path
|
|
65
|
+
|
|
66
|
+
The standalone tmux path is:
|
|
67
|
+
|
|
68
|
+
1. `projmux tmux print-config` prints bindings that call `projmux` directly.
|
|
69
|
+
2. `projmux tmux install` writes that snippet to `~/.config/tmux/projmux.conf` and includes it from `~/.tmux.conf`.
|
|
70
|
+
3. `projmux tmux popup-toggle <mode>` replaces `tmux-popup-toggle.sh` for sessionizer, session popup, sidebar, AI picker, and the unified settings popup.
|
|
71
|
+
4. `projmux attention <toggle|clear|window>` replaces tmux attention wrapper scripts for pane focus hooks and window badges.
|
|
72
|
+
5. `projmux ai status`, `projmux ai notify`, and `projmux ai watch-title` replace the AI pane state and notification shell scripts.
|
|
73
|
+
6. `projmux status <git|kube>` replaces tmux status-bar segment scripts for git branch and kube context rendering.
|
|
74
|
+
|
|
75
|
+
## App tmux runtime
|
|
76
|
+
|
|
77
|
+
The app runtime path is:
|
|
78
|
+
|
|
79
|
+
1. `projmux shell` writes `~/.config/projmux/tmux.conf` and launches `tmux -L projmux -f ~/.config/projmux/tmux.conf new-session -A -s main`.
|
|
80
|
+
2. `projmux tmux print-app-config` prints the config used by that isolated app server.
|
|
81
|
+
3. `projmux tmux install-app` writes the app config without touching `~/.tmux.conf`.
|
|
82
|
+
4. The app runtime uses a separate tmux socket and config from the user's normal tmux server, so projmux can own its status bar, bindings, badge, and popup behavior.
|