projmux 0.13.0 → 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.
@@ -422,26 +422,40 @@ user/global preference in this release.
422
422
  ## Codex app-server health
423
423
 
424
424
  Settings > AI includes a read-only `Codex control plane` row. It reports one of
425
- `App Server`, `Hook fallback`, or `Unavailable`, together with a closed reason,
426
- endpoint kind, connection state, lifecycle outcome/reason, and a sanitized
427
- version when initialization returned one. Read-only surfaces report
428
- `not-attempted/read-only`. `projmux doctor --section integrations` and explicit
429
- support reports expose the same bounded fields without socket paths, prompts,
430
- tokens, process output, or response payloads.
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.
431
435
 
432
436
  There is no app-server source setting or environment override. Authority is a
433
437
  capability result, not a preference: Projmux probes the existing local control
434
- socket through `codex app-server proxy` with a short timeout and otherwise keeps
435
- the current hook behavior. Doctor, Settings, and support reports never start or
436
- otherwise mutate the daemon.
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.
437
449
 
438
450
  The Codex integration has a lifecycle seam for later native features. Only an
439
- actual native user action may use it, and only an exact missing or
440
- connection-refused default control socket is eligible. That path invokes the
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
441
455
  official idempotent `codex app-server daemon start` command at most once per
442
456
  in-flight process decision, then retries proxy initialization with a bounded
443
- backoff. Phase 1 itself does not route Agent create/resume, usage, catalog,
444
- model, or review behavior through that seam.
457
+ backoff. Projmux never automatically stops, kills, restarts, adopts, or enables
458
+ remote control on the shared app server.
445
459
 
446
460
  The default `Codex` row in the provider picker launches immediately through the
447
461
  canonical create route. It does not start or probe the app-server, call
@@ -922,6 +936,15 @@ that target subtree atomically, runs the ordinary materializer, and performs an
922
936
  explicit client handoff last when `--client` is present. Restore never modifies
923
937
  or deletes the source snapshot.
924
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.
947
+
925
948
  ## Decoration Mode
926
949
 
927
950
  Settings > Appearance controls optional icon decoration per surface:
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 binary, atomically replaces
104
- `$(go env GOPATH)/bin/projmux`, runs `projmux config apply`, and reconciles the
105
- notify queue through `projmux notification reconcile`. Override the destination
106
- with `INSTALL_DIR=/usr/local/bin`.
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 release
125
- asset, replaces the current executable, and reapplies the live tmux config.
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 does not touch a live tmux bell hook. See
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).
@@ -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
 
package/docs/testing.md CHANGED
@@ -15,8 +15,10 @@ and humans run the same entrypoints.
15
15
  `tmux` server, and notify queue CRUD.
16
16
  - `make test-install-smoke` builds the same Docker image and runs
17
17
  `test/install/smoke.sh`. It validates `make install`, atomic binary
18
- replacement into an isolated install dir, `tmux apply`, and post-install
19
- `notify reconcile` initialization with a fresh HOME/XDG state tree.
18
+ replacement into an isolated install dir, pre-publication marker convergence,
19
+ concurrent legacy/candidate/installed shell and attach consumers, exact
20
+ server-generation/session preservation, `tmux apply`, and post-install notify
21
+ reconcile initialization with a fresh HOME/XDG state tree.
20
22
  - `make test-e2e` prepares one attempt-local immutable product binary, then
21
23
  runs four isolated Linux real-tmux fixtures plus the Codex lifecycle and npm
22
24
  staging fixtures. The required inventory is `L01`-`L19`, `C01`, and `N01`;
@@ -41,10 +43,15 @@ and humans run the same entrypoints.
41
43
  checks scanner/rule/baseline identity, PR-range/full-history secret scans,
42
44
  cache miss-to-hit convergence, privacy-safe artifacts, and the fail-closed
43
45
  aggregate. CI exposes their stable aggregate as `Test`.
44
- - `make deadcode` runs `go tool deadcode` (pinned via the go.mod tool
45
- directive) over the module and reports unreachable functions, filtering out
46
- the intentional/MUST-KEEP baseline in `.deadcode-allowlist.txt`; it fails
47
- only on NEW dead code, and `make fix` runs it after `go fix`.
46
+ - `make deadcode` runs the focused baseline-contract fixture, then runs
47
+ `go tool deadcode` (pinned via the go.mod tool directive) over the module.
48
+ `.deadcode-allowlist.txt` is exact to current findings: duplicate and stale
49
+ rows fail. `.deadcode-must-keep.txt` separately records proactive migration,
50
+ compatibility, and proof APIs as `symbol<TAB>non-empty reason`; duplicates
51
+ within either file, overlap across files, malformed reasons, and findings
52
+ outside the two-file union fail deterministically. `make test` also runs the
53
+ focused fixture, and `make fix` runs the complete deadcode gate after
54
+ `go fix`.
48
55
 
49
56
  ## Docker-Covered Checks
50
57
 
@@ -0,0 +1,157 @@
1
+ # Troubleshooting
2
+
3
+ Start with read-only diagnostics:
4
+
5
+ ```sh
6
+ projmux doctor
7
+ ```
8
+
9
+ `doctor` never installs packages, rewrites configuration, or changes a tmux
10
+ server. Run a remediation command only after reviewing the finding that
11
+ recommended it. For the operational journal's privacy and retention contract,
12
+ see [Operational Diagnostics](operational-diagnostics.md).
13
+
14
+ ## App socket marker migration
15
+
16
+ Projmux 0.13 and newer require two server-global markers before an ordinary
17
+ command may mutate the app tmux server:
18
+
19
+ - `@projmux_app=1` declares app ownership.
20
+ - `@projmux_socket_name=<name>` declares the logical `-L <name>` route.
21
+
22
+ An app server started by a pre-0.13 release can still be live with the first
23
+ marker and no logical marker. In that partial state, `shell`, attach, and
24
+ materialization commands fail closed and print the exact recovery command.
25
+ For the default app socket, run:
26
+
27
+ ```sh
28
+ projmux config apply --socket projmux
29
+ ```
30
+
31
+ This explicit apply keeps the live server and its sessions, binds `-L projmux`
32
+ to one absolute socket path and server PID, sources the generated config,
33
+ writes the missing logical marker, and verifies both markers against the same
34
+ server generation. Ordinary commands do not write the marker. Apply also
35
+ refuses a foreign server, a different existing logical marker, an alias/path
36
+ mismatch, or PID drift; do not replace the refusal with a raw `tmux set-option`
37
+ command.
38
+
39
+ For a non-default socket, use the exact name printed by the failing command:
40
+
41
+ ```sh
42
+ projmux config apply --socket <name>
43
+ ```
44
+
45
+ Then retry the original command.
46
+
47
+ ## Diagnostic sequence
48
+
49
+ Use this order so each step remains read-only until you deliberately run the
50
+ recovery command:
51
+
52
+ ```sh
53
+ projmux doctor --section runtime --verbose
54
+ projmux diagnostics log
55
+ tmux -L projmux show-options -gqv @projmux_app
56
+ tmux -L projmux show-options -gqv @projmux_socket_name
57
+ tmux -L projmux display-message -p -F '#{socket_path} #{pid}'
58
+ ```
59
+
60
+ Replace `projmux` in all three tmux commands with the exact logical socket name
61
+ you are diagnosing. Expected healthy marker output is `1` and that same socket
62
+ name. The final read records the physical socket/PID pair for comparison; it
63
+ does not grant authority or repair anything.
64
+
65
+ The marker-specific Doctor codes map to these actions:
66
+
67
+ | Code | Meaning | Remediation |
68
+ | --- | --- | --- |
69
+ | `runtime.route-marker.missing` | App-owned live server has no logical marker, normally after a pre-0.13 live-server upgrade. | Run the exact `projmux config apply --socket <name>` printed by the failing ordinary command, then retry it. |
70
+ | `runtime.route-marker.mismatch` | The app-owned server declares a different logical route. | Do not overwrite it. Inspect the diagnostic sequence and confirm which `-L` route owns the server. |
71
+ | `runtime.route-marker.unreadable` | Doctor could reach the socket but could not read one or both ownership markers. | Inspect `projmux diagnostics log`, tmux/socket permissions, and the exact marker reads. Do not apply until the read failure is understood. |
72
+
73
+ Other runtime Doctor codes use bounded remediation identifiers in text and
74
+ JSON:
75
+
76
+ | Code family | Remediation |
77
+ | --- | --- |
78
+ | `runtime.socket.unreachable` | Start the app with `projmux shell`; if a server should already exist, inspect the exact socket first. |
79
+ | `runtime.socket.probe-failed`, `runtime.backend.unknown` | Inspect `projmux diagnostics log` and the operational journal. |
80
+ | `runtime.config.generated-missing`, `runtime.config.generated-invalid` | Run `projmux config apply --socket <name>` after confirming the target server. |
81
+ | `runtime.config.generated-unreadable` | Inspect config and directory permissions before applying. |
82
+ | `runtime.config.applied-stale` | Run the exact config apply command to reload the generated config. |
83
+ | `runtime.config.applied-unknown` | Start or identify the app runtime before attempting a reload. |
84
+ | `logs.*` | Follow the finding's `inspect-state-permissions`, `inspect-log-permissions`, or `inspect-operational-journal` remediation. |
85
+ | `registry.materialize.*` | Inspect the reported Registry topology. Doctor is read-only and does not repair it. |
86
+
87
+ Informational `*.ready`, `*.current`, `*.reachable`, `*.none`, `*.clean`, and
88
+ `*.audited` codes need no remediation. JSON exposes the same `code` and
89
+ `remediation` values as verbose text.
90
+
91
+ ## Codex app-server install topology
92
+
93
+ Start with the read-only integration report:
94
+
95
+ ```sh
96
+ projmux doctor --section integrations --verbose
97
+ ```
98
+
99
+ The `Codex app-server` result keeps four readiness axes separate:
100
+
101
+ - `Endpoint readiness` says whether the existing endpoint is ready, dead, or
102
+ failed with a bounded reason.
103
+ - `running executable` plus the sanitized version fields distinguish a proven
104
+ managed executable from unknown identity and current from skewed versions.
105
+ - `manager ownership` comes only from the official daemon backend result; an
106
+ absent or unclear result is never guessed from endpoint health.
107
+ - `remote control` independently reports disabled, connecting, connected,
108
+ errored, unsupported, unavailable, or unknown.
109
+
110
+ `Source`/`reason`, `App-server probe`, `install capability`, and `lifecycle`
111
+ remain separate supporting fields. A ready endpoint therefore does not hide an
112
+ unmanaged process or version skew.
113
+
114
+ `external-cli-only` means the ordinary Codex CLI executable is present, but
115
+ the canonical managed payload needed by `codex app-server daemon start` was not
116
+ observed. It does not mean the ordinary CLI is unsupported and does not prove
117
+ who owns a running process.
118
+
119
+ An explicit native action refuses a ready unmanaged or version-skewed endpoint.
120
+ The refusal reports `shared-clients-disconnect`: replacing this shared process
121
+ can interrupt every attached Codex client. For a managed skew, confirm the
122
+ interruption and run `codex app-server daemon restart`. For an unmanaged
123
+ endpoint, close every sharing client, stop the process through the operator
124
+ that owns it, then run `codex app-server daemon start`. Projmux never performs
125
+ those stop/restart steps or invents an ownership-specific kill command.
126
+
127
+ If native app-server features are needed, review the
128
+ [official Codex CLI installation options](https://learn.chatgpt.com/docs/codex/cli)
129
+ and install or repair the managed standalone payload. Then rerun Doctor. Do not
130
+ copy binaries, create symlinks in the Codex home, or edit the control socket as
131
+ a diagnostic workaround. Doctor, Settings, and support-report collection never
132
+ start the daemon or modify the installation.
133
+
134
+ ## Incomplete npm install
135
+
136
+ If the npm shim exits before Projmux starts with:
137
+
138
+ ```text
139
+ projmux: unsupported or incomplete npm install for <platform>/<arch>.
140
+ Expected optional dependency @projmux/<platform>-<arch> to provide bin/projmux.
141
+ ```
142
+
143
+ the platform-specific optional package is missing. This can happen when npm
144
+ reuses stale package metadata or optional dependencies were disabled. Because
145
+ the Go binary is absent, `projmux doctor` cannot run yet. Re-resolve the current
146
+ release and its optional dependency:
147
+
148
+ ```sh
149
+ npm cache verify
150
+ npm install -g projmux@latest --include=optional
151
+ projmux version
152
+ projmux doctor
153
+ ```
154
+
155
+ If the same error remains, remove the incomplete global package, refresh npm's
156
+ package metadata, and reinstall. Do not copy a binary from another platform.
157
+ GitHub Release and source alternatives are documented in [Install](install.md).
package/docs/upgrading.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Upgrading
2
2
 
3
+ If an older live app server refuses ordinary commands after upgrading, or npm
4
+ cannot resolve the platform optional dependency, follow
5
+ [Troubleshooting](troubleshooting.md). The canonical marker recovery is the
6
+ exact `projmux config apply --socket <name>` printed by the refusal; ordinary
7
+ runtime commands never backfill missing markers.
8
+
3
9
  projmux has two update surfaces:
4
10
 
5
11
  - `projmux shell` reads the cached release status before opening the app. When
@@ -25,7 +31,9 @@ projmux update apply
25
31
  Use `--dry-run` to see the planned action and `--no-apply` to skip reloading
26
32
  the live tmux config after the binary changes. `--no-apply` suppresses live
27
33
  tmux access only; the new binary still migrates the keymap schema and
28
- marker-owned provider files, then writes the generated config. See
34
+ marker-owned provider files, then writes the generated config. It finishes by
35
+ printing `projmux config apply --socket projmux` as the explicit live
36
+ convergence still required before ordinary mutation. See
29
37
  [Keymap schema migration](#keymap-schema-migration) and
30
38
  [Managed Agent hook producer migration](#managed-agent-hook-producer-migration).
31
39
 
@@ -538,10 +546,17 @@ npm install -g projmux
538
546
  For npm-managed installs, `projmux update apply` runs:
539
547
 
540
548
  ```sh
549
+ <current-projmux> config apply --bin <published-projmux> --socket projmux
541
550
  npm install -g projmux@latest
542
551
  projmux config apply
543
552
  ```
544
553
 
554
+ The first apply must succeed before npm publication begins. The final apply is
555
+ post-publication verification by the new binary. Go, GitHub Release, and source
556
+ `make install` use the same pre-converge → publish → verify contract. A failed
557
+ pre-apply prevents publication; a publication or verification failure returns
558
+ non-zero and prints the exact `projmux config apply --socket projmux` recovery.
559
+
545
560
  `npm install -g projmux@latest` is used instead of `npm update -g projmux`
546
561
  because `npm update -g` honors the installed semver range and frequently
547
562
  refuses to move a global install across a newer minor/major release, leaving it
@@ -564,9 +579,10 @@ projmux update apply --no-apply # migrate + write config, skip the live reload
564
579
  projmux update apply --dry-run # print the steps only
565
580
  ```
566
581
 
567
- `projmux update apply` reinstalls via `go install`, atomically replaces the active
568
- file, and reapplies the live tmux config so a running `-L projmux` server picks
569
- up new bindings without a restart.
582
+ `projmux update apply` first converges the live route with the current binary
583
+ and exact eventual executable path, reinstalls via `go install`, then reapplies
584
+ with the published binary so a running `-L projmux` server picks up new bindings
585
+ without a restart.
570
586
 
571
587
  The command reads `PROJMUX_PROJDIR` from the calling shell and memoizes the
572
588
  primary path to `~/.config/projmux/projdir`, so the new binary keeps the same
@@ -585,8 +601,9 @@ PROJMUX_PROJDIR="/main/repos:/secondary/repos" projmux update apply
585
601
 
586
602
  When `PROJMUX_INSTALLER=github-release`, `projmux update apply` downloads the
587
603
  latest matching `projmux_<version>_<goos>_<goarch>.tar.gz` asset from GitHub
588
- Releases, extracts the binary, atomically replaces the current executable, and
589
- then runs the new binary's `projmux config apply` — or `config apply --no-reload`
604
+ Releases, extracts the binary, converges the exact live route, atomically
605
+ replaces the current executable, and then runs the new binary's
606
+ `projmux config apply` — or `config apply --no-reload`
590
607
  when `--no-apply` is set, so the keymap schema migration still happens.
591
608
 
592
609
  Set the installer explicitly if you manage a release binary outside npm or Go:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "projmux",
3
- "version": "0.13.0",
3
+ "version": "0.13.1",
4
4
  "description": "tmux project session manager",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/crevissepartners/projmux#readme",
@@ -28,9 +28,9 @@
28
28
  "package:npm:pack": "scripts/package-npm.sh --pack"
29
29
  },
30
30
  "optionalDependencies": {
31
- "@projmux/linux-x64": "0.13.0",
32
- "@projmux/linux-arm64": "0.13.0",
33
- "@projmux/darwin-x64": "0.13.0",
34
- "@projmux/darwin-arm64": "0.13.0"
31
+ "@projmux/linux-x64": "0.13.1",
32
+ "@projmux/linux-arm64": "0.13.1",
33
+ "@projmux/darwin-x64": "0.13.1",
34
+ "@projmux/darwin-arm64": "0.13.1"
35
35
  }
36
36
  }