projmux 0.16.0 → 0.16.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/docs/agent-message-replies.md +77 -14
- package/docs/architecture.md +355 -31
- package/docs/claude-coordination-endpoints.md +35 -13
- package/docs/cli-guide.md +688 -122
- package/docs/cli.md +1114 -222
- package/docs/configuration.md +597 -48
- package/docs/globalization.md +7 -4
- package/docs/hooks.md +466 -50
- package/docs/keybindings.md +9 -5
- package/docs/npm-distribution.md +4 -0
- package/docs/operational-diagnostics.md +270 -7
- package/docs/release.md +4 -0
- package/docs/replacement-contract.md +6 -0
- package/docs/repo-layout.md +3 -0
- package/docs/resource-attribution.md +4 -0
- package/docs/session-restore.md +11 -7
- package/docs/statusbar.md +23 -19
- package/docs/testing.md +68 -18
- package/docs/theme-palette.md +6 -6
- package/docs/tmux-surface-inventory.md +13 -0
- package/docs/upgrading.md +25 -23
- package/docs/usage-tracking.md +16 -1
- package/package.json +5 -5
package/docs/testing.md
CHANGED
|
@@ -5,25 +5,52 @@ and humans run the same entrypoints.
|
|
|
5
5
|
|
|
6
6
|
## Targets
|
|
7
7
|
|
|
8
|
-
- `make test` runs the fast Go unit suite.
|
|
9
|
-
and host shell dependencies.
|
|
8
|
+
- `make test` runs the fast Go unit suite. Apart from the real-tmux tests
|
|
9
|
+
below, these tests avoid tmux, TTY, GUI, and host shell dependencies.
|
|
10
10
|
- `make vet` runs `go vet ./...`. CI runs it in the Unit Tests job after
|
|
11
11
|
`make test`.
|
|
12
|
+
- The real-tmux Go tests in `internal/app` find tmux through one helper,
|
|
13
|
+
`requireRealTmux`. Without tmux they skip; `PROJMUX_REAL_TMUX_STRICT=1`
|
|
14
|
+
turns a missing tmux into a test failure instead, so a run that is meant to
|
|
15
|
+
exercise real tmux cannot pass by skipping. A new real-tmux test must call
|
|
16
|
+
the helper rather than its own `exec.LookPath("tmux")` skip, and the source
|
|
17
|
+
audit `TestRealTmuxSkipIsOwnedByOneHelper` fails on any other skip.
|
|
18
|
+
The CI Unit Tests job installs tmux and runs
|
|
19
|
+
`PROJMUX_REAL_TMUX_STRICT=1 make test` with a TMPDIR of at least 100 bytes,
|
|
20
|
+
so a missing tmux there fails the job instead of skipping those tests.
|
|
21
|
+
The same switch turns on the isolated real-tmux smokes in
|
|
22
|
+
`internal/integrations/tmux` and `internal/integrations/metadata`, which
|
|
23
|
+
otherwise wait for their own opt-in variable.
|
|
24
|
+
- A Go test that opens a unix socket must put it under a short root (the
|
|
25
|
+
`/tmp` + `os.MkdirTemp` idiom, e.g. codexbroker `newRuntimeDomain`,
|
|
26
|
+
`internal/app` `shortTempDomain`) rather than `t.TempDir()`, because the
|
|
27
|
+
socket path has a platform bound (Linux 108B, macOS 104B) and the long CI
|
|
28
|
+
TMPDIR fails such a test. Real-tmux tests put their `TMUX_TMPDIR` or
|
|
29
|
+
`tmux -S` root under `os.MkdirTemp("/tmp", …)` the same way, and the
|
|
30
|
+
liveguard private root, which holds a guarded package's `TMUX_TMPDIR` and
|
|
31
|
+
`XDG_STATE_HOME`, is made under `/tmp` too. Its owner holds a lock file in
|
|
32
|
+
that root for its whole life, so a later guarded owner reclaims the roots of
|
|
33
|
+
killed runs, whose lock is free, and leaves roots without that lock file
|
|
34
|
+
alone.
|
|
12
35
|
- Picker unit coverage includes the backend-neutral item/action contract,
|
|
13
36
|
native title-focused filtering, numeric selection, and shared close actions.
|
|
14
37
|
- `make test-integration` builds `test/docker/Dockerfile` and runs
|
|
15
38
|
`test/integration/linux-smoke.sh` in Docker. It validates Linux dependency
|
|
16
39
|
discovery, tmux config generation/install, app config reload against a real
|
|
17
|
-
`tmux` server, and notify queue CRUD.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
40
|
+
`tmux` server, and notify queue CRUD. It also runs `test/install/smoke.sh`,
|
|
41
|
+
so the required `Integration Tests` job covers the install smoke.
|
|
42
|
+
- `make test-install-smoke` builds the same Docker image and runs only
|
|
43
|
+
`test/install/smoke.sh`, as a local entrypoint. It validates `make install`,
|
|
44
|
+
atomic binary replacement into an isolated install dir, pre-publication
|
|
45
|
+
marker convergence, concurrent legacy/candidate/installed shell and attach
|
|
46
|
+
consumers, exact server-generation/session preservation, `tmux apply` into
|
|
47
|
+
the resolved `$XDG_CONFIG_HOME/projmux/tmux.conf`, and post-install notify
|
|
48
|
+
reconcile initialization with a fresh HOME/XDG state tree. It ends with a
|
|
49
|
+
`>> install smoke passed` line. `make verify` does not repeat it, because
|
|
50
|
+
`make test-integration` already runs it.
|
|
24
51
|
- `make test-e2e` prepares one attempt-local immutable product binary, then
|
|
25
52
|
runs four isolated Linux real-tmux fixtures plus the Codex lifecycle and npm
|
|
26
|
-
staging fixtures. The required inventory is `L01`-`
|
|
53
|
+
staging fixtures. The required inventory is `L01`-`L20`, `C01`, and `N01`;
|
|
27
54
|
every fixture has its own HOME/XDG/tmux/socket/evidence roots and every
|
|
28
55
|
consumer records the same binary SHA. `E2E_SCENARIO=<ID>` selects one exact
|
|
29
56
|
stable scenario for replay.
|
|
@@ -61,7 +88,7 @@ and humans run the same entrypoints.
|
|
|
61
88
|
the full product matrix. The shard target also pins the CI job list to the
|
|
62
89
|
manifest. A deterministic fake-runner start/release barrier proves local
|
|
63
90
|
default overlap is one and explicit parallel overlap is four while both use
|
|
64
|
-
one immutable binary, the exact
|
|
91
|
+
one immutable binary, the exact 22-scenario inventory, and the same result
|
|
65
92
|
hash. The target also pins one non-fail-fast CI job per shard and per suite,
|
|
66
93
|
each with its own runner, timeout, and uniquely named evidence artifacts, all
|
|
67
94
|
of them required children of the aggregate `Test` gate. It also pins the thin
|
|
@@ -70,21 +97,34 @@ and humans run the same entrypoints.
|
|
|
70
97
|
pending rather than failing, so dropping that job would deadlock merges. The
|
|
71
98
|
tag-triggered Release workflow uses the same four Linux shards and two suite
|
|
72
99
|
selectors on separate runners, then reduces them through the fail-closed
|
|
73
|
-
`Release E2E Tests` aggregate before `Build Release` starts.
|
|
100
|
+
`Release E2E Tests` aggregate before `Build Release` starts. `make test`
|
|
101
|
+
runs `make test-e2e-shards`, so the required Unit Tests job fails on shard
|
|
102
|
+
contract drift. The live dialogue canary's own contract is
|
|
103
|
+
`test/agent_dialogue_canary_test.py`, not this target.
|
|
104
|
+
- `make test` also runs the evidence contract (`make e2e-evidence-contract`),
|
|
105
|
+
`make test-e2e-reliability`, and `make test-e2e-residual-policy`, so the
|
|
106
|
+
required Unit Tests job fails when any of them does. `make test-e2e-contract`
|
|
107
|
+
is a local entry point for the admission and evidence halves, both of which
|
|
108
|
+
`make test` already runs. The reliability contract removes the artifact
|
|
109
|
+
directory it creates on every exit, and keeps one the caller passes in
|
|
110
|
+
`PROJMUX_E2E_ARTIFACTS`.
|
|
74
111
|
- `make test-e2e-coverage` validates
|
|
75
112
|
`test/e2e/ags-oedr-manifest.json`: executable scenario markers and shard
|
|
76
|
-
assignments must match all
|
|
113
|
+
assignments must match all 22 rows with orphan count zero. A matrix may move
|
|
77
114
|
out of real-tmux E2E only when its checked-in entry names executable lower
|
|
78
115
|
positive, negative, and fixed-point evidence and retains a real-boundary
|
|
79
116
|
sentinel. The manifest/orphan half is a prerequisite of `make test-e2e`,
|
|
80
117
|
while the referenced lower test runs in both this coverage target and the
|
|
81
|
-
required unit-test job
|
|
118
|
+
required unit-test job, so `make test-e2e-coverage` is a local entry point
|
|
119
|
+
whose two halves are already enforced.
|
|
82
120
|
- `make security` runs the exact three Security groups in parallel locally:
|
|
83
121
|
Go vulnerability/security, Go static quality, and repository policy.
|
|
84
122
|
`make security-serial` is the parity control and `make security-contract`
|
|
85
|
-
checks scanner/rule/baseline identity, PR-range
|
|
123
|
+
checks scanner/rule/baseline identity, PR-range and HEAD-history secret scans,
|
|
86
124
|
cache miss-to-hit convergence, privacy-safe artifacts, and the fail-closed
|
|
87
125
|
aggregate. CI exposes their stable aggregate as `Test`.
|
|
126
|
+
After adding or removing a Go package, refresh the package-set pin with
|
|
127
|
+
`make security-pin-refresh` (rule: `AGENTS.md` `## Security`).
|
|
88
128
|
- `make deadcode` runs the focused baseline-contract fixture, then runs
|
|
89
129
|
`go tool deadcode` (pinned via the go.mod tool directive) over the module.
|
|
90
130
|
`.deadcode-allowlist.txt` is exact to current findings: duplicate and stale
|
|
@@ -156,7 +196,7 @@ remains inside L17. Its row links creator-Registry admission, journal-path and
|
|
|
156
196
|
CLOEXEC handshake tests to the immediate-exit integration/E2E markers, and
|
|
157
197
|
also closes the focused fresh-root repeat harness plus the read-only
|
|
158
198
|
owner/queue observation and product-terminal controller marker. These rows add
|
|
159
|
-
no scenario ID: the audit still requires exactly
|
|
199
|
+
no scenario ID: the audit still requires exactly 22 stable scenarios and fails
|
|
160
200
|
closed if either source commit, guarantee set, lower selector, supporting
|
|
161
201
|
marker, or marker-before-pass edge drifts.
|
|
162
202
|
|
|
@@ -168,6 +208,15 @@ value for an explicitly observed cancellation; the shell harness does not
|
|
|
168
208
|
invent cancellation evidence from a signal whose semantic cause it cannot
|
|
169
209
|
attribute.
|
|
170
210
|
|
|
211
|
+
`smoke_contract_pass` records `pass` only when the contract shell's own stdout
|
|
212
|
+
and stderr between `smoke_contract_begin` and that call carry no Python
|
|
213
|
+
traceback, even one whose child status was consumed. A traceback ends the
|
|
214
|
+
scenario through the ordinary fail path at the pass line and logs
|
|
215
|
+
`E2E_CONTRACT id=<ID> guard=python-traceback stream=<stream> exception=<last
|
|
216
|
+
exception line>`; there is no exemption list. Output redirected to a file never
|
|
217
|
+
reaches the guard. `make e2e-traceback-guard-contract` pins this, including a
|
|
218
|
+
traceback written while the job log lags behind the pass call.
|
|
219
|
+
|
|
171
220
|
## Host-Only Checks
|
|
172
221
|
|
|
173
222
|
The Docker suites do not replace checks that depend on a real host terminal,
|
|
@@ -298,8 +347,9 @@ Observe:
|
|
|
298
347
|
```markdown
|
|
299
348
|
Host-only smoke validation:
|
|
300
349
|
|
|
301
|
-
- Docker-covered checks: `make test-integration
|
|
302
|
-
and `make test-e2e` cover portable Linux tmux/config/notify behavior
|
|
350
|
+
- Docker-covered checks: `make test-integration` (which includes the install
|
|
351
|
+
smoke) and `make test-e2e` cover portable Linux tmux/config/notify behavior
|
|
352
|
+
only.
|
|
303
353
|
- Terminal key delivery: not run / run on <terminal>; `projmux setup --timeout
|
|
304
354
|
10s` showed <result>; `Alt-1..5` app popup smoke <passed/failed/not run>.
|
|
305
355
|
- WSL toast: not run / run on <Windows + WSL distro>; detached-focus smoke
|
package/docs/theme-palette.md
CHANGED
|
@@ -9,11 +9,11 @@ semantic role map is `internal/theme/resolve.go`.
|
|
|
9
9
|
## Scope
|
|
10
10
|
|
|
11
11
|
The fallback palette is a semantic token layer. The effective theme is a global
|
|
12
|
-
user theme resolved from
|
|
13
|
-
built-in fallback values from `internal/theme/palette.go`. The
|
|
14
|
-
a semantic role map (`RenderRoles` for tmux chrome, `ANSIRoles`
|
|
15
|
-
surfaces) from the effective theme, and renderers consume those
|
|
16
|
-
bare palette literals.
|
|
12
|
+
user theme resolved from `${XDG_CONFIG_HOME:-$HOME/.config}/projmux/config.toml`,
|
|
13
|
+
followed by the built-in fallback values from `internal/theme/palette.go`. The
|
|
14
|
+
resolver derives a semantic role map (`RenderRoles` for tmux chrome, `ANSIRoles`
|
|
15
|
+
for native ANSI surfaces) from the effective theme, and renderers consume those
|
|
16
|
+
roles instead of bare palette literals.
|
|
17
17
|
|
|
18
18
|
- Native picker truecolor SGR tokens.
|
|
19
19
|
- Native sidebar and chip-strip 256-color SGR tokens.
|
|
@@ -124,7 +124,7 @@ Rules:
|
|
|
124
124
|
|
|
125
125
|
The effective theme resolves theme fields from:
|
|
126
126
|
|
|
127
|
-
1. Global
|
|
127
|
+
1. Global `${XDG_CONFIG_HOME:-$HOME/.config}/projmux/config.toml`
|
|
128
128
|
2. Built-in fallback preset `projmux`
|
|
129
129
|
|
|
130
130
|
Rules:
|
|
@@ -10,6 +10,7 @@ Primary production sources:
|
|
|
10
10
|
|
|
11
11
|
- `internal/integrations/mux/`
|
|
12
12
|
- `internal/integrations/tmux/`
|
|
13
|
+
- `internal/integrations/tmuxexec/`
|
|
13
14
|
- `internal/app/`
|
|
14
15
|
- generated config from `projmux config render standalone`,
|
|
15
16
|
`projmux config render app`, and `projmux shell`
|
|
@@ -44,6 +45,18 @@ The boundary is intentionally pragmatic:
|
|
|
44
45
|
- avoid spreading raw tmux invocation through app packages;
|
|
45
46
|
- avoid introducing an abstraction that only renames a single local call.
|
|
46
47
|
|
|
48
|
+
Every process projmux starts that may be a tmux command client is started
|
|
49
|
+
through `internal/integrations/tmuxexec`. It adds tmux's `-u` client flag, so
|
|
50
|
+
format output keeps its `\x1f` and `\t` separators and UTF-8 values when the
|
|
51
|
+
caller has no UTF-8 locale (no `LANG`/`LC_*`, or `LC_ALL=C`); without it tmux
|
|
52
|
+
rewrites those bytes to `_`. Clients that take over a terminal
|
|
53
|
+
(`attach-session`, a `new-session` that is not detached) are left as they are.
|
|
54
|
+
`TestTmuxSpawnSitesAreClosed` checks every package whose source holds the
|
|
55
|
+
literal `"tmux"` or that imports a tmux integration package: each process spawn
|
|
56
|
+
there must use that package or be on its closed list of spawns that never run
|
|
57
|
+
tmux. A spawn of the literal `"tmux"` fails in any package. A package that runs
|
|
58
|
+
tmux with neither the literal nor such an import is not checked.
|
|
59
|
+
|
|
47
60
|
## Semantic Command Surface
|
|
48
61
|
|
|
49
62
|
### Metadata And Inventory
|
package/docs/upgrading.md
CHANGED
|
@@ -61,9 +61,9 @@ With nothing left to choose, the setting that turned the screen off is gone.
|
|
|
61
61
|
|
|
62
62
|
- Settings > Projects > Project Sidebar > Closed Project startup is removed.
|
|
63
63
|
Project Sidebar keeps its Runtime diagnostics choice.
|
|
64
|
-
-
|
|
65
|
-
`projmux config apply` after upgrading (which
|
|
66
|
-
`projmux update apply` also run) removes it and prints one
|
|
64
|
+
- `${XDG_CONFIG_HOME:-$HOME/.config}/projmux/sidebar-startup-picker` is no
|
|
65
|
+
longer read. The first `projmux config apply` after upgrading (which
|
|
66
|
+
`make install` and `projmux update apply` also run) removes it and prints one
|
|
67
67
|
`reclaimed retired closed-Project startup setting: removed 1 file` line.
|
|
68
68
|
Only a regular file with that name is removed; a failure is reported and
|
|
69
69
|
never fails the apply, and later applies print nothing.
|
|
@@ -105,9 +105,9 @@ projmux no longer installs, reads, or judges the Antigravity `statusLine` in
|
|
|
105
105
|
prints the `usage unsupported` note; `agent capabilities` reports Antigravity
|
|
106
106
|
usage as unsupported. Working state still follows the official
|
|
107
107
|
`PreInvocation`/`Stop` hooks.
|
|
108
|
-
- Leftover
|
|
109
|
-
`<state>/usage/antigravity-*.json` sidecars, and cached Antigravity
|
|
110
|
-
`snapshots.json` are ignored, not deleted. Doctor JSON no longer has
|
|
108
|
+
- Leftover `${XDG_CONFIG_HOME:-$HOME/.config}/projmux/statusbar-visibility-*antigravity*`
|
|
109
|
+
files, `<state>/usage/antigravity-*.json` sidecars, and cached Antigravity
|
|
110
|
+
rows in `snapshots.json` are ignored, not deleted. Doctor JSON no longer has
|
|
111
111
|
`statusline_config_path`, and the diagnostic is named `Antigravity hooks`.
|
|
112
112
|
|
|
113
113
|
### Project snapshots removed
|
|
@@ -419,8 +419,9 @@ projmux get projects
|
|
|
419
419
|
|
|
420
420
|
### Pins are typed, and migrate on request
|
|
421
421
|
|
|
422
|
-
**Breaking.**
|
|
423
|
-
could not say whether the path was a Project. It is now a
|
|
422
|
+
**Breaking.** `${XDG_CONFIG_HOME:-$HOME/.config}/projmux/pins` held one absolute
|
|
423
|
+
path per line, which could not say whether the path was a Project. It is now a
|
|
424
|
+
typed envelope:
|
|
424
425
|
|
|
425
426
|
```text
|
|
426
427
|
projmux-pins v2
|
|
@@ -586,12 +587,12 @@ The deprecated top-level `projmux init` command and its legacy-only
|
|
|
586
587
|
|
|
587
588
|
### Keymap schema migration
|
|
588
589
|
|
|
589
|
-
|
|
590
|
-
marker. A file without one is v0 and uses the action ids
|
|
591
|
-
written; `schema_version = 1` uses canonical dotted ids such
|
|
592
|
-
`window.create` and `project-sidebar.runtime.stop`; `schema_version = 2`
|
|
593
|
-
those ids and adds two-to-four-stroke `sequences`. All versions read — the
|
|
594
|
-
spelling of every action stays a permanent read alias.
|
|
590
|
+
`${XDG_CONFIG_HOME:-$HOME/.config}/projmux/keymap.toml` is now versioned by a
|
|
591
|
+
root `schema_version` marker. A file without one is v0 and uses the action ids
|
|
592
|
+
projmux has always written; `schema_version = 1` uses canonical dotted ids such
|
|
593
|
+
as `window.create` and `project-sidebar.runtime.stop`; `schema_version = 2`
|
|
594
|
+
keeps those ids and adds two-to-four-stroke `sequences`. All versions read — the
|
|
595
|
+
v0 spelling of every action stays a permanent read alias.
|
|
595
596
|
|
|
596
597
|
The migration needs no command of its own. Every installer path ends by running
|
|
597
598
|
the newly installed binary's `projmux config apply`, which migrates first and only
|
|
@@ -616,7 +617,7 @@ fail before the keymap, generated config, or live server changes.
|
|
|
616
617
|
**Downgrading to a projmux that predates the schema:** restore the backup first.
|
|
617
618
|
|
|
618
619
|
```sh
|
|
619
|
-
cp
|
|
620
|
+
cp "${XDG_CONFIG_HOME:-$HOME/.config}/projmux/keymap.toml.pre-v1-<digest>.bak" "${XDG_CONFIG_HOME:-$HOME/.config}/projmux/keymap.toml"
|
|
620
621
|
```
|
|
621
622
|
|
|
622
623
|
An older binary reads `schema_version` as an unsupported root key and refuses
|
|
@@ -627,7 +628,7 @@ full ordering.
|
|
|
627
628
|
### Pane rename keymap action ID removed
|
|
628
629
|
|
|
629
630
|
The deprecated `rename-pane-topic` keybinding action ID has been removed. If
|
|
630
|
-
|
|
631
|
+
`${XDG_CONFIG_HOME:-$HOME/.config}/projmux/keymap.toml` still contains
|
|
631
632
|
`[bindings.rename-pane-topic]`, rename that table to
|
|
632
633
|
`[bindings.rename-pane-label]` before running Settings or
|
|
633
634
|
`projmux config apply`. Projmux now rejects the stale table with that exact
|
|
@@ -641,7 +642,8 @@ independent fallback.
|
|
|
641
642
|
### Theme is now global-only
|
|
642
643
|
|
|
643
644
|
Theme is a global user preference. The effective theme resolves from the global
|
|
644
|
-
`[theme]` in
|
|
645
|
+
`[theme]` in `${XDG_CONFIG_HOME:-$HOME/.config}/projmux/config.toml` plus a
|
|
646
|
+
built-in fallback preset.
|
|
645
647
|
|
|
646
648
|
If you previously set a `[theme]` section in a project's `.projmux/config.toml`,
|
|
647
649
|
it is now **deprecated and ignored** — it no longer overrides the global theme
|
|
@@ -650,11 +652,11 @@ The project `[theme]` keys are left in the file untouched (no warning, no
|
|
|
650
652
|
removal); they simply have no effect.
|
|
651
653
|
|
|
652
654
|
To restore your previous look, copy the values into the global
|
|
653
|
-
|
|
654
|
-
Settings > Theme. Settings no longer exposes a Project theme
|
|
655
|
-
separate Effective theme view has been merged into the Global
|
|
656
|
-
token row now shows its resolved value inline, with unset
|
|
657
|
-
dimmed `(fallback)` value.
|
|
655
|
+
`${XDG_CONFIG_HOME:-$HOME/.config}/projmux/config.toml` `[theme]` section, or
|
|
656
|
+
edit them through Settings > Theme. Settings no longer exposes a Project theme
|
|
657
|
+
editor, and the separate Effective theme view has been merged into the Global
|
|
658
|
+
theme view: each token row now shows its resolved value inline, with unset
|
|
659
|
+
tokens shown as their dimmed `(fallback)` value.
|
|
658
660
|
|
|
659
661
|
### Foreground split
|
|
660
662
|
|
|
@@ -780,7 +782,7 @@ apply refuses and names the path it found — the active executable is left
|
|
|
780
782
|
untouched. The scratch directory is removed on success and on every failure.
|
|
781
783
|
|
|
782
784
|
The command reads `PROJMUX_PROJDIR` from the calling shell and memoizes the
|
|
783
|
-
primary path to
|
|
785
|
+
primary path to `$HOME/.config/projmux/projdir`, so the new binary keeps the same
|
|
784
786
|
project root context as the one it replaces.
|
|
785
787
|
|
|
786
788
|
To switch the saved project root during the upgrade:
|
package/docs/usage-tracking.md
CHANGED
|
@@ -147,6 +147,17 @@ JSON document keyed by adapter, recording:
|
|
|
147
147
|
- per-adapter `last_collect` timestamp (drives the throttle)
|
|
148
148
|
- per-adapter `Backoff{Until, Consecutive}` (drives the cooldown)
|
|
149
149
|
|
|
150
|
+
A persistent `.snapshots.json.lock` next to the file serializes every
|
|
151
|
+
read-modify-write across the processes on one machine. The lock is never held
|
|
152
|
+
during an adapter call. Instead, a throttled refresh records `last_collect`
|
|
153
|
+
for the adapters it is about to walk before it calls them, so concurrent
|
|
154
|
+
refreshes collect each adapter once per throttle window. A refresh that cannot
|
|
155
|
+
take the lock within one second walks nothing and fails with a lock-timeout
|
|
156
|
+
error, which the operations journal records as `failure=state-lock-timeout`
|
|
157
|
+
(see [Collection failures](#collection-failures)). A healthy wait takes milliseconds,
|
|
158
|
+
so repeated rows point at a stuck lock holder. The lock does not coordinate
|
|
159
|
+
machines that share a synced directory.
|
|
160
|
+
|
|
150
161
|
Adapter failures merge over the prior slice rather than replacing it,
|
|
151
162
|
so a 429 keeps the last known good rows visible. A *partial* collect — some
|
|
152
163
|
rows dropped, some kept — still counts as a successful refresh for the models
|
|
@@ -334,7 +345,11 @@ When a collection fails, the failure is visible in three places:
|
|
|
334
345
|
Codex failure. Status codes, paths, upstream bodies, and
|
|
335
346
|
credentials never reach the row. Codex rollout fallback records
|
|
336
347
|
`source=rollout` plus its closed fallback reason; retained data records
|
|
337
|
-
`source=last-known-good` plus its closed stale reason. A
|
|
348
|
+
`source=last-known-good` plus its closed stale reason. A refresh that timed
|
|
349
|
+
out on the snapshot state lock records one `provider=projmux`
|
|
350
|
+
`failure=state-lock-timeout` row at `level=error`, without a source: no
|
|
351
|
+
adapter ran, so no provider owns it, and adapter failures that came with
|
|
352
|
+
the timeout keep their own rows. A healthy native
|
|
338
353
|
collection writes no row at all. Identical `(provider, source, failure)`
|
|
339
354
|
tuples are recorded at most once per
|
|
340
355
|
process run — the same suppression the notify/focus recorder uses — so a
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "projmux",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.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.16.
|
|
32
|
-
"@projmux/linux-arm64": "0.16.
|
|
33
|
-
"@projmux/darwin-x64": "0.16.
|
|
34
|
-
"@projmux/darwin-arm64": "0.16.
|
|
31
|
+
"@projmux/linux-x64": "0.16.1",
|
|
32
|
+
"@projmux/linux-arm64": "0.16.1",
|
|
33
|
+
"@projmux/darwin-x64": "0.16.1",
|
|
34
|
+
"@projmux/darwin-arm64": "0.16.1"
|
|
35
35
|
}
|
|
36
36
|
}
|