projmux 0.15.2 → 0.16.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/docs/cli-guide.md CHANGED
@@ -97,8 +97,9 @@ invocation context. Mixed Registry/Runtime pickers keep KIND in both profiles.
97
97
  Wide stdout preserves full values at every terminal width. See [Column profiles](column-profiles.md)
98
98
  for the exact per-kind matrix and migration from the previous default output.
99
99
 
100
- The resource routes (`get`, `describe`, `create`, `rename`, `rebind`, `delete`,
101
- `agent resume`) address stored resources through one shared selector grammar.
100
+ The resource routes (`get`, `describe`, `create`, `rename`, `label`, `rebind`,
101
+ `delete`, `agent resume`) address stored resources through one shared selector
102
+ grammar.
102
103
 
103
104
  The grammar in one paragraph: a value is either `uid:<uid>` or a bare
104
105
  `metadata.name`. There is no bare-uid form, values are never split on commas,
@@ -201,7 +202,7 @@ the item: only an exact UID-bound live Window name or Pane title sets
201
202
  `observed: true`; Project and Agent context, Registry fallbacks, and unmatched
202
203
  runtime objects remain unobserved. This is a read projection, not stored
203
204
  resource state or selector authority. It does not change `-o metadata`, the
204
- Registry or snapshot schema, singular `describe ... -o json`, or `get pane -o
205
+ Registry schema, singular `describe ... -o json`, or `get pane -o
205
206
  json`; an empty plural result remains one List document with `"items": []`.
206
207
 
207
208
  ### Reference scope: the active Project namespace
@@ -252,8 +253,27 @@ The contract:
252
253
  `create window|pane|agent|<provider>` is resource-backed on every spelling.
253
254
  There is no mode flag and no second parser: the same argv means the same thing
254
255
  whether or not `--project` is present, and `-w`, `--create-window`, `--pane`,
255
- `--selector`, `--placement`, `--name`, `--label`, `--cwd`, `--add-dir`, `-o`,
256
- and the `--` payload all reach the same parser either way.
256
+ `--selector`, `--placement`, `--cwd-from`, `--name`, `--label`, `-o`, and the
257
+ `--` payload all reach the same parser either way. `--cwd` and `--add-dir` are
258
+ provider create flags: they are defined on `create agent` and the three provider
259
+ shortcuts, not on `create window` or `create pane`.
260
+
261
+ `--cwd-from project|pane` selects where the new split starts. `project` (the
262
+ default) starts it in the owner Project root. `pane` starts it in the active
263
+ Pane's live directory while that directory is inside the owner Project root, and
264
+ otherwise starts it in the root and says so in one stderr line; it never
265
+ refuses. The flag cannot be combined with `--cwd`, which names an Agent working
266
+ directory outright.
267
+
268
+ On the CLI the flag is the only input: `create pane`, `create agent`, and the
269
+ provider shortcuts never read `[ai] split_cwd_from`, so with no `--cwd-from`
270
+ they always start in the owner Project root, whatever the global or project
271
+ config says. A CLI result is determined by its arguments, and scripts must not
272
+ change behavior because someone changed a Settings value. That config (and the
273
+ `AI > New splits start in` Settings row that writes it) only decides splits
274
+ started from the UI -- keybinding splits, the launcher, the resume picker's new
275
+ row, and the Pane menu -- in the order flag > project config > global config >
276
+ default. See [configuration.md](configuration.md).
257
277
 
258
278
  The scope resolves in two branches:
259
279
 
@@ -339,12 +359,22 @@ they name `--project` as the fix:
339
359
  gone — a `recoverable` runtime is reported, never adopted.
340
360
 
341
361
  Every create is **detached**: no create moves the client. Use `focus pane` or
342
- `-o pane-id` when you want to end up in the new pane. A natural create validates
362
+ `-o pane-id` when you want to end up in the new pane. One exception: the human
363
+ intent route `internal tmux window-create` (the `window.create` key and the
364
+ Window menu New At End) moves the pressing client to the new Window after its
365
+ create commits and then opens that Window's first Pane with the saved launch
366
+ default; public `create` stays detached and never reads that saved default. A natural create validates
343
367
  the inherited exact route and Pane containment. An explicit resource scope
344
368
  binds the selected app resource route without letting unrelated inherited
345
369
  `TMUX`/`TMUX_PANE` choose or change the resource target; exact Project plus
346
370
  `--create-window` therefore uses the validated app logical `-L` route on its
347
- first attempt, with no `env -u` workaround. Runtime safety remains independent
371
+ first attempt, with no `env -u` workaround. `agent resume` binds the same way,
372
+ and for the same reason: the Agent it rebinds is one exact reference and the
373
+ Pane it splits is that Agent's Window's stored `spec.anchorPaneRef`, so no
374
+ anchor Pane has to be typed or inherited to name a target that is already
375
+ named. Unsetting `TMUX` is not a substitute for either — it selects the
376
+ detached branch, which asks for an explicit `--anchor %N` instead of asking for
377
+ less. Runtime safety remains independent
348
378
  and may refuse before mutation. An inherited app-owned `TMUX` socket/PID stays
349
379
  route evidence: projmux validates its exact `-S` path, ownership/logical
350
380
  markers, logical `-L` alias, and PID while ignoring unrelated `TMUX_PANE`
@@ -415,12 +445,20 @@ disabling the keys.
415
445
  ### Rename and rebind live convergence
416
446
 
417
447
  `rename project|window|pane` commits the selected Registry `metadata.name` and
418
- then updates only its exact UID-bound live transport field:
448
+ then updates only its exact UID-bound live transport fields:
419
449
 
420
450
  - Project: `@projmux_project_name` (never the tmux session name)
421
- - Window: `@projmux_window_name` (never tmux `window_name`)
451
+ - Window: `@projmux_window_name` and the tmux tab `window_name` (never
452
+ `displayName`)
422
453
  - Pane: `@projmux_pane_label` (never raw `pane_title`)
423
454
 
455
+ The Window tab converges only when the invocation has a proven runtime route,
456
+ which is what running inside the projmux tmux runtime gives it. Outside one the
457
+ rename is Registry-only: it exits zero and prints one line on stderr saying the
458
+ tab still shows the old name until a rename runs inside that runtime. There is
459
+ no flag for either behavior; the next time that Window is materialized from the
460
+ Registry, the tab carries the committed name.
461
+
424
462
  `rename agent` changes only the Agent's stable root-scoped `metadata.name`.
425
463
  It does not change the Agent topic, provider, lifecycle state, or managed Pane
426
464
  name/title. `create agent` derives the managed Pane's name from the Agent's
@@ -442,6 +480,42 @@ already committed, and names the same public reconcile route as the retry. A
442
480
  valid unique Project UID wins over the old path after rebind; unknown and
443
481
  duplicate UID claims remain fail-closed.
444
482
 
483
+ ### Labels after creation
484
+
485
+ `projmux label project|window|pane|agent` writes `metadata.labels` on exactly
486
+ one resolved resource. It is the post-creation half of `create --label`, which
487
+ keeps its exact behavior: the same field, written by two routes at two moments.
488
+ A label change has no live projection at all -- no tmux option, no tab, no pane
489
+ title -- so the Registry commit is the whole operation and there is nothing to
490
+ converge afterwards.
491
+
492
+ The operand grammar is Kubernetes': `key=value` sets a label, `key=` sets it to
493
+ the empty string, and `key-` removes it. Set and remove operands may be mixed in
494
+ one invocation, and a key named twice is refused rather than resolved by argv
495
+ order.
496
+
497
+ Two properties follow from that grammar and are worth stating outright:
498
+
499
+ - **Shape decides what a positional token is, never the Registry.** A token
500
+ carrying `=` is always a label operand, and it can never be a resource name
501
+ anyway, because `=` is not a legal name rune. A token ending in `-` is always
502
+ a removal. A resource whose `metadata.name` happens to end in `-` is therefore
503
+ addressed by `uid:<uid>` or by its scope flag rather than positionally.
504
+ - **There is no `--overwrite` guard and no value policy.** Setting a key that
505
+ already holds a value overwrites it, and removing a key that is absent
506
+ succeeds and changes nothing; both report the resulting label set. A label
507
+ value has no length or character-set rule here, unlike in Kubernetes. The
508
+ syntax is borrowed; the value constraints deliberately are not, because
509
+ `create --label` has never had them and one field must not have two contracts
510
+ depending on which route wrote it.
511
+
512
+ What belongs in a label is decided by one question: is this a value you will
513
+ ever filter on? `--selector key=value` reads labels and only labels, so
514
+ classification that selects (`role=epic-owner`, `phase=task-0`) belongs there.
515
+ A value that is unique per resource -- a link, an artifact path -- fills the
516
+ selector space with keys nothing will ever match and belongs in an annotation
517
+ instead.
518
+
445
519
  ### Agent topic, interaction, activation, and workspace
446
520
 
447
521
  `projmux agent capabilities --provider <codex|claude|antigravity>` prints the
@@ -503,7 +577,8 @@ id and one text input. Immediately before that write it reads one bounded,
503
577
  content-free lifecycle snapshot: fresh active/in-progress returns
504
578
  `turn-in-progress`, fresh idle/terminal repairs stale cached state and starts
505
579
  once, and an unavailable or inconsistent snapshot returns
506
- `turn-state-unavailable` with no turn mutation. `steer` also reads that
580
+ `turn-state-unavailable` with no turn mutation. Broker read admission refusals
581
+ remain visible as `lifecycle-retry` or `lifecycle-busy`. `steer` also reads that
507
582
  content-free snapshot before any write and submits exactly once only when it
508
583
  still proves the same exact active turn. Fresh idle, terminal, or different-turn
509
584
  state returns `no-active-turn`; an unavailable or inconsistent read, including
@@ -516,6 +591,12 @@ supplies the cached exact turn id without adopting the steer preflight in this
516
591
  phase. These commands never install sticky model, effort, cwd, sandbox,
517
592
  permission, or collaboration overrides.
518
593
 
594
+ Codex coordination delivery chooses start or steer inside one native control
595
+ operation from one lifecycle snapshot. If that read returns `lifecycle-retry`,
596
+ it waits through the fixed retry window and reads once more before any write;
597
+ no provider write is ever retried.
598
+ An older observer that refuses this operation with `invalid-operation` gets one legacy start attempt, followed by steer only for `turn-in-progress`.
599
+
519
600
  Approval review shows only the safe one-shot intersection supplied by the
520
601
  exact pending request. Command, file, and network requests are limited to
521
602
  `accept`, `decline`, and `cancel`; permission grants echo the received supported
@@ -566,7 +647,7 @@ with its live `$N/@N` in the same commit. A non-last Pane is removed while its d
566
647
  Agent is retained Offline with its conversation identity. For a last Pane, that evidence is retained until a
567
648
  matching `window-unlinked` hook removes the Window; a final Project Window also
568
649
  removes its Window descendants while retaining the exact Project uid, root,
569
- reservation, pins, snapshots, and external assets as a valid zero-Window
650
+ reservation, pins, and external assets as a valid zero-Window
570
651
  Project. Managed runtime Stop is different: it stops only the exact runtime and
571
652
  keeps the complete desired Project/Window/Pane graph closed for a same-UID
572
653
  Continue. Shell and Claude/Codex clean exit have the same result; `/exit`, pane
@@ -616,19 +697,31 @@ owner Project root from `get`/`describe`, and a successful resume persists that
616
697
  normalized effective workspace without changing Window Project ownership.
617
698
 
618
699
  When `create agent -- <initial-prompt>` is used, normal resource creation and
619
- provider activation are distinct. Projmux first waits up to five seconds for an
620
- exact provider `SessionStart`; that readiness evidence leaves activation
621
- `pending` and opens an independent five-second initial-task acknowledgement
700
+ provider activation are distinct. Projmux first waits up to thirty-five seconds
701
+ for an exact provider `SessionStart`; that readiness evidence leaves activation
702
+ `pending` and opens an independent twelve-second initial-task acknowledgement
622
703
  window. A `UserPromptSubmit` acknowledgement may also arrive directly before
623
704
  the readiness observer sees `SessionStart`. The two stages are independently
624
- bounded, so provider startup plus an acknowledgement later than two seconds may
625
- take more than five but never more than ten seconds. Neither stage captures pane
626
- content or stores the prompt. Acknowledgement returns success and the requested
627
- exact `%N` output. If
628
- activation cannot be confirmed, the command exits nonzero while naming the
629
- exact Agent UID and Pane plus safe provider retry and `delete agent ... --yes`
630
- cleanup options. The live resources remain explicit and retryable rather than
631
- being reported as an ordinary success.
705
+ bounded, so provider startup plus a late acknowledgement may take more than
706
+ either bound alone but never more than forty-seven seconds. Both bounds are
707
+ sized from measured provider startup on a loaded machine, with headroom past
708
+ the measured peak, because a provider that is merely slow is not a failed one;
709
+ they are not sized for a dead provider, which is why exceeding them still
710
+ reports failure. Neither stage captures pane content or stores the prompt.
711
+ Acknowledgement returns success and the requested exact `%N` output.
712
+
713
+ If activation still cannot be confirmed, the command exits nonzero. A nonzero
714
+ exit here does not mean the Agent is gone or unusable: the Agent and its
715
+ managed Pane were created and are still live, and nothing is rolled back. The
716
+ diagnostic therefore names the exact Agent UID and Pane first and orders the
717
+ remediation cheapest-first — re-read the committed activation with `projmux get
718
+ agent uid:<uid>`, since a provider hook that arrives after the bound still
719
+ refines the activation to `acknowledged`; then look at the Pane or the provider
720
+ transcript for the initial task and retry it through the provider if it never
721
+ arrived; and only when neither read shows activation evidence, clean up with
722
+ `projmux delete agent uid:<uid> --yes`. Deletion is the last option rather than
723
+ the first, because a caller that acts on the exit code alone would otherwise
724
+ remove an Agent that is already working.
632
725
 
633
726
  Activation metadata is bounded to provider-hook provenance and fixed
634
727
  acknowledged/timed-out/failed diagnostics. Provider error strings and initial
@@ -734,17 +827,16 @@ client only after it converges; a refusal, a failed preflight, or a rolled-back
734
827
  partial leaves the client where it was and reports the exact stage. The
735
828
  activation is pinned to the session the open targets, so a Project whose
736
829
  Registry projects a different session name is refused instead of populating a
737
- session the open never reaches. With no saved `sidebar-startup-picker`
738
- preference, the closed-Project startup screen has exactly two neutral actions;
739
- the missing-file default is read-only and does not create a config file. Saved
740
- `on` retains that explicit choice, while saved `off` skips the screen and keeps
741
- the registered-Continue/unregistered-Fresh automatic decision. `Continue
830
+ session the open never reaches. A registered closed Project always gets the
831
+ startup screen, which has exactly two neutral actions; a root that is not a
832
+ registered Project never gets it and opens fresh. There is no setting that
833
+ skips the screen. `Continue
742
834
  project` materializes current Registry desired state with the same Project UID.
743
835
  A retained graph keeps descendant UIDs; a
744
836
  zero-Window Project atomically receives a new canonical Window/shell UID chain.
745
- A deleted Project may use only the exact usable snapshot compatibility path;
746
- an unavailable Continue is an explicit zero-write refusal with no Fresh
747
- fallback. `Recreate Project` is the one startup row that replaces identity, and it asks
837
+ A root that is not a registered Project cannot be continued: Continue is an
838
+ explicit zero-write refusal that points to `Clear layout and open`, with no Fresh
839
+ fallback. `Clear layout and open` is the one startup row that replaces identity, and it asks
748
840
  before it does. Choosing it opens a confirmation naming the exact old Project
749
841
  UID and its Window/Pane/Agent counts; declining returns to the startup rows
750
842
  with zero Registry writes, and an unreadable confirmation declines rather than
@@ -752,7 +844,7 @@ proceeds. An unregistered root has no identity to replace and is not asked.
752
844
  Confirmed, it atomically replaces the same-root graph with a new Project UID
753
845
  and new canonical Window/shell UIDs, then hands off only after ordinary
754
846
  materialization. A repeat replaces identity again. The root, git/worktrees,
755
- trust decision, unrelated roots, and snapshot bytes remain unchanged.
847
+ trust decision, and unrelated roots remain unchanged.
756
848
 
757
849
  Materialization launches or resumes declared Agents through the canonical
758
850
  provider/trust path and creates their managed Agent-owned Panes. An individual
@@ -780,9 +872,12 @@ report a final-window cascade with its actual root kind.
780
872
  Pane and Agent Registry-only deletion is deliberately narrower. It accepts
781
873
  only an explicit exact `uid:` selector: a Pane must carry durable
782
874
  `MissingRuntime=True/RuntimeUnbound` evidence, and an Agent must be `Offline`
783
- with no `paneRef` (with every retained descendant Pane also marked
784
- `MissingRuntime`). The exact routed server must answer with a non-empty socket
785
- identity and a non-empty Pane inventory that proves the target has zero mirrors.
875
+ or `Failed` with no `paneRef` (with every retained descendant Pane also marked
876
+ `MissingRuntime`). Both phases are accepted under the same authority; the
877
+ reported evidence names the phase, such as `Failed` or
878
+ `Offline+MissingRuntime`. The exact routed server must answer with a non-empty
879
+ socket identity and a non-empty Pane inventory that proves the target has zero
880
+ mirrors.
786
881
  A missing server, empty or failed inventory, unavailable or permission-denied
787
882
  transport, implicit/name/scope/`--all` selection, and duplicate or foreign
788
883
  mirrors are not absence authority and make zero writes. Dry-run and apply sign
@@ -799,7 +894,7 @@ typed resource's exact form to run instead —
799
894
  `projmux delete pane|agent uid:<uid> --socket-path <server> --dry-run`, then the
800
895
  same command with `--yes` — and says which evidence qualifies it. A target the
801
896
  `uid:` form would refuse too, such as a Pane without `MissingRuntime` or a
802
- `Running` or `Failed` Agent, gets no such pointer.
897
+ `Running` Agent, gets no such pointer.
803
898
 
804
899
  `delete window|pane|agent` names the server its live half addresses the same
805
900
  way `reconcile resources` does: `--socket <name>`, `--socket-path <absolute>`,
@@ -982,7 +1077,7 @@ hook payload, or a `make install` log.
982
1077
 
983
1078
  | Route | Purpose |
984
1079
  | --- | --- |
985
- | `internal tmux` | Generated config render/install/apply, popup entry helpers, pane rebalance/rename, snapshot autosave. |
1080
+ | `internal tmux` | Generated config render/install/apply, popup entry helpers, pane rebalance/rename, and the retained no-op `autosave-session-state`. |
986
1081
  | `internal status` | Status bar segment renderers (`git`, `project`, `usage`, `notify`, `resources`). |
987
1082
  | `internal statusbar` | Status bar click and shortcut dispatch (`click`, `usage-refresh`). |
988
1083
  | `internal preview` | Persisted preview cursor (`cycle-pane`, `cycle-window`, `select`). |
@@ -1078,31 +1173,21 @@ shows every key arriving, skip terminal remediation.
1078
1173
  ## doctor
1079
1174
 
1080
1175
  ```
1081
- projmux doctor [--json] [--section deps|runtime|integrations|session-state|logs] [--verbose]
1176
+ projmux doctor [--json] [--section deps|runtime|integrations|logs] [--verbose]
1082
1177
  ```
1083
1178
 
1084
1179
  Runs read-only diagnostics, including a dependency check for `tmux ≥ 3.4`,
1085
1180
  `git`, and `stty` (POSIX only), then reports read-only AI notify integration diagnostics
1086
- for Codex hooks, Claude Code hooks, Antigravity hooks/statusline, and the tmux bell
1181
+ for Codex hooks, Claude Code hooks, Antigravity hooks, and the tmux bell
1087
1182
  fallback. AI notify integration statuses are `installed`, `missing`, or
1088
1183
  `conflict`; missing or conflicting integrations are informational and do not
1089
- make doctor fail. It also reports read-only Session State resume metadata
1090
- diagnostics for saved agent panes, including `available`, `stale`, or
1091
- `unavailable` status plus confidence, source, updated-at, and the affected
1092
- snapshot/window/pane.
1093
-
1094
- Session State preview and doctor report the resume source captured on the pane.
1095
- Live `hook`/`session-id` metadata is high confidence; DB-validated Antigravity
1096
- `antigravity-last-conversation` and `antigravity-conversation-metadata` picker
1097
- sources are medium confidence; legacy `antigravity-history` is low confidence.
1098
- Disk discovery never lowers or overwrites an already captured live source.
1184
+ make doctor fail.
1099
1185
 
1100
1186
  The default text report shows per-section summaries plus failing or warning
1101
1187
  items. `--verbose` adds successful checks and complete typed detail, including
1102
1188
  versions, paths, confidence/source metadata, and displayed remediation.
1103
1189
  `--section` projects the same inventory used by text and JSON: `deps` selects
1104
- dependencies, `integrations` selects AI notify integrations, and
1105
- `session-state` selects resume metadata plus retention guidance. `runtime`
1190
+ dependencies, and `integrations` selects AI notify integrations. `runtime`
1106
1191
  selects the fixed `tmux` backend, an actual one-second read-only probe of the
1107
1192
  app socket, generated-versus-live config digest state, and a
1108
1193
  `projmux_process_vintage` census of this executable's live children by role and
@@ -1126,8 +1211,7 @@ bits are authoritative on both, so a readable path always resolves to a
1126
1211
  private or insecure classification. Doctor never changes permissions.
1127
1212
 
1128
1213
  JSON reports have integer `schema_version: 2`. An unfiltered report retains the
1129
- existing typed `dependencies`, `ai_notify_integrations`,
1130
- `session_state_resume`, and `session_state_prune` detail and adds ordered
1214
+ existing typed `dependencies` and `ai_notify_integrations` detail and adds ordered
1131
1215
  `runtime` and `logs` finding arrays. Every finding has closed `severity`,
1132
1216
  stable `code`, and closed `remediation`; bounded aggregates may add `count`
1133
1217
  and `safe_codes`. A filtered report contains only the selected typed field(s).
@@ -1150,8 +1234,9 @@ diagnose terminal key delivery; use `projmux setup` for that.
1150
1234
 
1151
1235
  JSON migration: consumers must switch on `schema_version` before decoding.
1152
1236
  Version 2 changes the previously empty/reserved `runtime` and `logs` arrays to
1153
- the typed finding shape above; field meanings inside the version 1 dependency,
1154
- integration, and Session State inventories are unchanged. Consumers that only
1237
+ the typed finding shape above; field meanings inside the version 1 dependency
1238
+ and integration inventories are unchanged. The former `session_state_resume`
1239
+ and `session_state_prune` fields are no longer emitted. Consumers that only
1155
1240
  understand version 1 must reject version 2 rather than decoding the new arrays
1156
1241
  as the old empty placeholder shape.
1157
1242
 
@@ -1275,7 +1360,7 @@ before anything is materialized.
1275
1360
  declares exactly one runtime outcome, and reporting `runtime=stopped` for a
1276
1361
  session that was never running would be false. `unregister project` is the
1277
1362
  inverse -- it removes the Registry graph and deliberately leaves the running
1278
- session, the root, Git/worktrees, and snapshots exactly as they were.
1363
+ session, the root, and Git/worktrees exactly as they were.
1279
1364
 
1280
1365
  `delete project` is a deprecated alias of `unregister project`. It keeps its
1281
1366
  exact behavior and its exact stdout; it adds one deprecation line on stderr and
@@ -1285,6 +1370,15 @@ removal in this release.
1285
1370
  The reference for a Project can be `uid:<uid>`, a bare `metadata.name`, or the
1286
1371
  absolute root path the Project claims.
1287
1372
 
1373
+ A Project registered without `--name` -- by `create project`, by opening an
1374
+ unregistered directory, or by `Clear layout and open` -- is named after its root
1375
+ directory, sanitized into a valid name (`~/src/my repo` becomes `my-repo`). If
1376
+ that basename sanitizes to nothing or another Project already holds it, the new
1377
+ Project is named by its exact uid instead; a numbered variant is never invented.
1378
+ `Clear layout and open` keeps an operator-chosen name, but not a name shaped
1379
+ like a Project uid. Windows, Panes, and Agents keep their exact-uid automatic
1380
+ names.
1381
+
1288
1382
  ### Operation receipts
1289
1383
 
1290
1384
  Every create, rename, delete, and Project lifecycle route reports what it did
@@ -1420,7 +1514,7 @@ Authoritative AI account usage. See [usage-tracking.md](usage-tracking.md)
1420
1514
  for adapter detail.
1421
1515
 
1422
1516
  ```
1423
- projmux agent usage [--model codex|claude|antigravity|all] [--window 5h|weekly|context|quota|all]
1517
+ projmux agent usage [--model codex|claude|all] [--window 5h|weekly|context|quota|all]
1424
1518
  [--json] [--force|-f]
1425
1519
  ```
1426
1520
 
@@ -1478,7 +1572,7 @@ Defensive ambiguous attribution stays in its stable internal bucket, is
1478
1572
  included in Attributed totals, and appears only as a bounded CPU/RSS/pane
1479
1573
  diagnostic rather than a project row. Warming, partial, unavailable, unknown,
1480
1574
  and overage states also remain explicit. No process
1481
- command list, mutation, history, graph, daemon, persistence, or Session State
1575
+ command list, mutation, history, graph, daemon, or persistence
1482
1576
  telemetry is created. Linux/tmux provides attribution; unsupported platforms
1483
1577
  show an unavailable reason rather than zero metrics.
1484
1578
 
@@ -1511,9 +1605,8 @@ projmux internal status resources
1511
1605
  local changes, `+N` staged entries, and `↑N`/`↓N` ahead/behind counts, with
1512
1606
  compact per-token colors in tmux output.
1513
1607
  - `usage` — HUD-style provider blocks containing only official `5h` and
1514
- `weekly` windows. Antigravity's exact `quota/gemini-weekly` snapshot is
1515
- projected as `weekly` without changing its cached identity; other named
1516
- quotas and context never consume status width. Claude typed `limits[]`
1608
+ `weekly` windows from Claude and Codex; named quotas and context never
1609
+ consume status width. Claude typed `limits[]`
1517
1610
  named/model rows are likewise excluded, so only its aggregate `5h` and
1518
1611
  `weekly` rows reach the status line. Narrow tiers keep one primary window per
1519
1612
  provider (`5h`, otherwise `weekly`) before hard truncation.
@@ -1605,7 +1698,7 @@ projmux agent capabilities [<agent-ref> | --provider <codex|claude|antigravity>]
1605
1698
  projmux internal agent-hook watch-title [pane]
1606
1699
  projmux internal agent-hook ingest codex-hook [--pane <pane_uid|pane_id>] < payload.json
1607
1700
  projmux internal agent-hook ingest claude-hook [--pane <pane_uid|pane_id>] < payload.json
1608
- projmux internal agent-hook ingest antigravity-hook [--event <PreInvocation|PostInvocation|PostToolUse|Stop|Statusline>] [--pane <pane_uid|pane_id>] < payload.json
1701
+ projmux internal agent-hook ingest antigravity-hook [--event <PreInvocation|PostInvocation|PostToolUse|Stop>] [--pane <pane_uid|pane_id>] < payload.json
1609
1702
  projmux internal agent-hook ingest bell --pane <pane_id>
1610
1703
  projmux diagnostics agent-hook [--tail N] [--json] [--path]
1611
1704
  projmux agent integrate codex [--dry-run] [--remove]
@@ -1668,6 +1761,120 @@ plain Agent on purpose; it is Codex-only and equivalent on `create agent
1668
1761
  multi-operand payloads, `agent resume`, Claude, and Antigravity are unaffected.
1669
1762
  See [Codex Native-Required Create Migration](codex-native-required-migration.md).
1670
1763
 
1764
+ An Agent can be given a persona: `create agent --provider claude
1765
+ --persona <name>` (and `create claude --persona <name>`) appends the stored
1766
+ persona to the new session's system prompt through Claude's
1767
+ `--append-system-prompt-file`; it never replaces the system prompt, so Claude
1768
+ Code's own tool instructions stay. Personas are files in
1769
+ `<config dir>/personas/<name>.md` (by default `~/.config/projmux/personas/`),
1770
+ at most 64 KiB each, managed with `projmux persona list|show|edit|set|delete`
1771
+ (`edit` opens `$EDITOR`, then `$VISUAL`; `set <name> --file <path>` or `-` is
1772
+ the non-interactive write). A persona's content is fixed when it is given: the create
1773
+ copies the content to a content-addressed snapshot
1774
+ `<state dir>/personas/sha256-<hex>.md`, passes only that path on the Claude
1775
+ command line, and records `projmux.io/persona` and `projmux.io/persona-digest`
1776
+ on the Agent. `agent resume` and Continue/topology replay pass that same
1777
+ snapshot again, found from the recorded digest and never from the persona file,
1778
+ so editing or deleting the persona file later never changes an existing Agent.
1779
+ If the snapshot is gone, the resume still proceeds without the persona and
1780
+ discloses one `persona-unavailable` line (on stderr for `agent resume`, among
1781
+ the replay notices for Continue). A missing, oversized, or badly named persona
1782
+ refuses with `persona-not-found`, `persona-too-large`, or
1783
+ `persona-name-invalid`, all with zero Registry, tmux, and snapshot writes.
1784
+
1785
+ A Codex Agent can be given a persona too, on one lane: a create that carries a
1786
+ prompt (`create agent --provider codex --persona <name> -- <prompt>`, and
1787
+ `create codex --persona <name> -- <prompt>`). That is the lane that opens a
1788
+ thread of its own, and starting the thread is the only moment Codex accepts a
1789
+ persona: the create sends the snapshot content as the thread's
1790
+ `developerInstructions`, and the shared app server records it once as the
1791
+ thread's `developer` message. The content goes over that connection and
1792
+ nowhere else -- never onto a command line, where `ps` would publish it -- and
1793
+ the create records the same `projmux.io/persona` and `projmux.io/persona-digest`
1794
+ annotations Claude records. From then on the thread carries the persona
1795
+ itself: `agent resume`, Continue/topology replay, and a resume picked from the
1796
+ Codex catalog re-send nothing and disclose nothing, because nothing was lost.
1797
+ A conversation opened from the resume picker inherits the two persona keys
1798
+ from the Agents that already record it, so the new Agent reports the persona
1799
+ its thread is running; it inherits no other launch value. A Codex Agent's
1800
+ persona cannot be changed afterwards: the instructions are fixed when the
1801
+ thread starts, `agent persona attach|detach` stays Claude-only, and starting
1802
+ over means a new Agent.
1803
+
1804
+ Every other `--persona` create refuses with `persona-provider-unsupported` and
1805
+ zero Registry, tmux, and snapshot writes: a Codex create with no prompt or with
1806
+ `--interactive-only` (its plain lane would have to spell the persona into
1807
+ argv), `--dialogue-reply-only`, and any other provider.
1808
+
1809
+ An existing Claude Agent can take on a persona later, or drop it:
1810
+ `projmux agent persona attach <agent-ref> <persona>` and
1811
+ `projmux agent persona detach <agent-ref>` (both with `[--project <ref>]
1812
+ [--window <ref>] [--yes] [--dry-run] [-o json]`). The Agent keeps its uid and
1813
+ its provider conversation. A Running Agent's managed Pane is closed through
1814
+ `delete pane`, which leaves it Offline, and the Agent is resumed through the
1815
+ same rebind `agent resume` uses, on a new managed Pane; an Offline or Failed
1816
+ Agent is only resumed. Before that the command writes the snapshot and records
1817
+ `projmux.io/persona`, `projmux.io/persona-digest`, and
1818
+ `projmux.io/system-prompt-snapshot=off` in one Registry change (detach removes
1819
+ the first two). The last key is sticky and makes every later resume of that
1820
+ Agent pass `--system-prompt-snapshot off`: Claude records the system prompt of
1821
+ a conversation's first request and replays that record on resume, so without
1822
+ it a persona attached after the conversation started would be ignored on the
1823
+ next resume. In steady state that costs little: each resume re-creates a
1824
+ byte-identical system prompt, so the prompt cache still hits and the extra cost
1825
+ is a few dozen cache-creation tokens per resume (measured +4 to +45); after the
1826
+ environment context in the system prompt changes (date, git state, CLAUDE.md),
1827
+ the first resume can re-cache the prompt prefix once. A Running Agent whose
1828
+ interaction is not `idle` or
1829
+ `response_complete` -- `unknown` included -- is refused with
1830
+ `persona-agent-busy` unless `--yes` confirms cutting its turn, and `--dry-run`
1831
+ (`-o json` for scripts) reports the target, its interaction, the current and
1832
+ new persona, and whether that confirmation is required without changing
1833
+ anything. The Agent owning the Pane the command runs in is refused with
1834
+ `persona-self-target`; an Agent with no stored conversation is refused with
1835
+ `persona-no-conversation`. Attaching the persona an Agent already runs with,
1836
+ same name and same content digest, reports `unchanged` and restarts nothing;
1837
+ after the persona file is edited the digest differs and the attach restarts
1838
+ with the new snapshot. Outside tmux the stop needs `--socket <name>` or
1839
+ `--socket-path <absolute>`, exactly as `delete pane` does. Refusals leave no
1840
+ snapshot, Registry, or Pane change. If the resume fails after the stop, the
1841
+ Agent stays Offline with its new annotations and stderr prints the
1842
+ `projmux agent resume uid:<agent> --project uid:<project> --window uid:<window>`
1843
+ command that finishes the job with the persona. If closing the managed Pane
1844
+ reports an error, the command checks whether that Pane is still alive: if it
1845
+ is, the previous annotations are restored; if it is already closed, the new
1846
+ annotations are kept and the resume proceeds with a warning on stderr (a failed
1847
+ resume prints the recovery command above); if it cannot tell, the previous
1848
+ annotations are restored and stderr prints the command to re-run.
1849
+
1850
+ A Claude Agent created with `--effort <level>` records it as `projmux.io/effort`
1851
+ on the Agent, because Claude does not restore a conversation's effort on
1852
+ resume. Every resume passes it again as `--effort <level>`: `agent resume`,
1853
+ Continue/topology replay, and the restart of `agent persona attach|detach`. A
1854
+ recorded value that is not one of `low`, `medium`, `high`, `xhigh`, or `max` is
1855
+ skipped, the resume still proceeds, and one `effort-invalid` line is disclosed
1856
+ where a `persona-unavailable` line would be. The model given with `--model` is
1857
+ not recorded or passed again: Claude restores the conversation's model itself
1858
+ on resume, and passing the create-time model would override a `/model` switch
1859
+ made in the session.
1860
+
1861
+ A Claude conversation opened from the resume picker creates a new Agent, and
1862
+ when Agents in the Registry already record that conversation (in any Project or
1863
+ Window, live or not) the new Agent inherits their launch values: the persona
1864
+ and its snapshot (`projmux.io/persona`, `projmux.io/persona-digest`), the
1865
+ system prompt snapshot mode (`projmux.io/system-prompt-snapshot`), and the
1866
+ effort (`projmux.io/effort`). It launches with them and records them, so its own
1867
+ later resumes behave like theirs; a snapshot that is gone or an effort Claude
1868
+ would not take is disclosed with `persona-unavailable` or `effort-invalid`, as
1869
+ on `agent resume`. Inheritance happens only when every such Agent records the
1870
+ same values; if they disagree, nothing is inherited and one
1871
+ `launch-values-ambiguous` notice names them. The creator, topic, and
1872
+ labels of those Agents are never inherited, and they keep their conversation
1873
+ and annotations. A Codex picker selection inherits the two persona keys under
1874
+ the same agreement rule and nothing else -- the snapshot mode and the effort
1875
+ are Claude launch options -- and it changes no argv, because the thread
1876
+ already carries the persona. Antigravity picker selections inherit nothing.
1877
+
1671
1878
  Automation callers get the new pane's handle from `-o pane-id` on the canonical
1672
1879
  create routes: `projmux create agent --provider <p> --placement right -o pane-id`
1673
1880
  and `projmux create pane --placement right -o pane-id` each print exactly the
@@ -1713,7 +1920,7 @@ other case reports review as unavailable without changing the Agent. This route
1713
1920
  projects only the initial response into interaction status. It does not claim
1714
1921
  the later notification-driven completion lifecycle.
1715
1922
 
1716
- Live Antigravity hook/session-state resume metadata remains a separate,
1923
+ Live Antigravity hook resume metadata remains a separate,
1717
1924
  high-confidence lane; it is not enumerated from disk by the picker. Within the
1718
1925
  picker's disk discovery, source order is the workspace-to-latest-UUID mapping
1719
1926
  in `cache/last_conversations.json`, workspace-bearing summarized rows in
@@ -1727,13 +1934,18 @@ conversation history. Cache rows have medium confidence and blank turns;
1727
1934
  summary. Legacy history is low confidence. Missing/malformed cache, stale
1728
1935
  missing-DB mappings, workspace-less metadata, and unknown fields degrade
1729
1936
  without failing Claude/Codex or legacy discovery.
1730
- Settings > AI Settings > Enabled agents controls Claude/Codex/Antigravity launch
1731
- visibility. Disabled agents are hidden from the selective picker and from the
1937
+ `Settings > Global > AI > Enabled providers`, or
1938
+ `projmux config providers [--enable <id> | --disable <id>]` through the same
1939
+ writer, controls Claude/Codex/Antigravity launch visibility. Disabled
1940
+ providers are hidden from the selective picker and from the
1732
1941
  default-mode picker. A saved default that later becomes disabled fails clearly
1733
1942
  instead of falling back to another agent. Direct
1734
1943
  Canonical `create agent --provider <p>` launches and the provider shortcuts also
1735
1944
  fail when disabled. If all AI agents are disabled, the selective picker still offers the
1736
1945
  plain `shell` split and shows guidance to re-enable Claude/Codex/Antigravity.
1946
+ While at least one agent is enabled, the selective picker also offers a `resume`
1947
+ row between the agents and `shell`; it opens the resume session list in the
1948
+ same popup.
1737
1949
  For user-level skill, slash-command, editor, or launcher registrations that
1738
1950
  call this contract, see [AI Agent Shortcuts](ai-agent-shortcuts.md).
1739
1951
 
@@ -1793,22 +2005,21 @@ precedence over catalog `action` for known Claude events too; for example a
1793
2005
  noisy notify event can be made state-only or quiet without changing installed
1794
2006
  Claude hook commands.
1795
2007
 
1796
- `ingest antigravity-hook` is the hook/statusline entrypoint for
2008
+ `ingest antigravity-hook` is the hook entrypoint for
1797
2009
  Antigravity CLI `agy` payloads. Official v1.1.12 hook commands must pass their
1798
2010
  event identity explicitly, for example
1799
2011
  `projmux internal agent-hook ingest antigravity-hook --event Stop`; the official stdin payload
1800
2012
  does not carry an event field. The explicit selector is authoritative, while
1801
2013
  payload `eventName` and its legacy aliases remain fallback inputs for existing
1802
2014
  manual wiring. `projmux agent integrate antigravity` manages exactly the named
1803
- `projmux` entry in `~/.gemini/config/hooks.json` and, separately, exactly the
1804
- `statusLine` member in `~/.gemini/antigravity-cli/settings.json`. The managed
1805
- statusline uses the official v1.1.12 `{type:"command", enabled:true,
1806
- stack_with_default:true}` shape and an absolute direct ingest command whose
1807
- stdout is empty, so the built-in statusline remains visible. It preserves every
2015
+ `projmux` entry in `~/.gemini/config/hooks.json`. It never creates or writes
2016
+ `~/.gemini/antigravity-cli/settings.json` and does not judge its `statusLine`;
2017
+ only `--remove` also strips a `statusLine` that an older projmux installed
2018
+ (its command carries `projmux-managed:antigravity-statusline:v1`), and
2019
+ `projmux config apply` removes that legacy entry on upgrade. It preserves every
1808
2020
  other named entry and unknown JSON value, resolves the running projmux
1809
2021
  executable to a stable absolute path, and supports `--dry-run` and `--remove`.
1810
- An existing unmanaged custom `statusLine` is an actionable conflict and is
1811
- never chained, wrapped, or rewritten. An existing
2022
+ An existing
1812
2023
  unmanaged `projmux` entry, another Antigravity projmux ingest command, malformed
1813
2024
  JSON, symlinks, and read/write permission failures are reported without
1814
2025
  rewriting the file. Doctor and Settings also report a managed entry as `stale`
@@ -1819,8 +2030,8 @@ The embedded v1.1.12 catalog contains the five official events `PreToolUse`,
1819
2030
  `PostToolUse`, `PreInvocation`, `PostInvocation`, and `Stop`. The managed entry
1820
2031
  installs `PreInvocation`, `PostInvocation`, `PostToolUse`, and `Stop`, each with
1821
2032
  an explicit `--event`; `PreToolUse` remains disabled because its response can
1822
- change permission policy. `Statusline` remains an explicit statusline selector
1823
- outside that official hook catalog.
2033
+ change permission policy. A leftover `--event Statusline` call from an older
2034
+ statusLine bridge exits 0 with empty stdout and changes nothing.
1824
2035
 
1825
2036
  `PreInvocation` moves the matched pane to thinking/busy without notifying.
1826
2037
  `PostInvocation` and `PostToolUse` remain quiet bookkeeping paths, with tool
@@ -1828,13 +2039,9 @@ errors retained in ingest diagnostics. `Stop` keeps the completion/error notify
1828
2039
  classification. Hook stdout is `{}` for the three non-Stop managed events and
1829
2040
  `{"decision":"stop"}` for Stop, including a shell fallback if ingest fails, so
1830
2041
  the hook cannot force continuation or synthesize a permission decision.
1831
- Official statusline `agent_state` values `thinking`, `working`, and `tool_use`
1832
- map to thinking/busy unless the pane already holds a terminal completion or
1833
- approval state; this prevents a late statusline refresh from regressing `Stop`.
1834
2042
  A new `PreInvocation` resets the pane to thinking for the next generation.
1835
- `idle` is quiet and does not clear an existing completion or approval state.
1836
- `tool_confirmation_pending=true` produces a stable-ID,
1837
- deduped approval-required row; false never produces a notification.
2043
+ Antigravity has no official approval-required or mid-turn busy event, so
2044
+ projmux reports neither for Antigravity.
1838
2045
 
1839
2046
  The managed JSON is the install source of truth. The command
1840
2047
  `agy -p '/hooks' --output-format json` is a read-only runtime diagnostic for
@@ -1850,19 +2057,11 @@ unknown reasons remain info completions with diagnostic metadata rather than
1850
2057
  being promoted to critical. Official camelCase fields retained by the parser
1851
2058
  also include `artifactDirectoryPath`, `modelName`, `invocationNum`,
1852
2059
  `initialNumSteps`, `toolCall`, `stepIdx`, `executionNum`, and `fullyIdle`.
1853
- Antigravity notify metadata uses `agent=antigravity`. Phase 3 session-state
1854
- restore is included: Antigravity ingest stores `conversationId` as pane thread
1855
- metadata for matching and as session-state resume metadata. Restore uses
1856
- `agy --conversation <uuid>` when that id is present and UUID-shaped; otherwise
1857
- session-state preview/doctor render `resume unavailable`. Structured statusline
1858
- `context_window.used_percentage` is persisted with its conversation id as
1859
- private hook/notify diagnostic metadata and is not surfaced as account usage.
1860
- The official `quota` map is persisted independently and surfaces each valid entry as
1861
- `quota/<exact bucket ID>` with independently retained absolute and relative
1862
- reset values. Bucket IDs are never mapped to `5h`/`weekly`, and account quota
1863
- is never inferred from the conversation-local gauge.
1864
- The earlier string percentage form remains a compatibility fallback.
1865
- Transcript contents are not read.
2060
+ Antigravity notify metadata uses `agent=antigravity`. Antigravity ingest stores
2061
+ `conversationId` as pane thread metadata for matching and as Agent resume
2062
+ metadata. Resume uses `agy --conversation <uuid>` when that id is present and
2063
+ UUID-shaped and is refused otherwise. projmux records no Antigravity usage,
2064
+ context, or quota. Transcript contents are not read.
1866
2065
 
1867
2066
  The canonical `internal agent-hook ingest bell --pane <pane_id>` route is the
1868
2067
  narrow tmux-bell fallback ingest path.
@@ -2046,6 +2245,8 @@ projmux internal tmux popup-sessions
2046
2245
  projmux internal tmux popup-preview <session>
2047
2246
  projmux internal tmux rebalance-panes
2048
2247
  projmux internal tmux rename-pane <pane> <label>
2248
+ projmux internal tmux window-rename --client <key> --anchor <%pane> (--name-stdin | -- <name>)
2249
+ projmux internal tmux pane-rename --client <key> --anchor <%pane> (--name-stdin | -- <name>)
2049
2250
  projmux internal tmux print-config [--bin <path>]
2050
2251
  projmux internal tmux print-app-config [--bin <path>]
2051
2252
  projmux internal tmux install [--bin <path>] [--config <path>] [--include <path>]
@@ -2059,10 +2260,18 @@ accepted by `popup-toggle` mirror the historical sessionizer surface:
2059
2260
  `notify-sidebar`, `recent-windows`, `resource-inspector`, `ai-split-picker-right`,
2060
2261
  `ai-split-picker-down`, `ai-split-resume-right`, `ai-split-resume-down`,
2061
2262
  `ai-split-settings`.
2062
- `rename-pane` sets only the pane-scoped user label
2063
- `@projmux_pane_label`; an empty label clears the option. It does not change the
2064
- raw tmux pane title, AI topic, or AI topic manual-ownership flag. The canonical
2065
- keybinding action id is `rename-pane-label`. The retired `rename-pane-topic`
2263
+ `rename-pane` is a label-only helper: it sets only the pane-scoped
2264
+ `@projmux_pane_label`, and an empty label clears the option. It does not change
2265
+ the Registry Pane name, so the next Continue restores that name, and it does not
2266
+ change the raw tmux pane title, AI topic, or AI topic manual-ownership flag. No
2267
+ generated binding uses it.
2268
+ `window-rename` and `pane-rename` are the generated rename routes behind the
2269
+ `rename-window` and `rename-pane-label` keybinding actions and the Window menu
2270
+ Rename item. They resolve the anchor Pane to its exact Registry Window or Pane
2271
+ and rename it through the same owner as `projmux rename window|pane`, then
2272
+ report one line to the client. The generated bindings pass the prompt response
2273
+ with `--name-stdin` inside a quoted here-document; see
2274
+ [keybindings.md](keybindings.md#rename-keys) for the input rules. The retired `rename-pane-topic`
2066
2275
  keymap action is no longer accepted: replace a stale
2067
2276
  `[bindings.rename-pane-topic]` table with `[bindings.rename-pane-label]`.
2068
2277
  The `projmux agent topic set/clear` commands keep
@@ -2196,7 +2405,7 @@ The live tmux inventory is under `runtime`: `runtime sessions`, `runtime
2196
2405
  attach`, `runtime stop`, `runtime tag`, and `runtime prune`. Project pins use
2197
2406
  `pin project list|add|remove|toggle|clear|migrate`; `list` takes `--kind
2198
2407
  project|candidate` and `migrate` takes `--dry-run`. Resource retention uses `prune
2199
- project|snapshot`, while explicit snapshot deletion uses `delete snapshot`.
2408
+ agent|project`.
2200
2409
 
2201
2410
  Popup-marker, preview, status, and tmux configuration plumbing is hidden under
2202
2411
  `internal session-popup`, `internal preview`, `internal status`, `internal
@@ -2209,35 +2418,24 @@ human configuration work should prefer `config render` and `config apply`.
2209
2418
  generated config. The generated app config uses absolute `$SHELL` as the
2210
2419
  tmux default shell when set, otherwise `/bin/sh`. `shell` starts or attaches
2211
2420
  the app session directly after resolving the target app session name and
2212
- startup directory. With no saved startup preference, Alt-1 sidebar project
2213
- open defaults to a two-action picker containing exactly `Continue project`
2214
- and `Recreate Project`; Esc returns to Projects without writing config. Saved `on`
2215
- keeps that picker, while saved `off` skips it and preserves the existing
2216
- automatic registered-Continue/unregistered-Fresh decision. `Continue
2217
- project` restores a deleted Project only from its usable exact snapshot and
2218
- otherwise refuses with zero Registry writes. `Recreate Project` confirms the
2421
+ startup directory. Alt-1 sidebar open of a registered closed Project shows a
2422
+ two-action picker containing exactly `Continue project` and
2423
+ `Clear layout and open`; Esc returns to Projects without writing config. A
2424
+ root that is not a registered Project skips the picker and opens fresh.
2425
+ `Continue
2426
+ project` on a root that is not a registered Project, including a deleted one,
2427
+ refuses with zero Registry writes and points to `Clear layout and open`. `Clear layout and open` confirms the
2219
2428
  exact old Project UID and its counts, then atomically replaces the Project
2220
2429
  with a new Project/Window/shell UID chain and one same-root claimant. A
2221
2430
  declined confirmation returns to the startup rows and writes nothing.
2222
- Repeating it allocates another new identity. Neither action modifies snapshot
2223
- bytes, the project directory, git/worktrees, unrelated roots, or trust state.
2224
- - `quit` — open an action picker with `Save Project snapshots and quit`, `Quit
2225
- without saving`, and `Cancel`. The safe first action takes one complete,
2226
- exact-socket Registry/resource-graph observation, freezes every live managed
2227
- Project session in Project UID/session order, and captures each latest
2228
- snapshot even when auto-save is off. Home/control, ephemeral, unattributed,
2229
- recoverable, foreign, and offline sessions are excluded and reported as
2230
- bounded class counts. Every target is attempted. A failed capture leaves the
2231
- successful per-session atomic files in place, reports the exact failed
2232
- session, and does not stop the app; retry captures every target again. Only an
2233
- all-success ledger reaches the existing physical-socket, app-marker, and
2234
- logical-route guarded shutdown. Named snapshots and Registry bytes are never
2235
- written, and the batch is not a multi-file transaction or topology freeze.
2236
- `Quit without saving` preserves the earlier guarded shutdown behavior:
2237
- missing servers and runtimes without the app marker are no-ops. Existing
2238
- non-interactive `--yes` and `--force` callers retain that same snapshot-free
2239
- behavior and exact shutdown route; the default command always uses the
2240
- action picker.
2431
+ Repeating it allocates another new identity. Neither action modifies the
2432
+ project directory, git/worktrees, unrelated roots, or trust state.
2433
+ - `quit` — open an action picker with `Quit projmux` and `Cancel`. `Quit
2434
+ projmux` runs the physical-socket, app-marker, and logical-route guarded
2435
+ shutdown; missing servers and runtimes without the app marker are no-ops.
2436
+ Quit never saves Project state. Non-interactive `--yes` and
2437
+ `--force` callers use the same shutdown route without the picker; the
2438
+ default command always uses the action picker.
2241
2439
  - `attach project <ref>` — enter a Project runtime from outside tmux.
2242
2440
  Automatic live-runtime attachment is `runtime attach`.
2243
2441
  - `settings` — interactive configuration UI for the project picker, AI