projmux 0.15.1 → 0.15.3
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-workflow.md +505 -23
- package/docs/architecture.md +17 -8
- package/docs/claude-coordination-endpoints.md +36 -0
- package/docs/cli-guide.md +79 -14
- package/docs/cli.md +40 -17
- package/docs/configuration.md +65 -0
- package/docs/heterogeneous-dialogue-canary.md +28 -0
- package/docs/keybindings.md +125 -1
- package/docs/legacy-cli-retirement.md +1 -1
- package/docs/settings-ia.md +31 -0
- package/docs/statusbar.md +10 -4
- package/docs/theme-palette.md +14 -0
- package/docs/usage-tracking.md +33 -6
- package/package.json +5 -5
package/docs/architecture.md
CHANGED
|
@@ -1008,10 +1008,14 @@ tmux transport mirror:
|
|
|
1008
1008
|
recovery route.
|
|
1009
1009
|
- `rename pane` changes `Pane.metadata.name` and its `@projmux_pane_label`
|
|
1010
1010
|
mirror only. It never writes the raw tmux `pane_title`.
|
|
1011
|
-
- `rename window` is the explicit stable-identity path: it changes
|
|
1012
|
-
`Window.metadata.name`, its root-scoped same-kind name reservation,
|
|
1013
|
-
|
|
1014
|
-
`window_name
|
|
1011
|
+
- `rename window` is the explicit stable-identity path: it changes
|
|
1012
|
+
`Window.metadata.name`, its root-scoped same-kind name reservation, the exact
|
|
1013
|
+
live `@projmux_window_name` transport mirror and, when the invocation has a
|
|
1014
|
+
proven runtime route, the tmux tab `window_name` through the canonical
|
|
1015
|
+
`rename-window -t @N -- <name>` -- the same argv shape the rename key and the
|
|
1016
|
+
Window menu Rename item go through. With no route it stays Registry-only and
|
|
1017
|
+
says on stderr that the tab did not converge. It never changes
|
|
1018
|
+
`metadata.displayName`.
|
|
1015
1019
|
- `rename project` likewise writes only `Project.metadata.name` and the exact
|
|
1016
1020
|
live session's `@projmux_project_name`; it never renames the tmux session.
|
|
1017
1021
|
`rebind project` preserves the Project uid and session name while updating
|
|
@@ -1906,7 +1910,10 @@ Resource-first create:
|
|
|
1906
1910
|
touched.
|
|
1907
1911
|
- **Everything is detached.** No create path issues `switch-client`,
|
|
1908
1912
|
`select-window`, `select-pane`, or `attach-session`. `focus pane` and
|
|
1909
|
-
`-o pane-id` are how a caller ends up in the new pane.
|
|
1913
|
+
`-o pane-id` are how a caller ends up in the new pane. One exception: the
|
|
1914
|
+
human intent route `internal tmux window-create` (`window.create` key, Window
|
|
1915
|
+
menu New At End) moves exactly the pressing client to the new Window after
|
|
1916
|
+
its create commits; public `create` stays detached.
|
|
1910
1917
|
- **Focus is navigation-only.** `focus project|window|pane` reads live tmux
|
|
1911
1918
|
inventory and may move an existing client, but has no Registry store and
|
|
1912
1919
|
issues no session/Window/Pane creation, identity-marker, rename, respawn, or
|
|
@@ -2004,9 +2011,11 @@ Selector and the implicit active target:
|
|
|
2004
2011
|
|
|
2005
2012
|
Projmux keeps visible naming separate from source metadata:
|
|
2006
2013
|
|
|
2007
|
-
- **User pane label** is
|
|
2008
|
-
|
|
2009
|
-
|
|
2014
|
+
- **User pane label** is pane-scoped metadata stored in `@projmux_pane_label`,
|
|
2015
|
+
the live mirror of the Pane's Registry `metadata.name`. The Rename Pane action
|
|
2016
|
+
renames the Registry Pane through the same owner as `rename pane`, which
|
|
2017
|
+
writes this mirror; an empty response changes nothing, and the action never
|
|
2018
|
+
writes the AI topic or raw pane title.
|
|
2010
2019
|
- **Pane border label** is the primary visible pane name. In the app tmux
|
|
2011
2020
|
config and native previews it resolves to user pane label first, agent AI
|
|
2012
2021
|
topic second, known interactive shell command (`zsh`, `bash`, `fish`, `sh`,
|
|
@@ -127,6 +127,22 @@ failure before any byte is a non-ambiguous `provider-write-zero`; partial bytes,
|
|
|
127
127
|
a write error after bytes, or a lost helper response is ambiguous and has
|
|
128
128
|
`autoResend=false`. A complete write plus helper return is only a transport
|
|
129
129
|
handoff, not proof that Claude parsed, displayed, processed, or answered it.
|
|
130
|
+
Push content has no length cap of its own: only the 8192-byte serialized
|
|
131
|
+
auth+user frame bounds it, and a size excess ends as
|
|
132
|
+
`provider-frame-too-large: frameBytes=N limitBytes=8192` with zero provider
|
|
133
|
+
bytes; the reply tool argv body stays at 4096 bytes.
|
|
134
|
+
|
|
135
|
+
`agent message send` applies the same budget to a Claude target before
|
|
136
|
+
acceptance, for plain sends and `--reply-to` alike. The sender renders the
|
|
137
|
+
content with the helper's renderer, once with its own executable and once with
|
|
138
|
+
the fixed executable phrase, keeps the longer frame, and counts an assumed
|
|
139
|
+
48-byte auth token; it never reads a messaging token. A frame over 8192 bytes
|
|
140
|
+
exits nonzero with `provider-frame-too-large: frameBytes=N limitBytes=8192`
|
|
141
|
+
before any receipt is stored or the helper is called. Codex targets are not
|
|
142
|
+
pre-checked. A helper started before this rule still caps push content at 4096
|
|
143
|
+
bytes and fails a larger body with `provider-frame-invalid-content`; the
|
|
144
|
+
sender's receipt then names the rendered content bytes and asks to re-activate
|
|
145
|
+
(restart) the target Agent.
|
|
130
146
|
|
|
131
147
|
The frozen frame is closed to Claude Code `2.1.263`. A different provider
|
|
132
148
|
version, helper replacement, provider restart, registration replacement, or
|
|
@@ -208,6 +224,26 @@ real-provider observation is opt-in through
|
|
|
208
224
|
`scripts/agent-dialogue-live-canary.sh`; each version-stress row must qualify
|
|
209
225
|
independently.
|
|
210
226
|
|
|
227
|
+
`TestClaudeDialogueStreamReplaysObservedFrameCorpus` pins the reply-only
|
|
228
|
+
validator's verdict on preserved real frame shapes. Neither it nor L20 proves
|
|
229
|
+
installed-provider compatibility, value drift (the corpus keeps top-level key
|
|
230
|
+
shape with placeholder values), or acceptance of unknown frames and fields (the
|
|
231
|
+
closed vocabulary rejects them by design). L20 replays every corpus item whose
|
|
232
|
+
verdict is `drop` through the production reply-only validator: the Claude
|
|
233
|
+
fixture reads the corpus at run time from `PROJMUX_FAKE_CLAUDE_OBSERVED_FRAMES`,
|
|
234
|
+
emits each dropped side frame with its key set unchanged after init and before
|
|
235
|
+
its startup result, and the scenario requires the emitted names to equal the
|
|
236
|
+
corpus drop set. Those frames are key-shape placeholders, not model output. L20
|
|
237
|
+
does not emit the two recorded real shapes that are rejected today:
|
|
238
|
+
`result-success-25-keys` (the result allowlist lacks `origin`) and
|
|
239
|
+
`system-init-allowlist-diff` (the init allowlist lacks `memory_paths` and
|
|
240
|
+
`terminal_slash_commands`). Shapes without preserved evidence are gaps, not
|
|
241
|
+
items, so neither the corpus nor L20 exercises them: `command_lifecycle` keys
|
|
242
|
+
and values, a non-null assistant `context_management`, `system`
|
|
243
|
+
`thinking_tokens`, hook and user `tool_result` frames, the exact real init key
|
|
244
|
+
set, every nested value, `rate_limit_event` envelope keys beyond `type` and
|
|
245
|
+
`rate_limit_info`, and the lost earlier shape inventories.
|
|
246
|
+
|
|
211
247
|
Provider sources: [SessionStart and Stop hooks](https://code.claude.com/docs/en/hooks)
|
|
212
248
|
and [cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging).
|
|
213
249
|
|
package/docs/cli-guide.md
CHANGED
|
@@ -252,8 +252,27 @@ The contract:
|
|
|
252
252
|
`create window|pane|agent|<provider>` is resource-backed on every spelling.
|
|
253
253
|
There is no mode flag and no second parser: the same argv means the same thing
|
|
254
254
|
whether or not `--project` is present, and `-w`, `--create-window`, `--pane`,
|
|
255
|
-
`--selector`, `--placement`, `--
|
|
256
|
-
|
|
255
|
+
`--selector`, `--placement`, `--cwd-from`, `--name`, `--label`, `-o`, and the
|
|
256
|
+
`--` payload all reach the same parser either way. `--cwd` and `--add-dir` are
|
|
257
|
+
provider create flags: they are defined on `create agent` and the three provider
|
|
258
|
+
shortcuts, not on `create window` or `create pane`.
|
|
259
|
+
|
|
260
|
+
`--cwd-from project|pane` selects where the new split starts. `project` (the
|
|
261
|
+
default) starts it in the owner Project root. `pane` starts it in the active
|
|
262
|
+
Pane's live directory while that directory is inside the owner Project root, and
|
|
263
|
+
otherwise starts it in the root and says so in one stderr line; it never
|
|
264
|
+
refuses. The flag cannot be combined with `--cwd`, which names an Agent working
|
|
265
|
+
directory outright.
|
|
266
|
+
|
|
267
|
+
On the CLI the flag is the only input: `create pane`, `create agent`, and the
|
|
268
|
+
provider shortcuts never read `[ai] split_cwd_from`, so with no `--cwd-from`
|
|
269
|
+
they always start in the owner Project root, whatever the global or project
|
|
270
|
+
config says. A CLI result is determined by its arguments, and scripts must not
|
|
271
|
+
change behavior because someone changed a Settings value. That config (and the
|
|
272
|
+
`AI > New splits start in` Settings row that writes it) only decides splits
|
|
273
|
+
started from the UI -- keybinding splits, the launcher, the resume picker's new
|
|
274
|
+
row, and the Pane menu -- in the order flag > project config > global config >
|
|
275
|
+
default. See [configuration.md](configuration.md).
|
|
257
276
|
|
|
258
277
|
The scope resolves in two branches:
|
|
259
278
|
|
|
@@ -339,7 +358,10 @@ they name `--project` as the fix:
|
|
|
339
358
|
gone — a `recoverable` runtime is reported, never adopted.
|
|
340
359
|
|
|
341
360
|
Every create is **detached**: no create moves the client. Use `focus pane` or
|
|
342
|
-
`-o pane-id` when you want to end up in the new pane.
|
|
361
|
+
`-o pane-id` when you want to end up in the new pane. One exception: the human
|
|
362
|
+
intent route `internal tmux window-create` (the `window.create` key and the
|
|
363
|
+
Window menu New At End) moves the pressing client to the new Window after its
|
|
364
|
+
create commits; public `create` stays detached. A natural create validates
|
|
343
365
|
the inherited exact route and Pane containment. An explicit resource scope
|
|
344
366
|
binds the selected app resource route without letting unrelated inherited
|
|
345
367
|
`TMUX`/`TMUX_PANE` choose or change the resource target; exact Project plus
|
|
@@ -376,10 +398,16 @@ The generated `MouseDown3Pane` menu treats its Horizontal Split, Vertical
|
|
|
376
398
|
Split, and Kill entries as Projmux resource actions. Both splits pass the exact
|
|
377
399
|
clicked pane through the popup-origin anchor above and reach the same canonical
|
|
378
400
|
`create pane` materializer as the CLI, so the new pane receives a Registry uid.
|
|
379
|
-
Kill resolves that anchor's mirrored uid and
|
|
380
|
-
including its printed delete result
|
|
381
|
-
|
|
382
|
-
|
|
401
|
+
Kill on a pane with `@projmux_pane_uid` resolves that anchor's mirrored uid and
|
|
402
|
+
reaches canonical `delete pane`, including its printed delete result; a pane
|
|
403
|
+
without the mirror runs tmux's own `kill-pane` instead of being refused. The
|
|
404
|
+
menu never falls back to a raw tmux mutation when either route refuses. The
|
|
405
|
+
reason is displayed on the exact client that opened the menu instead of being
|
|
406
|
+
lost as a `run-shell` exit code. The app config's `prefix >` and
|
|
407
|
+
`M-MouseDown3Pane` Pane menus follow the same rules, and its `prefix <`,
|
|
408
|
+
`MouseDown3Status`, and `M-MouseDown3Status` Window menus route Kill on a
|
|
409
|
+
mirrored Window to canonical `delete window`; see
|
|
410
|
+
[Managed menus](keybindings.md#managed-menus).
|
|
383
411
|
|
|
384
412
|
tmux Respawn has no equivalent in the current resource model: it preserves the
|
|
385
413
|
same pane handle, layout, Registry uid, and original command, while canonical
|
|
@@ -389,15 +417,40 @@ menu therefore omits Respawn entirely and does not expose a refusal handler or
|
|
|
389
417
|
invent a replace operation. User-authored tmux bindings remain outside this
|
|
390
418
|
managed-menu contract.
|
|
391
419
|
|
|
420
|
+
#### Managed close keys
|
|
421
|
+
|
|
422
|
+
The generated app config routes tmux's `prefix x` and `prefix &` through the
|
|
423
|
+
same resource routes whenever the target carries a Registry identity mirror.
|
|
424
|
+
`prefix x` on a Pane with `@projmux_pane_uid` confirms on the exact client, then
|
|
425
|
+
runs the Pane menu Kill route above: canonical `delete pane` with an
|
|
426
|
+
`intentional` termination receipt. The Agent that owned the Pane stays in the
|
|
427
|
+
Registry as Offline with a `deleted` exit, which Continue never replays.
|
|
428
|
+
`prefix &` on a Window with
|
|
429
|
+
`@projmux_window_uid` confirms, then runs `internal tmux window-delete`, which is
|
|
430
|
+
canonical `delete window` on that exact Window; a Project's last Window leaves a
|
|
431
|
+
zero-Window Project. A refusal is shown on that client and never falls back to
|
|
432
|
+
a raw kill. A target without the mirror keeps tmux's stock `confirm-before`
|
|
433
|
+
prompt and kill, with no Registry write. See
|
|
434
|
+
[Managed close keys](keybindings.md#managed-close-keys) for changing or
|
|
435
|
+
disabling the keys.
|
|
436
|
+
|
|
392
437
|
### Rename and rebind live convergence
|
|
393
438
|
|
|
394
439
|
`rename project|window|pane` commits the selected Registry `metadata.name` and
|
|
395
|
-
then updates only its exact UID-bound live transport
|
|
440
|
+
then updates only its exact UID-bound live transport fields:
|
|
396
441
|
|
|
397
442
|
- Project: `@projmux_project_name` (never the tmux session name)
|
|
398
|
-
- Window: `@projmux_window_name`
|
|
443
|
+
- Window: `@projmux_window_name` and the tmux tab `window_name` (never
|
|
444
|
+
`displayName`)
|
|
399
445
|
- Pane: `@projmux_pane_label` (never raw `pane_title`)
|
|
400
446
|
|
|
447
|
+
The Window tab converges only when the invocation has a proven runtime route,
|
|
448
|
+
which is what running inside the projmux tmux runtime gives it. Outside one the
|
|
449
|
+
rename is Registry-only: it exits zero and prints one line on stderr saying the
|
|
450
|
+
tab still shows the old name until a rename runs inside that runtime. There is
|
|
451
|
+
no flag for either behavior; the next time that Window is materialized from the
|
|
452
|
+
Registry, the tab carries the committed name.
|
|
453
|
+
|
|
401
454
|
`rename agent` changes only the Agent's stable root-scoped `metadata.name`.
|
|
402
455
|
It does not change the Agent topic, provider, lifecycle state, or managed Pane
|
|
403
456
|
name/title. `create agent` derives the managed Pane's name from the Agent's
|
|
@@ -537,7 +590,9 @@ generated `pane-exited` hook. The supervisor must have durably journaled a
|
|
|
537
590
|
same-generation `normal` receipt, the hook must name the exact `%N` Pane and
|
|
538
591
|
the owner Window must carry its exact last-positive `$N/@N` binding on the same
|
|
539
592
|
socket, and fresh preflight plus locked observations must still resolve the
|
|
540
|
-
same Registry owner chain.
|
|
593
|
+
same Registry owner chain. This includes Windows re-materialized by Project
|
|
594
|
+
start/Continue topology replay: the replay records each Window it materializes
|
|
595
|
+
with its live `$N/@N` in the same commit. A non-last Pane is removed while its directly owning
|
|
541
596
|
Agent is retained Offline with its conversation identity. For a last Pane, that evidence is retained until a
|
|
542
597
|
matching `window-unlinked` hook removes the Window; a final Project Window also
|
|
543
598
|
removes its Window descendants while retaining the exact Project uid, root,
|
|
@@ -2021,6 +2076,8 @@ projmux internal tmux popup-sessions
|
|
|
2021
2076
|
projmux internal tmux popup-preview <session>
|
|
2022
2077
|
projmux internal tmux rebalance-panes
|
|
2023
2078
|
projmux internal tmux rename-pane <pane> <label>
|
|
2079
|
+
projmux internal tmux window-rename --client <key> --anchor <%pane> (--name-stdin | -- <name>)
|
|
2080
|
+
projmux internal tmux pane-rename --client <key> --anchor <%pane> (--name-stdin | -- <name>)
|
|
2024
2081
|
projmux internal tmux print-config [--bin <path>]
|
|
2025
2082
|
projmux internal tmux print-app-config [--bin <path>]
|
|
2026
2083
|
projmux internal tmux install [--bin <path>] [--config <path>] [--include <path>]
|
|
@@ -2034,10 +2091,18 @@ accepted by `popup-toggle` mirror the historical sessionizer surface:
|
|
|
2034
2091
|
`notify-sidebar`, `recent-windows`, `resource-inspector`, `ai-split-picker-right`,
|
|
2035
2092
|
`ai-split-picker-down`, `ai-split-resume-right`, `ai-split-resume-down`,
|
|
2036
2093
|
`ai-split-settings`.
|
|
2037
|
-
`rename-pane` sets only the pane-scoped
|
|
2038
|
-
`@projmux_pane_label
|
|
2039
|
-
|
|
2040
|
-
|
|
2094
|
+
`rename-pane` is a label-only helper: it sets only the pane-scoped
|
|
2095
|
+
`@projmux_pane_label`, and an empty label clears the option. It does not change
|
|
2096
|
+
the Registry Pane name, so the next Continue restores that name, and it does not
|
|
2097
|
+
change the raw tmux pane title, AI topic, or AI topic manual-ownership flag. No
|
|
2098
|
+
generated binding uses it.
|
|
2099
|
+
`window-rename` and `pane-rename` are the generated rename routes behind the
|
|
2100
|
+
`rename-window` and `rename-pane-label` keybinding actions and the Window menu
|
|
2101
|
+
Rename item. They resolve the anchor Pane to its exact Registry Window or Pane
|
|
2102
|
+
and rename it through the same owner as `projmux rename window|pane`, then
|
|
2103
|
+
report one line to the client. The generated bindings pass the prompt response
|
|
2104
|
+
with `--name-stdin` inside a quoted here-document; see
|
|
2105
|
+
[keybindings.md](keybindings.md#rename-keys) for the input rules. The retired `rename-pane-topic`
|
|
2041
2106
|
keymap action is no longer accepted: replace a stale
|
|
2042
2107
|
`[bindings.rename-pane-topic]` table with `[bindings.rename-pane-label]`.
|
|
2043
2108
|
The `projmux agent topic set/clear` commands keep
|
package/docs/cli.md
CHANGED
|
@@ -39,7 +39,7 @@ Root parser bridges outside the route graph are censused from their parser token
|
|
|
39
39
|
|
|
40
40
|
Every route declares one allowed-effect record over seven independent resource axes. A pipe separates conditional success outcomes; preflight refusal remains zero-effect. `domain-effect=null` means the route has no typed extension beyond this resource tuple.
|
|
41
41
|
|
|
42
|
-
The machine-readable manifest contains
|
|
42
|
+
The machine-readable manifest contains 191 route-effect records, including hidden plumbing that the public route sections omit.
|
|
43
43
|
|
|
44
44
|
| Axis | Closed vocabulary |
|
|
45
45
|
| --- | --- |
|
|
@@ -75,7 +75,7 @@ projmux <command> [args...]
|
|
|
75
75
|
| [`projmux notification`](#projmux-notification) | canonical | Manage pending notification workflow state |
|
|
76
76
|
| [`projmux open`](#projmux-open) | canonical | Open a Project runtime and move the current client to it |
|
|
77
77
|
| [`projmux pin`](#projmux-pin) | canonical | Manage pinned project directories |
|
|
78
|
-
| [`projmux prune`](#projmux-prune) | canonical | Prune stale Projects and snapshots |
|
|
78
|
+
| [`projmux prune`](#projmux-prune) | canonical | Prune stale Projects, Agents, and snapshots |
|
|
79
79
|
| [`projmux quit`](#projmux-quit) | shortcut | Quit the app-owned projmux tmux runtime |
|
|
80
80
|
| [`projmux reconcile`](#projmux-reconcile) | canonical | Preview or repair Registry and exact tmux resource drift |
|
|
81
81
|
| [`projmux rebind`](#projmux-rebind) | canonical | Rebind a Project to a new absolute root without moving files |
|
|
@@ -761,7 +761,7 @@ Subcommands:
|
|
|
761
761
|
|
|
762
762
|
| Route | Summary |
|
|
763
763
|
| --- | --- |
|
|
764
|
-
| [`projmux agent message send`](#projmux-agent-message-send) | Submit bounded peer coordination; --source selects a source Agent anchor, not caller authentication (default: active Pane) |
|
|
764
|
+
| [`projmux agent message send`](#projmux-agent-message-send) | Submit bounded peer coordination; --source selects a source Agent anchor, not caller authentication (default: active Pane); exits nonzero after printing a failed, refused, expired, or stale receipt |
|
|
765
765
|
| [`projmux agent message status`](#projmux-agent-message-status) | Read a payload-free broker delivery receipt |
|
|
766
766
|
| [`projmux agent message qualify`](#projmux-agent-message-qualify) | Explicitly qualify one exact Claude target using owned current-version isolation evidence and one marker push |
|
|
767
767
|
|
|
@@ -769,7 +769,7 @@ Canonical spelling: `projmux agent message send`, `projmux agent message status`
|
|
|
769
769
|
|
|
770
770
|
#### `projmux agent message send`
|
|
771
771
|
|
|
772
|
-
Submit bounded peer coordination; --source selects a source Agent anchor, not caller authentication (default: active Pane)
|
|
772
|
+
Submit bounded peer coordination; --source selects a source Agent anchor, not caller authentication (default: active Pane); exits nonzero after printing a failed, refused, expired, or stale receipt
|
|
773
773
|
|
|
774
774
|
Selectorless authority: `explicit-target` — the route or caller must name the exact target.
|
|
775
775
|
|
|
@@ -1215,10 +1215,10 @@ Allowed effects:
|
|
|
1215
1215
|
```
|
|
1216
1216
|
projmux create project --root <absolute-path> [--name <name>] [--label key=value]... [-o <mode>]
|
|
1217
1217
|
projmux create window [--project <ref> | -p <ref>] [--name <name>] [--label key=value]... [-o <mode>] [-- <payload>]
|
|
1218
|
-
projmux create pane [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [--pane <ref>]... [--create-window] [--all-windows | --primary-window] [--placement right|down] [-o <mode>] [-- <payload>]
|
|
1219
|
-
projmux create agent --provider <provider> [--project <ref> | -p <ref>] [--cwd <path>] [--add-dir <path>]... [--interactive-only] [--window <ref> | -w <ref>]... [--pane <ref>]... [--create-window] [--all-windows | --primary-window] [--placement right|down] [-o <mode>] [-- <payload>]
|
|
1220
|
-
projmux create codex [--project <ref> | -p <ref>] [--cwd <path>] [--add-dir <path>]... [--interactive-only] [--window <ref> | -w <ref>]... [--create-window] [--all-windows | --primary-window] [--placement right|down] [-o <mode>] [-- <payload>]
|
|
1221
|
-
projmux create claude|antigravity [--project <ref> | -p <ref>] [--cwd <path>] [--add-dir <path>]... [--window <ref> | -w <ref>]... [--create-window] [--all-windows | --primary-window] [--placement right|down] [-o <mode>] [-- <payload>]
|
|
1218
|
+
projmux create pane [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [--pane <ref>]... [--create-window] [--all-windows | --primary-window] [--placement right|down] [--cwd-from project|pane] [-o <mode>] [-- <payload>]
|
|
1219
|
+
projmux create agent --provider <provider> [--project <ref> | -p <ref>] [--cwd <path>] [--add-dir <path>]... [--interactive-only] [--window <ref> | -w <ref>]... [--pane <ref>]... [--create-window] [--all-windows | --primary-window] [--placement right|down] [--cwd-from project|pane] [-o <mode>] [-- <payload>]
|
|
1220
|
+
projmux create codex [--project <ref> | -p <ref>] [--cwd <path>] [--add-dir <path>]... [--interactive-only] [--window <ref> | -w <ref>]... [--create-window] [--all-windows | --primary-window] [--placement right|down] [--cwd-from project|pane] [-o <mode>] [-- <payload>]
|
|
1221
|
+
projmux create claude|antigravity [--project <ref> | -p <ref>] [--cwd <path>] [--add-dir <path>]... [--window <ref> | -w <ref>]... [--create-window] [--all-windows | --primary-window] [--placement right|down] [--cwd-from project|pane] [-o <mode>] [-- <payload>]
|
|
1222
1222
|
projmux create notification --text <s> --target <SESSION[:WINDOW[.PANE]]> [--socket <s>]
|
|
1223
1223
|
projmux create snapshot
|
|
1224
1224
|
```
|
|
@@ -1308,7 +1308,7 @@ Allowed effects:
|
|
|
1308
1308
|
- `domain-effect=null`
|
|
1309
1309
|
|
|
1310
1310
|
```
|
|
1311
|
-
projmux create pane [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--all-windows | --primary-window] [--name <name>] [--label key=value]... [--placement right|down] [-o <mode>] [-- <payload>]
|
|
1311
|
+
projmux create pane [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--all-windows | --primary-window] [--name <name>] [--label key=value]... [--placement right|down] [--cwd-from project|pane] [-o <mode>] [-- <payload>]
|
|
1312
1312
|
```
|
|
1313
1313
|
|
|
1314
1314
|
Output modes (`-o`): `uid`, `name`, `ref`, `metadata`, `json`, `pane-id`, `none`, `receipt`
|
|
@@ -1331,7 +1331,7 @@ Allowed effects:
|
|
|
1331
1331
|
- `domain-effect=null`
|
|
1332
1332
|
|
|
1333
1333
|
```
|
|
1334
|
-
projmux create agent --provider <provider> [--project <ref> | -p <ref>] [--cwd <path>] [--add-dir <path>]... [--interactive-only] [--window <ref> | -w <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--all-windows | --primary-window] [--name <name>] [--label key=value]... [--placement right|down] [-o <mode>] [-- <payload>]
|
|
1334
|
+
projmux create agent --provider <provider> [--project <ref> | -p <ref>] [--cwd <path>] [--add-dir <path>]... [--interactive-only] [--window <ref> | -w <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--all-windows | --primary-window] [--name <name>] [--label key=value]... [--placement right|down] [--cwd-from project|pane] [-o <mode>] [-- <payload>]
|
|
1335
1335
|
```
|
|
1336
1336
|
|
|
1337
1337
|
Output modes (`-o`): `uid`, `name`, `ref`, `metadata`, `json`, `pane-id`, `none`, `receipt`
|
|
@@ -1396,7 +1396,7 @@ Allowed effects:
|
|
|
1396
1396
|
- `domain-effect=null`
|
|
1397
1397
|
|
|
1398
1398
|
```
|
|
1399
|
-
projmux create codex [--project <ref> | -p <ref>] [--cwd <path>] [--add-dir <path>]... [--interactive-only] [--window <ref> | -w <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--all-windows | --primary-window] [--name <name>] [--label key=value]... [--placement right|down] [-o <mode>] [-- <payload>]
|
|
1399
|
+
projmux create codex [--project <ref> | -p <ref>] [--cwd <path>] [--add-dir <path>]... [--interactive-only] [--window <ref> | -w <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--all-windows | --primary-window] [--name <name>] [--label key=value]... [--placement right|down] [--cwd-from project|pane] [-o <mode>] [-- <payload>]
|
|
1400
1400
|
```
|
|
1401
1401
|
|
|
1402
1402
|
Output modes (`-o`): `uid`, `name`, `ref`, `metadata`, `json`, `pane-id`, `none`, `receipt`
|
|
@@ -1419,7 +1419,7 @@ Allowed effects:
|
|
|
1419
1419
|
- `domain-effect=null`
|
|
1420
1420
|
|
|
1421
1421
|
```
|
|
1422
|
-
projmux create claude [--project <ref> | -p <ref>] [--cwd <path>] [--add-dir <path>]... [--window <ref> | -w <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--all-windows | --primary-window] [--name <name>] [--label key=value]... [--placement right|down] [-o <mode>] [-- <payload>]
|
|
1422
|
+
projmux create claude [--project <ref> | -p <ref>] [--cwd <path>] [--add-dir <path>]... [--window <ref> | -w <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--all-windows | --primary-window] [--name <name>] [--label key=value]... [--placement right|down] [--cwd-from project|pane] [-o <mode>] [-- <payload>]
|
|
1423
1423
|
```
|
|
1424
1424
|
|
|
1425
1425
|
Output modes (`-o`): `uid`, `name`, `ref`, `metadata`, `json`, `pane-id`, `none`, `receipt`
|
|
@@ -1442,7 +1442,7 @@ Allowed effects:
|
|
|
1442
1442
|
- `domain-effect=null`
|
|
1443
1443
|
|
|
1444
1444
|
```
|
|
1445
|
-
projmux create antigravity [--project <ref> | -p <ref>] [--cwd <path>] [--add-dir <path>]... [--window <ref> | -w <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--all-windows | --primary-window] [--name <name>] [--label key=value]... [--placement right|down] [-o <mode>] [-- <payload>]
|
|
1445
|
+
projmux create antigravity [--project <ref> | -p <ref>] [--cwd <path>] [--add-dir <path>]... [--window <ref> | -w <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--all-windows | --primary-window] [--name <name>] [--label key=value]... [--placement right|down] [--cwd-from project|pane] [-o <mode>] [-- <payload>]
|
|
1446
1446
|
```
|
|
1447
1447
|
|
|
1448
1448
|
Output modes (`-o`): `uid`, `name`, `ref`, `metadata`, `json`, `pane-id`, `none`, `receipt`
|
|
@@ -2600,7 +2600,7 @@ projmux pin project list|add|remove|toggle|clear
|
|
|
2600
2600
|
|
|
2601
2601
|
## `projmux prune`
|
|
2602
2602
|
|
|
2603
|
-
Prune stale Projects and snapshots
|
|
2603
|
+
Prune stale Projects, Agents, and snapshots
|
|
2604
2604
|
|
|
2605
2605
|
Selectorless authority: `refusal` — there is no safe selectorless action; refuse before output or mutation.
|
|
2606
2606
|
|
|
@@ -2618,16 +2618,39 @@ Allowed effects:
|
|
|
2618
2618
|
```
|
|
2619
2619
|
projmux prune snapshot [--older-than <duration>]
|
|
2620
2620
|
projmux prune project --missing --older-than <duration> [--yes]
|
|
2621
|
+
projmux prune agent --older-than <duration> [--no-session-ref] [--no-pane] [--exclude <agent-ref>]... [--yes]
|
|
2621
2622
|
```
|
|
2622
2623
|
|
|
2623
2624
|
Subcommands:
|
|
2624
2625
|
|
|
2625
2626
|
| Route | Summary |
|
|
2626
2627
|
| --- | --- |
|
|
2628
|
+
| [`projmux prune agent`](#projmux-prune-agent) | Delete Offline or Failed Agents past a bounded age whose session ref or managed Panes are gone; live Panes and Running Agents are never selected |
|
|
2627
2629
|
| [`projmux prune project`](#projmux-prune-project) | Delete Projects whose spec.root has been missing for a bounded age |
|
|
2628
2630
|
| [`projmux prune snapshot`](#projmux-prune-snapshot) | Inspect or delete preserved session snapshots (canonical spelling) |
|
|
2629
2631
|
|
|
2630
|
-
Canonical spelling: `projmux prune project`, `projmux prune snapshot`
|
|
2632
|
+
Canonical spelling: `projmux prune agent`, `projmux prune project`, `projmux prune snapshot`
|
|
2633
|
+
|
|
2634
|
+
### `projmux prune agent`
|
|
2635
|
+
|
|
2636
|
+
Delete Offline or Failed Agents past a bounded age whose session ref or managed Panes are gone; live Panes and Running Agents are never selected
|
|
2637
|
+
|
|
2638
|
+
Selectorless authority: `explicit-fan-out` — the route spelling is an intentional global or whole-set opt-in.
|
|
2639
|
+
|
|
2640
|
+
Allowed effects:
|
|
2641
|
+
|
|
2642
|
+
- `identity=removed`
|
|
2643
|
+
- `address=released`
|
|
2644
|
+
- `topology=removed`
|
|
2645
|
+
- `desired-state=removed`
|
|
2646
|
+
- `runtime=unchanged`
|
|
2647
|
+
- `focus=unchanged`
|
|
2648
|
+
- `cardinality=zero-or-more`
|
|
2649
|
+
- `domain-effect=null`
|
|
2650
|
+
|
|
2651
|
+
```
|
|
2652
|
+
projmux prune agent --older-than <duration> [--no-session-ref] [--no-pane] [--exclude <agent-ref>]... [--yes]
|
|
2653
|
+
```
|
|
2631
2654
|
|
|
2632
2655
|
### `projmux prune project`
|
|
2633
2656
|
|
|
@@ -2847,7 +2870,7 @@ Subcommands:
|
|
|
2847
2870
|
| Route | Summary |
|
|
2848
2871
|
| --- | --- |
|
|
2849
2872
|
| [`projmux rename project`](#projmux-rename-project) | Rename a Projmux Project resource; with no selector inside tmux, the active Project |
|
|
2850
|
-
| [`projmux rename window`](#projmux-rename-window) | Rename a Projmux Window resource; inside tmux a reference resolves within the active Project or ControlSession
|
|
2873
|
+
| [`projmux rename window`](#projmux-rename-window) | Rename a Projmux Window resource; inside tmux a reference resolves within the active Project or ControlSession, no selector means the active Window, and the tmux tab is renamed with it |
|
|
2851
2874
|
| [`projmux rename pane`](#projmux-rename-pane) | Rename a Projmux Pane resource; inside tmux a reference resolves within the active Project or ControlSession and no selector means the active Pane; does not change tmux pane_title |
|
|
2852
2875
|
| [`projmux rename agent`](#projmux-rename-agent) | Rename an Agent stable resource name within the active Project or ControlSession without changing its topic, provider, or managed Pane |
|
|
2853
2876
|
|
|
@@ -2880,7 +2903,7 @@ Output modes (`-o`): `receipt`, `none`
|
|
|
2880
2903
|
|
|
2881
2904
|
### `projmux rename window`
|
|
2882
2905
|
|
|
2883
|
-
Rename a Projmux Window resource; inside tmux a reference resolves within the active Project or ControlSession
|
|
2906
|
+
Rename a Projmux Window resource; inside tmux a reference resolves within the active Project or ControlSession, no selector means the active Window, and the tmux tab is renamed with it
|
|
2884
2907
|
|
|
2885
2908
|
Selectorless authority: `natural-omitted` — omission resolves one predictable current resource or documented contextual read/scope; any selector replaces it.
|
|
2886
2909
|
|
package/docs/configuration.md
CHANGED
|
@@ -342,6 +342,7 @@ success = "#5faf87"
|
|
|
342
342
|
action_required = "#ffaf00"
|
|
343
343
|
pane_active_bg = "default"
|
|
344
344
|
focus = "#00ffff"
|
|
345
|
+
provenance = "#ff8700"
|
|
345
346
|
```
|
|
346
347
|
|
|
347
348
|
`text_primary` controls primary content text in native terminal-rendered UI.
|
|
@@ -360,6 +361,13 @@ active-pane background tint, and `focus` is the active-pane border color. Each
|
|
|
360
361
|
of these is a public token: leave it unset to keep the historical built-in
|
|
361
362
|
color, or set it to repaint the matching chrome.
|
|
362
363
|
|
|
364
|
+
`provenance` is the compact usage label color for a provider row whose numbers
|
|
365
|
+
came from a fallback data source rather than its authoritative one (today: a
|
|
366
|
+
Codex row outside a healthy app-server). It is independent of `warning` and
|
|
367
|
+
`critical`, which stay reserved for usage thresholds, and of the ordinary AI
|
|
368
|
+
label color; the fallback value is orange. See `docs/usage-tracking.md` for what
|
|
369
|
+
the label looks like and `docs/theme-palette.md` for the preset contract.
|
|
370
|
+
|
|
363
371
|
Supported presets are `projmux`, `high-contrast`, `blue-hour`, `carbon-violet`,
|
|
364
372
|
`daylight`, `ember`, `forest`, and `rose`. `daylight` is the fully-light
|
|
365
373
|
preset; the others are dark. Preset colors paint projmux chrome only (status
|
|
@@ -517,6 +525,63 @@ desktop intent for both app-server and hook-fallback authority. Existing
|
|
|
517
525
|
runtime override exists, take precedence only while hook fallback is current;
|
|
518
526
|
they are never inferred or copied into the semantic policy store.
|
|
519
527
|
|
|
528
|
+
## Split Start Directory
|
|
529
|
+
|
|
530
|
+
New splits start in the owner Project root. `[ai] split_cwd_from = "pane"`
|
|
531
|
+
starts UI splits in the active Pane's live directory instead, while that
|
|
532
|
+
directory is inside the owner Project root. Settings exposes the same value as
|
|
533
|
+
`AI > New splits start in` (`Project root` / `Current Pane directory`); choosing
|
|
534
|
+
one writes only the global `[ai] split_cwd_from`.
|
|
535
|
+
|
|
536
|
+
Config paths (global and project both honored):
|
|
537
|
+
|
|
538
|
+
```text
|
|
539
|
+
~/.config/projmux/config.toml # global
|
|
540
|
+
<project>/.projmux/config.toml # project
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
Schema:
|
|
544
|
+
|
|
545
|
+
```toml
|
|
546
|
+
[ai]
|
|
547
|
+
split_cwd_from = "project" # project|pane; where a new shell or Agent split starts
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
Resolution depends on who starts the split.
|
|
551
|
+
|
|
552
|
+
**CLI** (`create pane`, `create agent`, and the provider shortcuts) — the flag
|
|
553
|
+
only:
|
|
554
|
+
|
|
555
|
+
1. `--cwd-from project|pane`
|
|
556
|
+
2. otherwise `project`
|
|
557
|
+
|
|
558
|
+
The CLI opens no config file for this decision. A CLI result is determined by
|
|
559
|
+
its arguments, so scripts and automation keep starting in the Project root when
|
|
560
|
+
someone changes this setting.
|
|
561
|
+
|
|
562
|
+
**UI** (keybinding splits, the launcher, the resume picker's new row, and the
|
|
563
|
+
Pane menu) — the config tiers:
|
|
564
|
+
|
|
565
|
+
1. an explicit per-call value (flag)
|
|
566
|
+
2. project `[ai] split_cwd_from`, read from the owner Project root
|
|
567
|
+
3. global/user `[ai] split_cwd_from`
|
|
568
|
+
4. built-in default (`project`)
|
|
569
|
+
|
|
570
|
+
There is no environment override, and an unknown value skips its own tier. The
|
|
571
|
+
project tier is always read from the owner Project root, so where a Pane sits
|
|
572
|
+
never changes which config decides. The Settings row shows the UI result and the
|
|
573
|
+
tier that decided it (`project`, `global`, or `default`).
|
|
574
|
+
|
|
575
|
+
With `pane` selected, the active Pane is the origin of the split: the Pane a
|
|
576
|
+
keybinding ran in, the Pane a right-click menu was opened on, or the anchor Pane
|
|
577
|
+
a CLI create resolved. Its live directory is used only when it is inside the
|
|
578
|
+
owner Project root. `$HOME`, another registered Project tree, a directory that no
|
|
579
|
+
longer exists, and an unreadable directory all start in the Project root and
|
|
580
|
+
report one line naming the reason and that root — on stderr for a CLI create
|
|
581
|
+
with `--cwd-from pane`, and as one client message for a split started from the
|
|
582
|
+
UI. A split is never refused for this reason. `--cwd` on `create agent` still
|
|
583
|
+
names the Agent working directory outright and ignores this setting.
|
|
584
|
+
|
|
520
585
|
## AI Resume Picker
|
|
521
586
|
|
|
522
587
|
The Agent resume picker lists the most recent
|
|
@@ -337,3 +337,31 @@ The selectorless E2E remains the single deterministic L20 scenario. Actual
|
|
|
337
337
|
active-tool/human overlap, multiple ordinary requests, same-UID recovery and
|
|
338
338
|
installed smoke remain separate unverified evidence. They are not run by this
|
|
339
339
|
qualification-plus-one-idle transaction and are not inferred from its result.
|
|
340
|
+
|
|
341
|
+
`TestClaudeDialogueStreamReplaysObservedFrameCorpus` replays the preserved
|
|
342
|
+
Claude Code 2.1.263 frame shapes through the reply-only validator and fails when
|
|
343
|
+
a recorded verdict moves. Neither it nor L20 proves:
|
|
344
|
+
|
|
345
|
+
- compatibility with the installed provider, which only this canary observes;
|
|
346
|
+
- value drift, because the corpus keeps top-level key shape and fills values
|
|
347
|
+
with placeholders;
|
|
348
|
+
- acceptance of unknown frames or fields, which the closed vocabulary rejects
|
|
349
|
+
by design.
|
|
350
|
+
|
|
351
|
+
L20 replays every corpus item whose verdict is `drop` through the production
|
|
352
|
+
reply-only validator. Its Claude fixture reads the corpus at run time, emits each
|
|
353
|
+
dropped side frame with its key set unchanged after init and before its startup
|
|
354
|
+
result, and the scenario requires the emitted names to equal the corpus drop
|
|
355
|
+
set. Those frames are key-shape placeholders, not model output. L20 does not
|
|
356
|
+
emit the recorded real shapes the validator rejects today:
|
|
357
|
+
|
|
358
|
+
- `result-success-25-keys`: the result allowlist lacks `origin`;
|
|
359
|
+
- `system-init-allowlist-diff`: the init allowlist lacks `memory_paths` and
|
|
360
|
+
`terminal_slash_commands`.
|
|
361
|
+
|
|
362
|
+
Shapes without preserved evidence are gaps, not corpus items, so neither the
|
|
363
|
+
corpus nor L20 exercises them: `command_lifecycle`
|
|
364
|
+
keys and values; a non-null assistant `context_management` value; `system`
|
|
365
|
+
`thinking_tokens` frames; hook and user `tool_result` frames; the exact real init
|
|
366
|
+
key set; nested values of every frame; `rate_limit_event` envelope keys beyond
|
|
367
|
+
`type` and `rate_limit_info`; and earlier shape inventories, which were lost.
|