projmux 0.6.7 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README-ko.md +36 -5
- package/README.md +40 -12
- package/docs/agent-workflow.md +8 -4
- package/docs/architecture.md +4 -3
- package/docs/assets/projmux-ai-attention.gif +0 -0
- package/docs/assets/projmux-skill-workflow.gif +0 -0
- package/docs/cli.md +11 -7
- package/docs/configuration.md +11 -10
- package/docs/keybindings.md +44 -31
- package/docs/native-picker-no-fzf-poc.md +3 -2
- package/docs/notify-queue.md +56 -19
- package/docs/settings-ia.md +12 -7
- package/docs/statusbar.md +31 -7
- package/docs/testing.md +5 -1
- package/package.json +5 -5
- package/docs/assets/projmux-shell-sidebar.gif +0 -0
- package/docs/readme-hero-gif-recording.md +0 -97
package/README-ko.md
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
<img src="docs/assets/projmux-icon.png" alt="projmux icon" width="112">
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
|
-
프로젝트별 tmux workspace를 빠르게 전환하고,
|
|
8
|
-
attention까지 함께 다루는 터미널
|
|
7
|
+
프로젝트별 tmux workspace를 빠르게 전환하고, Claude Code, Codex,
|
|
8
|
+
Antigravity pane의 preview/status context/attention까지 함께 다루는 터미널
|
|
9
|
+
workspace 도구입니다.
|
|
9
10
|
|
|
10
11
|
[](https://www.npmjs.com/package/projmux)
|
|
11
12
|
[](https://github.com/crevissepartners/projmux/actions/workflows/ci.yml)
|
|
@@ -15,7 +16,7 @@ attention까지 함께 다루는 터미널 workspace 도구입니다.
|
|
|
15
16
|
<p align="center">
|
|
16
17
|
<img src="docs/assets/projmux-ai-attention.gif" alt="projmux AI attention demo" width="820">
|
|
17
18
|
<br>
|
|
18
|
-
<em
|
|
19
|
+
<em>project를 오가며 AI permission 대기를 상태줄에서 확인하고, notification list에서 해당 pane으로 돌아갑니다.</em>
|
|
19
20
|
</p>
|
|
20
21
|
|
|
21
22
|
## 무엇인가
|
|
@@ -23,6 +24,8 @@ attention까지 함께 다루는 터미널 workspace 도구입니다.
|
|
|
23
24
|
`projmux`는 프로젝트 디렉터리를 오래 유지되는 tmux session으로 연결합니다.
|
|
24
25
|
프로젝트 전환, session preview, AI split 실행, tmux 안의 상태 표시를 한
|
|
25
26
|
키보드 중심 workspace 앱으로 묶습니다.
|
|
27
|
+
Claude Code와 Codex hook event를 직접 수집하고, 수동으로 연결한 Antigravity
|
|
28
|
+
hook/statusline event도 같은 notification 흐름으로 다룹니다.
|
|
26
29
|
|
|
27
30
|
터미널 workspace를 한 명령으로 열고, 한 세트의 키로 project/window/pane,
|
|
28
31
|
notification, settings 사이를 오가고 싶을 때 사용합니다.
|
|
@@ -59,7 +62,7 @@ projmux shell
|
|
|
59
62
|
|
|
60
63
|
- `Alt-1`: project sidebar.
|
|
61
64
|
- `Alt-2`: notification list.
|
|
62
|
-
- `Alt-3`:
|
|
65
|
+
- `Alt-3`: Recent Windows.
|
|
63
66
|
- `Alt-4`: AI split picker.
|
|
64
67
|
- `Alt-5`: settings.
|
|
65
68
|
- `Alt-6`: project switcher popup.
|
|
@@ -82,17 +85,45 @@ projmux shell
|
|
|
82
85
|
설정은 [Configuration](docs/configuration.md)을 참고하세요. installer별 update
|
|
83
86
|
동작은 [Upgrading](docs/upgrading.md)에 있습니다.
|
|
84
87
|
|
|
88
|
+
## 에이전트 스킬
|
|
89
|
+
|
|
90
|
+
projmux shortcut은 AI 도구의 user-level skill 또는 slash command로도 등록할
|
|
91
|
+
수 있습니다. 스킬은 같은 CLI contract를 감싸는 얇은 wrapper입니다:
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
projmux ai split --agent codex right
|
|
95
|
+
projmux ai split --agent claude down
|
|
96
|
+
projmux ai split --agent antigravity right
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
`/projmux:codex-right` 같은 Claude slash command를 등록한 뒤 prompt와 함께
|
|
100
|
+
실행시키면, Claude가 projmux command를 호출하고 현재 project에 붙은 managed
|
|
101
|
+
Codex pane이 새로 열립니다. prompt는 새 pane으로 바로 전달되고,
|
|
102
|
+
permission/completion hook event가 tmux 상태줄과 notification list에
|
|
103
|
+
표시됩니다.
|
|
104
|
+
Antigravity도 같은 managed split 경로로 실행되며, 수동 hook ingest와 session
|
|
105
|
+
resume 지원 범위는 CLI reference에 정리되어 있습니다.
|
|
106
|
+
|
|
107
|
+
설치 template과 naming convention은
|
|
108
|
+
[AI Agent Shortcuts](docs/ai-agent-shortcuts.md)에 정리되어 있습니다.
|
|
109
|
+
|
|
110
|
+
<p align="center">
|
|
111
|
+
<img src="docs/assets/projmux-skill-workflow.gif" alt="projmux skill workflow demo" width="820">
|
|
112
|
+
<br>
|
|
113
|
+
<em>Claude가 prompt와 함께 등록된 projmux skill을 호출해 managed Codex pane을 열고, Codex가 그 자리에서 응답합니다.</em>
|
|
114
|
+
</p>
|
|
115
|
+
|
|
85
116
|
## 추가 문서
|
|
86
117
|
|
|
87
118
|
- [Install](docs/install.md)
|
|
88
119
|
- [Configuration](docs/configuration.md)
|
|
89
120
|
- [Terminal Keybindings](docs/keybindings.md)
|
|
121
|
+
- [AI Agent Shortcuts](docs/ai-agent-shortcuts.md)
|
|
90
122
|
- [CLI Reference](docs/cli.md)
|
|
91
123
|
- [Statusbar](docs/statusbar.md)
|
|
92
124
|
- [Hooks](docs/hooks.md)
|
|
93
125
|
- [Usage tracking](docs/usage-tracking.md)
|
|
94
126
|
- [Agent Workflow](docs/agent-workflow.md)
|
|
95
|
-
- [README Hero GIF Recording](docs/readme-hero-gif-recording.md)
|
|
96
127
|
|
|
97
128
|
## 개발
|
|
98
129
|
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<strong>A tmux-native workspace for multi-agent AI development.</strong>
|
|
9
9
|
<br>
|
|
10
|
-
<em>
|
|
10
|
+
<em>Managed Claude Code, Codex, and Antigravity panes with hook-driven attention and agent-aware session resume.</em>
|
|
11
11
|
</p>
|
|
12
12
|
|
|
13
13
|
<p align="center">
|
|
@@ -25,20 +25,20 @@ projmux shell
|
|
|
25
25
|
<p align="center">
|
|
26
26
|
<img src="docs/assets/projmux-ai-attention.gif" alt="projmux AI attention demo" width="820">
|
|
27
27
|
<br>
|
|
28
|
-
<em>
|
|
28
|
+
<em>Switch between projects while an AI pane waits for permission, then jump back from the tmux notification list.</em>
|
|
29
29
|
</p>
|
|
30
30
|
|
|
31
31
|
## Why
|
|
32
32
|
|
|
33
|
-
Six tmux windows. Each one is running Claude Code or
|
|
34
|
-
repo. Three are idle. One is waiting on a permission prompt. One
|
|
35
|
-
hour ago and you have no idea which.
|
|
33
|
+
Six tmux windows. Each one is running Claude Code, Codex, or Antigravity on a
|
|
34
|
+
different repo. Three are idle. One is waiting on a permission prompt. One
|
|
35
|
+
crashed an hour ago and you have no idea which.
|
|
36
36
|
|
|
37
|
-
projmux ingests Claude Code and Codex hook events directly,
|
|
38
|
-
per-pane state in the tmux
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
fresh one.
|
|
37
|
+
projmux ingests Claude Code and Codex hook events directly, accepts manually
|
|
38
|
+
wired Antigravity hook/statusline events, shows live per-pane state in the tmux
|
|
39
|
+
status bar, and lets one keystroke take you to the pane that actually needs
|
|
40
|
+
you. It also remembers each agent's resume id, so after a reboot every pane
|
|
41
|
+
comes back as the *same* conversation — not a fresh one.
|
|
42
42
|
|
|
43
43
|
## Requirements
|
|
44
44
|
|
|
@@ -71,7 +71,7 @@ Inside the app:
|
|
|
71
71
|
|
|
72
72
|
- `Alt-1` opens the project sidebar.
|
|
73
73
|
- `Alt-2` opens the notification list.
|
|
74
|
-
- `Alt-3` opens
|
|
74
|
+
- `Alt-3` opens Recent Windows.
|
|
75
75
|
- `Alt-4` opens the AI split picker.
|
|
76
76
|
- `Alt-5` opens settings.
|
|
77
77
|
|
|
@@ -94,6 +94,35 @@ For detailed configuration, including `PROJMUX_PROJDIR`, managed roots,
|
|
|
94
94
|
notifications, and usage tracking, see [Configuration](docs/configuration.md).
|
|
95
95
|
For update behavior by installer type, see [Upgrading](docs/upgrading.md).
|
|
96
96
|
|
|
97
|
+
## Agent Skills
|
|
98
|
+
|
|
99
|
+
projmux shortcuts can also live in your AI tool as user-level skills or slash
|
|
100
|
+
commands. A skill is just a thin wrapper around the same CLI contract:
|
|
101
|
+
|
|
102
|
+
```sh
|
|
103
|
+
projmux ai split --agent codex right
|
|
104
|
+
projmux ai split --agent claude down
|
|
105
|
+
projmux ai split --agent antigravity right
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
After registering a Claude slash command such as `/projmux:codex-right`, ask
|
|
109
|
+
Claude to use it with a prompt. Claude runs the projmux command, Codex opens in
|
|
110
|
+
a managed pane attached to the current project, and the prompt is delivered
|
|
111
|
+
there immediately.
|
|
112
|
+
projmux tracks hook events from the opened pane and shows permission or
|
|
113
|
+
completion notifications in tmux.
|
|
114
|
+
Antigravity uses the same managed split path, with manual hook ingest and
|
|
115
|
+
session resume support documented in the CLI reference.
|
|
116
|
+
|
|
117
|
+
Install templates and naming conventions are in
|
|
118
|
+
[AI Agent Shortcuts](docs/ai-agent-shortcuts.md).
|
|
119
|
+
|
|
120
|
+
<p align="center">
|
|
121
|
+
<img src="docs/assets/projmux-skill-workflow.gif" alt="projmux skill workflow demo" width="820">
|
|
122
|
+
<br>
|
|
123
|
+
<em>Claude invokes a registered projmux skill with a prompt, opens a managed Codex pane, and Codex answers there.</em>
|
|
124
|
+
</p>
|
|
125
|
+
|
|
97
126
|
## More Docs
|
|
98
127
|
|
|
99
128
|
- [Install](docs/install.md)
|
|
@@ -105,7 +134,6 @@ For update behavior by installer type, see [Upgrading](docs/upgrading.md).
|
|
|
105
134
|
- [Hooks](docs/hooks.md)
|
|
106
135
|
- [Usage tracking](docs/usage-tracking.md)
|
|
107
136
|
- [Agent Workflow](docs/agent-workflow.md)
|
|
108
|
-
- [README Hero GIF Recording](docs/readme-hero-gif-recording.md)
|
|
109
137
|
|
|
110
138
|
## Development
|
|
111
139
|
|
package/docs/agent-workflow.md
CHANGED
|
@@ -32,11 +32,12 @@
|
|
|
32
32
|
- `make test`: fast unit coverage for app-layer AI split native agent launch/selective popup-toggle/settings/status/notification parity including AI pane option metadata, watcher metadata bootstrap for existing panes, capture-backed reply detection, missing-pane watcher shutdown, armed focus-only reply badge clearing, busy attention preservation on focus clear, manual AI topic preservation while watcher status still updates, agent-labeled desktop notification message context with pane-title-first body text, global/project-local lifecycle hook dispatch for post-create/pre-create/post-attach/send-noti with project hook and `.projmux/config.toml` trust-store hashing plus env/settings kill-switch gating, declarative startup command and hook run coverage, `send-noti` stdin JSON delivery plus `PROJMUX_NOTIFY_*` env payload, notify queue write success/failure/depth-guard dispatch rules, notify/statusbar/sidebar origin-client focus routing, project config env/kube session environment application, Settings project config env/kube/startup form writes with trust-store refresh and preserved hook commands, startup command send-keys orchestration plus startup pane replay markers, pre-create abort behavior, and shared projmux notification icon paths, and scoped even row/column resizing after shell and agent splits, status-bar git/kube segment parity including muted git branch block styling and compact dirty/staged/ahead/behind state colors, statusbar pwd display-only native-framed path popup with shared popup-wait-key/no-extra-payload-line command coverage, no clipboard or tmux buffer copy, and popup-wait-key cursor/raw-mode restore coverage, statusbar usage native HUD popup alignment/height-budget/threshold palette/muted sync-staleness/fallback coverage without raw CLI popup or popup-toggle stacking, statusbar settings click popup fallback and settings chip right-edge rendering without default trailing space, popup-toggle stale marker recovery, isolated `projmux shell` tmux app launch/config generation including home fallback plus project-context default session targeting from `PROJMUX_CWD` or nearest project marker, app-owned project-name statusbar layout, distinct project badge color, and quiet debounced session-state autosave command/app-config trigger, shell-entry welcome release prompt and inline update handling, shell update skip-by-latest-tag behavior plus best-effort stale-cache refresh, pane/window keybindings, keymap.toml tmux override rendering/stale unbinds including retired direct/UserKey cleanup, Settings Keybindings root/list/detail capture flows including parse-error rows, unsafe raw capture and timeout guards, disable/reset writes, app config regeneration, live tmux source-file reload, and no-live-tmux save behavior, window rename bindings, pane rename helper/binding, pane-exit rebalance command/hooks, hook-pane and after-select-pane based attention focus hooks, attention badge toggle/clear/list/window rendering, attach/current/kill/pin/preview/prune/sessions/session-popup/settings commands, switch, tag, tmux helper commands, update status/check/apply cache and installer detection including GitHub Release binary asset selection/extraction/replacement, doctor install-missing command selection, AI notify integration diagnostics, and Session State resume metadata diagnostics, Settings AI notify integration diagnostics read-only status/conflict/CLI guidance, and Settings About update status/check action wiring, untitled standalone popup-toggle marker close/config install, direct popup minimum sizing, AI picker minimum width and height, sidebar minimum width and compact badge spacing, preview select writes, popup render output after cycling, switch picker pin action behavior without inline settings rows, nested settings hub sections for AI defaults, project picker filesystem scan/pin actions, Project Root settings source/shadowing/set/current/clear flows, app/keybinding info including Ctrl-M rename forwarding, and About version/source rendering, switch picker focused-session kill, switch picker launcher-key abort bindings, switch explicit project-root, unconfigured-root, and weak managed-root heuristic parity, switch popup hiding new-session candidates while sidebar keeps create-capable rows, switch row project-name display with `~` pinned to the top and live-session-first sorting, pretty-path, preview-context including kube context/namespace, switch settings subcommand flows including add-current-pin, interactive add-pin picker, and settings label/preview polish including Phase 2 Settings/hookmaker/project-startup/trust/quit destructive row color regression strings, native preview wiring, baseline picker surface parity including prompt/footer/header fallback without app-name filler and search-key scoped card matching, sidebar compact action-only key footer, sidebar preview-window/start-position behavior without focus-time session switching, sidebar row/window ANSI styling with pane-aggregated attention badge state and AI topic labels, Alt+2/Alt+3 legacy popup row, preview-window, pane metadata, and pane-snapshot parity, switch read0 card rows with active/inactive title styling, right-side status badges, combined directory/git metadata with muted inactive branch styling, statusbar-matched block window tabs with window attention badges, read0 expect-key action parsing, restored pin/tag card badges, and restrained selected-row marker styling, switch preview metadata without duplicated directory/git rows, preview metadata rendering, popup pane display names for AI agents, AI topics, and shell commands, switch preview cycle bindings, sessions picker preview/cycle/open/kill wiring including attached-session fallback behavior, sessions picker launcher-key abort bindings, popup/switch preview summary formatting, popup sessions tmux entry helpers, switch/popup/session rendering, session identity, session-state Claude/Codex/Antigravity resume and declarative startup replay, session snapshot capture/autosave recipe classification including save/autosave pre-capture resume metadata refresh from live AI session ids including Antigravity conversation ids, Claude transcript paths, and Codex rollout log cwd matching/ambiguity skips, candidate discovery, config path derivation, popup preview read-models, and pure state rules including preview, tag, and lifecycle stores.
|
|
33
33
|
- `make test` also covers Settings > AI Settings > Enabled agents Phase 0 config behavior: missing config enables Claude, Codex, and Antigravity, unknown saved provider names are ignored without disabling known providers, Settings toggles persist Claude/Codex/Antigravity only, shell/selective are absent from enabled-agent rows, and a saved default split mode warns when its provider is disabled.
|
|
34
34
|
- `make test` also covers native Alt-1 sidebar `Sidebar:KillSession` mutable refresh: the action kills through the focused-session safety path, keeps the native picker session open, refreshes rows and preview with `picker.Action.Mutate`/`DeferredUpdate`, and preserves the previous-live-session guard.
|
|
35
|
+
- `make test` also covers Notify sidebar pane-grouped read-model rows and interactions: collapsed pane inbox group construction, fixed three-line group cards with stable project/provider, topic/context, aggregate metadata, and latest-preview slots including topic-with-project cases, child-count badges that match expandable child rows without rendering `+0`, childless group headers without strong fold affordance, selected/expanded marker-only row shape changes, duplicate label/preview reduction, worst-severity aggregation, inactive/gone group display and child-count rendering, pane-less fallback grouping, compact newest-first child event rows with warn/critical severity preservation, Right/Left fold mutation plus childless Right no-op refresh, folded and expanded live group Enter focus+ack with mixed-severity critical rows, inactive-but-routable group Enter focus+ack, gone group Enter cleanup without focus including critical rows, target-gone race cleanup, transient focus-failure no-ack refresh, child Enter focus/ack preservation, explicit group acknowledgement including mixed-severity critical rows, and grouped deferred refresh output with expanded-state pruning.
|
|
35
36
|
- `make test` also covers the AI provider metadata registry for Claude/Codex/Antigravity launch providers: registry-derived enabled-agent defaults and ordering, Settings enabled-agent rows, AI picker visibility for disabled providers, ambient usage model scope derivation for quota-supported providers, hook diagnostic provider metadata, Antigravity session-state support metadata, and explicit diagnostics for disabled providers without adding unsupported quota adapters.
|
|
36
37
|
- `make test` also covers usage HUD/all-model filtering from Settings > AI Settings > Enabled agents: ambient `status usage` and `usage --model all` scope collection/rendering to enabled Claude/Codex providers, all-disabled all-model output shows a Settings fallback without refreshing adapters, disabled cached rows/backoff do not leak into ambient output, and explicit `usage --model claude|codex` still collects/renders the requested provider even when disabled.
|
|
37
38
|
- `make test` also covers AI semantic badge renderer aggregation for window-list, sidebar rows, switch window tabs, popup pane summaries, and pane-border topic badges using prompt-required > response-complete > in-progress priority while preserving blank no-state lanes, response-complete live badge consume on attention clear without idling action-required/progress badges, plus Settings > Appearance AI badge style selection for dot/emoji/off pane-border, Alt-1 sidebar window/preview tabs, and tmux window-status compatibility with dot as the persisted/config fallback.
|
|
38
39
|
- `make test` also covers AI semantic badge Phase 3 theme-role hardening: `@projmux_ai_badge_kind` storage values and aggregate priority stay unchanged, `minimal` remains a read-time alias for the `off` badge style, progress/success/action-required badge roles stay distinct, permission/input status badges do not use critical red, and critical notify queue severity does not drive live AI status badge colors or desktop notification urgency.
|
|
39
|
-
- `make test` also covers keybinding surface tier catalog rules, action-centered `keymap.toml` `keys = [...]` multi-alias parsing/writing, quoted internal `Surface:Action` tables, legacy popup action ID aliases, canonical popup toggle names, AI split popup-vs-direct action labels, generated tmux config multi-alias rendering, global/direct conflict detection, surface-scoped native picker command conflict detection, Settings Keybindings list/search/detail surface-aware picker-local labels,
|
|
40
|
+
- `make test` also covers keybinding surface tier catalog rules, action-centered `keymap.toml` `keys = [...]` multi-alias parsing/writing, quoted internal `Surface:Action` tables, legacy popup action ID aliases, canonical popup toggle names, AI split popup-vs-direct action labels, generated tmux config multi-alias rendering, global/direct conflict detection, surface-scoped native picker command conflict detection, Settings Keybindings list/search/detail surface-aware picker-local labels, compact action-list state copy, flat Keys list/action detail rows, key detail remove/test rows, Add key default press-key flow with Advanced typed entry, collapsed Troubleshooting entry copy, Labs compatibility redirect to the Keybindings root, capture/add-key flows, unsafe raw capture, reset behavior, stale guide docs guards, and welcome/runtime footer copy that avoids hardcoded launch-key guides.
|
|
40
41
|
- `make test` also covers welcome revisit policy: legacy welcome state remains readable without suppressing shell entry, Enter continues without storing release skip, `s` stores an update skip for the current latest tag when an update is available, source installs show disabled Upgrade guidance, stale update cache refresh is best-effort, Settings > About > Welcome opens a Settings-native viewer without pending state, and shell prompt display does not schedule a redundant attach popup.
|
|
41
42
|
- `make test` also covers transport-dependent app tmux defaults for pane/window navigation (`M-Left`/`M-Right`/`M-Up`/`M-Down` and `M-S-Left`/`M-S-Right`) while keeping visible default chords, allowing additive safe plain aliases that do not store or remove the transport defaults, and no UserKey/CSI-u generated fallback.
|
|
42
43
|
- `make test` also covers direct `projmux ai split --agent <claude|codex|antigravity|shell|selective>` launches, enabled-agent gating for disabled direct launches and disabled saved defaults, `--force-agent` as an explicit direct CLI-only override, selective picker filtering with all-disabled shell fallback guidance, config-default preservation, extra args appended to resolved agent executables, managed pane metadata, title watcher startup, layout application, plain shell split behavior, selective picker delegation, invalid direct-agent usage errors, and regressions that direct concrete-agent and saved-default splits create a new pane without probing existing AI pane metadata or selecting an existing pane, including when launched from the current AI pane.
|
|
@@ -65,11 +66,14 @@
|
|
|
65
66
|
- `make test` also covers welcome revisit policy: legacy `skip_version` readability without shell suppression, `s` Skip until next vs Enter continue, Settings > About > Welcome native viewer, best-effort shell update cache refresh, and attach-popup no-duplicate/no-op behavior.
|
|
66
67
|
- `make test` also covers `projmux quit` action-picker rows, cancel/close no-op behavior, explicit quit of only app-owned mux runtimes marked by `@projmux_app=1` on the selected `tmux`/`psmux -L projmux` backend, missing/default runtime no-ops, dispatcher wiring, and `Settings > About > Quit projmux` routing through the same picker before any shutdown side effect.
|
|
67
68
|
- `make test` also covers the built-in semantic palette foundation: non-empty fallback truecolor/tmux tokens, distinct action/attention/AI/progress/danger roles, native picker chip/current/titlebar render strings including titlebar frame background/foreground inheritance without separate overlay ANSI, statusbar git/notify/usage/settings palette regressions, attention/pane-border/popup/switch progress color guards, renderer-only lead-mode topic prefix styling, settings/trust/destructive row color guards, Theme settings Phase 0/1 resolver behavior for project/global/fallback source labels, preset fill, explicit token override, invalid-layer warnings, and truecolor-to-tmux mapping, Phase 2 fallback render parity and project/global color isolation for native picker and tmux status/window background adapters, native popup-toggle `display-popup -s` body style propagation from the effective theme without touching global popup/shell/status styles, Phase 3 desired font config save/resolve plus unsupported `not applied` status without breaking no-adapter fallback rendering, and Phase 4 Settings theme editing boundaries for project/global resets, project inherit-vs-override labels, effective source labels, and project config theme values feeding the native project popup render path.
|
|
69
|
+
- `make test` also covers Recent Windows Phase 0 state/model behavior: server-scoped file paths, missing/corrupt state policy with corrupt-file backup, MRU newest-first recording, same-window dedupe and promotion, default queue limiting, current-window exclusion, cross-session candidate retention, gone-window pruning against live window inventory, and label fallback rules that keep win/pane ids as debug fallback instead of the primary row label.
|
|
70
|
+
- `make test` also covers Recent Windows Phase 1 native picker behavior: `projmux window recent` empty-state messaging, cross-session candidate picker rows with descriptive project/session/window/pane command age metadata, window-only switching without pane restoration, switch-failure refresh/prune handling, and gone-window pruning before picker selection.
|
|
71
|
+
- `make test` also covers Recent Windows Phase 2/3/4 keybinding, popup, and runtime recorder integration: `RecentWindows:Open` owns the guaranteed `M-3` launch default, generated tmux config uses client-scoped `tmux popup-toggle recent-windows`, the popup body runs `projmux window recent`, generated tmux config installs background `window record` hooks for window and client-session changes plus first-use population without `session-window-changed`, `window record` snapshots current tmux socket/session/window/active-pane metadata into the socket-scoped store with escaped field parsing, repeated same-window record fires dedupe instead of growing entries, the queue remains bounded by `recentwindows.DefaultLimit`, Settings > Keybindings shows Recent Windows with the `M-3` default, setup probe text names Recent Windows, `SessionPopupToggle` no longer owns the guaranteed `M-3` default, and escaped tmux field separators are parsed for current/list window metadata.
|
|
68
72
|
- Current focused unit coverage also includes strict notify SOT behavior
|
|
69
73
|
(TTL does not remove rows, focus success and target-gone clicks ack,
|
|
70
|
-
reconcile reports stale rows), `notify list --live` queue/live explanations, notify sidebar
|
|
71
|
-
|
|
72
|
-
actions, notify/statusbar/sidebar attention-vs-AI palette assertions including muted
|
|
74
|
+
reconcile reports inactive `queue-stale` rows), `notify list --live` queue/live explanations, notify sidebar
|
|
75
|
+
three-line grouped card rendering with child-count/fold semantics plus focus/ack/non-critical-clear/clear-all
|
|
76
|
+
actions, notify/statusbar/sidebar attention-vs-AI palette assertions including muted inactive/gone rows,
|
|
73
77
|
native picker-session-local `a` ack that refreshes the sidebar without
|
|
74
78
|
focusing or restarting the picker, non-critical `x` bulk clear that preserves critical rows, empty
|
|
75
79
|
state rendering after all visible non-critical rows are cleared, and notify queue-write refresh events
|
package/docs/architecture.md
CHANGED
|
@@ -139,13 +139,14 @@ does not own the truth of every live badge.
|
|
|
139
139
|
TTL is not a removal condition. `projmux notify list --live` adds a
|
|
140
140
|
read-only comparison against live pane state, explaining manual reply
|
|
141
141
|
badges without queue entries, live AI replies with/missing queue entries,
|
|
142
|
-
and stale `ai:` entries.
|
|
142
|
+
and inactive (`queue-stale`) `ai:` entries.
|
|
143
143
|
- **Ack** — `projmux notify ack <id>` removes one entry; `--all`
|
|
144
|
-
flushes everything.
|
|
144
|
+
flushes everything. Interactive focus/click handlers ack after successful
|
|
145
|
+
focus, and gone/unroutable targets clean up without focusing.
|
|
145
146
|
- **Reconcile** — `projmux notify reconcile` walks
|
|
146
147
|
`tmux list-panes -a` and back-fills entries for panes whose
|
|
147
148
|
attention state is `reply` AND whose AI agent option is set,
|
|
148
|
-
reporting
|
|
149
|
+
reporting inactive `ai:` entries that no longer match a live reply+agent pane without
|
|
149
150
|
acking them.
|
|
150
151
|
`make install` and `projmux upgrade` invoke it so the queue
|
|
151
152
|
recovers from any drift introduced by a lost daemon.
|
|
Binary file
|
|
Binary file
|
package/docs/cli.md
CHANGED
|
@@ -218,11 +218,15 @@ projmux notify reconcile [--json]
|
|
|
218
218
|
`--live` adds a non-mutating explanation table (or JSON report) that
|
|
219
219
|
compares queued entries with live pane attention. It calls out manual
|
|
220
220
|
reply badges that do not queue because no AI agent is attached, live AI
|
|
221
|
-
reply panes missing a queue entry, matched AI reply entries,
|
|
222
|
-
queue entries whose live pane no longer matches
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
221
|
+
reply panes missing a queue entry, matched AI reply entries, inactive
|
|
222
|
+
(`queue-stale`) queue entries whose live pane EXISTS but no longer matches
|
|
223
|
+
reply+agent state, and gone (`queue-gone`) entries whose pane is absent from
|
|
224
|
+
the real tmux live pane inventory (or which have no routable target).
|
|
225
|
+
`--ui=sidebar` opens the compact interactive notify list where Enter
|
|
226
|
+
focuses and acks live or inactive-routable targets, cleans gone/unroutable
|
|
227
|
+
targets without focusing, `a` acks the selected row, `x` clears non-critical
|
|
228
|
+
rows, and `Ctrl-X` clears all; opening or navigating the sidebar does not ack.
|
|
229
|
+
While open, the native
|
|
226
230
|
sidebar refreshes its row list on successful queue-write events without an
|
|
227
231
|
Alt-2 close/reopen toggle, using the same deferred refresh path as `a` and
|
|
228
232
|
`x`. The sidebar uses two-line cards with notification text first and
|
|
@@ -652,8 +656,8 @@ projmux tmux apply
|
|
|
652
656
|
Helpers tmux's keybindings and the install pipeline call into. Modes
|
|
653
657
|
accepted by `popup-toggle` mirror the historical sessionizer surface:
|
|
654
658
|
`session-popup`, `sessionizer`, `sessionizer-sidebar`,
|
|
655
|
-
`notify-sidebar`, `
|
|
656
|
-
`ai-split-settings`.
|
|
659
|
+
`notify-sidebar`, `recent-windows`, `ai-split-picker-right`,
|
|
660
|
+
`ai-split-picker-down`, `ai-split-settings`.
|
|
657
661
|
`apply` reloads the live `-L projmux` server's config without restarting
|
|
658
662
|
it; `make install` and `projmux upgrade` invoke it after replacing the
|
|
659
663
|
binary.
|
package/docs/configuration.md
CHANGED
|
@@ -87,14 +87,15 @@ language.
|
|
|
87
87
|
## Keymap File
|
|
88
88
|
|
|
89
89
|
Settings > Keybindings is the normal in-app editor for action keys. It lists
|
|
90
|
-
actions with current
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
90
|
+
actions with the current active keys and one state: Default, Custom, Available,
|
|
91
|
+
or Unbound. Open an action to see the action label, state, a flat Keys list,
|
|
92
|
+
Options, and a collapsed Troubleshooting row. Create flows start from
|
|
93
|
+
`+ Add key`, deletion lives under each key's detail, and action-level state
|
|
94
|
+
changes such as Unbind or Reset live under Options. Successful saves report the
|
|
95
|
+
keybinding as saved; failures identify the stage that failed.
|
|
96
|
+
|
|
97
|
+
Raw sequences that cannot be safely represented as a direct keybinding are not
|
|
98
|
+
persisted. Use Settings to save a custom key. When key delivery needs
|
|
98
99
|
terminal-layer remediation, first try the key in `projmux shell`, then run
|
|
99
100
|
`projmux setup` from the raw terminal, then use `projmux init` for supported
|
|
100
101
|
terminal adapters.
|
|
@@ -133,7 +134,7 @@ the direct AI pane actions, `ai-split-right` and `ai-split-down`. The direct
|
|
|
133
134
|
actions create a new managed AI pane each time they run, leaving existing AI
|
|
134
135
|
panes in place. `right` and `down` choose where the new pane is created.
|
|
135
136
|
|
|
136
|
-
Use an empty `keys` list to disable direct plain
|
|
137
|
+
Use an empty `keys` list to disable direct plain keys for the action when
|
|
137
138
|
editing the file by hand:
|
|
138
139
|
|
|
139
140
|
```toml
|
|
@@ -157,7 +158,7 @@ The file currently affects generated tmux config from `projmux tmux
|
|
|
157
158
|
print-config`, `projmux tmux install`, `projmux tmux print-app-config`,
|
|
158
159
|
`projmux tmux install-app`, and `projmux shell`. Terminal init adapters such as
|
|
159
160
|
Ghostty and Windows Terminal install built-in plain-byte mappings where needed;
|
|
160
|
-
they do not read `keymap.toml` or copy saved
|
|
161
|
+
they do not read `keymap.toml` or copy saved keys into terminal configs.
|
|
161
162
|
Changing terminal-layer mappings still requires rerunning `projmux init` and
|
|
162
163
|
restarting the terminal where that terminal requires it.
|
|
163
164
|
|
package/docs/keybindings.md
CHANGED
|
@@ -4,7 +4,7 @@ projmux is keyboard-driven, but the guaranteed launch contract is small:
|
|
|
4
4
|
fresh installs bind `Alt-1` through `Alt-5` as plain Meta sequences
|
|
5
5
|
(`M-1`..`M-5`, bytes `\x1b1`..`\x1b5`). Other actions remain discoverable in
|
|
6
6
|
Settings > Keybindings. Transport-dependent actions keep their built-in
|
|
7
|
-
transport default key, and Settings can add separate safe tmux plain
|
|
7
|
+
transport default key, and Settings can add separate safe tmux plain keys to
|
|
8
8
|
the same action. They are not installed as terminal-specific User-key
|
|
9
9
|
fallbacks. `UserN` and `CSI-u` are legacy/removal/unsupported targets, not
|
|
10
10
|
supported fallback guidance.
|
|
@@ -15,14 +15,13 @@ The recommended path when a key does not fire:
|
|
|
15
15
|
2. Run `projmux setup` outside tmux to see which bytes reach the process.
|
|
16
16
|
3. For supported terminals, preview `projmux init [terminal]`; add `--apply`
|
|
17
17
|
only after reviewing the merge.
|
|
18
|
-
4. For unsupported terminals, configure plain Meta bytes or add a
|
|
18
|
+
4. For unsupported terminals, configure plain Meta bytes or add a custom key in
|
|
19
19
|
Settings > Keybindings.
|
|
20
20
|
|
|
21
|
-
Settings
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
and tmux User keys are rejected as aliases.
|
|
21
|
+
Settings saves safe tmux plain chords for actions. Successful saves use simple
|
|
22
|
+
confirmation copy; if saving, runtime config update, or active tmux reload
|
|
23
|
+
fails, the error names the failed stage. Raw escape payloads, Windows Terminal
|
|
24
|
+
`sendInput` strings, and tmux User keys are rejected as action keys.
|
|
26
25
|
|
|
27
26
|
## Quick Start
|
|
28
27
|
|
|
@@ -32,10 +31,14 @@ These shortcuts are the guaranteed launch defaults. They need no tmux prefix.
|
|
|
32
31
|
| --- | --- |
|
|
33
32
|
| `Alt-1` | Project sidebar |
|
|
34
33
|
| `Alt-2` | Notify sidebar |
|
|
35
|
-
| `Alt-3` |
|
|
34
|
+
| `Alt-3` | Recent Windows |
|
|
36
35
|
| `Alt-4` | AI split popup picker |
|
|
37
36
|
| `Alt-5` | Settings |
|
|
38
37
|
|
|
38
|
+
`RecentWindows:Open` opens the cross-project recent windows queue. It switches
|
|
39
|
+
to the selected live tmux window using that window's current active pane; it is
|
|
40
|
+
separate from `last-pane` and from the existing-session popup.
|
|
41
|
+
|
|
39
42
|
The tmux prefix remains the upstream default `Ctrl-b`. Inside a running
|
|
40
43
|
session, `Ctrl-b ?` lists the live tmux bindings.
|
|
41
44
|
|
|
@@ -43,19 +46,25 @@ session, `Ctrl-b ?` lists the live tmux bindings.
|
|
|
43
46
|
|
|
44
47
|
Settings > Keybindings lists the full action catalogue. In particular, sidebar
|
|
45
48
|
keymap actions, pane switching, window switching, and rename actions remain
|
|
46
|
-
visible.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
visible.
|
|
50
|
+
|
|
51
|
+
The Settings flow is intentionally simple: the root is one action list with a
|
|
52
|
+
key summary and state. The key summary uses the first key plus `+N`, or
|
|
53
|
+
`Not bound` when no key is active. State vocabulary is limited to Default,
|
|
54
|
+
Custom, Available, and Unbound. Each action detail shows the action label,
|
|
55
|
+
state, a flat Keys list with `+ Add key`, Options, and a collapsed
|
|
56
|
+
Troubleshooting row with Test key delivery and Advanced... entry points. Key
|
|
57
|
+
rows open key detail for Remove key and Test key. Add key opens Press a key by
|
|
58
|
+
default; Enter key name and raw diagnostics live under Advanced. Options covers
|
|
59
|
+
unbinding the action and reset/use-default flows. Diagnostic/probe/init
|
|
60
|
+
workflows are not first-class Settings tabs; use `projmux setup` and
|
|
61
|
+
`projmux init` from the terminal when key delivery needs remediation.
|
|
62
|
+
|
|
63
|
+
Optional direct keys can be added for actions such as:
|
|
56
64
|
|
|
57
65
|
| Canonical action | Meaning |
|
|
58
66
|
| --- | --- |
|
|
67
|
+
| `RecentWindows:Open` | Recent windows queue across projects |
|
|
59
68
|
| `ProjectSwitcherToggle` | Project switcher popup |
|
|
60
69
|
| `AISplitPickerToggle` | AI split popup picker; pressing again closes the picker popup |
|
|
61
70
|
| `ai-split-right` | Open a new direct AI split to the right |
|
|
@@ -77,20 +86,20 @@ movement. Previous/next window remain transport-dependent and the generated app
|
|
|
77
86
|
tmux config binds `M-S-Left` / `M-S-Right` to the tmux window navigation
|
|
78
87
|
commands. These default transport keys are always rendered by projmux, because
|
|
79
88
|
delivery still depends on the terminal forwarding the modifier-arrow sequence.
|
|
80
|
-
Settings can add extra safe plain
|
|
81
|
-
`previous-window`; those
|
|
89
|
+
Settings can add extra safe plain keys, such as `M-[` for
|
|
90
|
+
`previous-window`; those keys are saved to `keymap.toml` as `keys = [...]`
|
|
82
91
|
without storing or replacing the transport default. Rename actions no longer
|
|
83
92
|
have a built-in terminal fallback; use tmux's prefix rename flow or configure
|
|
84
|
-
an explicit safe
|
|
93
|
+
an explicit safe key where the action is editable.
|
|
85
94
|
|
|
86
95
|
## Product Requirements
|
|
87
96
|
|
|
88
97
|
Settings > Keybindings stays a discovery surface. It must continue to expose
|
|
89
98
|
launch toggles, sidebar keymap actions, picker-local actions, pane switching,
|
|
90
|
-
window switching, and rename actions. The
|
|
91
|
-
terminal remediation surface:
|
|
92
|
-
terminal mapping preview/apply, and init execution rows stay out of
|
|
93
|
-
detail.
|
|
99
|
+
window switching, and rename actions. The basic Settings flow is not the
|
|
100
|
+
terminal remediation surface: key-role replacement, disable-default, typed
|
|
101
|
+
fallback, terminal mapping preview/apply, and init execution rows stay out of
|
|
102
|
+
the action detail.
|
|
94
103
|
|
|
95
104
|
The product model does not support `UserN` or `CSI-u` as fallback guidance.
|
|
96
105
|
Windows Terminal and Ghostty adapters use built-in plain Meta/control bytes or
|
|
@@ -110,10 +119,14 @@ by different picker surfaces, while conflicts inside one surface are rejected.
|
|
|
110
119
|
| `SessionPopup:KillSession` | Kill the focused session |
|
|
111
120
|
| `SessionPopup:CyclePreviewWindowPrev` / `SessionPopup:CyclePreviewWindowNext` | Preview windows |
|
|
112
121
|
| `SessionPopup:CyclePreviewPanePrev` / `SessionPopup:CyclePreviewPaneNext` | Preview panes |
|
|
113
|
-
| `NotifySidebar:Ack` / `NotifySidebar:ClearNonCritical` / `NotifySidebar:ClearAll` | Manage notifications |
|
|
122
|
+
| `NotifySidebar:Ack` / `NotifySidebar:AckGroup` / `NotifySidebar:ClearNonCritical` / `NotifySidebar:ClearAll` | Manage notifications |
|
|
123
|
+
|
|
124
|
+
Notify sidebar Right/Left child-row show/hide behavior is picker-local and is
|
|
125
|
+
not part of the Settings action catalog. `NotifySidebar:AckGroup` defaults to
|
|
126
|
+
uppercase `A`, distinct from `NotifySidebar:Ack` on lowercase `a`.
|
|
114
127
|
|
|
115
|
-
Runtime picker footers render key guides from the merged keymap,
|
|
116
|
-
|
|
128
|
+
Runtime picker footers render key guides from the merged keymap, using the
|
|
129
|
+
first active key as the representative key.
|
|
117
130
|
|
|
118
131
|
## Keymap File
|
|
119
132
|
|
|
@@ -150,7 +163,7 @@ so Settings can distinguish them from the `Alt-4` popup picker toggle.
|
|
|
150
163
|
## Diagnose: `projmux setup`
|
|
151
164
|
|
|
152
165
|
Run `projmux setup` outside tmux to find out which projmux keys reach the raw
|
|
153
|
-
terminal. Settings > Keybindings remains the action
|
|
166
|
+
terminal. Settings > Keybindings remains the action-key editor; setup is the
|
|
154
167
|
terminal delivery diagnostic.
|
|
155
168
|
|
|
156
169
|
| Status | Meaning |
|
|
@@ -184,7 +197,7 @@ projmux init --allow-symlink
|
|
|
184
197
|
|
|
185
198
|
The merge is idempotent: matching bindings are no-ops, missing bindings are
|
|
186
199
|
added, and keys already mapped to a different user action are skipped with a
|
|
187
|
-
warning. `projmux init` does not read `keymap.toml`; direct tmux
|
|
200
|
+
warning. `projmux init` does not read `keymap.toml`; direct tmux keys still
|
|
188
201
|
belong in Settings > Keybindings or the keymap file.
|
|
189
202
|
|
|
190
203
|
### Ghostty
|
|
@@ -219,7 +232,7 @@ previous/next window:
|
|
|
219
232
|
"actions": [
|
|
220
233
|
{ "command": { "action": "sendInput", "input": "\u001b1" }, "id": "User.projmuxSidebar" },
|
|
221
234
|
{ "command": { "action": "sendInput", "input": "\u001b2" }, "id": "User.projmuxNotifySidebar" },
|
|
222
|
-
{ "command": { "action": "sendInput", "input": "\u001b3" }, "id": "User.
|
|
235
|
+
{ "command": { "action": "sendInput", "input": "\u001b3" }, "id": "User.projmuxRecentWindows" },
|
|
223
236
|
{ "command": { "action": "sendInput", "input": "\u001b4" }, "id": "User.projmuxAIPicker" },
|
|
224
237
|
{ "command": { "action": "sendInput", "input": "\u001b5" }, "id": "User.projmuxSettings" },
|
|
225
238
|
{ "command": { "action": "sendInput", "input": "\u0002r" }, "id": "User.projmuxAISplitRight" },
|
|
@@ -112,7 +112,7 @@ The fzf compatibility surface for the native engine is tracked in
|
|
|
112
112
|
the top border off screen.
|
|
113
113
|
- Native preview panes normalize tabs and control bytes before horizontal
|
|
114
114
|
clipping, preventing long preview rows from wrapping and consuming extra
|
|
115
|
-
vertical viewport rows in
|
|
115
|
+
vertical viewport rows in session popups.
|
|
116
116
|
- Native sidebar list scrollbars use the fixed list viewport as their track and
|
|
117
117
|
measure multi-line cards in rendered rows, so the thumb does not shrink or
|
|
118
118
|
jump when card heights vary.
|
|
@@ -179,8 +179,9 @@ Manual UX checks for the Docker sandbox:
|
|
|
179
179
|
- Alt-1 opens with the top border/title visible, not clipped.
|
|
180
180
|
- Vertical borders stay continuous while moving Up/Down.
|
|
181
181
|
- Alt-1 closes the sidebar immediately when pressed again.
|
|
182
|
-
- Alt-2, Alt-
|
|
182
|
+
- Alt-2, Alt-4, and Alt-5 open their matching native popups and close
|
|
183
183
|
on the same Alt key immediately.
|
|
184
|
+
- Alt-3 opens Recent Windows.
|
|
184
185
|
- Arrow keys move selection without leaking `^[[` text into the query.
|
|
185
186
|
|
|
186
187
|
`fzf` is intentionally not installed in the image.
|
package/docs/notify-queue.md
CHANGED
|
@@ -106,21 +106,48 @@ table `ID AGE SEV SRC TARGET TEXT`. `--severity` / `--source` are
|
|
|
106
106
|
repeatable filters. Without `--live`, this command reads only the queue and
|
|
107
107
|
preserves the stable JSON array used by scripts.
|
|
108
108
|
|
|
109
|
-
`--ui=sidebar` opens the notify queue as an interactive right-side
|
|
110
|
-
run inside the tmux popup surface.
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
and
|
|
117
|
-
|
|
109
|
+
`--ui=sidebar` opens the notify queue as an interactive right-side pane/session
|
|
110
|
+
inbox when run inside the tmux popup surface. The queue source of truth remains
|
|
111
|
+
flat; the sidebar builds a read-only grouped view for display. The first screen
|
|
112
|
+
shows collapsed group rows keyed by pane when available, then window, then
|
|
113
|
+
session/external fallback. Each group row is a fixed three-line card: line 1
|
|
114
|
+
keeps project/session plus agent/provider with newest age, line 2 keeps
|
|
115
|
+
topic/pane-title/task context plus severity/live-state aggregate
|
|
116
|
+
metadata, and line 3 keeps the latest notification preview. Collapsed group
|
|
117
|
+
cards do not promote window/pane ids as primary information. A `+N` badge is
|
|
118
|
+
shown only when the group can unfold, and `N` is the number of child
|
|
119
|
+
notification rows that will appear; one-notification group headers omit both
|
|
120
|
+
the count badge and strong fold marker. Right/Left show and hide child rows for
|
|
121
|
+
foldable groups inside the native sidebar only; this fold state is
|
|
122
|
+
session-local and is not persisted. Right on a childless group refreshes
|
|
123
|
+
without adding rows. Enter on a group row, whether folded or expanded, focuses
|
|
124
|
+
the group's representative pane and acknowledges every visible notification in
|
|
125
|
+
that group only after focus succeeds. Inactive means an `ai:` queue entry points
|
|
126
|
+
to a pane that no longer matches live reply+agent state; it is not a time-age
|
|
127
|
+
TTL state, and Enter still focuses the target when it is routable. If the
|
|
128
|
+
representative target is gone/unroutable, Enter treats the selected pane inbox
|
|
129
|
+
as explicit cleanup and acknowledges/prunes the visible group without focusing,
|
|
130
|
+
including critical notifications. If a live- or inactive-looking representative target
|
|
131
|
+
disappears during focus, Enter uses the same gone-group cleanup policy. Other
|
|
132
|
+
focus failures keep the group pending, show a clear message, and refresh/prune
|
|
133
|
+
the list. Expanded child notification rows are compact event rows with age,
|
|
134
|
+
message preview, and severity/state while keeping the existing focus/ack-one
|
|
135
|
+
behavior. The surface actions
|
|
136
|
+
`NotifySidebar:Ack`, `NotifySidebar:AckGroup`,
|
|
137
|
+
`NotifySidebar:ClearNonCritical`, and `NotifySidebar:ClearAll` are internal
|
|
138
|
+
picker actions; direct launch aliases are edited in Settings, while internal
|
|
139
|
+
picker aliases are adjusted in `keymap.toml` when needed.
|
|
140
|
+
`NotifySidebar:AckGroup` defaults to uppercase `A` and explicitly
|
|
141
|
+
acknowledges every visible notification in the selected group, including
|
|
142
|
+
critical notifications. Runtime footer key guides read the merged keymap and
|
|
143
|
+
show the default alias when present, otherwise the first configured alias, so
|
|
144
|
+
custom aliases do not make the UI stale.
|
|
145
|
+
`NotifySidebar:Ack`, `NotifySidebar:AckGroup`, and
|
|
118
146
|
`NotifySidebar:ClearNonCritical` refresh rows, live state, and selection inside
|
|
119
147
|
the same native picker session; `NotifySidebar:ClearAll` still closes the
|
|
120
|
-
popup and prints a summary. Rows are intentionally compact:
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
intentionally does not expose a separate metadata detail view.
|
|
148
|
+
popup and prints a summary. Rows are intentionally compact: hidden queue ids
|
|
149
|
+
remain action values but the sidebar has no search input and intentionally does
|
|
150
|
+
not expose a separate metadata detail view.
|
|
124
151
|
|
|
125
152
|
When a new pending notification is successfully pushed by any app producer
|
|
126
153
|
(`notify push`, reply-ready, reconcile backfill, or bell fallback), open native
|
|
@@ -142,11 +169,20 @@ output becomes `{queue, live, rows, errors}`. Typical states:
|
|
|
142
169
|
queue entry.
|
|
143
170
|
- `live-ai-reply-missing-queue` — a live AI reply pane lacks the derived
|
|
144
171
|
queue entry; run `projmux notify reconcile` to back-fill it.
|
|
145
|
-
- `queue-stale` —
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
172
|
+
- `queue-stale` — preserved machine-readable state for an inactive target:
|
|
173
|
+
an `ai:` queue entry whose pane still EXISTS in the live tmux pane inventory,
|
|
174
|
+
but no longer matches reply+agent state. It is not TTL/time age. Surfaced in
|
|
175
|
+
the sidebar/statusbar as `INACTIVE` / `INA`; Enter still focuses and acks if
|
|
176
|
+
the target is routable.
|
|
177
|
+
- `queue-gone` — the queue entry's target is gone. This is now determined two
|
|
178
|
+
ways: (a) the entry has no routable target (empty session), or (b) the entry
|
|
179
|
+
carries a pane target whose pane id is absent from the real tmux live pane
|
|
180
|
+
inventory (`tmux list-panes -a`). Surfaced as `GONE` / `GON`, and Enter/ack
|
|
181
|
+
cleans it up without focusing. The inventory check is best-effort: when the
|
|
182
|
+
pane inventory cannot be read (tmux error, or an empty/unrecognized reply),
|
|
183
|
+
membership-based GONE is skipped so a missing tmux server never falsely
|
|
184
|
+
dims/gones every row, and only pane-target rows are eligible (window/session-
|
|
185
|
+
only rows keep the empty-session check only).
|
|
150
186
|
- `queue-only` — a non-AI/external queue entry is pending and has no live AI
|
|
151
187
|
reply-pane requirement.
|
|
152
188
|
|
|
@@ -176,7 +212,8 @@ path), then:
|
|
|
176
212
|
- pushes/refreshes one `ai:<session>:<pane>` entry for every pane
|
|
177
213
|
whose attention state is `reply` AND whose agent option is non-empty;
|
|
178
214
|
- reports every existing queue entry whose id starts with `ai:` and whose
|
|
179
|
-
pane no longer matches that condition as stale
|
|
215
|
+
pane no longer matches that condition as inactive/`queue-stale`, without
|
|
216
|
+
acking it.
|
|
180
217
|
|
|
181
218
|
Successful backfill pushes publish the same best-effort open-sidebar refresh
|
|
182
219
|
event as other pending queue additions.
|
package/docs/settings-ia.md
CHANGED
|
@@ -24,16 +24,22 @@ view-first layout:
|
|
|
24
24
|
commands, `Pane navigation`, `Window navigation`, and `Rename` groups or
|
|
25
25
|
equivalent searchable rows.
|
|
26
26
|
- `Settings > Keybindings > Action` keeps the user-facing edit path small:
|
|
27
|
-
action,
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
action label, state, a flat Keys list, Options, and a collapsed
|
|
28
|
+
Troubleshooting row. Keys shows only currently active/effective keys plus
|
|
29
|
+
`+ Add key`. Pressing a key row opens key detail, where Remove key and Test
|
|
30
|
+
key live. Options offers Unbind and Reset to default/Use default when
|
|
31
|
+
state-appropriate. Add key opens the default Press a key flow with Cancel and
|
|
32
|
+
Advanced...; typed key-name entry and raw diagnostics live under Advanced. It
|
|
33
|
+
does not expose Default key, Apply State, Delivery, Advanced Delivery,
|
|
34
|
+
key-role replacement, terminal mapping preview, or terminal mapping apply
|
|
35
|
+
rows as always-visible sections.
|
|
30
36
|
- Terminal delivery remediation lives outside Settings primary flow. The
|
|
31
37
|
supported order is `projmux shell` first, then `projmux setup`, then
|
|
32
38
|
`projmux init` for supported terminal adapters.
|
|
33
39
|
- Rows that cannot safely be edited still stay visible. Mark diagnostic-only
|
|
34
40
|
rows with the delivery path and reason instead of hiding them or turning them
|
|
35
|
-
into unsupported editable
|
|
36
|
-
|
|
41
|
+
into unsupported editable keys. Transport-dependent rows stay visible with
|
|
42
|
+
their default transport key and additive custom-key entry; replacing or
|
|
37
43
|
disabling the transport default is not exposed.
|
|
38
44
|
- `Alt-1..5` are the only guaranteed zero-config launch defaults. `UserN` and
|
|
39
45
|
`CSI-u` are legacy/removal/unsupported targets, not supported fallback
|
|
@@ -64,8 +70,7 @@ view-first layout:
|
|
|
64
70
|
edit catalog `install` values or run agent install/remove commands.
|
|
65
71
|
- `Settings > Session State > Sidebar startup picker` controls the Alt-1
|
|
66
72
|
project-open startup selector. The saved file remains
|
|
67
|
-
`${XDG_CONFIG_HOME:-$HOME/.config}/projmux/sidebar-startup-picker
|
|
68
|
-
stale `labs:sidebar-startup-picker` action opens this Session State detail.
|
|
73
|
+
`${XDG_CONFIG_HOME:-$HOME/.config}/projmux/sidebar-startup-picker`.
|
|
69
74
|
- `Settings > Labs` keeps experimental toggles, but keybindings no longer have a
|
|
70
75
|
visible Labs row. The hidden compatibility action redirects to the
|
|
71
76
|
`Settings > Keybindings` action list, not to a diagnostic default.
|
package/docs/statusbar.md
CHANGED
|
@@ -141,13 +141,35 @@ last collect timestamp when present, falls back to the cache file mtime when
|
|
|
141
141
|
needed, and keeps stale sync metadata muted instead of escalating it to a
|
|
142
142
|
warning color.
|
|
143
143
|
The notification HUD detail surface opens the right-side notification popup
|
|
144
|
-
through the notify sidebar action,
|
|
145
|
-
attention-tinted title. When notification
|
|
146
|
-
`emoji`, the bell appears before the title text.
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
render
|
|
150
|
-
|
|
144
|
+
through the notify sidebar action, showing the grouped pane/session inbox with
|
|
145
|
+
collapsed group rows and the same attention-tinted title. When notification
|
|
146
|
+
icon decoration is `symbol` or `emoji`, the bell appears before the title text.
|
|
147
|
+
Foldable group rows show `+N`, where `N` is the number of child notification
|
|
148
|
+
rows shown after Right. One-notification group headers omit the count and do
|
|
149
|
+
not render as strongly foldable. Right/Left show and hide child rows locally
|
|
150
|
+
inside the native sidebar; Right on a childless group refreshes without adding
|
|
151
|
+
rows. Enter on a group row, whether folded or expanded, focuses the group's
|
|
152
|
+
representative pane and acknowledges every visible notification in that group
|
|
153
|
+
only after focus succeeds. Inactive means an `ai:` queue entry no longer
|
|
154
|
+
matches live reply+agent state (its pane still EXISTS in tmux), not that the
|
|
155
|
+
row is old; if the target remains routable, Enter and statusbar clicks still
|
|
156
|
+
focus and then ack. Gone means the target is unroutable (empty session) or the
|
|
157
|
+
row's pane id is absent from the real tmux live pane inventory
|
|
158
|
+
(`tmux list-panes -a`). The inventory check is best-effort: an unreadable or
|
|
159
|
+
empty/unrecognized tmux reply is treated as "unavailable", so a missing tmux
|
|
160
|
+
server never falsely gones routable rows. If the
|
|
161
|
+
representative target is gone/unroutable, Enter cleans up the selected group
|
|
162
|
+
without focusing and acknowledges every visible notification in that group,
|
|
163
|
+
including critical notifications. A
|
|
164
|
+
target-gone focus race follows the same cleanup policy; other focus failures
|
|
165
|
+
keep the group pending and show a clear message before refresh/prune. Enter on
|
|
166
|
+
a child notification preserves the existing focus and ack-one behavior.
|
|
167
|
+
`NotifySidebar:AckGroup` remains the explicit group ack action and acknowledges
|
|
168
|
+
every visible notification in the selected group, including critical
|
|
169
|
+
notifications.
|
|
170
|
+
Internal notify commands use `NotifySidebar:*` IDs in `keymap.toml`; runtime
|
|
171
|
+
footers render key guides from the merged keymap and prefer the default alias
|
|
172
|
+
when it is still configured.
|
|
151
173
|
|
|
152
174
|
Empty `#{mouse_status_range}` (a click on whitespace) falls through to
|
|
153
175
|
`select-window -t @<mouse_window>` when `--mouse-window` is non-empty,
|
|
@@ -180,6 +202,8 @@ them as `display-message` toasts:
|
|
|
180
202
|
|
|
181
203
|
- `notify` click whose focus dispatch exits 2 (target unresolved):
|
|
182
204
|
ack the entry, toast `notify target gone; cleared`.
|
|
205
|
+
- `notify` click whose AI target is inactive because it no longer matches live
|
|
206
|
+
reply+agent state: focus and ack when the target is still routable.
|
|
183
207
|
- Any other focus failure: keep the entry, toast `focus failed:
|
|
184
208
|
<reason>`.
|
|
185
209
|
- `session`, `kube`, or `git` popup launch failure: toast
|
package/docs/testing.md
CHANGED
|
@@ -21,6 +21,10 @@ and humans run the same entrypoints.
|
|
|
21
21
|
`test/e2e/linux-smoke.sh`. It validates a minimal real-tmux workflow:
|
|
22
22
|
sessions, panes, config sourcing, reply-state notify reconciliation, focus
|
|
23
23
|
notify fallback, and status notify rendering.
|
|
24
|
+
- `make deadcode` runs `go tool deadcode` (pinned via the go.mod tool
|
|
25
|
+
directive) over the module and reports unreachable functions, filtering out
|
|
26
|
+
the intentional/MUST-KEEP baseline in `.deadcode-allowlist.txt`; it fails
|
|
27
|
+
only on NEW dead code, and `make fix` runs it after `go fix`.
|
|
24
28
|
|
|
25
29
|
## Docker-Covered Checks
|
|
26
30
|
|
|
@@ -90,7 +94,7 @@ Observe:
|
|
|
90
94
|
|
|
91
95
|
- `Alt-1` opens the project sidebar.
|
|
92
96
|
- `Alt-2` opens the notification sidebar.
|
|
93
|
-
- `Alt-3` opens
|
|
97
|
+
- `Alt-3` opens Recent Windows.
|
|
94
98
|
- `Alt-4` opens the AI split picker.
|
|
95
99
|
- `Alt-5` opens Settings.
|
|
96
100
|
- Pressing the same launch key again closes the popup instead of typing escape
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "projmux",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "tmux project session manager",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/crevissepartners/projmux#readme",
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
"package:npm:pack": "scripts/package-npm.sh --pack"
|
|
29
29
|
},
|
|
30
30
|
"optionalDependencies": {
|
|
31
|
-
"@projmux/linux-x64": "0.
|
|
32
|
-
"@projmux/linux-arm64": "0.
|
|
33
|
-
"@projmux/darwin-x64": "0.
|
|
34
|
-
"@projmux/darwin-arm64": "0.
|
|
31
|
+
"@projmux/linux-x64": "0.7.0",
|
|
32
|
+
"@projmux/linux-arm64": "0.7.0",
|
|
33
|
+
"@projmux/darwin-x64": "0.7.0",
|
|
34
|
+
"@projmux/darwin-arm64": "0.7.0"
|
|
35
35
|
}
|
|
36
36
|
}
|
|
Binary file
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
# README Hero GIF Recording
|
|
2
|
-
|
|
3
|
-
This recipe records the README hero GIF:
|
|
4
|
-
|
|
5
|
-
- `docs/assets/projmux-ai-attention.gif`
|
|
6
|
-
|
|
7
|
-
The maintained recorder is kept in the local dotfiles checkout at:
|
|
8
|
-
|
|
9
|
-
```sh
|
|
10
|
-
/home/es5h/dotfiles/bin/projmux/projmux-record-readme-gifs.py
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## Prerequisites
|
|
14
|
-
|
|
15
|
-
Install or verify these local tools before recording:
|
|
16
|
-
|
|
17
|
-
- `python3`
|
|
18
|
-
- `git`
|
|
19
|
-
- `tmux`
|
|
20
|
-
- `ffmpeg` and `ffprobe`
|
|
21
|
-
- `Xvfb`
|
|
22
|
-
- `openbox`
|
|
23
|
-
- `ghostty`
|
|
24
|
-
- `xdotool`
|
|
25
|
-
- `xwininfo`
|
|
26
|
-
- `script` from util-linux
|
|
27
|
-
- authenticated `codex`
|
|
28
|
-
|
|
29
|
-
Build the local projmux binary first:
|
|
30
|
-
|
|
31
|
-
```sh
|
|
32
|
-
make build
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
The script expects `.bin/projmux` by default. Override paths only when needed:
|
|
36
|
-
|
|
37
|
-
```sh
|
|
38
|
-
PROJMUX_RECORD_REPO=/path/to/projmux \
|
|
39
|
-
PROJMUX_RECORD_BIN=/path/to/projmux \
|
|
40
|
-
PROJMUX_RECORD_DISPLAY=117 \
|
|
41
|
-
PROJMUX_RECORD_SCREEN=2560x1440x24 \
|
|
42
|
-
PROJMUX_RECORD_KEEP_TMP=1 \
|
|
43
|
-
python3 /home/es5h/dotfiles/bin/projmux/projmux-record-readme-gifs.py
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
For the normal checkout, run:
|
|
47
|
-
|
|
48
|
-
```sh
|
|
49
|
-
python3 /home/es5h/dotfiles/bin/projmux/projmux-record-readme-gifs.py
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Scenario Contract
|
|
53
|
-
|
|
54
|
-
The recording uses a private demo home, XDG config/state dirs, demo git
|
|
55
|
-
projects, and an isolated `CODEX_HOME`. It copies the local Codex auth/config
|
|
56
|
-
into that isolated home, trusts the demo projects/hooks, and seeds usage cache
|
|
57
|
-
data so the tmux status line shows the Codex HUD during the capture.
|
|
58
|
-
|
|
59
|
-
The scenario records the AI attention flow:
|
|
60
|
-
|
|
61
|
-
1. Start in `mobile-client` with no pending notification.
|
|
62
|
-
2. Open the AI picker and launch a real Codex pane.
|
|
63
|
-
3. Ask Codex to do a short task.
|
|
64
|
-
4. Use the projmux sessionizer sidebar to move to `atlas-api`.
|
|
65
|
-
5. Keep working in zsh while Codex finishes in the previous project.
|
|
66
|
-
6. When the Codex completion notification exists, open the notification sidebar.
|
|
67
|
-
7. Select the notification and return focus to the original Codex pane.
|
|
68
|
-
|
|
69
|
-
## Visual Guardrails
|
|
70
|
-
|
|
71
|
-
- Keep the native picker UI native. The script runs picker commands through
|
|
72
|
-
`script(1)` with a fixed PTY size so fzf/terminal UI rendering is captured
|
|
73
|
-
instead of degraded line-mode output.
|
|
74
|
-
- Keep the terminal in zsh with the demo prompt so the project and git branch
|
|
75
|
-
are visible.
|
|
76
|
-
- Keep the Codex usage HUD visible in the tmux status line.
|
|
77
|
-
- Use the sessionizer sidebar for project movement in 4a.
|
|
78
|
-
- Capture the Ghostty X11 window geometry with `xwininfo` and feed that exact
|
|
79
|
-
rectangle to ffmpeg. This prevents the GIF from drifting away from `(0, 0)`.
|
|
80
|
-
|
|
81
|
-
## Verification
|
|
82
|
-
|
|
83
|
-
After recording, inspect the resulting streams:
|
|
84
|
-
|
|
85
|
-
```sh
|
|
86
|
-
ffprobe -v error -select_streams v:0 \
|
|
87
|
-
-show_entries stream=width,height,nb_frames,duration \
|
|
88
|
-
-of default=noprint_wrappers=1 \
|
|
89
|
-
docs/assets/projmux-ai-attention.gif
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
Expected final shape is roughly 1110px wide and about 16-18 seconds, with the
|
|
93
|
-
native picker, zsh prompt, Codex pane, notification sidebar, and usage HUD
|
|
94
|
-
visible in the relevant frames.
|
|
95
|
-
|
|
96
|
-
Set `PROJMUX_RECORD_KEEP_TMP=1` when you need to inspect intermediate MP4s,
|
|
97
|
-
Ghostty logs, or palette files under `/tmp/projmux-readme-record-*`.
|