projmux 0.6.5 → 0.6.7

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.
@@ -15,13 +15,21 @@ view-first layout:
15
15
  actions live inside that view.
16
16
  - `Settings > Project Picker > Project Root` shows effective and saved values
17
17
  first, then the edit actions, then the explanatory hints.
18
- - `Settings > Keybindings` is the single entry point for keybinding work. The
19
- page is split into four chips: `Bindings`, `Diagnostic`, `Probe`, and `Init`.
20
- - `Settings > Keybindings > Bindings` is a keybinding discovery surface, not
21
- only a launch-toggle editor. It must show `Toggle Project Sidebar` with the
18
+ - `Settings > Keybindings` is a single action list plus a simple action detail.
19
+ It does not expose `Bindings`, `Diagnostic`, `Probe`, or `Init` as first-class
20
+ chips/tabs in the Settings root flow.
21
+ - `Settings > Keybindings` is a keybinding discovery surface, not only a
22
+ launch-toggle editor. It must show `Toggle Project Sidebar` with the
22
23
  guaranteed `Alt-1` / `M-1` default, plus sidebar-local commands, picker-local
23
24
  commands, `Pane navigation`, `Window navigation`, and `Rename` groups or
24
25
  equivalent searchable rows.
26
+ - `Settings > Keybindings > Action` keeps the user-facing edit path small:
27
+ action, current keybinding/aliases, `Add alias`, and reset. It does not offer
28
+ replace-primary, disable-default, typed-fallback, terminal mapping preview, or
29
+ terminal mapping apply rows.
30
+ - Terminal delivery remediation lives outside Settings primary flow. The
31
+ supported order is `projmux shell` first, then `projmux setup`, then
32
+ `projmux init` for supported terminal adapters.
25
33
  - Rows that cannot safely be edited still stay visible. Mark diagnostic-only
26
34
  rows with the delivery path and reason instead of hiding them or turning them
27
35
  into unsupported editable aliases. Transport-dependent rows stay visible with
@@ -54,9 +62,13 @@ view-first layout:
54
62
  runtime action values and writes only
55
63
  `${XDG_CONFIG_HOME:-$HOME/.config}/projmux/ai-hook-actions.json`. It does not
56
64
  edit catalog `install` values or run agent install/remove commands.
65
+ - `Settings > Session State > Sidebar startup picker` controls the Alt-1
66
+ project-open startup selector. The saved file remains
67
+ `${XDG_CONFIG_HOME:-$HOME/.config}/projmux/sidebar-startup-picker`, and the
68
+ stale `labs:sidebar-startup-picker` action opens this Session State detail.
57
69
  - `Settings > Labs` keeps experimental toggles, but keybindings no longer have a
58
- visible Labs row. The hidden compatibility action still redirects to the
59
- unified Keybindings page.
70
+ visible Labs row. The hidden compatibility action redirects to the
71
+ `Settings > Keybindings` action list, not to a diagnostic default.
60
72
  - `Settings > Labs > Project Hooks` is overview-first. The Labs root opens the
61
73
  overview, and the on/off mutation rows live one level deeper.
62
74
  - `Settings > AI Settings` is view-first. The root contains `Default split
@@ -99,5 +111,6 @@ Shell bootstrap UX is phase-split:
99
111
  - `projmux welcome` remains the stdout revisit command.
100
112
  - `Settings > About > Welcome` opens a visible native viewer independent of
101
113
  shell skip state.
102
- - Shell `skip_version` state applies only to the automatic `projmux shell`
103
- prompt; it does not hide manual revisit surfaces.
114
+ - Legacy shell `skip_version` state remains readable for compatibility but no
115
+ longer suppresses the automatic `projmux shell` prompt; release skips live in
116
+ `update-skip.json` and do not hide manual revisit surfaces.
package/docs/statusbar.md CHANGED
@@ -33,6 +33,28 @@ row 1 [#S] #{pane_current_path} ⎈ <ctx>/<ns> <git>  %H:%M
33
33
  clicks on tmux 3.4+, so a `run-shell` handler can't recover the
34
34
  target after the fact — the Go dispatcher's
35
35
  `isWindowListRangeToken` fallback is now defense-in-depth only.
36
+ Each window tab reserves a one-cell live pane attention prefix from
37
+ `projmux attention window #{window_id}` before the index. AI panes use the
38
+ semantic `@projmux_ai_badge_kind` first: approval/input-required panes use
39
+ the action-required amber-orange role, response-complete panes use the
40
+ non-critical success green role, and in-progress panes use the progress
41
+ yellow role. Red/critical is reserved for error, failure, and risk chrome;
42
+ permission or input-required status badges do not use it.
43
+ Legacy busy/reply title and attention-state markers remain the fallback, and
44
+ no-state windows render a blank placeholder so title alignment and click range
45
+ width stay stable. This live window-list badge is independent from the row-0
46
+ notify queue segment and from notify queue severity or desktop notification
47
+ urgency. For example, an approval request may remain a critical queued
48
+ notification while its live status badge renders action-required amber-orange.
49
+ Pane focus hooks and `projmux attention clear` consume only the
50
+ response-complete live badge, including stale `@projmux_ai_state=waiting`
51
+ fallback state; action-required and in-progress live badges remain visible.
52
+ Window-list badges and app pane-border badges use the same semantic priority,
53
+ with display style controlled by Settings > Appearance > AI badge style and persisted in
54
+ `~/.config/projmux/ai-badge-style`. The default is `dot`; `emoji` renders
55
+ `⏳` for approval/input-required, `✅` for response-complete, and `🔄` for
56
+ in-progress. `off` (also accepted as `minimal` when read from disk) preserves
57
+ the same spacing without drawing a marker.
36
58
  The session, pwd, kube, and git segments on this row are wrapped
37
59
  in `#[range=user|<id>]` ranges and dispatched through the projmux
38
60
  handler. The standalone config also wraps the right-side `projmux`
@@ -95,9 +117,10 @@ When the notify block is wider than its cell budget, clipping shrinks the body
95
117
  text first and appends an ellipsis while preserving project, state, agent, age,
96
118
  and count metadata. If the segment is still too wide, the age is dropped next
97
119
  while badges and the `+N` count stay visible when possible. Very narrow widths
98
- fall back to the severity-colored dot plus clipped text and count; the final
120
+ fall back to dotless clipped text plus the `+N` count when it fits; the final
99
121
  hard-truncate path still closes with `#[default]` so later status segments do
100
- not inherit notification styling.
122
+ not inherit notification styling. That dotless narrow fallback applies only to
123
+ the queued notify segment, not to the separate window-list live attention badge.
101
124
  `usage` opens a native-framed detail HUD for the compact usage bar. It reads
102
125
  the cached usage state in-process, keeps the existing `projmux usage` CLI
103
126
  output shape unchanged for external consumers, aligns model/window rows with
package/docs/testing.md CHANGED
@@ -54,3 +54,128 @@ desktop shell, or OS integration:
54
54
 
55
55
  Keep those checks as manual or host-run smoke validation until a dedicated
56
56
  host harness exists.
57
+
58
+ Use this smoke checklist when a change touches terminal delivery, host desktop
59
+ notifications, or reviewer confidence around those boundaries. If the change
60
+ does not touch those areas, copy the PR-note block below and mark the relevant
61
+ rows `not run`.
62
+
63
+ ### Terminal Key Delivery
64
+
65
+ Run the raw key probe outside tmux, in the terminal emulator being claimed:
66
+
67
+ ```sh
68
+ projmux setup --timeout 10s
69
+ ```
70
+
71
+ Observe:
72
+
73
+ - `Alt-1` through `Alt-5` report `OK plain`. These are the guaranteed
74
+ zero-config launch defaults.
75
+ - If a guaranteed key reports `MISS timeout`, preview a supported terminal
76
+ mapping with `projmux init ghostty` or `projmux init windows-terminal`,
77
+ apply it with the same command plus `--apply`, restart that terminal if
78
+ required, and rerun `projmux setup --timeout 10s`.
79
+ - Optional direct aliases and transport-dependent chords may be reported by
80
+ the probe, but they are not part of the guaranteed host smoke unless the PR
81
+ explicitly changes them.
82
+
83
+ Then run the app in the same terminal:
84
+
85
+ ```sh
86
+ projmux shell
87
+ ```
88
+
89
+ Observe:
90
+
91
+ - `Alt-1` opens the project sidebar.
92
+ - `Alt-2` opens the notification sidebar.
93
+ - `Alt-3` opens the existing-session picker.
94
+ - `Alt-4` opens the AI split picker.
95
+ - `Alt-5` opens Settings.
96
+ - Pressing the same launch key again closes the popup instead of typing escape
97
+ bytes into the shell or picker input.
98
+
99
+ ### WSL Toast
100
+
101
+ Run this from WSL with Windows Terminal available. The detached tmux server is
102
+ intentional: `projmux focus` falls back to the product desktop notification
103
+ path when there is no attached client to switch.
104
+
105
+ ```sh
106
+ sock="${TMPDIR:-/tmp}/projmux-host-smoke.sock"
107
+ tmux -S "$sock" kill-server 2>/dev/null || true
108
+ tmux -S "$sock" new-session -d -s projmux-host-smoke 'sleep 600'
109
+ PROJMUX_DESKTOP_NOTIFY_MODE=notify \
110
+ projmux focus --socket "$sock" --target projmux-host-smoke --json
111
+ tmux -S "$sock" kill-server
112
+ ```
113
+
114
+ Observe:
115
+
116
+ - The JSON includes `"ok":true`, `"dispatch":"notify-only"`, and
117
+ `"reason":"no-attached-client"`.
118
+ - Windows shows a short projmux toast with `session ready:
119
+ projmux-host-smoke`.
120
+ - In `notify` mode, the toast has no click-to-focus action and should not
121
+ auto-raise the host terminal.
122
+ - No visible PowerShell or console window remains open after the toast.
123
+
124
+ If the PR changes click-to-focus behavior, repeat with
125
+ `PROJMUX_DESKTOP_NOTIFY_MODE=raise`, click the toast, and record whether the
126
+ host terminal returns to the target. `raise` should also be the only mode where
127
+ `projmux focus` performs post-switch osfocus. Otherwise leave click callbacks
128
+ marked as manual/not run.
129
+
130
+ ### macOS GUI Notification
131
+
132
+ The built-in desktop sender is Linux/WSL-oriented. On macOS, smoke the
133
+ documented `PROJMUX_NOTIFY_HOOK` escape hatch with an `osascript` sender:
134
+
135
+ ```sh
136
+ hook="${TMPDIR:-/tmp}/projmux-macos-notify.sh"
137
+ cat >"$hook" <<'SH'
138
+ #!/bin/sh
139
+ title=${1:-projmux}
140
+ body=${2:-}
141
+ osascript \
142
+ -e 'on run argv' \
143
+ -e 'display notification (item 2 of argv) with title (item 1 of argv)' \
144
+ -e 'end run' \
145
+ "$title" "$body"
146
+ SH
147
+ chmod 0755 "$hook"
148
+
149
+ sock="${TMPDIR:-/tmp}/projmux-host-smoke.sock"
150
+ tmux -S "$sock" kill-server 2>/dev/null || true
151
+ tmux -S "$sock" new-session -d -s projmux-host-smoke 'sleep 600'
152
+ PROJMUX_NOTIFY_HOOK="$hook" \
153
+ projmux focus --socket "$sock" --target projmux-host-smoke --json
154
+ tmux -S "$sock" kill-server
155
+ ```
156
+
157
+ Observe:
158
+
159
+ - The JSON includes `"ok":true`, `"dispatch":"notify-only"`, and
160
+ `"reason":"no-attached-client"`.
161
+ - macOS shows a Notification Center banner with `session ready:
162
+ projmux-host-smoke`.
163
+ - If macOS prompts for notification permission, record that state in the PR
164
+ instead of treating the product command as verified.
165
+
166
+ ### PR Note Template
167
+
168
+ ```markdown
169
+ Host-only smoke validation:
170
+
171
+ - Docker-covered checks: `make test-integration`, `make test-install-smoke`,
172
+ and `make test-e2e` cover portable Linux tmux/config/notify behavior only.
173
+ - Terminal key delivery: not run / run on <terminal>; `projmux setup --timeout
174
+ 10s` showed <result>; `Alt-1..5` app popup smoke <passed/failed/not run>.
175
+ - WSL toast: not run / run on <Windows + WSL distro>; detached-focus smoke
176
+ produced `dispatch=notify-only`; observed <toast/no toast/notes>.
177
+ - macOS GUI notification: not run / run on <macOS version>; hook smoke
178
+ produced `dispatch=notify-only`; observed <banner/permission prompt/notes>.
179
+ - Desktop notification click callbacks: not run unless this PR changes
180
+ click-to-focus behavior; result <notes>.
181
+ ```
@@ -41,6 +41,14 @@ onto these stable names:
41
41
  | `critical` | destructive/error/critical state | settings remove/quit, notify critical badge, statusbar critical usage |
42
42
  | `warning` | progress, pending, warning, busy state | AI busy/thinking indicators, notify pending title, usage warning |
43
43
 
44
+ AI semantic status badges use renderer-only state roles layered on top of that
45
+ inventory: `progress`, `success`, and `action_required`. The fallback contract
46
+ is progress yellow, success green, action-required amber-orange. These roles are
47
+ separate from notify queue severity and desktop notification urgency; an AI
48
+ approval row can be `critical` in the notify queue while the live status badge
49
+ uses `action_required`, not red. `critical` remains reserved for error, failure,
50
+ destructive, over-limit, or risk states.
51
+
44
52
  Renderer-only role names such as `accent.ai`, `state.progress`, `git.branch`,
45
53
  and trust colors remain in `internal/theme/palette.go` until Phase 2+ maps each
46
54
  surface to the resolver tokens. The key product contract for this phase is that
@@ -127,10 +135,11 @@ Accents and state:
127
135
  | `accent.action` | `141;205;142`, strong `122;199;173` | `colour29` bg / `colour230` fg |
128
136
  | `accent.attention` | notify HUD background/project family | `colour53`, project `colour90` |
129
137
  | `accent.ai` | notify agent `colour37` family | `colour37` bg / `colour121` fg |
130
- | `state.progress` | `255;204;102`; switch attention/busy dot and pending notify title/bell/badge `colour220` | `colour220` |
131
- | `state.warning` | usage/status popup ANSI 256 wrapper | `colour214` |
138
+ | `state.progress` | `255;204;102`; switch attention/busy dot, pane-border in-progress badge, and pending notify title/bell/badge `colour220` | `colour220` |
139
+ | `state.action_required` | AI approval/input-required status badge amber-orange; currently aliases the established warning token | `colour214` |
140
+ | `state.warning` | usage/status popup warning ANSI 256 wrapper; non-AI warning chrome | `colour214` |
132
141
  | `state.danger` | `255;107;107` | `colour160` |
133
- | `state.success` | settings/trust green families | `colour72`, `colour151` |
142
+ | `state.success` | settings/trust green families; pane-border response-complete badge | `colour72`, `colour151` |
134
143
  | `state.ahead` | switch/git metadata and notify age ANSI 256 wrapper | `colour153` |
135
144
  | `git.branch` | switch/sidebar branch badge uses the statusbar git branch block colors | `colour30` bg / `colour231` fg |
136
145
 
@@ -140,6 +149,7 @@ Surface-specific tokens:
140
149
  | --- | --- |
141
150
  | Native picker | current row, titlebar, rule, pointer, highlight, muted text, chip active/inactive/disabled |
142
151
  | Statusbar row 1 | session identity, cwd secondary text, divider, git branch block, git dirty/staged/ahead/behind, settings action chip, clock |
152
+ | App pane borders | semantic AI badge marker style (`dot`, `emoji`, or spacing-preserving `off`) plus action-required/success/progress state color |
143
153
  | Notify HUD/sidebar | line bg/fg, project badge, info/warn/crit/stale/gone badges, AI agent badge, count/age text |
144
154
  | Usage HUD/popup | OK/warning/critical/over-limit bars and numbers, empty cells, muted sync age |
145
155
  | Settings | add/type/open action, destructive remove/quit, back/cancel, info/read-only, dim description, root action/dim rows, trust trusted/stale/untrusted |
package/docs/upgrading.md CHANGED
@@ -3,13 +3,14 @@
3
3
  projmux has two update surfaces:
4
4
 
5
5
  - `projmux shell` reads the cached release status before opening the app. When
6
- the cache is fresh and a newer release is available, startup shows a picker
7
- with Update Now, Later, and Skip This Version actions.
6
+ the cache is missing or stale, startup attempts a short best-effort refresh
7
+ and continues if it fails. When a newer release is available, the shell
8
+ welcome offers Continue, Upgrade, and Skip until next actions.
8
9
  - Settings > About > Update shows the current version, detected installer,
9
10
  cached latest version, Check Updates, and Update Now actions.
10
11
 
11
- Startup never reaches the network. Refresh the cache explicitly when you want
12
- projmux to check GitHub Releases:
12
+ Refresh the cache explicitly when you want a full foreground GitHub Releases
13
+ check:
13
14
 
14
15
  ```sh
15
16
  projmux update check
@@ -24,6 +25,11 @@ projmux update apply
24
25
  Use `--dry-run` to see the planned action and `--no-apply` to skip reloading
25
26
  the live tmux config after the binary changes.
26
27
 
28
+ Shell Upgrade invokes only `projmux update apply`. Shell Skip until next stores
29
+ the current latest release tag in `update-skip.json`; the prompt appears again
30
+ when the cached latest tag changes. For `source` and unknown installer sources,
31
+ Upgrade prints guidance and continues shell entry without applying anything.
32
+
27
33
  ## npm Installs
28
34
 
29
35
  The recommended install path is:
@@ -1,10 +1,26 @@
1
1
  # Usage tracking
2
2
 
3
3
  `projmux usage` and `projmux status usage` report authoritative 5-hour
4
- and weekly utilisation for both Claude Code and the Codex CLI. Both
5
- adapters read from the upstream's own view of the account so the
4
+ and weekly utilisation for enabled AI agents. `--model all`, the tmux
5
+ HUD, and the statusbar usage popup use Settings > AI Settings > Enabled
6
+ agents as the source of truth, so disabled Claude/Codex providers are
7
+ not refreshed or rendered on ambient/all surfaces. Explicit read-only
8
+ requests such as `projmux usage --model claude` or `--model codex`
9
+ still collect and render that provider even when it is disabled.
10
+
11
+ Both adapters read from the upstream's own view of the account so the
6
12
  percentages match what `claude /usage` and `codex` show natively.
7
13
 
14
+ Antigravity is intentionally not registered as a 5-hour/weekly quota adapter.
15
+ The only stable Phase 0b usage signal is statusline `context_window`, which is
16
+ conversation context-window usage, not account quota usage. `projmux usage
17
+ --model antigravity` and ambient all-model table output therefore render an
18
+ explicit unsupported note when Antigravity is enabled. The statusbar usage
19
+ popup shows an `Antigravity ctx ... unsupported` row, while the compact tmux
20
+ status segment stays silent unless Claude/Codex quota rows exist. Projmux does
21
+ not infer quota, reset timestamps, or account limits from screen scraping,
22
+ tokens, history, OAuth/cache files, or binary strings.
23
+
8
24
  ## Adapters
9
25
 
10
26
  ### Claude (`internal/core/usage/adapters/claude`)
@@ -79,12 +95,13 @@ across machines (Dropbox, iCloud Drive).
79
95
  ### `projmux usage`
80
96
 
81
97
  ```
82
- projmux usage [--model codex|claude|all] [--window 5h|weekly|all]
98
+ projmux usage [--model codex|claude|antigravity|all] [--window 5h|weekly|all]
83
99
  [--json] [--force|-f]
84
100
  ```
85
101
 
86
- Calls `Manager.Collect` (or `ForceCollect` with `--force`), filters by
87
- model/window, and renders the tab-aligned table:
102
+ For `--model all`, calls `Manager.Collect` (or `ForceCollect` with
103
+ `--force`) only for providers enabled in Settings > AI Settings >
104
+ Enabled agents, filters by window, and renders the tab-aligned table:
88
105
 
89
106
  ```
90
107
  MODEL WINDOW PCT RESETS_AT STALE
@@ -103,16 +120,27 @@ instead. A backoff note is appended to the human table:
103
120
  claude is in backoff, try again in 30m (use --force to bypass)
104
121
  ```
105
122
 
123
+ When no AI agents are enabled, all-model table output contains no
124
+ provider rows and prints a short Settings hint. `--json` returns an
125
+ empty array. Explicit `--model claude` and `--model codex` bypass the
126
+ enabled-agent filter for read-only inspection and collect/render only
127
+ the requested adapter. Explicit `--model antigravity` renders the same
128
+ unsupported/context-window-only note even when Antigravity is disabled, because
129
+ there is no supported Antigravity quota adapter to collect.
130
+
106
131
  ### `projmux status usage`
107
132
 
108
133
  ```
109
134
  projmux status usage [--max-width N] [--force|-f]
110
135
  ```
111
136
 
112
- The HUD bar wired to the tmux status interval. Triggers an
113
- opportunistic refresh: `MaybeCollect(throttle=30s)` (subject to
114
- per-adapter throttle and active backoff). Errors are swallowed unless
115
- `PROJMUX_USAGE_DEBUG` is set. Then loads the cache and renders.
137
+ The HUD bar wired to the tmux status interval. It scopes the registry to
138
+ enabled AI agents, then triggers an opportunistic refresh:
139
+ `MaybeCollect(throttle=30s)` (subject to per-adapter throttle and active
140
+ backoff). Disabled providers are not refreshed just to be hidden. Errors
141
+ are swallowed unless `PROJMUX_USAGE_DEBUG` is set. Then it loads the
142
+ cache, filters to the same enabled-agent scope, and renders. If no AI
143
+ agents are enabled, the status segment emits nothing.
116
144
 
117
145
  Output degrades through six tiers as `--max-width` shrinks:
118
146
 
@@ -132,10 +160,11 @@ because the rollout file is always near-current (no throttle gap to report).
132
160
  ### Statusbar usage popup
133
161
 
134
162
  `projmux statusbar click usage` renders a native-framed popup from the same
135
- cache instead of shelling out to `projmux usage`. This keeps `projmux usage
136
- --json` backwards-compatible for CLI consumers while giving the tmux click path
137
- a structured table with aligned rows, right-aligned numeric values, dim
138
- unavailable cells, amber usage at 80%, and red usage at 95%.
163
+ cache instead of shelling out to `projmux usage`. The popup filters rows and
164
+ sync metadata to the same enabled-agent scope as the ambient HUD. This keeps
165
+ `projmux usage --json` backwards-compatible for CLI consumers while giving the
166
+ tmux click path a structured table with aligned rows, right-aligned numeric
167
+ values, dim unavailable cells, amber usage at 80%, and red usage at 95%.
139
168
 
140
169
  The popup sync line uses the maximum authoritative `LastCollect` timestamp from
141
170
  the cache. If that field is unavailable, it falls back to the snapshots file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "projmux",
3
- "version": "0.6.5",
3
+ "version": "0.6.7",
4
4
  "description": "tmux project session manager",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/crevissepartners/projmux#readme",
@@ -23,14 +23,14 @@
23
23
  "README-ko.md",
24
24
  "LICENSE"
25
25
  ],
26
- "optionalDependencies": {
27
- "@projmux/darwin-arm64": "0.6.5",
28
- "@projmux/darwin-x64": "0.6.5",
29
- "@projmux/linux-arm64": "0.6.5",
30
- "@projmux/linux-x64": "0.6.5"
31
- },
32
26
  "scripts": {
33
27
  "package:npm": "scripts/package-npm.sh",
34
28
  "package:npm:pack": "scripts/package-npm.sh --pack"
29
+ },
30
+ "optionalDependencies": {
31
+ "@projmux/linux-x64": "0.6.7",
32
+ "@projmux/linux-arm64": "0.6.7",
33
+ "@projmux/darwin-x64": "0.6.7",
34
+ "@projmux/darwin-arm64": "0.6.7"
35
35
  }
36
36
  }