projmux 0.15.3 → 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/README-ko.md +3 -4
- package/README.md +3 -3
- package/docs/agent-message-replies.md +149 -6
- package/docs/ai-agent-shortcuts.md +6 -5
- package/docs/architecture.md +467 -66
- package/docs/claude-coordination-endpoints.md +192 -20
- package/docs/cli-guide.md +872 -148
- package/docs/cli.md +1459 -485
- package/docs/codex-installed-compatibility.md +6 -11
- package/docs/codex-native-required-migration.md +1 -59
- package/docs/configuration.md +694 -222
- package/docs/globalization.md +18 -5
- package/docs/hooks.md +529 -62
- package/docs/keybindings.md +74 -4
- package/docs/legacy-cli-retirement.md +3 -3
- package/docs/legacy-diagnostics-inventory.md +4 -4
- package/docs/native-picker.md +3 -5
- package/docs/notify-queue.md +1 -1
- package/docs/npm-distribution.md +4 -0
- package/docs/operational-diagnostics.md +319 -34
- package/docs/pr-guideline.md +66 -22
- package/docs/release.md +101 -0
- package/docs/replacement-contract.md +72 -58
- package/docs/repo-layout.md +3 -0
- package/docs/resource-attribution.md +6 -2
- package/docs/session-restore.md +50 -80
- package/docs/settings-ia.md +14 -22
- package/docs/statusbar.md +38 -37
- package/docs/testing.md +83 -18
- package/docs/theme-palette.md +6 -6
- package/docs/tmux-surface-inventory.md +21 -10
- package/docs/troubleshooting.md +2 -4
- package/docs/upgrading.md +161 -24
- package/docs/usage-tracking.md +40 -49
- package/package.json +5 -5
- package/docs/agent-workflow.md +0 -2596
- package/docs/codex-generation-pool.md +0 -623
- package/docs/codex-stored-qualification.md +0 -45
package/README-ko.md
CHANGED
|
@@ -72,8 +72,8 @@ projmux create claude --project mobile-client -- "마이그레이션 계획 초
|
|
|
72
72
|
|
|
73
73
|
- [Resource Inspector](docs/resource-attribution.md) — 프로젝트·창·pane별 CPU와
|
|
74
74
|
RSS를 실시간으로 봅니다.
|
|
75
|
-
- [
|
|
76
|
-
|
|
75
|
+
- [Project Startup](docs/session-restore.md) — 닫힌 프로젝트를 Registry에 저장된
|
|
76
|
+
창 구성으로 이어 열거나 새로 만듭니다.
|
|
77
77
|
- 검색 루트, 키 설정, 업데이트는 설정에서 바꿉니다.
|
|
78
78
|
|
|
79
79
|
## 요구 사항
|
|
@@ -93,8 +93,7 @@ projmux create claude --project mobile-client -- "마이그레이션 계획 초
|
|
|
93
93
|
[상태 표시줄](docs/statusbar.md) ·
|
|
94
94
|
[훅](docs/hooks.md) ·
|
|
95
95
|
[사용량 추적](docs/usage-tracking.md) ·
|
|
96
|
-
[운영 진단](docs/operational-diagnostics.md)
|
|
97
|
-
[에이전트 작업 흐름](docs/agent-workflow.md)
|
|
96
|
+
[운영 진단](docs/operational-diagnostics.md)
|
|
98
97
|
|
|
99
98
|
## 개발
|
|
100
99
|
|
package/README.md
CHANGED
|
@@ -72,7 +72,8 @@ Templates and naming conventions are in
|
|
|
72
72
|
|
|
73
73
|
- Live per-project, per-window, and per-pane CPU/RSS in the
|
|
74
74
|
[Resource Inspector](docs/resource-attribution.md).
|
|
75
|
-
-
|
|
75
|
+
- Registry-based Continue project and Clear layout and open in
|
|
76
|
+
[Project Startup](docs/session-restore.md).
|
|
76
77
|
- Search roots, keybindings, and updates in Settings.
|
|
77
78
|
|
|
78
79
|
## Requirements
|
|
@@ -92,8 +93,7 @@ Templates and naming conventions are in
|
|
|
92
93
|
[Statusbar](docs/statusbar.md) ·
|
|
93
94
|
[Hooks](docs/hooks.md) ·
|
|
94
95
|
[Usage tracking](docs/usage-tracking.md) ·
|
|
95
|
-
[Operational Diagnostics](docs/operational-diagnostics.md)
|
|
96
|
-
[Agent Workflow](docs/agent-workflow.md)
|
|
96
|
+
[Operational Diagnostics](docs/operational-diagnostics.md)
|
|
97
97
|
|
|
98
98
|
## Development
|
|
99
99
|
|
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
# Explicit reply recovery
|
|
2
2
|
|
|
3
3
|
An explicit Claude reply names the original request with `--reply-to`. The
|
|
4
|
-
broker preserves that request's `conversationRef`, reverses its
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
broker preserves that request's `conversationRef`, reverses its source and
|
|
5
|
+
target Agents, and retains peer, untrusted, coordination-only authority. The
|
|
6
|
+
reply goes to each Agent's current activation, and the original deadline must
|
|
7
|
+
still be current. A reply cannot extend that deadline.
|
|
8
|
+
|
|
9
|
+
Correlation follows the Agent and its provider conversation, not one
|
|
10
|
+
activation. Either Agent may have been relaunched into the same conversation
|
|
11
|
+
since the original, for example by `agent relaunch`: it now runs in a new Pane
|
|
12
|
+
under a new activation, and a reply to the earlier message still commits and
|
|
13
|
+
is delivered there. A reply to another Agent or on another provider is still
|
|
14
|
+
refused as `invalid-explicit-reply-correlation`. When one of the original's
|
|
15
|
+
Agents is now in another provider conversation (another Claude session), the
|
|
16
|
+
reply is refused with `explicit-reply-conversation-changed` and stores
|
|
17
|
+
nothing; the original cannot be answered there, so send a new message without
|
|
18
|
+
`--reply-to`. A `--dialogue-reply-only` Agent's reply tool follows the same
|
|
19
|
+
rule for the original's sender: it still permits a reply to a sender
|
|
20
|
+
relaunched into the same conversation, and denies one to a sender now in
|
|
21
|
+
another conversation. Source metadata remains an unverified routing
|
|
8
22
|
claim; an explicit reply also requires the registered provider's descendant
|
|
9
23
|
caller and any existing qualification and execution guard.
|
|
10
24
|
|
|
@@ -33,12 +47,75 @@ execution guard, use the existing bounded command without that flag:
|
|
|
33
47
|
projmux agent message send uid:<original-source-agent> --reply-to <original-request-ref> -- '<corrected reply>'
|
|
34
48
|
```
|
|
35
49
|
|
|
50
|
+
Operator input from an operator client has no Agent route to reverse, so a reply
|
|
51
|
+
to it is refused with `explicit-reply-operator-origin` and stores nothing.
|
|
52
|
+
|
|
53
|
+
Within the same provider session, a reply also commits after the Claude lease
|
|
54
|
+
helper was replaced, for example by compact. The new helper did not push the
|
|
55
|
+
original, so it reads the original from the durable store and judges it by the
|
|
56
|
+
same checks. It reads the store only while its own route is the Registry's
|
|
57
|
+
current authority for the Agent; a replaced or unregistered helper reads and
|
|
58
|
+
writes nothing, and is refused with `broker-reply-helper-not-current`.
|
|
59
|
+
`broker-reply-original-not-found` means the original is in neither the helper
|
|
60
|
+
nor the store.
|
|
61
|
+
|
|
62
|
+
## Reply refusal tokens
|
|
63
|
+
|
|
64
|
+
Each refusal names its cause with one token. The CLI prints it after
|
|
65
|
+
`replyTo=<ref>:`, the Claude helper returns it as the `reply-refused` reason,
|
|
66
|
+
and the store returns it as the reply conflict reason. A token asks for one
|
|
67
|
+
action, so two causes that need different actions never share one.
|
|
68
|
+
`invalid-explicit-reply-correlation` is kept for a reply that does not match
|
|
69
|
+
its original. Every refusal here except `broker-reply-outcome-unknown` comes
|
|
70
|
+
before the reply is written anywhere: no provider saw it, so following the
|
|
71
|
+
action cannot duplicate it. The retry rules below govern an attempt that was
|
|
72
|
+
stored.
|
|
73
|
+
|
|
74
|
+
| Token | Cause | Action |
|
|
75
|
+
| --- | --- | --- |
|
|
76
|
+
| `invalid-explicit-reply-correlation` | The reply's Agents, providers, or `conversationRef` do not match the original. | Check that `--reply-to` names a message you received and that the positional Agent is its sender. |
|
|
77
|
+
| `explicit-reply-conversation-changed` | One of the original's Agents is now in another provider conversation. | Send a new message without `--reply-to`. |
|
|
78
|
+
| `invalid-explicit-reply-envelope` | The reply itself is not a valid envelope, for example a payload over the limit. | Correct the reply, for example shorten it, and send it with a fresh ref. |
|
|
79
|
+
| `explicit-reply-operator-origin` | The original is operator input from an operator client. | There is no Agent to answer; do not reply to it. |
|
|
80
|
+
| `explicit-reply-deadline-expired` | The original's deadline has passed. | Send a new message without `--reply-to`. |
|
|
81
|
+
| `explicit-reply-deadline-extended` | The reply's deadline is later than the original's. | Send the reply without a longer `--ttl`. |
|
|
82
|
+
| `explicit-reply-source-route-stale`, `explicit-reply-target-route-stale` | The replying or the answered Agent's route is not its current one, for example during a relaunch, or the helper serving the reply is not the replying Agent's. | Wait until the Agent is registered again, then send the reply. |
|
|
83
|
+
| `explicit-reply-route-stale` | The helper found a route no longer current at the moment it committed. | As above. |
|
|
84
|
+
| `broker-reply-original-not-found` | The original is in neither the helper nor the store, for example because it was reclaimed. | Send a new message without `--reply-to`. |
|
|
85
|
+
| `broker-reply-original-not-delivered` | The original never reached its target, so there is nothing to answer. | Inspect the original with `agent message status`; do not reply to it. |
|
|
86
|
+
| `broker-reply-original-without-envelope` | The helper holds the ref, but not as an Agent message it can answer. | Send a new message without `--reply-to`. |
|
|
87
|
+
| `broker-reply-helper-closed` | The replying Agent's Claude helper is shutting down, for example for a restart. | Wait for the new helper to register, then send the reply. |
|
|
88
|
+
| `broker-reply-helper-not-current` | The Registry no longer names this helper as the Agent's current one; it was replaced. | Wait for the current helper to register, then send the reply. |
|
|
89
|
+
| `broker-reply-unavailable` | The helper runs without a message broker and can commit no reply. | Relaunch the Agent so it starts a helper with one. |
|
|
90
|
+
| `broker-reply-store-unavailable` | The helper could not use the durable message store. | Check the state directory, then send the reply. |
|
|
91
|
+
| `broker-reply-store-busy` | Another writer held the message store. | Send the reply again. |
|
|
92
|
+
| `broker-reply-store-malformed` | The message store file could not be read as a store. | Inspect the store; do not resend until it reads. |
|
|
93
|
+
| `broker-reply-store-capacity` | The store is full and nothing can be reclaimed; see below. | Wait for records to be reclaimed. |
|
|
94
|
+
| `reply-already-committed` | Another reply to the original was already committed. | Inspect it with `previousRef`; do not resend. |
|
|
95
|
+
| `reply-ref-envelope-mismatch` | The same reply ref was used before with different content. | Use a fresh ref. |
|
|
96
|
+
| `broker-reply-outcome-unknown` | A commit was attempted and its result is not known. | Inspect the reply status; do not resend. |
|
|
97
|
+
|
|
98
|
+
A Claude helper that started before a build keeps that build's tokens until it
|
|
99
|
+
is replaced. An older helper therefore still reports most of these causes as
|
|
100
|
+
`invalid-explicit-reply-correlation`, and the CLI prints whichever token the
|
|
101
|
+
helper sent.
|
|
102
|
+
|
|
103
|
+
## Retries
|
|
104
|
+
|
|
36
105
|
A same-ref call returns the original immutable receipt and never pushes again.
|
|
37
106
|
Changing its payload is refused with the earlier ref and cause. A fresh ref
|
|
38
107
|
allows one new attempt only when every previous attempt is known-zero. Failed
|
|
39
108
|
records and the original request remain available; recovery never deletes or
|
|
40
|
-
resets them.
|
|
41
|
-
|
|
109
|
+
resets them.
|
|
110
|
+
|
|
111
|
+
Store capacity treats the two kinds of attempt differently. A first attempt,
|
|
112
|
+
one whose original has no stored attempt yet, is a new acceptance rather than a
|
|
113
|
+
recovery, so a full store reclaims room for it under the same rule a new
|
|
114
|
+
message uses, while pinning the original and every attempt already stored
|
|
115
|
+
against it. A recovery attempt, which follows an earlier known-zero attempt, is
|
|
116
|
+
still refused with a capacity error rather than discarding the history it is
|
|
117
|
+
recovering from. Either way a reclaimed record moves to the history log below
|
|
118
|
+
instead of being deleted, and a store with nothing reclaimable refuses both.
|
|
42
119
|
|
|
43
120
|
Delivered replies, partial writes, unknown outcomes, pending attempts, expired
|
|
44
121
|
deadlines, and stale routes must not be resent. Inspect their status and the
|
|
@@ -47,3 +124,69 @@ the stored state and specific zero-write reason must agree. These rules also
|
|
|
47
124
|
apply after store reload and to concurrent callers. Automatic resend is
|
|
48
125
|
disabled, and replies whose delivery target is Codex do not gain a new retry
|
|
49
126
|
policy here.
|
|
127
|
+
|
|
128
|
+
## Reclaimed records move to a history log
|
|
129
|
+
|
|
130
|
+
The store is a bounded hot inbox. When it accepts a new message, or a first
|
|
131
|
+
explicit reply attempt, it first reclaims records that went terminal more than
|
|
132
|
+
24 hours ago, and then, if it is still at its record limit, the oldest
|
|
133
|
+
unprotected terminal record. Before either step it expires any accepted or
|
|
134
|
+
held record whose deadline has passed, exactly as a status read would, so such
|
|
135
|
+
a record becomes terminal at that moment and follows the same reclaim rules;
|
|
136
|
+
its 24 hours count from that expiry, not from its deadline. Reclaiming is not
|
|
137
|
+
deleting: every reclaimed record is appended to
|
|
138
|
+
`<state>/agent-messages/history.jsonl`, one JSON object per line, under the same
|
|
139
|
+
file lock and with the same private directory and file permissions as the store.
|
|
140
|
+
|
|
141
|
+
The append is fsynced before the store renames its own new file into place, so a
|
|
142
|
+
crash in that window can leave a record in both the store and the log, but never
|
|
143
|
+
in neither.
|
|
144
|
+
|
|
145
|
+
Each line carries the envelope's own key names:
|
|
146
|
+
|
|
147
|
+
```json
|
|
148
|
+
{"schemaVersion":1,"evictedAt":"…","reason":"retention","adapter":"claude-coordination",
|
|
149
|
+
"messageRef":"…","conversationRef":"…","replyTo":"…",
|
|
150
|
+
"state":"delivered","deliveryReason":"unspecified","handoffObserved":false,
|
|
151
|
+
"acceptedAt":"…","terminalAt":"…","payloadBytes":466,"payloadSHA256":"…",
|
|
152
|
+
"source":{"agentUID":"…","provider":"…"},
|
|
153
|
+
"target":{"agentUID":"…","provider":"…"}}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
`reason` is `retention` for the 24-hour rule and `capacity` for the record
|
|
157
|
+
limit. `replyTo` is omitted when the record is not a reply. `outcomeUnknown`
|
|
158
|
+
appears, as `true`, only on a failed record whose outcome is unknown; it is
|
|
159
|
+
absent otherwise. `source` and `target` carry only `agentUID` and `provider`:
|
|
160
|
+
the Pane and activation generation fence a live delivery, and the incarnation
|
|
161
|
+
follows the provider conversation; all three mean nothing once the record has
|
|
162
|
+
left the store. The envelope's `deadline` is not written. A line for operator
|
|
163
|
+
input (see [Operator input](claude-coordination-endpoints.md#operator-input)) carries
|
|
164
|
+
`"origin":{"kind":"operator","client":"<client>"}` in place of `source`; an Agent
|
|
165
|
+
message's line has no `origin`. Every other key is always present.
|
|
166
|
+
|
|
167
|
+
Lines written by earlier builds may still be in the same file. They carry full
|
|
168
|
+
routes (`paneUID`, `activationGeneration`, `incarnation`), a `deadline`, and
|
|
169
|
+
`outcomeUnknown` even when it is `false`, and they read the same way: a reader
|
|
170
|
+
ignores keys it does not expect and reads an absent key as its zero value, so
|
|
171
|
+
both shapes give the same edges, states and times. Lines written before the
|
|
172
|
+
payload digest existed have no `payloadSHA256` key and read with an empty
|
|
173
|
+
digest, which means "not recorded", not a mismatch; earlier lines are not
|
|
174
|
+
backfilled. All of these are `schemaVersion` 1: every added key is additive.
|
|
175
|
+
|
|
176
|
+
`schemaVersion` starts at 1 and follows the same rule as the
|
|
177
|
+
coordination frame's field of that name: an absent or zero value reads as 1, and
|
|
178
|
+
a reader that meets a higher version reads the fields it knows rather than
|
|
179
|
+
discarding the line or failing. It is independent of the durable envelope
|
|
180
|
+
version and of the store file version.
|
|
181
|
+
|
|
182
|
+
The log does not keep the message body. It records `payloadBytes`, the original
|
|
183
|
+
payload length, and `payloadSHA256`, the SHA-256 of the payload's exact bytes
|
|
184
|
+
as 64 lowercase hex characters, and has no `payload` key at all: the log is
|
|
185
|
+
unbounded in time, and its intended consumers need the message graph, not its
|
|
186
|
+
text. The digest lets a consumer that holds the text elsewhere, such as a
|
|
187
|
+
transcript, prove it is the same message; the reader and its consumers compute
|
|
188
|
+
it with the same function (`PayloadSHA256` in `internal/core/agentmessage`).
|
|
189
|
+
|
|
190
|
+
The active log rotates to `history.jsonl.1` once it would pass 8 MiB, replacing
|
|
191
|
+
any earlier `history.jsonl.1`. At most two generations exist, so the log's disk
|
|
192
|
+
use is bounded even though its history is not complete.
|
|
@@ -53,11 +53,12 @@ Everything after `--` reaches the configured provider executable. Placeholder
|
|
|
53
53
|
model, permission, and agent flags are private customization examples, not
|
|
54
54
|
project defaults. Omit the separator when there is no payload.
|
|
55
55
|
|
|
56
|
-
Settings > AI
|
|
57
|
-
Antigravity may launch. Canonical create routes respect that setting.
|
|
58
|
-
no
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
`Settings > Global > AI > Enabled providers` controls whether Claude, Codex,
|
|
57
|
+
and Antigravity may launch. Canonical create routes respect that setting.
|
|
58
|
+
There is no per-launch override for a disabled provider; enable it in Settings
|
|
59
|
+
or with `projmux config providers --enable <id>` (`--disable <id>` turns one
|
|
60
|
+
off), which goes through the same writer. For a plain shell split use
|
|
61
|
+
`projmux create pane`, not an Agent provider.
|
|
61
62
|
|
|
62
63
|
Interactive provider and resume selection belong to the app's picker surfaces.
|
|
63
64
|
CLI automation should choose an explicit provider or use `projmux agent resume
|