projmux 0.12.2 → 0.13.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.
- package/README.md +3 -0
- package/docs/agent-workflow.md +277 -20
- package/docs/ai-agent-shortcuts.md +22 -3
- package/docs/architecture.md +1291 -90
- package/docs/cli-guide.md +572 -69
- package/docs/cli.md +498 -67
- package/docs/configuration.md +220 -35
- package/docs/hooks.md +17 -3
- package/docs/install.md +23 -7
- package/docs/keybindings.md +5 -3
- package/docs/legacy-cli-retirement.md +37 -8
- package/docs/operational-diagnostics.md +58 -2
- package/docs/session-restore.md +73 -157
- package/docs/settings-ia.md +48 -24
- package/docs/statusbar.md +10 -2
- package/docs/testing.md +93 -10
- package/docs/troubleshooting.md +157 -0
- package/docs/upgrading.md +266 -11
- package/docs/usage-tracking.md +56 -10
- package/package.json +5 -5
package/docs/configuration.md
CHANGED
|
@@ -56,10 +56,46 @@ The saved workdir file is:
|
|
|
56
56
|
It stores one absolute path per line. Lines beginning with `#` are comments.
|
|
57
57
|
The file is read only when no env root list is set.
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
Workdirs are a **scan source and nothing else**. Adding a root, and scanning one,
|
|
60
|
+
never registers a Registry Project: a discovered child is an unregistered
|
|
61
|
+
candidate until `projmux create project --root <path>` or opening it once from the
|
|
62
|
+
Projects sidebar registers that exact path. See
|
|
63
|
+
[upgrading.md](upgrading.md#discovery-no-longer-registers-projects).
|
|
60
64
|
|
|
61
|
-
Project
|
|
62
|
-
|
|
65
|
+
## Project pins
|
|
66
|
+
|
|
67
|
+
Pins are presentation preferences, stored typed:
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
~/.config/projmux/pins
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
projmux-pins v2
|
|
75
|
+
project proj-kwo4qozry2sr2ycij2g45zyvam
|
|
76
|
+
candidate /home/dev/src/scratch
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
A `project` pin references a Registry Project uid, so its displayed root and name
|
|
80
|
+
come from the Registry and the pin survives a rebind, a rename, and a missing
|
|
81
|
+
root. A `candidate` pin references a path no Project claims. Neither kind is a
|
|
82
|
+
discovery source and neither is managed identity.
|
|
83
|
+
|
|
84
|
+
`projmux pin project list [--kind project|candidate]` prints both collections with
|
|
85
|
+
their kind. `pin project add|remove|toggle <dir>` accepts the same directory
|
|
86
|
+
argument it always has and resolves it to a typed pin — exactly one Project with
|
|
87
|
+
that root makes the pin managed, none makes it a candidate, more than one is
|
|
88
|
+
refused — with `uid:<uid>` available to name a Project directly.
|
|
89
|
+
|
|
90
|
+
A pre-v2 file of bare paths is read without being rewritten and migrated only on
|
|
91
|
+
request with `projmux pin project migrate`; see
|
|
92
|
+
[upgrading.md](upgrading.md#pins-are-typed-and-migrate-on-request) for the
|
|
93
|
+
per-line outcomes and the ambiguity refusal.
|
|
94
|
+
|
|
95
|
+
## Legacy Project Layout Snapshots
|
|
96
|
+
|
|
97
|
+
Older checkouts may already have named layout snapshots in the legacy storage
|
|
98
|
+
directory:
|
|
63
99
|
|
|
64
100
|
```text
|
|
65
101
|
<project>/.projmux/layouts/<name>.toml
|
|
@@ -68,9 +104,9 @@ checkouts may already have named snapshots in the legacy storage directory:
|
|
|
68
104
|
The project context comes from `PROJMUX_CWD` when set, otherwise projmux walks
|
|
69
105
|
upward from the current directory to the nearest `.projmux` or `.git` marker.
|
|
70
106
|
Files outside that project tree are not discovered. This storage is treated as
|
|
71
|
-
legacy import data for
|
|
72
|
-
|
|
73
|
-
layout or preset feature.
|
|
107
|
+
legacy import data for explicit conversion and preview. Closed-Project startup
|
|
108
|
+
does not expose legacy snapshot choices; current user-facing surfaces describe
|
|
109
|
+
the restore unit as a snapshot, not as a separate layout or preset feature.
|
|
74
110
|
|
|
75
111
|
The legacy schema is intentionally close to the session-state snapshot shape:
|
|
76
112
|
|
|
@@ -159,9 +195,12 @@ marker-only edit with a digest-named pre-v2 backup. [docs/keybindings.md](keybin
|
|
|
159
195
|
table, the upgrade ordering and the downgrade procedure.
|
|
160
196
|
|
|
161
197
|
This marker is a separate version domain from the CLI resource registry's
|
|
162
|
-
`apiVersion: projmux.io/v1alpha1` / camelCase `schemaVersion:
|
|
198
|
+
`apiVersion: projmux.io/v1alpha1` / camelCase `schemaVersion: 2` envelope. The
|
|
163
199
|
two have separate markers, separate backups and separate rollbacks; neither one
|
|
164
|
-
failing affects the other.
|
|
200
|
+
failing affects the other. A successful Registry v1 → v2 migration keeps its
|
|
201
|
+
private repair/loss evidence at `<exact-versioned-backup>.migration-report.json`,
|
|
202
|
+
including that backup's absolute path and SHA-256; failed or repeated passes
|
|
203
|
+
publish no report.
|
|
165
204
|
|
|
166
205
|
Legacy `prefix = ...` entries still parse during migration so existing files
|
|
167
206
|
do not break. Settings preserves existing prefix entries when rewriting the
|
|
@@ -380,6 +419,104 @@ warning with the unsupported value and source.
|
|
|
380
419
|
Project-local locale override is not part of the runtime policy. Locale is a
|
|
381
420
|
user/global preference in this release.
|
|
382
421
|
|
|
422
|
+
## Codex app-server health
|
|
423
|
+
|
|
424
|
+
Settings > AI includes a read-only `Codex control plane` row. It reports one of
|
|
425
|
+
`App Server`, `Hook fallback`, or `Unavailable`, together with the existing
|
|
426
|
+
effective reason. Endpoint readiness, running executable/version, official
|
|
427
|
+
daemon-manager ownership, and remote-control capability are separate closed
|
|
428
|
+
axes. Separate `probe_reason` and `install_capability` fields preserve the
|
|
429
|
+
app-server root cause and bounded PATH/managed-payload topology. Lifecycle
|
|
430
|
+
outcome/reason and sanitized CLI, managed, and running versions remain
|
|
431
|
+
independent. Read-only surfaces report `not-attempted/read-only`.
|
|
432
|
+
`projmux doctor --section integrations` and explicit support reports expose the
|
|
433
|
+
same bounded fields without executable/socket paths, prompts, tokens, process
|
|
434
|
+
output, or response payloads.
|
|
435
|
+
|
|
436
|
+
There is no app-server source setting or environment override. Authority is a
|
|
437
|
+
capability result, not a preference: Projmux probes the existing local control
|
|
438
|
+
socket through `codex app-server proxy`, reads official manager evidence through
|
|
439
|
+
`codex app-server daemon version`, and reads remote-control state through
|
|
440
|
+
`remoteControl/status/read`, all with short timeouts. An older endpoint that
|
|
441
|
+
does not expose the last method reports `unsupported` on that axis without
|
|
442
|
+
hiding endpoint readiness. Doctor, Settings, and support reports never start or
|
|
443
|
+
otherwise mutate the daemon, configuration, login state, or control socket.
|
|
444
|
+
|
|
445
|
+
An `external-cli-only` install capability acknowledges that the ordinary CLI
|
|
446
|
+
exists while the canonical managed daemon payload was not observed. It does
|
|
447
|
+
not identify a package manager. Install topology is not manager ownership:
|
|
448
|
+
only the official daemon response's backend field proves a managed process.
|
|
449
|
+
|
|
450
|
+
The Codex integration has a lifecycle seam for later native features. Only an
|
|
451
|
+
actual native user action may use it. A ready unmanaged, version-skewed, or
|
|
452
|
+
ownership/version-unknown endpoint is refused without mutation and reports the
|
|
453
|
+
shared-client interruption risk plus bounded operator recovery. Only an exact
|
|
454
|
+
missing or connection-refused default control socket is start-eligible. That path invokes the
|
|
455
|
+
official idempotent `codex app-server daemon start` command at most once per
|
|
456
|
+
in-flight process decision, then retries proxy initialization with a bounded
|
|
457
|
+
backoff. Projmux never automatically stops, kills, restarts, adopts, or enables
|
|
458
|
+
remote control on the shared app server.
|
|
459
|
+
|
|
460
|
+
The default `Codex` row in the provider picker launches immediately through the
|
|
461
|
+
canonical create route. It does not start or probe the app-server, call
|
|
462
|
+
`model/list`, or add `--model` or `model_reasoning_effort`; the Codex process
|
|
463
|
+
therefore keeps its own configured defaults.
|
|
464
|
+
|
|
465
|
+
The separate `Codex advanced launch` action uses the readiness path to read
|
|
466
|
+
every page of the current app-server `model/list`. Its second picker shows only
|
|
467
|
+
visible models and their advertised reasoning efforts. The display also carries
|
|
468
|
+
the advertised default, supported input modalities, and whether personality is
|
|
469
|
+
supported; the boolean personality capability is not expanded into invented
|
|
470
|
+
personality choices. The selected model and effort are launch-only CLI
|
|
471
|
+
overrides (`--model` and `--config model_reasoning_effort=...`); Projmux never
|
|
472
|
+
writes a Codex configuration file. Each normalized catalog is tied to its live
|
|
473
|
+
connection and negotiated-version epoch. Projmux retains that connection from
|
|
474
|
+
picker render through pre-create validation and refreshes `model/list` before
|
|
475
|
+
building argv, so a disconnect or removed option invalidates the selection. If
|
|
476
|
+
advanced discovery fails, is empty, or comes from an older Codex, that action
|
|
477
|
+
reports the exact unavailable reason and creates nothing; the separate default
|
|
478
|
+
`Codex` row remains available.
|
|
479
|
+
|
|
480
|
+
Picker chrome and semantic annotations such as default, unspecified modality,
|
|
481
|
+
and personality support use the Projmux message catalog. Model display names,
|
|
482
|
+
effort identifiers, and advertised modality tags remain exact provider data and
|
|
483
|
+
are not translated.
|
|
484
|
+
|
|
485
|
+
`projmux agent review` starts `review/start` only for a Running Codex Agent whose
|
|
486
|
+
Registry Agent, owned Pane, activation generation, stored thread, and live Pane
|
|
487
|
+
thread all match exactly. Review availability is based on the negotiated
|
|
488
|
+
app-server version for that connection and is confirmed by the method call;
|
|
489
|
+
Codex 0.149 does not advertise a separate review capability bit. Older versions
|
|
490
|
+
or a method-not-found response are reported explicitly as unavailable. The
|
|
491
|
+
initial `review/start` response is projected into Agent interaction lifecycle;
|
|
492
|
+
the lifecycle observer described below owns later app-server terminal events.
|
|
493
|
+
|
|
494
|
+
A natively created or resumed Codex Agent keeps a content-free lifecycle
|
|
495
|
+
observer on its exact Agent UID, Pane UID/runtime handle, activation generation,
|
|
496
|
+
and thread ID. While its initialized proxy connection and snapshot are current,
|
|
497
|
+
the app server is the only attention authority: active, idle, waiting for input,
|
|
498
|
+
and exact unresolved approval requests project the Agent interaction and badge.
|
|
499
|
+
Only an exact successful `turn/completed` projects response-complete and queues a
|
|
500
|
+
completion notification; failed and interrupted turns become idle. Disconnect
|
|
501
|
+
and thread unload first invalidate the epoch and clear stale attention, then
|
|
502
|
+
enable hook fallback. A reconnect starts a new epoch from `thread/read`; events
|
|
503
|
+
from older epochs or other identities are ignored.
|
|
504
|
+
|
|
505
|
+
`describe agent` and the Codex Agent event Settings page report the effective
|
|
506
|
+
lifecycle source, a closed reason, and active/pending/inactive epoch status.
|
|
507
|
+
These diagnostics never retain prompts, reasoning, output, approval reasons, or
|
|
508
|
+
diff content. Settings aggregates multiple live Codex Panes as counts and says
|
|
509
|
+
`mixed` when native and fallback authority coexist.
|
|
510
|
+
|
|
511
|
+
Projmux does not install, bootstrap, restart, stop, or reconfigure the Codex
|
|
512
|
+
daemon, does not stop the shared daemon when Projmux exits, and does not manage
|
|
513
|
+
Codex authentication. There is no custom socket or remote-control setting.
|
|
514
|
+
The semantic approval/completion policy below drives the same badge, queue, and
|
|
515
|
+
desktop intent for both app-server and hook-fallback authority. Existing
|
|
516
|
+
`ai-hook-actions.json` values remain byte-for-byte unchanged and, when an exact
|
|
517
|
+
runtime override exists, take precedence only while hook fallback is current;
|
|
518
|
+
they are never inferred or copied into the semantic policy store.
|
|
519
|
+
|
|
383
520
|
## AI Resume Picker
|
|
384
521
|
|
|
385
522
|
The Agent resume picker lists the most recent
|
|
@@ -424,6 +561,19 @@ column (`./`, `./web`, `./api`) so child-directory sessions are easy to tell
|
|
|
424
561
|
apart. A missing or zero depth is identical to the historical behavior. Settings
|
|
425
562
|
edits write the global config.
|
|
426
563
|
|
|
564
|
+
Codex uses the local app-server conversation catalog as its primary source.
|
|
565
|
+
Each picker invocation follows opaque `thread/list` cursors to completion with
|
|
566
|
+
explicit `cli`, `vscode`, and `appServer` source kinds, non-archived filtering,
|
|
567
|
+
provider recency ordering, and exact-cwd filtering at depth 0. Wider depth is a
|
|
568
|
+
bounded client-side path-tree filter. Native rows use the exact thread id, the
|
|
569
|
+
provider-owned name (or only a short id when unnamed), git branch, and runtime
|
|
570
|
+
status; prompt preview and transcript turns are never read for titles. If the
|
|
571
|
+
native catalog is unavailable, unsupported, malformed, or returns invalid
|
|
572
|
+
pagination, that invocation discards all native rows and performs one rollout
|
|
573
|
+
fallback. The picker annotates Codex rows with source, confidence, runtime
|
|
574
|
+
status, and a closed fallback reason, so native and rollout rows are never
|
|
575
|
+
silently merged.
|
|
576
|
+
|
|
427
577
|
Antigravity uses the upstream v1.1.12 current-storage boundary before its
|
|
428
578
|
legacy history fallback. `cache/last_conversations.json` contributes the latest
|
|
429
579
|
UUID mapped to a matching workspace; `cache/conversation_metadata.json`
|
|
@@ -439,6 +589,13 @@ is not a disk-picker candidate. When a disk picker selection creates a pane,
|
|
|
439
589
|
its source is persisted so Session State preview and doctor can report medium
|
|
440
590
|
confidence for DB-validated cache sources or low confidence for legacy history.
|
|
441
591
|
|
|
592
|
+
Session State saves the exact bound Codex session/thread id before considering
|
|
593
|
+
discovery. An existing bound session id or persisted resume id is replayed
|
|
594
|
+
without an app-server read. Only a thread-only candidate is validated with
|
|
595
|
+
`thread/read` and `includeTurns=false`; this validation is probe-only and never
|
|
596
|
+
starts the shared daemon. Failure retains the persisted id or uses the current
|
|
597
|
+
rollout fallback, and a read response can never substitute a different id.
|
|
598
|
+
|
|
442
599
|
## Environment Variables
|
|
443
600
|
|
|
444
601
|
| Variable | Purpose |
|
|
@@ -589,6 +746,21 @@ overrides catalog `action` values during ingest, including known Codex and
|
|
|
589
746
|
Claude events. It does not change hook installation; `projmux agent integrate`
|
|
590
747
|
continues to use the embedded/local catalog `install` fields.
|
|
591
748
|
|
|
749
|
+
Codex native lifecycle semantics are stored separately at:
|
|
750
|
+
|
|
751
|
+
```text
|
|
752
|
+
${XDG_CONFIG_HOME:-$HOME/.config}/projmux/ai-semantic-policies.json
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
The two closed events are `approval_required` and `response_complete`. Each can
|
|
756
|
+
be `notify` (badge + queue + desktop), `state` (badge only), or `quiet` (no
|
|
757
|
+
badge, queue, or desktop). Settings labels these choices `Notify`, `State only`,
|
|
758
|
+
and `Quiet`. The selected intent applies to both the app-server epoch and hook
|
|
759
|
+
fallback. An explicit raw `PermissionRequest` or `Stop` runtime override takes
|
|
760
|
+
precedence only during hook fallback; catalog defaults do not override this
|
|
761
|
+
semantic store. Saving this file does not infer from, rewrite, or normalize the
|
|
762
|
+
raw hook override file.
|
|
763
|
+
|
|
592
764
|
Delivery depends on the event handler. Specialized notify handlers, such as
|
|
593
765
|
Codex `PermissionRequest` and `Stop`, can write the in-app notify queue and use
|
|
594
766
|
the configured OS desktop notification path. Known Codex events without a
|
|
@@ -699,33 +871,31 @@ override with `inherit`, `on`, and `off`; `inherit` follows the global value,
|
|
|
699
871
|
while `on` and `off` take precedence. Auto-save only updates the latest
|
|
700
872
|
snapshot. Named snapshots are manual and are never updated by auto-save.
|
|
701
873
|
|
|
702
|
-
Project open from the Alt-1 sidebar defaults to
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
the self-closing sidebar process to keep running. Deny/cancel refreshes the
|
|
721
|
-
original sidebar query/selection context with a visible status message. Existing
|
|
722
|
-
sessions switch directly without a startup picker.
|
|
874
|
+
Project open from the Alt-1 sidebar defaults to `Continue project`, which
|
|
875
|
+
materializes the closed Project's current Registry desired state before moving
|
|
876
|
+
the client. The optional `Settings > Session State > Sidebar startup picker`
|
|
877
|
+
toggle enables a native `Start project` step with exactly `Continue project` and
|
|
878
|
+
`Open fresh`. `Open fresh` confirms exact `Window n / Pane n / Agent n` counts
|
|
879
|
+
and conversation-pointer loss, then atomically replaces the old Project graph
|
|
880
|
+
with a new Project UID and a new canonical Window/shell UID pair. Exactly one
|
|
881
|
+
same-root Project claimant remains. Snapshot bytes, the root directory,
|
|
882
|
+
Git/worktree data, and the trust decision remain unchanged. Esc returns to
|
|
883
|
+
Projects with zero writes. After
|
|
884
|
+
the startup mode is selected, project automation trust is evaluated if needed.
|
|
885
|
+
The Alt-1 sidebar opens trust as the shared client-scoped `Trust project
|
|
886
|
+
automation` popup instead of inline sidebar rows. The selected open
|
|
887
|
+
continuation runs in a detached tmux job that can close the sidebar before trust
|
|
888
|
+
without depending on the self-closing sidebar process to keep running.
|
|
889
|
+
Deny/cancel refreshes the original sidebar query/selection context with a
|
|
890
|
+
visible status message. Existing sessions switch directly without a startup
|
|
891
|
+
picker.
|
|
723
892
|
|
|
724
893
|
Default `projmux shell` no longer opens a startup picker or replays session-state
|
|
725
894
|
snapshots before attach. It still derives the default app session identity and
|
|
726
895
|
startup directory from the current project context when available; otherwise it
|
|
727
|
-
uses the `home` target and home directory.
|
|
728
|
-
|
|
896
|
+
uses the `home` target and home directory. Snapshot restore is an explicit CLI
|
|
897
|
+
operation that requires both the source session and the exact target Project;
|
|
898
|
+
it is not a Project-startup choice.
|
|
729
899
|
|
|
730
900
|
Settings > Session State is global settings only: global auto-save, auto-save
|
|
731
901
|
interval, and storage/retention policy. Settings > Project > Session State
|
|
@@ -749,7 +919,8 @@ Manual snapshot actions are available from the CLI:
|
|
|
749
919
|
projmux get snapshots
|
|
750
920
|
projmux create snapshot
|
|
751
921
|
projmux delete snapshot [--session <name>]
|
|
752
|
-
projmux restore snapshot --
|
|
922
|
+
projmux restore snapshot --session <snapshot-session> [--project <ref> | -p <ref>] --dry-run
|
|
923
|
+
projmux restore snapshot --session <snapshot-session> [--project <ref> | -p <ref>] --yes [--client <tmux-client>]
|
|
753
924
|
```
|
|
754
925
|
|
|
755
926
|
`status` prints the source label (`autosave`, `layout(<name>)`, or `fresh`), the
|
|
@@ -758,8 +929,21 @@ target session. Older snapshots without a source field display as `autosave`.
|
|
|
758
929
|
`save` captures the current tmux session immediately and intentionally bypasses
|
|
759
930
|
the autosave debounce and disabled-autosave gate; it still requires a current
|
|
760
931
|
tmux session. `delete` removes the target snapshot without an interactive
|
|
761
|
-
confirmation.
|
|
762
|
-
|
|
932
|
+
confirmation. Restore treats the snapshot as desired-state input for one exact
|
|
933
|
+
closed Project, never as a global Registry replacement or tmux replay.
|
|
934
|
+
`--dry-run` prints scoped projection counts with zero writes. `--yes` commits
|
|
935
|
+
that target subtree atomically, runs the ordinary materializer, and performs an
|
|
936
|
+
explicit client handoff last when `--client` is present. Restore never modifies
|
|
937
|
+
or deletes the source snapshot.
|
|
938
|
+
|
|
939
|
+
Interactive `projmux quit` also offers `Save Project snapshots and quit`. It
|
|
940
|
+
recaptures the latest snapshot for every live Registry-bound Project on the
|
|
941
|
+
exact app server, regardless of the global or Project auto-save toggle, and
|
|
942
|
+
stops the server only after all captures succeed. A partial failure keeps the
|
|
943
|
+
server running and keeps each successful atomic snapshot for inspection or
|
|
944
|
+
retry. Control/Home, ephemeral, unmanaged, conflicted, and sibling-server
|
|
945
|
+
sessions are never promoted into Project snapshots. `Quit without saving`,
|
|
946
|
+
`quit --yes`, and `quit --force` perform no snapshot inventory or store I/O.
|
|
763
947
|
|
|
764
948
|
## Decoration Mode
|
|
765
949
|
|
|
@@ -807,7 +991,8 @@ The saved values are `on` or `off` in these files:
|
|
|
807
991
|
~/.config/projmux/statusbar-visibility-agent-usage-window-antigravity-weekly
|
|
808
992
|
```
|
|
809
993
|
|
|
810
|
-
Missing, empty, and invalid values resolve to the
|
|
994
|
+
Missing, empty, and invalid values resolve to `on` except the Codex `5h`
|
|
995
|
+
window, whose ambient HUD default is `off`; an explicit saved `on` restores it.
|
|
811
996
|
Settings shows whether the effective value came from `saved` or `default` and
|
|
812
997
|
marks an invalid saved value as ignored. Saving a toggle regenerates the app
|
|
813
998
|
and standalone tmux output, and Settings source-reloads the generated app config
|
package/docs/hooks.md
CHANGED
|
@@ -239,6 +239,17 @@ notify, including unmanaged hooks/conflict details and the relevant
|
|
|
239
239
|
hooks-engine events. It reads a single JSON payload from stdin. The embedded
|
|
240
240
|
default install catalog is based on Codex CLI 0.130.0:
|
|
241
241
|
|
|
242
|
+
For an exact native app-server Agent, this raw hook path is fallback-only. The
|
|
243
|
+
pane is marked `pending` before its lifecycle observer starts; `pending`,
|
|
244
|
+
`provider-control-plane`, and `invalidating` authority suppress every Codex hook
|
|
245
|
+
event before any badge, queue, desktop, or Registry interaction write. Only
|
|
246
|
+
after the native epoch is invalidated may `provider-hook` become current and the
|
|
247
|
+
table below apply. Existing hook installation and runtime overrides are kept
|
|
248
|
+
byte-for-byte. `PermissionRequest` and `Stop` use the same semantic policy as
|
|
249
|
+
native lifecycle events unless an explicit raw runtime override exists; that
|
|
250
|
+
override regains its existing meaning only in fallback. Catalog defaults are
|
|
251
|
+
not semantic overrides.
|
|
252
|
+
|
|
242
253
|
| Event | Behavior |
|
|
243
254
|
| --- | --- |
|
|
244
255
|
| `PreToolUse` | marks the matched pane hook-active and writes a quiet ingest diagnostic; no notify queue entry is pushed |
|
|
@@ -247,7 +258,7 @@ default install catalog is based on Codex CLI 0.130.0:
|
|
|
247
258
|
| `PostToolUse` | marks the matched pane hook-active and writes a quiet ingest diagnostic; no notify queue entry is pushed |
|
|
248
259
|
| `PreCompact` | marks the matched pane hook-active and writes a quiet ingest diagnostic; no notify queue entry is pushed |
|
|
249
260
|
| `PostCompact` | marks the matched pane hook-active and writes a quiet ingest diagnostic; no notify queue entry is pushed |
|
|
250
|
-
| `SessionStart` | marks the matched pane hook-active and writes a quiet ingest diagnostic; no notify queue entry is pushed |
|
|
261
|
+
| `SessionStart` | marks the matched pane hook-active and writes a quiet ingest diagnostic; for an exact managed initial-task binding it records `pending` startup readiness and opens the separately bounded acknowledgement window, but never acknowledges the task; no notify queue entry is pushed |
|
|
251
262
|
| `Stop` | pushes an info Codex completion row |
|
|
252
263
|
|
|
253
264
|
Codex hook payload parsing accepts the common fields
|
|
@@ -366,7 +377,10 @@ runtime file only changes ingest behavior (`notify`, `state`, or `quiet`);
|
|
|
366
377
|
`projmux agent integrate codex` still uses the catalog `install` field to decide
|
|
367
378
|
which hooks to write. Runtime overrides also apply to known specialized
|
|
368
379
|
events, so `Stop` or `PermissionRequest` can be made state-only or quiet
|
|
369
|
-
without changing which hook commands are installed
|
|
380
|
+
without changing which hook commands are installed while hook fallback is
|
|
381
|
+
current. Without such an explicit override, app-server and hook-fallback
|
|
382
|
+
approval/completion use the same semantic policy described in
|
|
383
|
+
[Configuration](configuration.md#notifications). When a known Codex event
|
|
370
384
|
without a specialized handler, such as `PreToolUse` or `PostToolUse`, is set to
|
|
371
385
|
runtime `notify`, projmux pushes a generic in-app notify row such as
|
|
372
386
|
`PreToolUse · Bash` with agent/category metadata. That generic path is
|
|
@@ -437,7 +451,7 @@ default install catalog is based on Claude Code 2.1.140 and represents the
|
|
|
437
451
|
| `Notification` | pushes a Claude notify row for response-ready, approval-required, or input-ready based on `notification_type` |
|
|
438
452
|
| `UserPromptSubmit` | marks the matched pane hook-active and sets AI state to thinking/busy; no notify queue entry is pushed |
|
|
439
453
|
| `UserPromptExpansion` | marks the matched pane hook-active and writes a quiet ingest diagnostic; no notify queue entry is pushed |
|
|
440
|
-
| `SessionStart` | marks the matched pane hook-active and writes a quiet ingest diagnostic; no notify queue entry is pushed |
|
|
454
|
+
| `SessionStart` | marks the matched pane hook-active and writes a quiet ingest diagnostic; for an exact managed initial-task binding it records `pending` startup readiness and opens the separately bounded acknowledgement window, but never acknowledges the task; no notify queue entry is pushed |
|
|
441
455
|
| `Stop` | pushes a Claude completion row, using the last assistant transcript text when `transcript_path` is readable |
|
|
442
456
|
| `StopFailure` | pushes a critical Claude error row with error type/message metadata when present |
|
|
443
457
|
| `SubagentStart` | marks the matched pane hook-active and writes a quiet ingest diagnostic; no notify queue entry is pushed |
|
package/docs/install.md
CHANGED
|
@@ -21,6 +21,11 @@ projmux doctor
|
|
|
21
21
|
`doctor` performs read-only diagnostics for runtime tools such as `tmux`,
|
|
22
22
|
`git`, and `stty`.
|
|
23
23
|
|
|
24
|
+
If the npm shim reports `unsupported or incomplete npm install`, or a live
|
|
25
|
+
pre-0.13 app server is missing its logical socket marker, use the canonical
|
|
26
|
+
[Troubleshooting](troubleshooting.md) diagnosis and recovery steps. Doctor is
|
|
27
|
+
read-only; its displayed remediation is never executed automatically.
|
|
28
|
+
|
|
24
29
|
Provider integrations are opt-in and use the canonical installer spelling:
|
|
25
30
|
|
|
26
31
|
```sh
|
|
@@ -100,10 +105,15 @@ cd projmux
|
|
|
100
105
|
make install
|
|
101
106
|
```
|
|
102
107
|
|
|
103
|
-
`make install` builds the
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
`make install` builds the candidate, uses that candidate to run
|
|
109
|
+
`config apply --bin <install-target>` before publication, atomically replaces
|
|
110
|
+
`$(go env GOPATH)/bin/projmux`, and runs the installed binary's `config apply`
|
|
111
|
+
again as post-publication verification. This ordering migrates a pre-0.13 live
|
|
112
|
+
server's exact logical socket marker before a consumer that requires it becomes
|
|
113
|
+
reachable. A convergence or publication failure is non-zero and prints the
|
|
114
|
+
exact `projmux config apply --socket <name>` recovery. Successful installs then
|
|
115
|
+
reconcile the notify queue through `projmux notification reconcile`. Override
|
|
116
|
+
the destination with `INSTALL_DIR=/usr/local/bin`.
|
|
107
117
|
|
|
108
118
|
Update source checkouts with the repository workflow:
|
|
109
119
|
|
|
@@ -121,11 +131,14 @@ marked as release-managed:
|
|
|
121
131
|
export PROJMUX_INSTALLER=github-release
|
|
122
132
|
```
|
|
123
133
|
|
|
124
|
-
With that set, `projmux update apply` downloads the latest matching
|
|
125
|
-
asset,
|
|
134
|
+
With that set, `projmux update apply` downloads and verifies the latest matching
|
|
135
|
+
release asset, converges the exact live route before replacement, atomically
|
|
136
|
+
replaces the current executable, and reapplies the live tmux config as
|
|
137
|
+
post-publication verification.
|
|
126
138
|
`--no-apply` skips the live reload only — the new binary still migrates the
|
|
127
139
|
keymap schema and marker-owned provider files, then writes the generated
|
|
128
|
-
config. It
|
|
140
|
+
config. It prints the exact explicit apply required before ordinary mutation
|
|
141
|
+
and does not touch a live tmux bell hook. See
|
|
129
142
|
[Upgrading](upgrading.md#managed-agent-hook-producer-migration).
|
|
130
143
|
|
|
131
144
|
## npm Packaging Details
|
|
@@ -133,3 +146,6 @@ config. It does not touch a live tmux bell hook. See
|
|
|
133
146
|
Repository packaging and publish details are maintained in
|
|
134
147
|
[npm Distribution](npm-distribution.md). That document is for maintainers; end
|
|
135
148
|
users should not need it for installation.
|
|
149
|
+
|
|
150
|
+
For incomplete optional dependencies, Doctor findings, and live app socket
|
|
151
|
+
marker recovery, see [Troubleshooting](troubleshooting.md).
|
package/docs/keybindings.md
CHANGED
|
@@ -239,9 +239,9 @@ by different picker surfaces, while conflicts inside one surface are rejected.
|
|
|
239
239
|
|
|
240
240
|
| Surface action | Meaning |
|
|
241
241
|
| --- | --- |
|
|
242
|
-
| `Sidebar:KillSession` |
|
|
242
|
+
| `Sidebar:KillSession` | Stop only the focused Project runtime; preserve its Project UID and desired Window/Pane topology |
|
|
243
243
|
| `Sidebar:PinProject` | Pin or unpin the focused directory |
|
|
244
|
-
| `SessionPopup:KillSession` |
|
|
244
|
+
| `SessionPopup:KillSession` | Stop only the focused runtime Session; preserve managed Registry identity and desired topology |
|
|
245
245
|
| `SessionPopup:CyclePreviewWindowPrev` / `SessionPopup:CyclePreviewWindowNext` | Preview windows |
|
|
246
246
|
| `SessionPopup:CyclePreviewPanePrev` / `SessionPopup:CyclePreviewPaneNext` | Preview panes |
|
|
247
247
|
| `NotifySidebar:Ack` / `NotifySidebar:AckGroup` / `NotifySidebar:ClearNonCritical` / `NotifySidebar:ClearAll` | Manage notifications |
|
|
@@ -406,7 +406,9 @@ installed yet, and only it knows its own canonical ids.
|
|
|
406
406
|
|
|
407
407
|
`--no-apply` suppresses the live tmux reload, not the migration. Installer paths
|
|
408
408
|
still invoke the new binary as `config apply --no-reload` so the schema does not
|
|
409
|
-
fall behind the binary that writes it.
|
|
409
|
+
fall behind the binary that writes it. They omit pre-publication live
|
|
410
|
+
convergence entirely and print the exact explicit `config apply --socket`
|
|
411
|
+
still required before ordinary mutation.
|
|
410
412
|
|
|
411
413
|
### Downgrading or rolling back
|
|
412
414
|
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
# Legacy CLI Retirement Ledger
|
|
2
2
|
|
|
3
|
-
Phase 2 removed the human-facing compatibility argv below.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
Phase 2 removed the human-facing compatibility argv below. The mixed roots
|
|
4
|
+
retain only their canonical children: rejected `attach`, `focus`, `pin`, and
|
|
5
|
+
`prune` compatibility shapes return exit 2 with exact replacement guidance and
|
|
6
|
+
no stdout, handler reach, or pre-dispatch migration. The fully removed roots
|
|
7
|
+
`current`, `kill`, `notify`, `sessions`, `session-state`, `tag`, `upgrade`, and
|
|
8
|
+
`usage` are absent from the catalog and handler map, so every argv under them
|
|
9
|
+
uses the ordinary root unknown-command contract (exit 1, no stdout or side
|
|
10
|
+
effect, and root help plus `unknown command: <root>` on stderr).
|
|
11
|
+
|
|
12
|
+
Phase 3 removed the final hidden `ai` producer dispatcher and catalog node.
|
|
13
|
+
The `ai` root and the seven removed old internal top-level aliases use that same
|
|
14
|
+
unknown-command contract.
|
|
10
15
|
|
|
11
16
|
| Removed argv | Replacement |
|
|
12
17
|
| --- | --- |
|
|
13
|
-
| `ai split`, `ai picker` | `create agent`, `create pane`, or a provider shortcut |
|
|
18
|
+
| `ai split`, `ai picker` | `create agent`, `create pane`, or a provider shortcut. The `split` handler itself is now gone: the hidden `internal agent-pane launch-default|picker` bridge produces canonical create intents, so `--agent`, `--force-agent`, and `--print-pane-id` have no implementation left. Use `-o pane-id` on a canonical create for the pane handle |
|
|
14
19
|
| `ai settings` | `config edit` |
|
|
15
20
|
| `ai status`, `ai topic`, `ai integrate` | `agent status`, `agent topic`, `agent integrate` |
|
|
16
21
|
| `ai notify [notify] [pane]` | `create notification --text ... --target ...`; translate the old pane/payload because the input and semantics changed |
|
|
@@ -84,3 +89,27 @@ The old notify action drove an immediate desktop-notification path from pane
|
|
|
84
89
|
state; `create notification` creates a queue row and therefore requires an
|
|
85
90
|
explicit `--text` and `--target`. The old reset action cleared transient
|
|
86
91
|
desktop dedupe state, which the public queue commands do not reproduce.
|
|
92
|
+
|
|
93
|
+
## Post-retirement invariants
|
|
94
|
+
|
|
95
|
+
This breaking boundary removes only the compatibility argv listed above. It
|
|
96
|
+
does not narrow the canonical resource model that shipped after the retirement
|
|
97
|
+
work began. In particular:
|
|
98
|
+
|
|
99
|
+
- Resource Project and Window scope keeps the paired `--project` / `-p` and
|
|
100
|
+
`--window` / `-w` options. Plural Window, Pane, and Agent reads keep
|
|
101
|
+
`--all-projects` / `-A`.
|
|
102
|
+
- Registry-first startup and explicit reconciliation keep materializing the
|
|
103
|
+
recorded Project, Window, and Pane topology without adopting a foreign tmux
|
|
104
|
+
identity.
|
|
105
|
+
- An explicitly selected Offline Window remains canonically deletable from the
|
|
106
|
+
Registry, cascading through its descendant Agent and Pane records without
|
|
107
|
+
issuing a tmux `kill-window` for a mirror that does not exist.
|
|
108
|
+
- Root help and `docs/cli.md` remain generated from the current command
|
|
109
|
+
manifest. They advertise the canonical resource routes and their current
|
|
110
|
+
scope options, never the retired roots.
|
|
111
|
+
|
|
112
|
+
These are preservation constraints for the retirement release, not aliases
|
|
113
|
+
for the removed commands. A future change to one of these contracts needs its
|
|
114
|
+
own feature or fix decision and must not be smuggled into compatibility
|
|
115
|
+
cleanup.
|
|
@@ -36,6 +36,14 @@ operation instead of recording nested outcomes. Lifecycle ownership replaces
|
|
|
36
36
|
the generic top-level `command.outcome`; it never duplicates it. Start/outcome
|
|
37
37
|
append failures are ignored and do not change the command result.
|
|
38
38
|
|
|
39
|
+
Project lifecycle operator diagnostics also keep plans mutually exclusive:
|
|
40
|
+
`stop`, `close-window`, `delete-project`, and `fresh` are distinct operation
|
|
41
|
+
classes. Startup and unregister failures print the closed action, failing
|
|
42
|
+
stage, old Project UID, and new Project UID (or `-` when absent). These opaque
|
|
43
|
+
UIDs and stage labels are bounded control data; root paths, pane content,
|
|
44
|
+
history, prompts, transcripts, and snapshot contents are never identity or
|
|
45
|
+
intent authority.
|
|
46
|
+
|
|
39
47
|
Session State mutations use one outcome-only `session-state.outcome` record
|
|
40
48
|
per selected attempt. The closed operations are `session-state.save`,
|
|
41
49
|
`session-state.autosave`, `session-state.restore`, and `session-state.delete`;
|
|
@@ -198,6 +206,53 @@ the source. Windows ACL privacy is reported as unverified because `os.FileMode`
|
|
|
198
206
|
cannot prove it; a separate finding preserves the metadata-only writability
|
|
199
207
|
result, and Doctor does not modify ACLs.
|
|
200
208
|
|
|
209
|
+
### Registry materialization invariant audit
|
|
210
|
+
|
|
211
|
+
`projmux doctor --section registry` reports the admission difference between
|
|
212
|
+
what the Registry writer accepts and what activation can rebuild.
|
|
213
|
+
`Registry.Validate` and the materialization planner now share the final-v2
|
|
214
|
+
Window contract. Validation allows a same-Window managed Agent
|
|
215
|
+
`spec.anchorPaneRef` with an empty optional `spec.defaultShellPaneRef`; the
|
|
216
|
+
materializer classifies that shape as convergent and plans an explicit
|
|
217
|
+
`allocate default shell` stage before Window/Agent activation. A repeated
|
|
218
|
+
successful materialization is write-free. The audit remains useful for damaged
|
|
219
|
+
or stale refs, but an intentional offline Agent-only Window is not a finding.
|
|
220
|
+
|
|
221
|
+
The verdict is the consumer predicate itself, not a maintained list of suspect
|
|
222
|
+
shapes. Every Registry Project is planned through the shipped topology planner
|
|
223
|
+
with no observed sessions, and the refusals that offline plan records *are* the
|
|
224
|
+
difference. Nothing in the audit re-decides which stored topology can be
|
|
225
|
+
materialized, so the section cannot drift away from the route it describes.
|
|
226
|
+
|
|
227
|
+
The section is read-only in the strongest available sense. The Registry read is
|
|
228
|
+
the zero-write snapshot read, so running diagnostics on a machine that never
|
|
229
|
+
created a Project neither creates nor repairs the state directory, and the tmux
|
|
230
|
+
runner handed to the planner refuses every call instead of reaching a server.
|
|
231
|
+
The audit never writes, repairs, or migrates a Registry; repairing a stored
|
|
232
|
+
topology the materializer cannot build is a separate, explicitly requested
|
|
233
|
+
operation.
|
|
234
|
+
|
|
235
|
+
Findings use the shared severity/code/remediation/count shape:
|
|
236
|
+
|
|
237
|
+
| Code | Severity | Meaning |
|
|
238
|
+
| --- | --- | --- |
|
|
239
|
+
| `registry.materialize.audited` | info | `count` is the number of Projects planned. Always emitted. |
|
|
240
|
+
| `registry.materialize.clean` | info | The difference set is empty. Emitted explicitly, and printed without `--verbose`, because a silent clean audit is indistinguishable from a section that never ran. |
|
|
241
|
+
| `registry.materialize.unavailable` | warning | The Registry could not be read; nothing was planned. |
|
|
242
|
+
| `registry.materialize.fatal.<kind>` | error | `count` stored resources of that kind are refused in a way that stops the whole Project from activating. |
|
|
243
|
+
| `registry.materialize.skipped.<kind>` | warning | `count` stored resources of that kind are refused as single items; the Project still opens without them. |
|
|
244
|
+
|
|
245
|
+
`<kind>` is one of `project`, `window`, `pane`, `agent`, or `other`.
|
|
246
|
+
`fatal` and `skipped` are read off the planner's own refusal split rather than
|
|
247
|
+
re-decided here.
|
|
248
|
+
|
|
249
|
+
The refusal reasons are the planner's own wording and are rendered only under
|
|
250
|
+
`--verbose`, following the report's rule that path-bearing detail is opt-in: a
|
|
251
|
+
stale-cwd reason quotes a stored absolute path. Those reasons are never
|
|
252
|
+
serialized in any format. The support report therefore carries the same codes,
|
|
253
|
+
kinds, and counts as the text report and no reason wording at all, rather than
|
|
254
|
+
relying on the redaction allowlist to hash a private path out of an archive.
|
|
255
|
+
|
|
201
256
|
## Storage and retention
|
|
202
257
|
|
|
203
258
|
The path is
|
|
@@ -227,8 +282,9 @@ arm`, `attention clear`, `attention window`, `internal tmux autosave-session-sta
|
|
|
227
282
|
to the journal; an error from any of them still records exactly one safe error
|
|
228
283
|
outcome. Explicit user mutations such as `attention toggle` retain their
|
|
229
284
|
state-changing success record. Direct top-level help and explicit preview-only intents (`update
|
|
230
|
-
apply --dry-run`, AI integration dry-runs, and
|
|
231
|
-
|
|
285
|
+
apply --dry-run`, AI integration dry-runs, and snapshot projection restore with
|
|
286
|
+
`--dry-run`) are also read-only. Approved snapshot projection restore is a
|
|
287
|
+
state-changing operation. Doctor is a stricter
|
|
232
288
|
boundary: successes and errors never append to this journal, so diagnostics do
|
|
233
289
|
not make its filesystem contract self-defeating. Support report success and
|
|
234
290
|
errors likewise never append; its strict reader shares the viewer's tolerant
|