projmux 0.5.3 → 0.6.1

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.
@@ -29,15 +29,27 @@
29
29
  - `make fmt`: repository formatting for Go, shell snippets, and generated docs where applicable.
30
30
  - `make fix`: safe automatic fixes such as `go fix` and repository-approved cleanup steps.
31
31
  - `make npm-pack`: local npm binary package staging and `npm pack --dry-run` for the root package plus platform packages.
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/pane-startup/post-attach with project hook and .projmux/config.toml trust-store hashing plus env/settings kill-switch gating, declarative startup/hook run precedence, project config env/kube session environment application, Settings project config env/kube/startup form writes with trust-store refresh and preserved hook commands, pane-startup command capture/send-keys orchestration, 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 branch block styling, statusbar pwd display-only native-framed path popup, no clipboard or tmux buffer copy, and simple Enter-close popup command, statusbar usage native HUD popup alignment/threshold/sync-staleness/fallback coverage without raw CLI popup or popup-toggle stacking, statusbar settings click popup fallback, isolated `projmux shell` tmux app launch/config generation including home-project default session targeting, app-owned project-name statusbar layout, and distinct project badge color, first-run/version-bump shell welcome state and inline update handling, shell startup update prompt actions for fresh installer-aware cached updates, pane/window keybindings, keymap.toml tmux override rendering/stale unbinds, Settings Keybindings root/list/detail/typed edit flows including parse-error rows, invalid chord and typed-cancel 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, 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, 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 resume replay, candidate discovery, config path derivation, popup preview read-models, and pure state rules including preview, tag, and lifecycle stores.
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 branch block styling, statusbar pwd display-only native-framed path popup, no clipboard or tmux buffer copy, and simple Enter-close popup command, statusbar usage native HUD popup alignment/threshold/sync-staleness/fallback coverage without raw CLI popup or popup-toggle stacking, statusbar settings click popup fallback, 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, first-run/version-bump shell welcome state and inline update handling, shell startup update prompt actions for fresh installer-aware cached updates, pane/window keybindings, keymap.toml tmux override rendering/stale unbinds, 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, 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 resume and declarative startup replay, session snapshot capture/autosave recipe classification including save/autosave pre-capture resume metadata refresh from live AI session 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
+ - `make test` also covers Settings IA regression guards for `send-noti` visibility in Hooks, no nested Project recipe inside Hooks, Project recipe/AI/Labs view-first detail rows, Notifications root/Desktop notifications/Delivery sources relocation, Delivery sources command-row clipboard copy, and Labs Project Hooks overview-first rows.
34
+ - `make test` also covers Settings > Session State as global settings-only UI with default-off auto-save and no window/pane tree, Settings > Project > Session State project-derived identity plus project auto-save override/effective source rows and distinct Save latest snapshot / Save named snapshot labels, closed-project save disabled reasons, named snapshot portable path conversion, project/global auto-save precedence, Projects > Sessions > State read-only latest/named snapshot overview with window/pane cwd/recipe/agent-resume health, user-facing `projmux session-state` status/save/delete/restore dry-run actions including explicit manual save bypass of disabled autosave and agent resume status/confidence preview, and Project open sidebar startup coverage for Labs opt-in `Start project`, default-off empty creation, Latest snapshot, Named snapshot, Empty session, Back, saved-at row metadata, existing-session skip, startup-before-trust ordering, trust approve continuation, and trust deny/cancel no-session behavior.
35
+ - `make test` also covers `projmux shell` usage without startup selector flags, project-context default target lookup from `PROJMUX_CWD` or nearest project marker, explicit `--session` separation from project-derived defaults, and direct empty attach behavior without shell startup picker/replay.
36
+ - `make test` also covers manual Session State Save snapshot and restore dry-run preview actions, title-first pane preview labels with legacy snapshot fallback, missing-snapshot messaging, and the absence of the removed statusbar State shortcut.
37
+ - `make test` also covers legacy named-snapshot storage compatibility for `.projmux/layouts/*.toml`, supported interpolation validation, malformed-file list warnings, portable conversion helpers, dry-run conversion to the session-state restore preview with source labels, missing current-session failure, destructive live replay helper behavior with fresh/internal source marking and fresh saved-snapshot cleanup, and the session-state live replay helper that stages windows, moves them by tmux ID, and removes extra live windows.
38
+ - `make test` also covers `projmux ai integrate codex` default hooks install/idempotence/dry-run/removal, compatibility legacy Codex notify mode install/idempotence, dry-run preview, unmanaged `notify = ...` conflict refusal, managed-block removal, catalog-driven Codex hook event installation with local override merging, nested inline Codex hook schema, `[features]` merge/preservation, preservation of unrelated Codex/Claude config and unmanaged hook entries, Settings Codex `/hooks` review notice and tested-version rows, and remove-all behavior for projmux-managed Codex blocks.
39
+ - `make test` also covers `projmux ai ingest codex-hook` event parsing, PermissionRequest critical queue rows with tool/action metadata, Stop info queue rows, UserPromptSubmit busy/no-queue behavior, quiet/no-notify diagnostics for non-firing Codex hook events including override-added catalog events, cataloged hook notification body formatting, hook-active pane marking, topic preservation without hook candidate writes, and mutable resume metadata writes for `@projmux_ai_resume_id`, source, and updated-at.
40
+ - `make test` also covers `projmux ai integrate claude` user-level Claude Code hook settings install/idempotence, dry-run preview, unmanaged projmux ingest command conflict refusal across all settings events, managed-command removal by marker even for stale events outside the current catalog, preservation of unrelated settings/hooks, catalog-driven Claude hook event installation with local override merging, and managed wiring for the 29 Claude Code 2.1.140 events in the embedded default catalog.
41
+ - `make test` also covers `projmux ai ingest claude-hook` core and extra Claude Code hook ingest for event parsing, transcript fallback, cataloged hook notification body formatting, permission summary formatting, UserPromptSubmit busy/no-queue behavior, Notification severity/text mapping, StopFailure/TeammateIdle text/severity/metadata mapping, SubagentStop quiet/no-notify diagnostics, unknown future-event quiet fallback, hook-active pane marking, topic preservation without hook candidate writes, mutable resume metadata writes for `@projmux_ai_resume_id`, source, and updated-at, and Claude transcript path preservation.
42
+ - `make test` also covers `projmux ai integrate tmux-bell` dry-run/install/remove tmux command planning, managed `alert-bell` hook append/idempotence/removal, preservation of unmanaged bell hooks, and `projmux ai ingest bell --pane` queue push/metadata/dedupe behavior for non-AI-managed panes.
43
+ - `make test` also covers `projmux ai ingest log` tail/path rendering and bounded JSONL log trimming for ingest diagnostics.
44
+ - `make test` also now covers onboarding revisit and welcome wiring (`projmux welcome`, `Settings > About > Welcome`, `pending_attach_welcome`, attach-time `welcome --popup` one-time claim/env suppression/tmux popup payload, and generated `client-attached` app config wiring) via shell welcome tests.
33
45
  - Current focused unit coverage also includes strict notify SOT behavior
34
- (TTL does not remove rows, focus success acks, reconcile reports stale
35
- rows), `notify list --live` queue/live explanations, notify sidebar
46
+ (TTL does not remove rows, focus success and target-gone clicks ack,
47
+ reconcile reports stale rows), `notify list --live` queue/live explanations, notify sidebar
36
48
  two-line card rendering with age/project/window/pane metadata plus focus/ack/clear-all
37
49
  actions, and `focus` dispatch diagnostics for session fallback, unresolved
38
- targets, window fallback, pane fallback, explicit id failures, and
50
+ targets, window fallback, pane fallback, explicit id failures as unresolved exits, and
39
51
  notify-only fallback.
40
- - Picker focused unit coverage includes backend-neutral picker item/action mapping, native title-focused filtering, numeric selection, shared close actions including raw and CSI-u Ctrl-X native custom actions, deprecated picker backend value normalization, AI picker title chrome and stable search-key ordering, Settings title chrome and root section order, Settings Labs shell without backend choices plus keybinding diagnostic list/detail/probe outcome/init delegation coverage, environment override normalization, compact multi-line metadata gutters with one-column-indented metadata, proportional native scrollbar thumb rendering, multiline partial next/previous item row rendering with rendered-row scrollbar units, fixed split-preview and sidebar list viewports with scrollbar tracks, native up/down-family navigation wrap with empty-list safety and PageUp/PageDown/Home/End clamp regression coverage, native mouse down/follow-drag/release behavior, preview tab/control normalization before width clipping, optional native frame titlebars without same-line rule fill, titled native Alt-1 sidebar chrome, statusbar-preserving sidebar popup height, native-only compact project sidebar popup sizing, and notify sidebar title/popup sizing.
52
+ - Picker focused unit coverage includes backend-neutral picker item/action mapping, native title-focused filtering, numeric selection, shared close actions including raw and CSI-u Ctrl-X native custom actions, deprecated picker backend value normalization, AI picker title chrome and stable search-key ordering, Settings title chrome and root section order, Settings Labs shell without backend choices plus keybinding diagnostic list/detail/probe outcome/init delegation coverage, environment override normalization, compact multi-line metadata gutters with one-column-indented metadata, proportional native scrollbar thumb rendering, multiline partial next/previous item row rendering with rendered-row scrollbar units, fixed split-preview and sidebar list viewports with scrollbar tracks, native up/down-family navigation wrap with empty-list safety and PageUp/PageDown/Home/End clamp regression coverage, native mouse down/follow-drag/release behavior, preview tab/control normalization before width clipping, optional native frame titlebars without same-line rule fill and with titlebar border reset guards, titled native Alt-1 sidebar chrome, statusbar-preserving sidebar popup height, native-only compact project sidebar popup sizing, and notify sidebar title/popup sizing.
41
53
  - `make test-integration`: Docker-backed Linux integration smoke with real `tmux`, `git`, and `stty`; covers `doctor`, tmux config print/install/apply, and notify queue CRUD against isolated HOME/XDG paths.
42
54
  - `make test-install-smoke`: Docker-backed source install smoke; covers `make install`, atomic binary replacement, `tmux apply` against a live `projmux` socket, and post-install notify queue initialization.
43
55
  - `make test-e2e`: Docker-backed real-tmux workflow smoke for session/pane setup, app config sourcing, reply-state notify reconciliation, focus notify fallback, and status notify rendering with contextual project/state/agent badges. Host-only terminal, WSL, macOS, and GUI notification behavior remains outside Docker; see [docs/testing.md](testing.md).
package/docs/cli.md CHANGED
@@ -43,6 +43,7 @@ projmux <command> [args...]
43
43
  | `tmux` | Open tmux popup entry helpers / install generated config. |
44
44
  | `update` | Check installer-aware GitHub release update status. |
45
45
  | `upgrade` | Self-update via `go install`. |
46
+ | `welcome` | Print the shell onboarding guide again. |
46
47
  | `usage` | Report AI token usage across 5h and weekly windows. |
47
48
  | `version` | Print the current version. |
48
49
 
@@ -102,20 +103,38 @@ projmux doctor --install-missing [--dry-run] [--include-optional]
102
103
  ```
103
104
 
104
105
  Runs a dependency check: `tmux ≥ 3.4`, `git`, `stty` (POSIX only), and
105
- `kubectl` (optional). Exit code `0` even when optional deps are missing;
106
+ `kubectl` (optional), then reports read-only AI notify integration diagnostics
107
+ for Codex hooks, Claude Code hooks, and the tmux bell
108
+ fallback. AI notify integration statuses are `installed`, `missing`, or
109
+ `conflict`; missing or conflicting integrations are informational and do not
110
+ make doctor fail. It also reports read-only Session State resume metadata
111
+ diagnostics for saved agent panes, including `available`, `stale`, or
112
+ `unavailable` status plus confidence, source, updated-at, and the affected
113
+ snapshot/window/pane.
114
+
115
+ Exit code `0` even when optional deps or AI notify integrations are missing;
106
116
  non-zero only when a required dep is missing or stale. `--json` emits a
107
- machine-readable array; the default is the human report with suggested install
108
- commands per platform. `--install-missing` is explicit opt-in and runs
109
- generated install commands only for missing or stale required dependencies.
110
- `--dry-run` prints those commands without executing them. `--include-optional`
111
- also includes optional missing dependencies such as `kubectl` when an install
112
- command is available. Install flags cannot be combined with `--json`. Doctor
113
- does not diagnose terminal key delivery; use `projmux setup` for that.
117
+ machine-readable object with `dependencies`, `ai_notify_integrations`, and
118
+ `session_state_resume`; the default is the human report with suggested install
119
+ commands per platform, AI integration install/remove/dry-run commands, and
120
+ Session State resume metadata health. `--install-missing` is explicit opt-in
121
+ and runs generated install commands only for missing or stale required
122
+ dependencies. `--dry-run` prints those commands without executing them.
123
+ `--include-optional` also includes optional missing dependencies such as
124
+ `kubectl` when an install command is available. Install flags cannot be combined
125
+ with `--json`. Doctor does not diagnose terminal key delivery; use `projmux
126
+ setup` for that.
127
+
128
+ `Settings > Notifications > Delivery sources` shows active Codex hooks, Claude,
129
+ and tmux statuses, conflicts, config paths, and copyable AI integration
130
+ install/remove/dry-run commands. Settings does not install or remove external
131
+ Codex, Claude, or tmux notify wiring.
114
132
 
115
133
  ## focus
116
134
 
117
135
  ```
118
136
  projmux focus --target SESSION[:WINDOW[.PANE]] [--socket <path>]
137
+ [--client <tty>]
119
138
  [--source ai|status-bar|external|os-notification|toast]
120
139
  [--kind reply-ready|busy-cleared|segment-click|toast-click|custom]
121
140
  [--json]
@@ -130,6 +149,12 @@ client is attached on that socket, it emits the configured desktop
130
149
  notification instead. `--socket` is explicit; when omitted, the socket is
131
150
  derived from `$TMUX`.
132
151
 
152
+ `--client` is a preferred origin tmux client. In-app consumers such as the
153
+ status bar and notify sidebar pass the clicked client so focus redirects that
154
+ display first. If that client is gone, focus falls back to an attached client
155
+ already viewing the target session, then the stable first attached client.
156
+ Toast clicks do not pass `--client`.
157
+
133
158
  `--uri` is the entry point used by the WSL Toast click handler (see
134
159
  [configuration.md](configuration.md#toast-click-handler-wsl--windows-terminal)).
135
160
  The pane id from the URI is resolved to a `SESSION:WINDOW.%paneID` target
@@ -140,7 +165,8 @@ via `tmux display-message`, and the URI's `socket` overrides any
140
165
  Exit codes:
141
166
 
142
167
  - `0` — focused (or the notify-only fallback fired).
143
- - `2` — target session could not be resolved (`focusExitNotResolved`).
168
+ - `2` — target session/window/pane could not be resolved
169
+ (`focusExitNotResolved`).
144
170
 
145
171
  `--source`/`--kind` are telemetry labels logged when
146
172
  `PROJMUX_FOCUS_DEBUG` is set. `--json` prints a single-line JSON payload
@@ -150,7 +176,7 @@ distinguish unresolved sessions (`reason=session-unresolved`, exit 2),
150
176
  session rename/prefix fallback (`session_state=fallback`), window index
151
177
  fallback (`window_state=index-fallback-session`), pane index fallback
152
178
  (`pane_state=index-fallback-window`), and explicit id failures
153
- (`window-id-unresolved` / `pane-id-unresolved`).
179
+ (`window-id-unresolved` / `pane-id-unresolved`, exit 2).
154
180
 
155
181
  ## notify
156
182
 
@@ -164,7 +190,7 @@ projmux notify push --text <s> --target <SESSION[:WINDOW[.PANE]]>
164
190
  [--socket <s>] [--severity info|warn|critical]
165
191
  [--source ai|k8s|git|external] [--ttl <seconds>]
166
192
  [--id <s>] [--json]
167
- projmux notify list [--live] [--json] [--limit N] [--ui table|sidebar]
193
+ projmux notify list [--live] [--json] [--limit N] [--ui table|sidebar] [--client <tty>]
168
194
  [--severity ...] [--source ...]
169
195
  projmux notify ack <id> | --all
170
196
  projmux notify reconcile [--json]
@@ -173,7 +199,10 @@ projmux notify reconcile [--json]
173
199
  - `push` — append (or refresh, with `--id`) one entry. `--ttl` defaults to
174
200
  `600` seconds as freshness metadata; it does not remove rows from
175
201
  `notify list`. `--text` is hard-capped to 80 runes (longer text is
176
- truncated server-side).
202
+ truncated server-side). After a successful queue write, projmux fires
203
+ declarative `[hooks.send-noti]` asynchronously if configured. That hook gets
204
+ a JSON payload on stdin plus `PROJMUX_NOTIFY_*` env vars, and it does not
205
+ replace the normal desktop notification path.
177
206
  - `list` — newest-first pending queue table `ID AGE SEV SRC TARGET TEXT`
178
207
  (or JSON). `--severity` and `--source` are repeatable filters.
179
208
  `--live` adds a non-mutating explanation table (or JSON report) that
@@ -185,7 +214,8 @@ projmux notify reconcile [--json]
185
214
  acks the selected row, and `Ctrl-X` clears all; opening or navigating the
186
215
  sidebar does not ack. The sidebar uses two-line cards with notification text
187
216
  first and compact age/project/window/pane metadata below. Hidden queue ids
188
- remain action values, but the sidebar has no search input.
217
+ remain action values, but the sidebar has no search input. `--client` is
218
+ used by tmux popup launchers to keep row-select focus on the clicked client.
189
219
  - `ack <id>` removes one entry; `--all` flushes the queue.
190
220
  - `reconcile` — walks `tmux list-panes -a` and back-fills entries for
191
221
  panes whose attention state is `reply` AND whose AI agent option is
@@ -294,6 +324,13 @@ projmux ai settings
294
324
  projmux ai status set <thinking|waiting|idle> [--pane <id>]
295
325
  projmux ai notify <reset|notify> [--pane <id>]
296
326
  projmux ai watch-title [--pane <id>]
327
+ projmux ai ingest codex-hook < payload.json
328
+ projmux ai ingest claude-hook < payload.json
329
+ projmux ai ingest bell --pane <pane_id>
330
+ projmux ai ingest log [--tail N] [--json] [--path]
331
+ projmux ai integrate codex [--dry-run] [--remove]
332
+ projmux ai integrate claude [--dry-run] [--remove]
333
+ projmux ai integrate tmux-bell [--dry-run] [--remove]
297
334
  projmux ai topic ...
298
335
  ```
299
336
 
@@ -303,6 +340,211 @@ notifier. `status set waiting` is the trigger that flips a pane to the
303
340
  reply-ready state — that transition pushes an `ai:<session>:<pane>`
304
341
  entry into the notify queue.
305
342
 
343
+ `ingest codex-hook` is the hook-facing entrypoint for Codex hooks-engine JSON.
344
+ It reads one JSON payload from stdin and handles the default Codex hook catalog
345
+ `PreToolUse`, `PermissionRequest`, `PostToolUse`, `PreCompact`, `PostCompact`,
346
+ `SessionStart`, `UserPromptSubmit`, and `Stop` as exposed by Codex CLI 0.130.0.
347
+ It accepts the common Codex hook fields `hook_event_name`/`event_name`,
348
+ `thread_id`, `session_id`, `turn_id`, `cwd`, `transcript_path`, `model`,
349
+ `tool_name`, nested `tool.name`, `tool_input`, and `input`. `UserPromptSubmit`
350
+ marks the matched pane hook-active and moves it to thinking/busy without
351
+ pushing a queue entry. `Stop` pushes an info completion row. `PermissionRequest`
352
+ pushes a critical approval row with the tool name and concise action summary.
353
+ The other Codex events are quiet: they mark the pane hook-active and write
354
+ ingest diagnostics, but do not push notify queue entries.
355
+ For event names without a specialized notify/state handler, ingest falls back
356
+ to quiet/log-only handling. A local catalog entry with `"action": "quiet"`
357
+ therefore lets newly discovered events be installed and observed without
358
+ creating notification noise; `"notify"` and `"state"` still require a built-in
359
+ handler before they can change pane state or push queue rows.
360
+
361
+ `ingest claude-hook` is the hook-facing entrypoint for Claude Code hooks. It
362
+ reads one JSON payload from stdin and handles the default Claude Code 2.1.140
363
+ hook catalog: `PreToolUse`, `PostToolUse`, `PostToolUseFailure`,
364
+ `PostToolBatch`, `PermissionDenied`, `Notification`, `UserPromptSubmit`,
365
+ `UserPromptExpansion`, `SessionStart`, `Stop`, `StopFailure`,
366
+ `SubagentStart`, `SubagentStop`, `PreCompact`, `PostCompact`, `SessionEnd`,
367
+ `PermissionRequest`, `Setup`, `TeammateIdle`, `TaskCreated`,
368
+ `TaskCompleted`, `Elicitation`, `ElicitationResult`, `ConfigChange`,
369
+ `InstructionsLoaded`, `WorktreeCreate`, `WorktreeRemove`, `CwdChanged`, and
370
+ `FileChanged`. It uses the same pane matching order as Codex ingest
371
+ (`$TMUX_PANE`, payload `cwd`, then cached session id), marks matched panes
372
+ hook-active, and writes metadata-bearing notify queue entries only for
373
+ reply-ready, input-ready, approval-required, error, and teammate-idle events.
374
+ `SubagentStop` and the other lifecycle/tool events are quiet: they mark the
375
+ pane hook-active and write ingest diagnostics, but do not push notify queue
376
+ entries. `UserPromptSubmit` only moves the pane to thinking/busy and does not
377
+ push a queue entry.
378
+ Unknown Claude events also fall back to quiet/log-only handling after pane
379
+ matching. Catalog `action` is honored for quiet fallback events; notify/state
380
+ actions need built-in handlers for event-specific body text and state changes.
381
+
382
+ `ingest bell --pane <pane_id>` is the narrow tmux-bell fallback ingest path.
383
+ It does not require the pane to be AI-managed. Projmux resolves session,
384
+ window, pane, title, command, and socket metadata from tmux, pushes an info
385
+ queue row such as `bell · <pane title>`, and suppresses repeat bell rows from
386
+ the same pane for 5 seconds.
387
+
388
+ `ingest log` prints recent ingest diagnostics from
389
+ `$XDG_STATE_HOME/projmux/ai-ingest.log`, or `~/.local/state/projmux/ai-ingest.log`
390
+ when `XDG_STATE_HOME` is unset. Ingest paths append compact JSONL records for
391
+ parse errors, unsupported events, missing pane matches, deduped bells,
392
+ state-only transitions, quiet high-volume events, and notify pushes. Raw hook
393
+ payloads are not stored. The log is capped at 1 MiB and trimmed to the most
394
+ recent roughly 512 KiB when it grows past the cap. Use `--json` for raw JSONL
395
+ and `--path` to print the resolved file path.
396
+
397
+ For `Stop`, projmux reads `transcript_path` when present and extracts the last
398
+ assistant text from the transcript tail; if that is unavailable, it falls back
399
+ to a generic Claude completion row. `PermissionRequest` rows expose the tool
400
+ name plus a concise input summary, preferring Bash commands, file paths, and
401
+ URLs when those fields exist.
402
+
403
+ Hook row text is intentionally compact: agent label, event category, then the
404
+ best available summary. Structured details remain in queue metadata and are
405
+ available from `notify list --json`; the sidebar does not add a separate
406
+ metadata detail view.
407
+
408
+ The extra Claude events accept conservative field aliases while Claude's event
409
+ schemas settle. `StopFailure` reads `error_type`/`errorType`/`failure_type` and
410
+ `error_message`/`errorMessage`/`message`/`reason`, plus nested
411
+ `error.type|name|code` and `error.message|text|reason`. `SubagentStop` reads
412
+ `subagent_type`/`subagentType`/`agent_type`, `subagent_id`/`subagentId`, and
413
+ nested `subagent.type|name|kind|id`. `TeammateIdle` reads
414
+ `teammate_name`/`teammateName`, `teammate_id`/`teammateId`,
415
+ `teammate_context`/`teammateContext`/`context`/`reason`/`message`, and nested
416
+ `teammate.name|id|context|status|reason|message`.
417
+
418
+ Claude Code hook ingest is available through `ingest claude-hook`, but
419
+ `integrate claude` is the opt-in user-level wiring command for
420
+ `~/.claude/settings.json`. It installs command hooks for every event whose
421
+ effective Claude hook catalog entry has `"install": true`. The embedded default
422
+ catalog is based on Claude Code 2.1.140 and lives at
423
+ `internal/app/ai_hook_catalogs/claude.json`; a local override may be placed at
424
+ `${XDG_CONFIG_HOME:-$HOME/.config}/projmux/ai-hooks.d/claude.json` to disable
425
+ or add events before projmux itself is released:
426
+
427
+ ```json
428
+ {
429
+ "provider": "claude",
430
+ "events": [
431
+ { "name": "Stop", "install": false, "action": "notify" },
432
+ { "name": "FutureEvent", "install": true, "action": "quiet" }
433
+ ]
434
+ }
435
+ ```
436
+
437
+ The embedded Claude catalog contains all 29 Claude Code 2.1.140 events:
438
+ `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `PostToolBatch`,
439
+ `PermissionDenied`, `Notification`, `UserPromptSubmit`,
440
+ `UserPromptExpansion`, `SessionStart`, `Stop`, `StopFailure`,
441
+ `SubagentStart`, `SubagentStop`, `PreCompact`, `PostCompact`, `SessionEnd`,
442
+ `PermissionRequest`, `Setup`, `TeammateIdle`, `TaskCreated`,
443
+ `TaskCompleted`, `Elicitation`, `ElicitationResult`, `ConfigChange`,
444
+ `InstructionsLoaded`, `WorktreeCreate`, `WorktreeRemove`, `CwdChanged`, and
445
+ `FileChanged`. `SubagentStop` remains quiet/log-only.
446
+
447
+ The managed command receives Claude's hook JSON on stdin, keeps stdout/stderr
448
+ quiet, and exits successfully even if ingest fails so it does not block Claude
449
+ Code behavior. `--dry-run` previews the JSON update, and `--remove` deletes
450
+ only commands carrying the projmux marker. Removal and unmanaged conflict
451
+ detection scan every `hooks` event in the settings file rather than trusting the
452
+ current catalog, so stale managed events from older catalogs are still removed.
453
+ Existing unrelated Claude settings and hooks are preserved. If any event already
454
+ contains an unmanaged `projmux ai ingest claude-hook` command, projmux refuses
455
+ to install over it and leaves the settings file untouched.
456
+
457
+ `projmux ai integrate codex` manages a hooks-engine
458
+ block in `~/.codex/config.toml`. It enables `[features] hooks = true`,
459
+ merging into an existing `[features]` table when present, and installs broad
460
+ command hooks for every event whose effective Codex hook catalog entry has
461
+ `"install": true`. The embedded default catalog is based on Codex CLI 0.130.0
462
+ and lives at `internal/app/ai_hook_catalogs/codex.json`; a local override may
463
+ be placed at `${XDG_CONFIG_HOME:-$HOME/.config}/projmux/ai-hooks.d/codex.json`:
464
+
465
+ ```json
466
+ {
467
+ "provider": "codex",
468
+ "events": [
469
+ { "name": "Stop", "install": false, "action": "notify" },
470
+ { "name": "FutureEvent", "install": true, "action": "quiet" }
471
+ ]
472
+ }
473
+ ```
474
+
475
+ The embedded Codex catalog contains the 8 Codex CLI 0.130.0 events
476
+ `PreToolUse`, `PermissionRequest`, `PostToolUse`, `PreCompact`,
477
+ `PostCompact`, `SessionStart`, `UserPromptSubmit`, and `Stop`.
478
+
479
+ ```toml
480
+ [features]
481
+ hooks = true
482
+
483
+ [[hooks.PreToolUse]]
484
+ matcher = "*"
485
+ [[hooks.PreToolUse.hooks]]
486
+ type = "command"
487
+ command = "projmux ai ingest codex-hook >/dev/null 2>&1 || true"
488
+
489
+ [[hooks.PermissionRequest]]
490
+ matcher = "*"
491
+ [[hooks.PermissionRequest.hooks]]
492
+ type = "command"
493
+ command = "projmux ai ingest codex-hook >/dev/null 2>&1 || true"
494
+
495
+ [[hooks.PostToolUse]]
496
+ matcher = "*"
497
+ [[hooks.PostToolUse.hooks]]
498
+ type = "command"
499
+ command = "projmux ai ingest codex-hook >/dev/null 2>&1 || true"
500
+
501
+ [[hooks.PreCompact]]
502
+ matcher = "*"
503
+ [[hooks.PreCompact.hooks]]
504
+ type = "command"
505
+ command = "projmux ai ingest codex-hook >/dev/null 2>&1 || true"
506
+
507
+ [[hooks.PostCompact]]
508
+ matcher = "*"
509
+ [[hooks.PostCompact.hooks]]
510
+ type = "command"
511
+ command = "projmux ai ingest codex-hook >/dev/null 2>&1 || true"
512
+
513
+ [[hooks.SessionStart]]
514
+ matcher = "*"
515
+ [[hooks.SessionStart.hooks]]
516
+ type = "command"
517
+ command = "projmux ai ingest codex-hook >/dev/null 2>&1 || true"
518
+
519
+ [[hooks.UserPromptSubmit]]
520
+ matcher = "*"
521
+ [[hooks.UserPromptSubmit.hooks]]
522
+ type = "command"
523
+ command = "projmux ai ingest codex-hook >/dev/null 2>&1 || true"
524
+
525
+ [[hooks.Stop]]
526
+ matcher = "*"
527
+ [[hooks.Stop.hooks]]
528
+ type = "command"
529
+ command = "projmux ai ingest codex-hook >/dev/null 2>&1 || true"
530
+ ```
531
+
532
+ Codex hooks are the default integration mode. The hooks install is idempotent,
533
+ preserves unrelated Codex config and unmanaged hook entries, and refuses to
534
+ install over unmanaged projmux Codex hook commands it cannot safely own.
535
+ `--remove` removes projmux-managed Codex hooks wiring. `--dry-run` prints the
536
+ planned change without writing. Codex may still require reviewing or trusting
537
+ the hook through its `/hooks` flow before commands run.
538
+
539
+ `integrate tmux-bell` is opt-in server-level tmux wiring for arbitrary tools
540
+ that emit BEL or OSC 9. It applies `allow-passthrough on`, `monitor-bell on`,
541
+ `bell-action other`, and appends a marked `alert-bell` hook that invokes
542
+ `projmux ai ingest bell --pane "#{pane_id}"`. `--dry-run` prints the tmux
543
+ commands. tmux `alert-bell` is a window alert and does not expose
544
+ `#{hook_pane}` on tmux 3.4, so `#{pane_id}` is the best available pane context.
545
+ `--remove` unsets only hook entries carrying the projmux marker and leaves
546
+ user-owned `alert-bell` hooks alone.
547
+
306
548
  ## tmux
307
549
 
308
550
  ```
@@ -381,6 +623,19 @@ to `~/.config/projmux/projdir`. npm-installed binaries reject this
381
623
  command; use `projmux update apply` or `npm update -g projmux` for npm
382
624
  installs.
383
625
 
626
+ ## welcome
627
+
628
+ ```
629
+ projmux welcome
630
+ ```
631
+
632
+ Prints the onboarding shell guide (`projmux shell` welcome view) without
633
+ starting tmux. This is useful when you want to revisit the key/shortcut/update
634
+ walkthrough at any time.
635
+
636
+ Usage is argument-free. Passing positional arguments prints usage and returns a
637
+ usage error.
638
+
384
639
  ## sessions / session-popup / preview / pin / kill / prune / tag
385
640
 
386
641
  The lifecycle helpers retained from earlier releases. They share their
@@ -404,21 +659,30 @@ flags with the top-level `switch` UX:
404
659
  by the shell jump binding).
405
660
  - `shell` — boot the isolated `-L projmux` tmux server with the
406
661
  generated config. The generated app config uses absolute `$SHELL` as the
407
- tmux default shell when set, otherwise `/bin/sh`.
662
+ tmux default shell when set, otherwise `/bin/sh`. `shell` starts or attaches
663
+ the app session directly after resolving the target app session name and
664
+ startup directory. Alt-1 sidebar project open defaults to `Empty session`; the
665
+ Labs `Sidebar startup picker` opt-in shows `Latest snapshot`, `Named
666
+ snapshot`, and `Empty session` before creating a closed project session.
667
+ `Latest snapshot` is auto-saved; named snapshots are fixed until the user
668
+ saves or replaces them.
408
669
  - `attach auto [--keep=N] [--fallback=home|ephemeral]` — auto-attach to
409
670
  the most recent session, with bounded retention and a fallback policy.
410
671
  - `settings` — interactive configuration UI for the project picker, AI
411
- splits, Appearance mode, Project Root management, the
412
- switcher's saved workdirs list, Labs, and About/Update status. In Project
672
+ splits, Notifications, Appearance mode, Project Root management, the
673
+ switcher's saved workdirs list, Labs (experimental), Settings > Keybindings,
674
+ and About/Update status. The keybinding flow now lives under
675
+ `Settings > Keybindings` with `Bindings`, `Diagnostic`, `Probe`, and `Init`
676
+ chips, and includes the `Welcome` entry in About. In Project
413
677
  Picker, `Project Root` manages the saved
414
678
  primary root (`~/.config/projmux/projdir`) and displays whether the effective
415
679
  value comes from `PROJMUX_PROJDIR`, tmux `@projmux_projdir`, saved config, or
416
680
  no configured source. When no source is configured, the direct-set prompt
417
681
  starts with `$HOME` as an editable fallback, but `$HOME` is not used as the
418
682
  effective root unless saved. `Workdirs` remains separate: those entries are
419
- additional search roots, not the primary root. Appearance stores
420
- `~/.config/projmux/statusbar-decoration` as `off` (default), `symbol`, or
421
- `emoji` and updates the live tmux option when available. Labs remains
683
+ additional search roots, not the primary root. Appearance stores per-surface
684
+ path/git/notify icon decoration as `off` (default), `symbol`, or `emoji` and
685
+ updates the matching live tmux option when available. Labs remains
422
686
  available for experimental settings. The About section reads the cached
423
687
  update status without network access;
424
688
  selecting Check Updates runs `projmux update check`, and Update Now runs
@@ -433,4 +697,4 @@ flags with the top-level `switch` UX:
433
697
  - [notify-queue.md](notify-queue.md) — queue file format and lifecycle.
434
698
  - [usage-tracking.md](usage-tracking.md) — adapter HTTP/file behaviour.
435
699
  - [keybindings.md](keybindings.md) — terminal key delivery and CSI-u.
436
- - [hooks.md](hooks.md) — `post-create` hook contract.
700
+ - [hooks.md](hooks.md) — lifecycle hooks, startup commands, and `send-noti` payload contract.