projmux 0.12.1 → 0.12.2
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 +10 -5
- package/docs/architecture.md +53 -0
- package/docs/cli-guide.md +67 -15
- package/docs/cli.md +54 -54
- package/docs/configuration.md +6 -4
- package/docs/resource-attribution.md +11 -4
- package/docs/session-restore.md +12 -5
- package/docs/settings-ia.md +9 -2
- package/package.json +5 -5
package/docs/agent-workflow.md
CHANGED
|
@@ -38,10 +38,13 @@
|
|
|
38
38
|
- `make test`: CLI information architecture v2 Phase 1 resource metadata foundation: `internal/core/metadata` unit and table tests cover the closed `Project`/`Window`/`Pane`/`Agent` kind set under `apiVersion: projmux.io/v1alpha1`, the one-time name-base seed priorities for every kind (Agent topics and raw pane titles are excluded everywhere), name-key validation, the persisted `nameReservations` suffix allocator proving the lowest free suffix is scan-order independent and that an explicit collision fails with `ErrNameConflict` and zero reservations written, offline Project bootstrap topology with a resolvable `spec.primaryPaneRef`, uid immutability across runtime creation, teardown, and rebind, zero heuristic uid merges (same-basename roots stay distinct; only an exact saved root reuses its uid), rebind and root-missing/root-returning `MissingRoot` condition lifecycle with preserved first-observed timestamps and name reservations, reverse-order operation rollback restoring a byte-identical registry, the closed Agent phase set with its exit classification and resumable Offline/Failed transitions, `schemaVersion` classification that fails closed on any newer envelope and on an unversioned document (production registers no migration step, since v1 is the first shipped envelope), a `testdata/registry-v0-source.json` → `testdata/registry-v1-migrated.golden` migration pair driven by a test-injected older step with reservation backfill that never renumbers existing names, full registry structural validation, and Session State round-tripping through additive `omitempty` `metadata` blocks at the unchanged snapshot `version: 1` including deterministic positional reconciliation of pre-metadata snapshots. `internal/integrations/metadata` covers the locked `<state>/projmux/metadata/registry.json` store: a newer `schemaVersion`, malformed JSON, and a content-bearing document with no `schemaVersion` are all refused byte-for-byte with no write, no temp file, no backup, and no quarantine on `Load`/`Update`/`Migrate`, while an absent, empty, or whitespace-only file still yields a fresh empty registry; migration atomicity is proven against a test-registered older step by injected failures after the backup, after the staged temp write, and just before the atomic replace, each leaving the original bytes and no leaked temp; a successful migration keeps a verifiable pre-migration backup and is idempotent; a failing operation writes nothing; a bootstrap registry golden freezes the camelCase file format and 0600 mode; concurrent registrations serialize through the lock with unique allocated names; and an end-to-end test round-trips an offline snapshot through both the registry store and the session-state store, reconciling every Window and Pane back by uid. The tmux mirror tests pin the exact session/window/pane option writes, the new window-scoped options, `automatic-rename off` on managed windows, `rename pane` touching only `@projmux_pane_label` and never `pane_title`, uid ↔ target resolution in both directions, and write-free legacy observation. `internal/app` and `cmd/projmux` prove the metadata usage-error seam: explicit name and rebind-root collisions reach exit code 2 through the existing `UsageError` path with zero mutations, while a newer registry schema stays a runtime error at exit code 1.
|
|
39
39
|
- `make test`: CLI information architecture v2 Phase 2 selector and read-only resolution: `internal/core/selector` unit and table tests cover the pure selector grammar and the read-only resolution engine over a structurally validated registry fixture that carries duplicate `displayName`s, an offline Project, a `MissingRoot` Project, and Window/Pane names repeated across owner scopes. An aggregate negative table proves the excluded forms resolve **0 occurrences** — an implicit comma split of two real names, a duplicate `displayName`, a real `spec.root`/`spec.cwd` path, a tmux `%N`/`@N`/`$N` handle, and a bare uid without the `uid:` prefix — while `displayName` is still reported as ambiguity context and the `uid:` form does resolve. A recorded per-stage trace pins the fixed name/uid-union -> AND label-filter -> uid-dedupe order with a 3/2/1 shape no other ordering can produce; repeated singular `--window`/`--pane` occurrences union in argv order and collapse by uid; the Pane universe is owner-scoped across Projects, Windows, and Agent-managed Panes; Window/Pane status is inherited from the owning Project as live/offline/`missing-root` with `MissingRoot` outranking a stale live session; and the resolver never mutates the registry it is handed. The `<verb, kind>` cardinality matrix pins the contract cells (`get windows` 0..N, `rename window` exact-one, repeated `create --window` 1..N) and a violation returns a usage error whose ambiguity listing is bounded to 5 candidate rows carrying name/`displayName`/owner context plus an omitted count. `internal/cli` proves `cwd` is accepted by exactly one canonical route: `ResolveOutputToken` grants it only on `get pane` and rejects it on every other read kind and on every named mutation route, the shared `-o` catalog still excludes it, and the new `get` node owns only the `pane` kind while the `current` compatibility route is left untouched. `internal/app` covers the route: `get pane --current -o cwd` emits a single trailing-newline path scalar from one tmux `display-message` query; `-o cwd` without `--current` and `--current` with any other projection or with selectors are usage errors with 0 bytes on stdout and 0 tmux calls; ambiguity, no-match, an emptied label filter, and an unresolvable `--project` scope are exact-one violations with 0 bytes on stdout; the output table pins default/uid/name/ref/metadata/json/none for a resolved read; the read loads the registry through a store path that creates no directory and no lock file when no registry exists; and `get` is excluded from the pre-dispatch legacy-hook filesystem migration. `internal/integrations/metadata` pins the zero-side-effect `LoadReadOnly` read, and `cmd/projmux` proves a bounded cardinality failure reaches exit code 2 with the listing on stderr and 0 bytes on stdout.
|
|
40
40
|
- `make test`: Implicit active target selector Phase 3 managed runtime binding convergence: a normal live-reload `config apply` invokes the existing registry matcher/reconciler/mirror only after successful `source-file` and routes every inventory and mirror call through the exact supplied `-L` socket; `--no-reload` and config/keymap preflight failures make zero live calls. Generated app config installs synchronous `after-new-window` and `after-split-window` boundaries that pass the expanded absolute `#{socket_path}` to hidden plumbing and use exact `-S` routing with no default socket or inherited `$TMUX` fallback. Unit/integration tables cover blank bindable Window/Pane repair to the original registry uids, ambiguous and foreign refusal, identity/owner/name-reservation preservation, two-socket isolation, and a repeat pass with zero `set-option`/`rename-window` calls and zero registry byte write. `get pane`, `describe pane`, and active-target resolution open zero write transactions and issue only the required option read. The CLI catalog, public option/environment surface, registry schema, Project scope, and heuristic/name/cwd matching remain unchanged.
|
|
41
|
-
- `make test` / `make test-integration` / `make test-e2e`: public resource reconciliation adds `projmux reconcile resources [--dry-run] [--socket <name> | --socket-path <absolute>] [-o json]` to the CLI manifest/help/reference. One planner runs the production Registry reconciler, mutator, matcher, and tmux Mirror over a cloned Registry and a zero-write tmux overlay; normalized allocation display values keep stable item keys/order without making opaque UIDs a matching key. Tests pin missing/stale/foreign/orphan Registry and tmux items, human/JSON target plus changed/no-op/failed counts, exact `-L`, absolute/inherited `-S`, no-flag outside-tmux pre-mutation usage refusal, two-socket isolation, dry-run byte stability, repeat no-op, and whole-session containment for unknown/duplicate/wrong-owner bindings, including a rootless UID-less session whose name is claimed by multiple Registry Projects. Execute scopes observation to Registry graphs safely attributable to the selected socket, replans under the Registry lock, commits Registry authority before non-transactional mirror writes, guards every planned live write through its current Project/Window/Pane UID binding before the first mutation, and reports completed stages, each current remaining drift item in human and JSON output, and the exact retry. Injected Registry commit failure publishes zero planned UID and changes neither Registry nor tmux; injected post-commit tmux failure leaves one authoritative identity graph that the exact retry converges without duplicates. A second socket and its pre-existing Registry graph remain byte/model identical. `doctor`, `get`, and `describe` remain read-only, the route skips unrelated legacy/config migration, and no config apply, default-socket fallback, state-loss recovery, heuristic merge, rename/rebind, or Agent semantic-status work is introduced.
|
|
41
|
+
- `make test` / `make test-integration` / `make test-e2e`: public resource reconciliation adds `projmux reconcile resources [--dry-run] [--materialize-project <name|uid:uid>] [--socket <name> | --socket-path <absolute>] [-o json]` to the CLI manifest/help/reference. One planner runs the production Registry reconciler, mutator, matcher, and tmux Mirror over a cloned Registry and a zero-write tmux overlay; normalized allocation display values keep stable item keys/order without making opaque UIDs a matching key. Tests pin missing/stale/foreign/orphan Registry and tmux items, human/JSON target plus changed/no-op/failed counts, exact `-L`, absolute/inherited `-S`, no-flag outside-tmux pre-mutation usage refusal, two-socket isolation, dry-run byte stability, repeat no-op, and whole-session containment for unknown/duplicate/wrong-owner bindings, including a rootless UID-less session whose name is claimed by multiple Registry Projects. Execute scopes observation to Registry graphs safely attributable to the selected socket, replans under the Registry lock, commits Registry authority before non-transactional mirror writes, guards every planned live write through its current Project/Window/Pane UID binding before the first mutation, and reports completed stages, each current remaining drift item in human and JSON output, and the exact retry. Injected Registry commit failure publishes zero planned UID and changes neither Registry nor tmux; injected post-commit tmux failure leaves one authoritative identity graph that the exact retry converges without duplicates. A second socket and its pre-existing Registry graph remain byte/model identical. `doctor`, `get`, and `describe` remain read-only, the route skips unrelated legacy/config migration, and no config apply, default-socket fallback, state-loss recovery, heuristic merge, rename/rebind, or Agent semantic-status work is introduced.
|
|
42
|
+
- `make test` / `make test-integration` / `make test-e2e`: explicit Registry desired-topology materialization adds the exact-one `--materialize-project <name|uid:uid>` opt-in to `reconcile resources` without changing the default plan or strict reads. A separate pure Project graph plan and ledger executor cover deterministic zero-write human/JSON preview, offline `-L` full and live `-L`/`-S` partial creation in Registry insertion order, fresh session/Window primary binding, primary reconstruction from an exact-bound shell anchor, additional Window/shell Pane creation, exact uid/name/owner/CWD mirrors, stable retries that preserve selector and socket, second-run no-op with no ensure/lease/write, raw-kill recreation versus canonical-delete exclusion, and two-socket isolation. Negative tables reject duplicate selectors, a present-but-blank selector that must not degrade into the broad default reconcile (zero Registry read, transaction, write, tmux call, and output), invalid root/CWD, zero Windows, non-shell or indirect primary refs, every pre-existing uid-less Pane, unknown/duplicate/wrong-owner claims, name collisions, races, and injected failures before mutation or with ownership-checked reverse rollback and explicit residual drift. Pre-mutation owner-set proofs reject a Window relinked to a foreign session, a Pane join-paned out of its planned Window before planning, and the same move injected at the plan-to-execute boundary. A server-wide uid preflight runs before the selected Project session is created, so an offline Project whose desired Window or Pane uid is already claimed by a foreign session is refused with zero sessions created, zero pre/post-create hook runs, and zero runtime mutation; the inventory is refreshed after the session exists to cover its new tuple and any race since. a `new-window` or `split-window` that tmux mutated before reporting a synchronous hook failure has its exact attributed handle claimed and ledgered so rollback removes it, leaving byte-identical runtime and Registry. Call logs prove stored commands, Offline/Failed Agents, Agent-owned Panes, snapshots, notifications, ephemeral sessions, and historic geometry are never replayed. Initial Pane cwd is separate from the unchanged Project hook/root cwd. The isolated real-tmux smoke uses inherited-environment removal plus a unique `TMUX_TMPDIR` and two exact `-L` sockets, and observes zero-write preview, live partial Window/Pane repair back to the original uids, a zero-write repeat no-op, an empty start command on every recreated Pane, canonical delete that is not replayed, offline full topology rebuild under the original Project/Window/Pane uids, no Agent left Running, a byte-identical second socket, and cleanup of only the sockets whose queried `#{socket_path}` is under the smoke root. Offline arbitrary `-S` session creation is an explicit safety refusal because the public name-only `PROJMUX_SOCKET` cannot encode an exact socket path; live partial `-S` remains supported, and the refusal can be lifted only with a future versioned hook socket-path contract.
|
|
43
|
+
- `make test` / `make test-e2e`: closed Project topology startup parity routes the non-snapshot closed-Project open through the same explicit Registry topology engine, so `Use Project topology` materializes every Registry Window and Window-owned shell Pane before the client moves instead of creating one default Session. The Registry lock, prevalidation order, tmux write pass, and ownership-checked rollback now live in one shared transaction that both `reconcile resources --materialize-project` and startup activation call, with the public route's human/JSON report, retry string, stage list, and no-op wording unchanged. Activation is pinned to the exact session the open targets: a Project whose Registry projects a different session name is refused at `topology prevalidation` with zero sessions created and zero Registry writes. Startup tables cover picker-off default and picker-on `Project topology` producing the identical materialize-then-open order with no `EnsureSession` fallback, `Latest snapshot`/`Named snapshot` staying wholly on the snapshot engine with zero topology activation, a failed activation surfacing the exact stage with no open and no ensure, an existing live Project opening with neither activation nor trust gate, and the retired `empty` mode/value spelling on the internal `switch sidebar-open` transport still resolving to the topology start. A directory with no Registry Project and a Project with no Registry Window both report nothing to materialize through the zero-write snapshot read -- zero transactions, zero writes, zero tmux calls -- so a first open of an unregistered directory keeps its single default session. The production wiring is asserted to bind the `-L projmux` exact socket rather than an inherited client. Startup copy is catalog-backed in en-US and ko-KR for the `Project topology` row, its shared `restore every saved Window and shell Pane` description, the Settings ask/topology choices, and the `Esc: Project topology` footer, and the picker no longer advertises `Empty session`. The isolated real-tmux startup smoke strips inherited `TMUX`/`TMUX_PANE`, uses a unique `TMUX_TMPDIR` with an exact `-L` socket plus a sibling socket, attaches a real client, opens a closed multi-Window/multi-Pane Project through the installed `switch open` route, and observes the full Registry uid topology, the client moved to that session, an empty start command on every recreated Pane, no Agent left Running, a failed activation that leaves the client where it was, a byte-identical sibling socket, and cleanup of only the sockets whose queried `#{socket_path}` is under the smoke root.
|
|
42
44
|
- `make test` / `make test-integration` / `make test-e2e`: rename/rebind transport convergence keeps Registry uid/name/root authority and writes only the corresponding exact live field after the Registry transaction: Project name → `@projmux_project_name` without session rename, Window name → `@projmux_window_name` without `displayName`/`window_name`, Pane name → `@projmux_pane_label` without `pane_title`, and Project root → `@projmux_project_path` without filesystem or uid change. Public `rename agent` adds the exact-one Agent cardinality/aliases and changes only Window-scoped `metadata.name` plus its reservation, preserving topic annotations, provider, lifecycle linkage, and managed Pane metadata with zero tmux writes. Unit tables pin field-specific call logs, offline and inventory-unavailable later convergence, duplicate UID refusal, and post-commit live-write failures that exit nonzero with the public reconcile retry while retaining durable Registry drift. Immediate projection exists only for an inherited absolute `$TMUX` socket, routes every lookup/write through exact `-S`, targets stable `$N`/`@N`/`%N` handles, and performs zero tmux calls outside tmux or for a malformed relative inherited socket. Public reconcile treats a known unique Project UID as authoritative over the stale old path after rebind, plans/guards only the path-anchor write, repeats no-op, and keeps unknown/duplicate claims fail-closed. The isolated real-tmux smoke uses inherited-environment removal plus a validated exact socket path, asserts session/window/pane runtime names and a second socket remain unchanged, exercises offline later reconcile and injected option-write failure/retry, and cleans only the contained sockets.
|
|
43
45
|
- `make test` / `make test-e2e`: canonical resource create lifecycle reentrancy coverage pins the private, session-scoped create lease passed atomically through `new-session -e`, exact-socket/session lifecycle inspection, live-only deferral, stale-lease cleanup, and a second in-transaction reconciliation after explicit mirrors. Standalone `after-new-window`/`after-split-window` hooks remain synchronous. Window/Pane materialization preserves combined tmux output on non-zero exit, accepts only one exact newly observed `@N`/`%N` handle for ownership-checked reverse rollback, emits zero stdout on failure, keeps the registry byte-identical, reports ambiguous or ownership-mismatched residual drift, and never removes an unrelated object. The isolated tmux smoke exercises `--create-window`, exact returned pane IDs, registry/runtime uid agreement, and forced synchronous-hook failure cleanup; the existing Agent-create smoke covers canonical creation in a live managed Window with its stub provider.
|
|
44
|
-
- `make test` / `make test-e2e`:
|
|
46
|
+
- `make test` / `make test-e2e`: create-window foreign-session attribution hardens the same lifecycle boundary with an atomic `Created` plus `$N`/`@N`/`%N` new-session result and exact owner verification. Before the first reconcile import, lease, mirror, or Registry write, create now requires the selected live session to carry the registered Project's exact uid and canonical root with no server-wide duplicate uid/root claimant; the check repeats against the reconciler's fresh inventory and immediately before an inner create, so outer-miss/inner-hit, first-use discovery, blank/foreign same-name, and duplicate-other-session races fail closed. New Windows accept only the exact composite `@N`/`%N` pair that is the sole global before/after addition under the stable `$N`; wrong, pre-existing, wrong-session, missing, or ambiguous handles remain unclaimed with exact residual diagnostics and byte-identical Registry/pre-existing options. Claim injection tests pin uid claim → rollback ledger → full mirror ordering for Session/Window/Pane, ownership-checked rollback, and chained name/uid selector refusal. The isolated real-tmux smoke preserves blank and foreign same-name sessions byte for byte on the exact contained socket, then runs eight concurrent same-name `--create-window` racers and requires one Window, nine unique Pane uid mirrors, exact returned `%N` handles, and unchanged pre-existing bindings.
|
|
47
|
+
- `make test` / `make test-e2e`: Window resource deletion converges the Registry desired-topology cascade and an exact live tmux binding when one exists. Non-implicit targets (explicit references or `--all`) inventory only `-L projmux`: zero exact `@projmux_window_uid` mirrors, including a typed absent-server result, is a valid Registry-only offline cascade, while one exact mirror is killed under the owning Project's Registry-authoritative session. Duplicate, foreign, stale-session, generic inventory-failure, and preflight-to-execution race states remain fail-closed; selector-omitted active deletion still requires its exact live mirror and refuses an implicit foreign-caller socket. The plan and confirmation include the exact `@N` kill plus implicit Project-session end when present, while an offline plan explicitly reports that no tmux Window will be killed; `--dry-run` renders the complete resource/live-or-offline cascade with zero Registry transactions and zero tmux writes. Execution revalidates both resource and live signatures under the Registry lock, preserves the Project, sibling Windows, unrelated sockets, and Registry bytes on pre-mutation failure, and reports exact removed `@N`/session plus retained Registry UIDs if the store commit fails. Repeat deletion of an already-removed offline UID is a no-match with zero writes. A self-target commits and flushes the Registry result before queueing a shell-quoted exact-socket kill. The isolated real-tmux smoke covers live sibling/last-Window/self-target parity plus an offline Window with shell and Agent descendants, byte-identical offline dry-run, exact Registry-only cascade, repeat no-match, and foreign-socket preservation.
|
|
45
48
|
- `make test` / `make test-e2e`: Pane and Agent live-binding deletion extends the same fail-closed boundary to `delete pane|agent`. One exact `-L projmux` Pane inventory joins each Registry Pane uid through its owning Agent/Window/Project graph to the exact `@projmux_pane_uid`, `@projmux_window_uid`, optional session Project uid, and Registry-authoritative session projection; missing, duplicate, foreign-Window/Project, stale-session, and foreign-caller-socket rows cause zero writes. Agent deletion derives its runtime targets only from its Registry-owned managed Panes—never process content—and removes the Agent, managed Pane resources, and exact `%N` objects while preserving sibling Panes, Windows, and owner graph; deleting the current managed Pane alone preserves the Agent as `Offline` with a cleared `paneRef`. Dry-run, confirmation, and result output list every exact Pane plus implicit last-Pane Window and last-Window session cascades. Execution revalidates both resource and live signatures under the Registry lock, kills external targets before commit, and reports already-killed exact Pane/window/session/Pane-uid tuples with retained Registry UIDs on partial tmux or store failure. A caller-containing plan writes the complete deleted-Pane tombstone set under the Registry lock before commit; a partial tombstone or store failure restores every reachable marker while the Registry identities still exist, and any incomplete rollback keeps those Registry owners authoritative. After commit and flush, exact-socket background kills are queued only from revalidated tombstones, so any unqueued survivor remains explicitly tombstoned and retryable. Both anchored import and repair matching refuse that marker, preventing a failed delayed kill from re-importing a deleted Pane as an orphan. The isolated smoke strips inherited `TMUX`/`TMUX_PANE`, validates both socket paths below its dedicated root, covers sibling, last-Pane, managed-Pane-to-Offline, Agent cascade, anti-reimport, and second-socket preservation, and cleans up only the validated exact sockets.
|
|
46
49
|
- `make test-e2e`: Implicit active target selector Phase 3 runs installed-shape apply and lifecycle convergence against real tmux servers under a dedicated `TMUX_TMPDIR`, after stripping inherited `TMUX`/`TMUX_PANE`. It verifies the real `#{socket_path}` stays below the smoke root; deleted managed Window/Pane uid options return to their original registry identities after exact-socket apply; a newly created Window and a split Pane carry bindings before the creating tmux command returns and before an implicit read; repeat apply/lifecycle leaves registry bytes and bindings unchanged; a second socket remains untouched; and cleanup kills only the validated exact sockets.
|
|
47
50
|
- `make test`: Implicit active target selector Phase 2 scopes selector-omitted `get windows|panes|agents` inside tmux to the Project derived from the active Window uid mirror and registry owner chain through the selector engine's single `windowScope` seam. Tables pin inside/outside/missing-binding behavior, explicit `--project` parity, registry-wide `--all-projects`, read-route rejection of bare `--all`, unchanged global `get projects`, and unchanged notification/snapshot/destructive boundaries; the generated CLI reference documents the 0.x feature-minor default narrowing and its same-release escape hatch.
|
|
@@ -54,6 +57,7 @@
|
|
|
54
57
|
- `make test`: CLI information architecture v2 Phase 7 Agent create composition: `create agent` and the `codex`/`claude`/`antigravity` shortcuts gain a resource-backed detached route behind the same `--project` dispatch discriminator `create pane` uses, so the `--project`-less invocation stays the byte-identical `ai split` bridge while the canonical route allocates a Window-owned Agent plus its Agent-owned `<agent-name>-pane` managed Pane, reuses the Phase 6 anchor resolution, `--create-window` ensure, operation ledger and rollback, and enforces a new `{create, Agent} = 1..N` fan-out cell that four tests falsify when it is weakened; a matrix covers provider-required refusals on every canonical spelling, shortcut-to-canonical registry-snapshot equivalence, non-reuse against a Window that already owns a running Agent of the same provider (`codex` → `codex-1` → `codex-2`, first Agent's `status.paneRef` untouched), Window-scoped explicit `--name` (legal across two Windows, exit 2 with zero mutations inside one), payload-after-`--` reaching the provider launch but never the Agent or Pane name, all seven shared `-o` modes end to end with `AgentList`/`AgentMetadataList` envelopes for a single result and `-o pane-id` resolving to the managed Pane rather than the anchor, multi-window fan-out hitting each Window's own anchor exactly once, four failure stages each leaving the registry byte-identical with no `Failed` Agent behind, six racers converging on one ensured Window uid under the real on-disk lock with `-race -count=10`, the Settings enabled-agents gate applying to the canonical route as a plain error without promoting `--force-agent`, and a help-honesty audit that runs every advertised `-o` token and every advertised `--flag` of the Agent node and all three shortcuts; the identity projections of the compatibility bridge become exit 2 naming `--project` as the fix instead of exit 1 claiming the composition is unwired.
|
|
55
58
|
- `make test-e2e`: CLI information architecture v2 Phase 7 Agent create against a real tmux server on the same dedicated exact socket under the smoke root, with inherited `TMUX`/`TMUX_PANE` stripped from every call and only the verified `#{socket_path}` killed: a stub provider binary proves the launch actually ran in the created pane with the project root as its cwd, the managed pane carries both the Projmux Pane uid mirror and the `@projmux_ai_managed`/`@projmux_ai_agent` options, the active window and pane are unchanged and the new pane is not active, the `codex` shortcut allocates `codex-1` instead of reusing the first Agent, a `--` payload reaches the provider argv while the name stays `codex-2`, a missing `--provider` and an explicit name collision are each exit 2 with zero stdout and an unchanged registry md5, and the `--project`-less bridge still refuses its identity projections with a message naming `--project`.
|
|
56
59
|
- `make test` / `make test-e2e`: canonical create even-axis parity shares the legacy AI split geometry parser, row/column peer selector, and deterministic remainder distributor across `create pane`, `create agent`, and every provider shortcut; route tests pin split → Window-local geometry read → axis-only resize ordering for explicit/default anchors, right/down placement, fan-out, ensured Windows, one-pane no-op, malformed/unreadable topology, unrelated rows/columns, and silent post-split observation/resize failures with zero false rollback. The shared geometry format carries the materializer's escaped `\037` row separator rather than a raw tab, and a dedicated test pins both that the format holds no raw tab and that a `_`-sanitized row parses as no geometry: tmux 3.5a rewrites a raw tab in list output to `_` while 3.6 emits it verbatim, so the tab spelling parsed every row as a single field and made equalization a silent no-op on 3.5a — the version the e2e image runs. The isolated real-tmux create smoke repeats horizontal and vertical canonical creates to four panes, measures a maximum one-cell size difference, preserves raw pane IDs, Registry mirrors, focus, and an unrelated Window's exact geometry, and retains exact socket-contained cleanup.
|
|
60
|
+
- `make test` / `make test-e2e`: resource scope short-option parity registers `-p` for Project and `-w` for Window on the shared selector, standalone Pane read, resource-backed create, and canonical focus seams, while `-A` remains exclusive to `get windows|panes|agents`. Deterministic matrices compare long-only, short-only, and mixed argv for selector results, cardinality/error bytes, positional interleave, repeated Window order, stdout/stderr/exit, Registry mutation, and tmux call plans; explicit negatives keep Pane without a shortcut, reject `-A` elsewhere, and leave `agent usage --window` without `-w`. Help-honesty and generated-reference checks require every advertised alias to parse and preserve the root-help and command-tree goldens byte-for-byte. The isolated real-tmux smoke exercises short-form create agent/pane, read, focus, and all-Project escape on its exact guarded socket, with the first `--` preserving all following scope-looking payload bytes.
|
|
57
61
|
- `make test` / `make test-e2e`: Registry–tmux Phase 6 Agent interaction and launch-readiness coverage pins exact active/explicit Agent topic and semantic-status resolution, Registry-first commit plus exact live projection and public reconcile retry, Offline topic resume mirroring, lifecycle-separated closed interaction kinds with restart/stale/Offline current-`unknown` invalidation, and Agent-owned Pane plus shell-manual-attention Window badge priority without durable glyph/color/aggregate state. Provider hooks coalesce session-ref and semantic observations into one Registry transaction when both occur and never synthesize an Agent for a shell Pane. Initial-prompt create distinguishes `Running` resource creation from bounded provider activation, returns an exact Agent/Pane retry-and-cleanup diagnostic when unconfirmed, and proves prompt non-persistence plus zero pane capture. Provider-neutral `--cwd`/repeatable `--add-dir` validation rejects nonexistent, traversal/symlink escape, unauthorized sibling, duplicate, and provider-unsupported paths before runtime mutation; preserves the Window's Project owner; stores effective Agent/Pane workspace; and forwards only caller-explicit additional roots through Codex/Claude argv. The isolated real-tmux slice uses exact primary/foreign sockets to cover immediate topic/status projection, Offline topic-to-resume mirroring, committed projection failure plus public reconcile retry/no-op, raw title/topic non-identity, foreign-socket containment, and explicit cross-Project workspace with unchanged owner Project. Compatibility `ai topic|status` keeps its stdout/stderr/exit surface while forwarding managed Pane changes through Agent authority, and notify queue acknowledgement/TTL/severity plus shell manual attention remain unchanged.
|
|
58
62
|
- `make docs`: regenerates `docs/cli.md` from the `internal/cli` command manifest through `go run ./internal/tools/gendocs`. The render goes to stdout and is captured through a temp file, so a failed generator cannot truncate the checked-in page. Run it whenever a route, summary, usage synopsis, output mode, or field projection changes; `make test` fails until the checked-in page matches.
|
|
59
63
|
- `make test`: CLI information architecture v2 Phase 8 generated CLI reference: `docs/cli.md` is rendered from the command tree in `internal/cli/catalog.go` -- the same manifest the binary renders `projmux help` from -- and the hand-maintained prose it used to hold moved to `docs/cli-guide.md`, which the generated page, `README.md`, and `README-ko.md` all link. The drift gate compares the checked-in page byte for byte against a fresh render and names `make docs` in its failure, so the CI `Unit Tests` job catches a stale page; a determinism test renders twice and rejects an embedded repository or temp path, which is what makes regeneration on an unchanged tree a guaranteed no-op. Coverage is a two-way diff rather than a count: every public route and sub-route in the tree has a section and every section in the document is a real node, with a non-vacuity guard that both a canonical and a shortcut route exist to cover. The internal boundary is held on the published page as well as in the primary listing -- no hidden route gets a section, and no `Canonical spelling:` line may point at an executable path absent from the manifest. The generator reads the command tree and never `canonical.go`; canonical-only summaries are therefore checked as an explicit divergent set rather than leaking into command help. Advertisement-honesty checks keep registry reads aligned with the outputs their handlers implement and keep restore limited to its shipped dry-run preview contract.
|
|
@@ -70,6 +74,7 @@
|
|
|
70
74
|
- `make test`: Columnar default for list reads Phase 0 plus display-first resource projection: the default human plural reads (`get projects|windows|panes|agents`) are space-aligned tables whose first two columns are always `DISPLAY NAME`, `NAME`, followed by the existing per-kind columns in their prior relative order (`STATUS`, owner chain, optional AGENT/SESSION, `AGE`). Four whole-table goldens pin Project aliases, the already-projected tmux Window display/tab beside its distinct stable name, and current Pane/Agent fallback; the fallback uses metadata.name only when `strings.TrimSpace(metadata.displayName)` is empty and preserves a non-empty stored displayName byte-for-byte. Adversarial Pane `status.displayTitle` and Agent topic values, raw-title wording, tmux handles, duplicate display aliases, and selector negatives prove that secondary display data is never promoted and that only metadata.name or explicit `uid:` remains selectable. Each golden also asserts zero box/rule characters, tabs, and trailing whitespace. Widths stay terminal-display-cell based through `projmuxpicker.VisibleLen`; Hangul, long values, empty interior/trailing cells, and the direct rune-count falsification remain covered. The table remains gated on `OutputModeDefault` plus plural `list`: singular `get`, `describe`, and rename/create summaries remain byte-frozen, as do scalar `-o uid|name|ref|none` and whole List-envelope `-o metadata|json` projections. Zero rows still succeed with zero stdout/stderr bytes, and the injected-clock AGE boundary/determinism suite remains unchanged.
|
|
71
75
|
- `make test`: Resource timestamps surfacing Phase 0 timestamps in read surfaces: the registry has always stored `metadata.createdAt` on every resource, `Condition.firstObservedAt`/`lastTransitionAt` on every observed condition, and `Agent.status.lastTransitionAt` on every Agent, and `-o json` has always emitted them -- but no human-facing surface printed a single one of them, so `describe pane` carried zero time rows and the columnar `get` carried no `AGE`. Both now render, and nothing new is collected: no tmux query, no schema field, and no second relative-time implementation. The plural reads gain an `AGE` column, last on all four kinds because that is the one column whose width moves with the clock and last is the only position where growing it cannot walk an owner-chain column sideways; it is rendered through `i18n.FormatDuration`'s compact form, the same single implementation `notify list` already renders its own AGE through. `internal/app` pins the arithmetic as a boundary table asserted from both sides of every unit rollover (`59s`/`1m`, `59m`/`1h`, `23h`/`1d`, up to `900d`), plus the three cases that render an empty cell rather than a number -- a uid that has left the registry, a resource stored before `createdAt` was stamped whose zero Time would otherwise date it to year 1, and a caller that passed no clock -- and a whole-table golden spanning `9s`/`47m`/`6h`/`11d` in one read, which is also the alignment case because the widest cell sets the column. Determinism is stated as a two-sided claim rather than a single assertion, since only the pair is falsifiable: the same injected clock twice must be byte-identical (which a renderer ignoring the clock would also satisfy) **and** a clock advanced three days must produce a different table (which a renderer reading `time.Now` would fail), so only a renderer reading the passed-in clock and nothing else survives both. The clock reaches exactly one projection: `writeResourceProjection` takes it as an explicit parameter and the singular call sites (`get pane`, `describe`, `rename`, and the create fan-out, whose default projection is the `<kind>/<name> created` line and never the table) pass the zero Time, which `resourceAgeCell` renders as no age at all rather than as "created exactly now". `describe` gains absolute UTC instants instead: a `CreatedAt` row beside the identity rows on all four kinds, `PhaseSince` under an Agent's phase, and the second half of a condition's stored pair (`lastTransitionAt` beside the `firstObservedAt` that was already there), each omitted when the registry file predates the field so a pre-`createdAt` registry keeps its exact current block. The machine-consumer contract is frozen the whole way: `-o uid|name|ref|none` byte for byte, and `-o metadata|json` as whole documents rather than by substring -- they are rendered from the same `ObjectMeta` the AGE cell reads, so a new key anywhere in either reddens. The Columnar track's `describe pane` byte-golden moves by exactly one row and keeps its own purpose intact: what it guards is that the columnar table is reachable only with `list` true, and a header line or a padded column in a singular route still reddens it.
|
|
72
76
|
- `make test`: Settings IA re-cut Phase 0 full navigation cutover: the visible Settings tree is declared once in `internal/app/settings_nav.go` and frozen by `internal/app/testdata/settings-nav-tree.golden`, so an IA change is a golden diff rather than a shape spread across the section loops. Structural tests prove the catalog is a tree (unique ids, resolvable parents, a scope root at the top of every path), that every control hangs off exactly one owning `[View]` and that only a View owns children (row-affordance exclusivity), and that each rendered picker value maps onto exactly one navigation node whose owning loop the closed reachability table actually handles (control-owner cardinality); the drift guard runs in both directions, so a section loop cannot grow a row the golden does not show. The removed-path negative guard proves `Labs`, the separate `Theme` root, `Project recipe` and `Effective merge view` are neither rendered, nor catalogued, nor routable through `runSection` — the retired handlers, action metadata, and i18n entries are absent rather than hidden redirects — and the legacy-copy guard rejects the retired vocabulary (`AI Settings`, `Project Picker`, `Project Root`, `Workdirs`, `Enabled agents`, `Default split mode`, `Resume picker`, `Session State`, `Kill Session`, `New window`, `Hook quiet policy`, `Delivery sources`, `Labs`, `Usage HUD`, `Path icon`, `Notify icon`, …) across navigation labels, rendered rows and keymap display labels, in both locales. Display renaming is proven display-only: the keymap action IDs (`new-window`, `Sidebar:KillSession`, `ai-split-right`, …), the `sessionstate:`/`project-hooks:`/`live-resources:`/`statusbar-decoration:`/`workdir:`/`projdir:`/`switch:`/`keymap:`/`theme:` action spellings and their owner contracts are all unchanged behind the renamed rows. Keybinding navigation is category-based: an exhaustiveness test requires every catalog action to carry exactly one explicit category (never an ID-prefix inference), every surface action to sit in the sidebar/picker category with a display label for its surface, one display label per action, and each action to render exactly once across the rendered categories, while the category rows carry their members' action IDs, labels, chords and state so search still crosses the category boundary. The action detail projects the product semantics the target IA asks for — target kind, result kind, placement and anchor — and pins that every interactive right/down split declares the explicit current-Pane anchor and a right/down placement, that `Create <Provider> Agent` is always-new, and that resume names the existing `Offline`/`Failed` Agent it rebinds. Navigation is proven side-effect free (opening the root, every section and every container writes no config and runs no tmux command), every `[State]` row carries the catalogued passive value so Enter can never fall through, and the promoted rows keep their old state at the new route (Resources reads the same `live-resources` file it read from Labs, the project automation policy the same `project-hooks` file, Theme the same global `[theme]` block through `Appearance > Theme`). The pinned Project item view keeps Project identity separable (display name, unique name, uid, bound root, condition, missing-since, runtime) and offers same-uid remediation through the canonical `rebind project` route instead of re-pinning, with the unregistered-path case rendering a disabled rebind row carrying its reason. The Agent Usage HUD ownership guard keeps `agent usage` canonical: no Settings row spells a `Usage` resource or a `get usage` read, and `docs/settings-ia.md` names the owner.
|
|
77
|
+
- `make test` also covers Settings directional hierarchy parity: every catalogued navigation/actionable/passive/Back kind has a Right/Left outcome; Right opens only forward-navigation rows and never executes mutation, passive, or Back rows; child and grandchild Left return exactly one View while root Left stays in place; Esc and the Settings popup-toggle close action remain available at root and every visited depth; en-US/ko-KR frames advertise the arrows; and typed-query, color-grid, scope-chip/chord, and key-recorder input retain their existing native semantics. A native root → child → grandchild → back → root interaction and a config-tree mutation-negative audit pin the shared policy without changing global picker arrows.
|
|
73
78
|
- `make test`: Settings IA re-cut Phase 1 Automation and Notification ownership: the two containers are proven to be different product concepts by their labels alone. Automation names only Projmux-owned user scripts and the policy that gates them (`Projmux session lifecycle`, `After notification queued`, `Project automation policy`) and never a Provider or an integration; Notifications names only delivery and projection and never a lifecycle script or a `[hooks.*]` key. The Provider inventory is pinned to the Claude/Codex/Antigravity enum: the tmux bell producer is filtered out of Provider Integrations by producer identity and rendered flat at its own `tmux event source` View, whose wiring row says in words that the bell is not an Agent Provider. `Agent event behavior` renders the same Provider enum, so a Provider can never be wireable in one destination and missing from the other, and a provider x event matrix walks every event to its four-way `default`/`notify`/`state`/`quiet` choice and asserts each choice is addressed to the provider and event that rendered it. The two Provider destinations are proven disjoint: install/remove/conflict/config-path/`Check integration` rows exist only in the wiring detail and the `ai-hook-set:` choices only in the behavior view, with neither surface rendering the other's action prefix. `Check integration` (and `Check` for the bell) is an observable read-only action rather than a placeholder: it re-reads the shipped doctor diagnostic, reports status/config path/conflict as Settings feedback, shells out to nothing, leaves the config tree byte-identical, and errors on an unknown id. The `[hooks.send-noti]` + `PROJMUX_NOTIFY_HOOK` parity test sets both at once and proves they are a supported combination rather than an either/or: each keeps its own resolved value, the desktop row disclaims the fan-out and the Automation row disclaims the sender, neither row renders the other's value, and the three session lifecycle events stay empty. An automation event x scope matrix walks `pre-create`/`post-create`/`post-attach`/`send-noti` in both scopes, keeps the technical `[hooks.<event>]` spelling in the state row, requires the project scope to name its missing-context reason instead of falling through to a global value, and pins `send-noti` as a sibling of the lifecycle list rather than a fourth member of it. The attention guard keeps live Pane badges out of every Notifications surface while the badge style keeps its Appearance home, and the retired `Hook quiet policy` vocabulary is gone from the shared UI text catalog and from the rendered rows in both locales while staying on the negative-guard list.
|
|
74
79
|
- `make test`: interaction-first Keybindings details keep action state, current single keys/sequences, and add/manage/remove/reset/test actions ahead of passive explanation. `TestSettingsKeybindingActionDetailMatrix` verifies semantic/handler/`internal/cli` manifest parity directly against the internal models while separately proving every rendered selectable row is handled; `TestSettingsKeybindingActionDetailPrioritizesStateBindingsAndActions` freezes the default/custom/unbound row order and mutation reachability; `TestSettingsKeybindingKeyDetailRowsAreAllHandled` keeps replace/remove/test routes and requires an unavailable test row to carry both reason and next step; and `TestSettingsKeybindingRetiredContainerCopyIsGone` renders Action/Key/Sequence surfaces in en-US and ko-KR and rejects visible Target/Result/Placement/Anchor/Handler, canonical storage/delivery, cancellation teaching, and Advanced/Details/Delivery/About-style containers. Delivery outcome, one-reader, unavailable/cancel/no-write, capture/typed normalization, feedback-stage recovery, protected-action, reserved-key, sequence storage/runtime, and distinct create/resume parity tests remain in the maintained suite.
|
|
75
80
|
- `make test-e2e`: Settings IA re-cut Phase 0 native navigation smoke against the real attached tmux client: a deep search from the Settings root walks `Appearance > Status Bar > Git > Icon` — proving search lands on the owning View rather than executing a control, and that reaching the icon chooser writes no decoration file — then returns to the root through the Back rows, and the keybinding recorder flow now reaches its action through the `Launch & popups` category, searching for the action's own name at the root to prove search crosses the category boundary.
|
|
@@ -115,7 +120,7 @@
|
|
|
115
120
|
- `make test` also covers AI desktop notification dedupe precedence (env override > Settings saved value > default), Desktop notifications mode persistence through `desktop-notify-mode`, saved-config precedence over live tmux options, `projmux config apply` regeneration of `@projmux_desktop_notify_mode`, configured dedupe-window collapse/send behavior, Settings > Notifications AI dedupe preset/custom rows, explicit notify focus consume rules for selected critical rows and older same-pane non-critical AI cleanup, preservation of critical/permission/stop-failure/external/git/k8s rows during bulk cleanup, `projmux internal focus --uri` compatibility-input queue consume, and attention clear paths that do not ack the queue.
|
|
116
121
|
- `make test` also covers the two-state desktop notification contract: `NormalizeDesktopNotifyMode` accepting only `off`/`notify` while reading retired `raise`/`auto-raise`/`autoraise` literals as `notify`, per-source legacy-alias resolution that keeps env > saved file > tmux option precedence instead of falling through, a platform-neutral `notify` default including WSL + Windows Terminal, saved/tmux-applied values restricted to `off`/`notify`, Settings > Notifications > Desktop notifications offering exactly `Off` and `Notify` with no `Raise` row/description/search keyword in English and Korean, WSL Toasts carrying no `launch`/`activationType="protocol"` payload and writing no `projmux://` protocol-handler registration, and `projmux focus` never dispatching a host-window focus adapter in any mode.
|
|
117
122
|
- `make test` also covers AI hook runtime action precedence over catalog defaults, runtime quiet for known Codex notify events, runtime notify for known Claude quiet events, generic in-app-only notify rows for known Codex hook events without specialized handlers, suppression of desktop notification and `send-noti` dispatch on that generic path, separation of runtime hook action from catalog install events, Settings > Notifications hook quiet policy display/write behavior without external install/remove execution, hook desktop notification payload parity with the in-app queue text across the shared OS notification payload, normal/transient OS urgency and expiration for critical AI queue rows, and dormant title/capture fallback gating once a pane is hook-active.
|
|
118
|
-
- `make test` also covers Settings > Session State as global settings-only UI with default-off auto-save, Sidebar startup picker relocation/compatibility, and no window/pane tree, Settings > Project > Session State project-derived identity plus project auto-save override/effective source rows and distinct Save latest snapshot / Save named snapshot labels, closed-project save disabled reasons, named snapshot portable path conversion, project/global auto-save precedence, Projects > Sessions > State read-only latest/named snapshot overview with window/pane cwd/recipe/agent-resume health, user-facing canonical snapshot status/save/delete/restore actions including explicit manual save bypass of disabled autosave and agent resume status/confidence preview, and Project open sidebar startup coverage for Session State opt-in `Start project`, default-off
|
|
123
|
+
- `make test` also covers Settings > Session State as global settings-only UI with default-off auto-save, Sidebar startup picker relocation/compatibility, and no window/pane tree, Settings > Project > Session State project-derived identity plus project auto-save override/effective source rows and distinct Save latest snapshot / Save named snapshot labels, closed-project save disabled reasons, named snapshot portable path conversion, project/global auto-save precedence, Projects > Sessions > State read-only latest/named snapshot overview with window/pane cwd/recipe/agent-resume health, user-facing canonical snapshot status/save/delete/restore actions including explicit manual save bypass of disabled autosave and agent resume status/confidence preview, and Project open sidebar startup coverage for Session State opt-in `Start project`, default-off Project topology creation, Latest snapshot, Named snapshot, Project topology, Back, saved-at row metadata, existing-session skip, startup-before-trust ordering, detached sidebar open continuation before client-scoped separate trust popup handoff without sidebar inline trust UI, trust approve continuation, and trust deny/cancel no-session sidebar refresh behavior.
|
|
119
124
|
- `make test` also covers `projmux shell` usage without startup selector flags, project-context default target lookup from `PROJMUX_CWD` or nearest project marker, explicit `--session` separation from project-derived defaults, and direct empty attach behavior without shell startup picker/replay.
|
|
120
125
|
- `make test` also covers pane identity separation and projection: canonical `rename-pane-label` prompts with `pane label:` initialized only from the current label, Enter confirms, empty Enter clears, and native Esc cancels; unchanged Ctrl-Shift-M default and Settings expose only `rename-pane-label`, while stale `[bindings.rename-pane-topic]` keymaps fail with an exact `[bindings.rename-pane-label]` replacement. AI topic set/clear keep existing topic/manual ownership, no raw-title action is exposed, and pane border/window tab/popup/sidebar/recent-window resolve user label → agent AI topic → known shell → raw title.
|
|
121
126
|
- `make test` also covers session snapshot pane identity capture, old/new decode, and replay field-matrix contracts: `Pane.Label`, raw title, recipe topic/manual ownership, startup fields, and agent/resume metadata stay separate; old snapshots leave label and ownership absent without equality inference; tmux creation-returned pane ids are the replay targets; and agent direct-start never copies a saved topic into the raw title.
|
|
@@ -156,8 +161,8 @@
|
|
|
156
161
|
- `make test` also covers stale state cleanup policy: successful prune, runtime stop, runtime sessions picker, and switch/sidebar session kills trigger best-effort preview-row cleanup; notify refresh publishing sweeps dead-PID sockets while preserving live-PID sockets; snapshot prune listing distinguishes dead sessions from old live persistent sessions without deleting either, explicit named deletion removes only selected snapshots, malformed snapshots remain preserved with a warning, and doctor documents the manual-only retention policy.
|
|
157
162
|
- `make test` also covers Recent Windows Phase 2/3/4 keybinding, popup, and runtime recorder integration: `RecentWindows:Open` owns the guaranteed `M-3` launch default, generated tmux config uses client-scoped `tmux popup-toggle recent-windows`, the popup body runs `projmux window recent`, generated tmux config installs background `window record` hooks for window and client-session changes plus first-use population without `session-window-changed`, `window record` snapshots current tmux socket/session/window/active-pane metadata into the socket-scoped store with escaped field parsing, repeated same-window record fires dedupe instead of growing entries, the queue remains bounded by `recentwindows.DefaultLimit`, Settings > Keybindings shows Recent Windows with the `M-3` default, setup probe text names Recent Windows, `SessionPopupToggle` no longer owns the guaranteed `M-3` default, and escaped tmux field separators are parsed for current/list window metadata.
|
|
158
163
|
- `make test` also covers the Linux resource-attribution Phase 0 contract: tmux-only typed socket/session/window/pane PID/TTY/current-path/project-anchor inventory without unsupported placeholder values; explicit project-anchor priority plus read-only current-path fallback through canonical pinned/root-child discovery, longest-root matching, outside/home exclusion, and linked explicit/fallback conflict handling; one-pass procfs stat/meminfo collection; PID+starttime reuse defense and SID ownership; first/invalid/logical-CPU-change unknown CPU; host-share/core-equivalent CPU and RSS/host-ratio memory; unique pane-to-window-to-project conservation; linked-anchor `Shared / ambiguous`, missing-anchor `Unassigned`, setsid escape, fast-exit/race/permission partial states; and explicit host remainder/overage without silent clamping. The opt-in `PROJMUX_RESOURCE_PROJECT_FALLBACK_SMOKE=1 go test -run TestResourceProjectFallbackTransientSmoke -v ./internal/integrations/tmux` test provides an isolated read-only fallback fixture, while `PROJMUX_RESOURCE_TMUX_SOCKET=projmux PROJMUX_RESOURCE_EXPECT_PROJECT_ROOT=/path/to/project go test -run TestResourceAttributionRealTmuxReadOnlySmoke -v ./internal/integrations/tmux` provides sanitized live-socket project-bucket/count evidence; benchmark commands and current measurements are maintained in [resource-attribution.md](resource-attribution.md).
|
|
159
|
-
- `make test` also covers the Resource Inspector Phase 1 vertical slice: immediate non-actionable warming chrome; Project → Window → Pane → read-only detail hierarchy with project/window `PANES n` and pane `PROCESSES n` projections;
|
|
160
|
-
- `make test` also covers the Resource Inspector readable-layout Phase 0 contract: non-duplicating scope breadcrumbs; separate host, attributed, Other, diagnostic, list/detail, and contextual-action bands; primary identity separated from secondary context; vertically comparable CPU/Memory/count clusters; deterministic 80x24 and wide themed frame geometry without border bleed; en-US/ko-KR copy and
|
|
164
|
+
- `make test` also covers the Resource Inspector Phase 1 vertical slice: immediate non-actionable warming chrome; Project → Window → Pane → read-only detail hierarchy with project/window `PANES n` and pane `PROCESSES n` projections; concrete-project and `No project match` drill-down plus the non-actionable Other summary; defensive Shared attribution omitted from project rows while its CPU/RSS/pane aggregate remains in Attributed totals and a bounded non-drillable Sample diagnostic; shared label → active-agent topic → interactive shell → raw-title pane identity precedence with reused `Process <PaneCommand>`/PID-SID/Pane %N/TTY secondary and detail naming; resource-only Right/Enter forward, Left back with root no-op, all-depth Esc close, and complete Alt-Left action/hint removal; statusbar-parity CPU 70/90 and memory 75/90 exact semantic boundaries with severity-word-free values, unavailable `--`, lifecycle text, and resolved default/custom theme roles; Name-default Tab-computed CPU/Memory/Name ordering that remains stable across automatic refresh; stable-id search metadata plus refresh selection/query/breadcrumb/focus preservation and vanished-row nearest-neighbor behavior; fresh/stale/partial/unavailable/empty/gone/overage transitions with atomic refresh-progress/footer updates; an exact fixed five-row divider/Host/Attributed/Coverage/Sample bottom summary dock that remains independent of scroll/search and separate from the action footer, with bounded diagnostics on Sample only, minimum navigable list height, and no divider/border bleed; changed-row synchronized differential frames at 80x24 and wide en-US/ko-KR layouts; truthful RSS-sum rendering; immediate automatic pre-collection not-fresh progress with the last complete sample retained, gated non-overlapping two-second and Ctrl-R sampling, cancellation, and prior-sample disposal; direct CLI and client-scoped popup mode; no-default `Resources:Open` catalog/Settings/config/custom-alias close behavior; statusbar `resources` range/click byte-equivalence, Labs visibility independence, other-client isolation, and existing `projmux internal status resources`/window-click fallback regression.
|
|
165
|
+
- `make test` also covers the Resource Inspector readable-layout Phase 0 contract: non-duplicating scope breadcrumbs; separate host, attributed, Other, diagnostic, list/detail, and contextual-action bands; primary identity separated from secondary context; vertically comparable CPU/Memory/count clusters; deterministic 80x24 and wide themed frame geometry without border bleed; en-US/ko-KR copy and concrete/Unassigned stable-root parity with no Shared root row; read-only pane detail without search, pointer, Enter, or sort affordances; explicit non-actionable Other/empty/vanished surfaces; populated/empty deferred action reconciliation without hidden sort; and resource-scoped directional hierarchy flow while collector, attribution, cadence, and client-scoped popup contracts remain unchanged.
|
|
161
166
|
- Current focused unit coverage also includes strict notify SOT behavior
|
|
162
167
|
(TTL does not remove rows, focus success and target-gone clicks ack,
|
|
163
168
|
reconcile reports inactive `queue-stale` rows), `get notifications --live` queue/live explanations, notify sidebar
|
package/docs/architecture.md
CHANGED
|
@@ -433,6 +433,13 @@ Runtime observation and resource status:
|
|
|
433
433
|
never releases a name reservation** — the same preservation contract
|
|
434
434
|
`MissingRoot` established for a Project whose root disappeared. There is no
|
|
435
435
|
auto-prune.
|
|
436
|
+
- Explicit canonical deletion is the authority that retires that preserved
|
|
437
|
+
desired topology. A non-implicit `delete window` target (an explicit
|
|
438
|
+
reference or `--all`) accepts zero exact Window mirrors on its selected
|
|
439
|
+
socket as a Registry-only cascade through the Window's Agents and Panes. One
|
|
440
|
+
exact mirror is killed before the Registry commit; duplicate, foreign,
|
|
441
|
+
stale-owner, inventory-failure, and plan-to-execution race states remain
|
|
442
|
+
fail-closed. An implicit active Window is never treated as offline.
|
|
436
443
|
- The inventory is a pure **read**. It never writes, re-mirrors, or adopts a uid
|
|
437
444
|
onto a live tmux object; reattaching a lost binding belongs to the reconciler
|
|
438
445
|
(see *Binding reapply and adoption* below). After a tmux server restart the
|
|
@@ -625,6 +632,52 @@ Public resource reconciliation:
|
|
|
625
632
|
unchanged Project UID, and becomes a no-op after convergence. Unknown or
|
|
626
633
|
duplicate Project UID claims remain refused.
|
|
627
634
|
|
|
635
|
+
Explicit Registry topology materialization:
|
|
636
|
+
|
|
637
|
+
- `reconcile resources --materialize-project <name|uid:uid>` selects exactly
|
|
638
|
+
one Registry Project and uses a separate pure plan. The default reconciliation
|
|
639
|
+
shadow never calls the materializer, and the materialization plan never runs
|
|
640
|
+
blank adoption, orphan minting, or Agent phase observation. Registry insertion
|
|
641
|
+
order determines session/Window/Window-owned shell Pane creation order; report
|
|
642
|
+
keys provide a separately stable rendering order.
|
|
643
|
+
- Registry presence is desired topology. Missing runtime sessions, Windows, and
|
|
644
|
+
Window-owned `role=shell` Panes are drift; canonical Registry deletion removes
|
|
645
|
+
that desire. Exact uid/name/owner mirrors are retained. Stored Pane CWD drives
|
|
646
|
+
only that Pane's detached runtime cwd, while Project root remains the session
|
|
647
|
+
path anchor and `PROJMUX_CWD` hook value. `Pane.spec.command`, Agent-owned
|
|
648
|
+
Panes, Agent providers, snapshots, notifications, and ephemeral sessions are
|
|
649
|
+
never execution inputs.
|
|
650
|
+
- Preflight rejects a missing/invalid root or Pane CWD, a zero-Window Project,
|
|
651
|
+
a primary ref that is not a direct Window-owned shell Pane, and foreign,
|
|
652
|
+
duplicate, wrong-owner, or ambiguous live claims before the first create.
|
|
653
|
+
Execute rechecks the same plan under the Registry lock. A server-wide uid
|
|
654
|
+
preflight runs first, *before* the selected Project session is created,
|
|
655
|
+
because creating it runs the public pre/post-create hooks whose side effects no
|
|
656
|
+
rollback can undo; a missing server is read as an empty inventory. The
|
|
657
|
+
inventory is then refreshed once the session exists, so the new tuple is
|
|
658
|
+
covered and any race since the preflight is caught. Together, and before the
|
|
659
|
+
first Window or Pane mutation, they prove that every planned live Window is
|
|
660
|
+
owned by the selected Session, every planned live Pane is owned by its planned
|
|
661
|
+
Window, and every planned Window/Pane uid is live on exactly the expected
|
|
662
|
+
handle or nowhere at all. UID equality alone is insufficient: a
|
|
663
|
+
relinked Window or a join-paned Pane keeps its uid, and a Window relinked out
|
|
664
|
+
of the selected Session is invisible to a selected-Session plan. Each created
|
|
665
|
+
Pane proves its own parent before its uid claim. It records only objects it
|
|
666
|
+
creates -- including one that tmux mutated before reporting a synchronous
|
|
667
|
+
hook failure -- and rolls those objects back in reverse order only while their
|
|
668
|
+
exact uid mirror still proves ownership. External hook effects are outside
|
|
669
|
+
that rollback guarantee. A successful repeat performs no session ensure,
|
|
670
|
+
lease write, tmux create, Registry replace, or mirror write.
|
|
671
|
+
- Exact `--socket/-L` supports offline full materialization with the existing
|
|
672
|
+
pre/post-create hook contract. Exact `--socket-path/-S` supports live partial
|
|
673
|
+
Window/Pane repair. Offline session creation through arbitrary `-S` is a
|
|
674
|
+
stable safety refusal: the public hook contract exposes name-only
|
|
675
|
+
`PROJMUX_SOCKET`, so an absolute path cannot be represented without either
|
|
676
|
+
silently routing hook re-entry to another server or changing that public
|
|
677
|
+
contract. A future versioned hook socket-path contract can lift the refusal.
|
|
678
|
+
Only the selected exact socket is claimed and mutated; sibling sockets are
|
|
679
|
+
tested unchanged, and no global uniqueness across unknown sockets is claimed.
|
|
680
|
+
|
|
628
681
|
Agent runtime linkage:
|
|
629
682
|
|
|
630
683
|
- Once a live tmux pane has settled on a registry Pane, reconcile decides which
|
package/docs/cli-guide.md
CHANGED
|
@@ -71,13 +71,24 @@ The resource routes (`get`, `describe`, `create`, `rename`, `rebind`, `delete`,
|
|
|
71
71
|
The grammar in one paragraph: a value is either `uid:<uid>` or a bare
|
|
72
72
|
`metadata.name`. There is no bare-uid form, values are never split on commas,
|
|
73
73
|
and a `displayName`, a `spec.root` path, or a raw tmux `%N`/`@N`/`$N` handle
|
|
74
|
-
never resolves anything. `--project` occurs at most once and fixes the
|
|
75
|
-
`--window` and `--pane` repeat and union in argv order;
|
|
74
|
+
never resolves anything. `--project`/`-p` occurs at most once and fixes the
|
|
75
|
+
Project scope; `--window`/`-w` and `--pane` repeat and union in argv order;
|
|
76
|
+
`--selector key=value`
|
|
76
77
|
repeats and ANDs. A singular route also accepts the target as a positional
|
|
77
78
|
`<ref>`, which may appear before or after the flags. How many resolved targets
|
|
78
79
|
each `<verb, kind>` pair accepts is a declared matrix, not a per-route rule, and
|
|
79
80
|
a violation is exit `2` with a candidate listing bounded to five rows.
|
|
80
81
|
|
|
82
|
+
`-p` always means Project, never Pane; Pane has no shorthand. The three plural
|
|
83
|
+
reads `get windows|panes|agents` also accept `-A` as the exact alias of
|
|
84
|
+
`--all-projects`. That escape is mutually exclusive with either spelling of the
|
|
85
|
+
Project selector and is not registered on any other route. Long-only,
|
|
86
|
+
short-only, and mixed scope occurrences share the same value sinks, so repeated
|
|
87
|
+
Window order, cardinality, output, and mutation plans do not depend on spelling.
|
|
88
|
+
For resource-backed `create pane|agent|<provider>`, only aliases before the
|
|
89
|
+
first `--` are Projmux scope flags; every token after it, including `-p`, `-w`,
|
|
90
|
+
`--project`, and `--window`, remains opaque payload in its original order.
|
|
91
|
+
|
|
81
92
|
### Empty selector: the active tmux target
|
|
82
93
|
|
|
83
94
|
Inside tmux, an invocation that carries **no selector at all** addresses the
|
|
@@ -100,7 +111,7 @@ The contract:
|
|
|
100
111
|
--name current` succeeds — so a sentinel token would silently shadow a real
|
|
101
112
|
resource.
|
|
102
113
|
- **"No selector at all" means exactly that.** Any positional `<ref>`, any
|
|
103
|
-
`--project
|
|
114
|
+
`--project`/`-p`, `--window`/`-w`, `--pane`, or any `--selector` label keeps the
|
|
104
115
|
pre-existing behavior unchanged. The fallback is never blended into a
|
|
105
116
|
partially specified selector.
|
|
106
117
|
- **Only the singular routes.** The plural reads (`get projects|windows|panes|
|
|
@@ -246,7 +257,7 @@ source, different output, different failure surface — both stay.
|
|
|
246
257
|
## reconcile resources
|
|
247
258
|
|
|
248
259
|
```text
|
|
249
|
-
projmux reconcile resources [--dry-run] [--socket <name> | --socket-path <absolute>] [-o json]
|
|
260
|
+
projmux reconcile resources [--dry-run] [--materialize-project <name|uid:uid>] [--socket <name> | --socket-path <absolute>] [-o json]
|
|
250
261
|
```
|
|
251
262
|
|
|
252
263
|
`reconcile resources` is the explicit repair boundary for drift between the
|
|
@@ -288,6 +299,42 @@ It does not run `config apply`, reload unrelated configuration, reconstruct a
|
|
|
288
299
|
missing Registry, heuristically merge identities, or turn a read verb into a
|
|
289
300
|
write transaction.
|
|
290
301
|
|
|
302
|
+
`--materialize-project <name|uid:uid>` is the explicit activation opt-in for
|
|
303
|
+
one exact Registry Project. Its separate pure plan treats Registry insertion
|
|
304
|
+
order as desired topology and reports a missing persistent session, each
|
|
305
|
+
missing Window, and each missing Window-owned `role=shell` Pane. Execute creates
|
|
306
|
+
only that missing subset on the selected socket, mirrors the existing Registry
|
|
307
|
+
UID/name/owner graph, preserves each Pane's stored CWD, and is a true no-op when
|
|
308
|
+
the graph is already live. The option is exact-one: repeating it is a usage
|
|
309
|
+
error, and the reported retry preserves both the selector and socket route.
|
|
310
|
+
|
|
311
|
+
Opening a closed Project is the other activation authority for that same
|
|
312
|
+
engine. The Alt-1 sidebar/`switch open` path materializes the selected Project's
|
|
313
|
+
declared shell topology on the app's own `-L projmux` socket and moves the
|
|
314
|
+
client only after it converges; a refusal, a failed preflight, or a rolled-back
|
|
315
|
+
partial leaves the client where it was and reports the exact stage. The
|
|
316
|
+
activation is pinned to the session the open targets, so a Project whose
|
|
317
|
+
Registry projects a different session name is refused instead of populating a
|
|
318
|
+
session the open never reaches. Choosing `Latest snapshot` or `Named snapshot`
|
|
319
|
+
instead stays entirely on the Session State snapshot engine. Reading whether a
|
|
320
|
+
Project declares topology is a zero-write snapshot read, so opening a directory
|
|
321
|
+
that was never registered still creates no Registry state.
|
|
322
|
+
|
|
323
|
+
Materialization never starts or resumes an Agent, creates an Agent-owned Pane,
|
|
324
|
+
or executes `Pane.spec.command`; that field remains a one-time name seed. A
|
|
325
|
+
new Window binds only its own tmux-created primary Pane. On an existing Window,
|
|
326
|
+
every pre-existing uid-less Pane is refused rather than adopted; foreign,
|
|
327
|
+
duplicate, wrong-owner, or otherwise ambiguous UID state is refused before the
|
|
328
|
+
first create. Layout uses the existing deterministic right-axis equalizer and does
|
|
329
|
+
not promise historic geometry. Canonical Registry deletion removes desired
|
|
330
|
+
topology, so a deleted Window or Pane is not recreated; raw runtime loss while
|
|
331
|
+
the resource remains is drift and is materialized. A non-implicit offline
|
|
332
|
+
Window target (an explicit reference or `--all`) can be canonically deleted
|
|
333
|
+
Registry-only: its complete Agent/Pane cascade is shown under `--dry-run`, no
|
|
334
|
+
tmux object is killed, and unrelated live objects and sockets are untouched. A
|
|
335
|
+
unique live mirror keeps the exact-kill path, while duplicate, foreign,
|
|
336
|
+
stale-owner, inventory-failure, and revalidation-race states are refused.
|
|
337
|
+
|
|
291
338
|
## Internal plumbing (`projmux internal ...`)
|
|
292
339
|
|
|
293
340
|
`internal` is a hidden namespace for the routes generated tmux config, tmux
|
|
@@ -545,8 +592,8 @@ back into the unredacted Doctor Go types.
|
|
|
545
592
|
|
|
546
593
|
```
|
|
547
594
|
projmux focus project <ref> [--socket <path>] [--client <tty>] [--json]
|
|
548
|
-
projmux focus window <ref>
|
|
549
|
-
projmux focus pane <ref>
|
|
595
|
+
projmux focus window <ref> -p <project-ref> [--socket <path>] [--client <tty>] [--json]
|
|
596
|
+
projmux focus pane <ref> -p <project-ref> -w <window-ref> [--socket <path>] [--json]
|
|
550
597
|
```
|
|
551
598
|
|
|
552
599
|
Moves one attached client to an exact live Project, Window, or Pane. It never
|
|
@@ -702,10 +749,12 @@ core-equivalent CPU. Project and window rows count panes, while pane rows count
|
|
|
702
749
|
the attributed processes. Pane rows and detail share the resolved pane identity
|
|
703
750
|
and label the tmux current command, PID/SID, pane id, and TTY separately. Memory
|
|
704
751
|
is explicitly an RSS sum (shared pages can be counted more than once) plus its
|
|
705
|
-
host ratio. `No project match
|
|
706
|
-
`Other / unattributed`
|
|
707
|
-
|
|
708
|
-
|
|
752
|
+
host ratio. Concrete projects and `No project match` are the only project
|
|
753
|
+
drill-down groups; non-drillable `Other / unattributed` remains explicit.
|
|
754
|
+
Defensive ambiguous attribution stays in its stable internal bucket, is
|
|
755
|
+
included in Attributed totals, and appears only as a bounded CPU/RSS/pane
|
|
756
|
+
diagnostic rather than a project row. Warming, partial, unavailable, unknown,
|
|
757
|
+
and overage states also remain explicit. No process
|
|
709
758
|
command list, mutation, history, graph, daemon, persistence, or Session State
|
|
710
759
|
telemetry is created. Linux/tmux provides attribution; unsupported platforms
|
|
711
760
|
show an unavailable reason rather than zero metrics.
|
|
@@ -1368,11 +1417,14 @@ human configuration work should prefer `config render` and `config apply`.
|
|
|
1368
1417
|
generated config. The generated app config uses absolute `$SHELL` as the
|
|
1369
1418
|
tmux default shell when set, otherwise `/bin/sh`. `shell` starts or attaches
|
|
1370
1419
|
the app session directly after resolving the target app session name and
|
|
1371
|
-
startup directory. Alt-1 sidebar project open defaults to `
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
`Latest snapshot`
|
|
1375
|
-
|
|
1420
|
+
startup directory. Alt-1 sidebar project open defaults to `Project topology`,
|
|
1421
|
+
which materializes the Project's Registry Windows and Window-owned shell Panes
|
|
1422
|
+
before the client moves; the Session State `Sidebar startup picker` opt-in
|
|
1423
|
+
shows `Latest snapshot`, `Named snapshot`, and `Project topology` before
|
|
1424
|
+
starting a closed project session. `Latest snapshot` is auto-saved; named
|
|
1425
|
+
snapshots are fixed until the user saves or replaces them. A directory with no
|
|
1426
|
+
Registry Project, and a Project with no Registry Window, still start as a
|
|
1427
|
+
single default session.
|
|
1376
1428
|
- `quit` — open an action picker with `Quit projmux` and `Cancel`. Selecting
|
|
1377
1429
|
`Quit projmux` terminates only a `tmux -L projmux` runtime whose global
|
|
1378
1430
|
`@projmux_app` option is set by the generated app config. Missing servers,
|
package/docs/cli.md
CHANGED
|
@@ -64,7 +64,7 @@ Manage Agent state, topic, integrations, and account usage
|
|
|
64
64
|
projmux agent status [get [<agent-ref>] | set <unknown|idle|in_progress|approval_required|input_required|response_complete> [<agent-ref>]] [--agent <ref>]
|
|
65
65
|
projmux agent topic get|clear [<agent-ref>] [--agent <ref>]
|
|
66
66
|
projmux agent topic set <text> [<agent-ref>] [--agent <ref>]
|
|
67
|
-
projmux agent resume <ref> [--project <ref>] [--window <ref>]...
|
|
67
|
+
projmux agent resume <ref> [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]...
|
|
68
68
|
projmux agent integrate <provider> [--dry-run]
|
|
69
69
|
projmux agent usage [--model <name>] [--window <name>] [--json] [--force]
|
|
70
70
|
```
|
|
@@ -103,7 +103,7 @@ projmux agent topic set <text> [<agent-ref>] [--agent <ref>]
|
|
|
103
103
|
Rebind an Offline or Failed Agent to a new managed Pane
|
|
104
104
|
|
|
105
105
|
```
|
|
106
|
-
projmux agent resume <ref> [--project <ref>] [--window <ref>]... [--selector key=value]...
|
|
106
|
+
projmux agent resume <ref> [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [--selector key=value]...
|
|
107
107
|
```
|
|
108
108
|
|
|
109
109
|
### `projmux agent integrate`
|
|
@@ -283,10 +283,10 @@ projmux config apply [--bin <path>] [--config <path>] [--socket <name>]
|
|
|
283
283
|
Create Projmux resources
|
|
284
284
|
|
|
285
285
|
```
|
|
286
|
-
projmux create window --project <ref> [--name <name>] [--label key=value]... [-o <mode>] [-- <payload>]
|
|
287
|
-
projmux create pane --project <ref> [--window <ref>]... [--pane <ref>]... [--create-window] [--placement right|down] [-o <mode>] [-- <payload>]
|
|
288
|
-
projmux create agent --provider <provider> --project <ref> [--cwd <path>] [--add-dir <path>]... [--window <ref>]... [--pane <ref>]... [--create-window] [--placement right|down] [-o <mode>] [-- <payload>]
|
|
289
|
-
projmux create codex|claude|antigravity --project <ref> [--cwd <path>] [--add-dir <path>]... [--window <ref>]... [--create-window] [--placement right|down] [-o <mode>] [-- <payload>]
|
|
286
|
+
projmux create window {--project <ref> | -p <ref>} [--name <name>] [--label key=value]... [-o <mode>] [-- <payload>]
|
|
287
|
+
projmux create pane {--project <ref> | -p <ref>} [--window <ref> | -w <ref>]... [--pane <ref>]... [--create-window] [--placement right|down] [-o <mode>] [-- <payload>]
|
|
288
|
+
projmux create agent --provider <provider> {--project <ref> | -p <ref>} [--cwd <path>] [--add-dir <path>]... [--window <ref> | -w <ref>]... [--pane <ref>]... [--create-window] [--placement right|down] [-o <mode>] [-- <payload>]
|
|
289
|
+
projmux create codex|claude|antigravity {--project <ref> | -p <ref>} [--cwd <path>] [--add-dir <path>]... [--window <ref> | -w <ref>]... [--create-window] [--placement right|down] [-o <mode>] [-- <payload>]
|
|
290
290
|
projmux create notification --text <s> --target <SESSION[:WINDOW[.PANE]]> [--socket <s>]
|
|
291
291
|
projmux create snapshot
|
|
292
292
|
```
|
|
@@ -316,7 +316,7 @@ Canonical spelling: `projmux create window`, `projmux create pane`, `projmux cre
|
|
|
316
316
|
Create a Window and its initial Pane below one Project; the runtime is materialized detached
|
|
317
317
|
|
|
318
318
|
```
|
|
319
|
-
projmux create window --project <ref> [--name <name>] [--label key=value]... [-o <mode>] [-- <payload>]
|
|
319
|
+
projmux create window {--project <ref> | -p <ref>} [--name <name>] [--label key=value]... [-o <mode>] [-- <payload>]
|
|
320
320
|
```
|
|
321
321
|
|
|
322
322
|
Output modes (`-o`): `uid`, `name`, `ref`, `metadata`, `json`, `pane-id`, `none`
|
|
@@ -326,7 +326,7 @@ Output modes (`-o`): `uid`, `name`, `ref`, `metadata`, `json`, `pane-id`, `none`
|
|
|
326
326
|
Create a shell Pane; --project splits the resolved Windows detached, without it the current Window
|
|
327
327
|
|
|
328
328
|
```
|
|
329
|
-
projmux create pane --project <ref> [--window <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--name <name>] [--label key=value]... [--placement right|down] [-o <mode>] [-- <payload>]
|
|
329
|
+
projmux create pane {--project <ref> | -p <ref>} [--window <ref> | -w <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--name <name>] [--label key=value]... [--placement right|down] [-o <mode>] [-- <payload>]
|
|
330
330
|
projmux create pane [--placement right|down] [-o <mode>]
|
|
331
331
|
```
|
|
332
332
|
|
|
@@ -337,7 +337,7 @@ Output modes (`-o`): `uid`, `name`, `ref`, `metadata`, `json`, `pane-id`, `none`
|
|
|
337
337
|
Create an Agent and its managed Pane; --provider is required, and --project splits the resolved Windows detached
|
|
338
338
|
|
|
339
339
|
```
|
|
340
|
-
projmux create agent --provider <provider> --project <ref> [--cwd <path>] [--add-dir <path>]... [--window <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--name <name>] [--label key=value]... [--placement right|down] [-o <mode>] [-- <payload>]
|
|
340
|
+
projmux create agent --provider <provider> {--project <ref> | -p <ref>} [--cwd <path>] [--add-dir <path>]... [--window <ref> | -w <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--name <name>] [--label key=value]... [--placement right|down] [-o <mode>] [-- <payload>]
|
|
341
341
|
projmux create agent --provider <provider> [--placement right|down] [-o pane-id|none] [-- <payload>]
|
|
342
342
|
```
|
|
343
343
|
|
|
@@ -364,7 +364,7 @@ projmux create snapshot
|
|
|
364
364
|
Provider shortcut for create agent --provider codex
|
|
365
365
|
|
|
366
366
|
```
|
|
367
|
-
projmux create codex --project <ref> [--cwd <path>] [--add-dir <path>]... [--window <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--name <name>] [--label key=value]... [--placement right|down] [-o <mode>] [-- <payload>]
|
|
367
|
+
projmux create codex {--project <ref> | -p <ref>} [--cwd <path>] [--add-dir <path>]... [--window <ref> | -w <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--name <name>] [--label key=value]... [--placement right|down] [-o <mode>] [-- <payload>]
|
|
368
368
|
projmux create codex [--placement right|down] [-o pane-id|none] [-- <payload>]
|
|
369
369
|
```
|
|
370
370
|
|
|
@@ -375,7 +375,7 @@ Output modes (`-o`): `uid`, `name`, `ref`, `metadata`, `json`, `pane-id`, `none`
|
|
|
375
375
|
Provider shortcut for create agent --provider claude
|
|
376
376
|
|
|
377
377
|
```
|
|
378
|
-
projmux create claude --project <ref> [--cwd <path>] [--add-dir <path>]... [--window <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--name <name>] [--label key=value]... [--placement right|down] [-o <mode>] [-- <payload>]
|
|
378
|
+
projmux create claude {--project <ref> | -p <ref>} [--cwd <path>] [--add-dir <path>]... [--window <ref> | -w <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--name <name>] [--label key=value]... [--placement right|down] [-o <mode>] [-- <payload>]
|
|
379
379
|
projmux create claude [--placement right|down] [-o pane-id|none] [-- <payload>]
|
|
380
380
|
```
|
|
381
381
|
|
|
@@ -386,7 +386,7 @@ Output modes (`-o`): `uid`, `name`, `ref`, `metadata`, `json`, `pane-id`, `none`
|
|
|
386
386
|
Provider shortcut for create agent --provider antigravity
|
|
387
387
|
|
|
388
388
|
```
|
|
389
|
-
projmux create antigravity --project <ref> [--cwd <path>] [--add-dir <path>]... [--window <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--name <name>] [--label key=value]... [--placement right|down] [-o <mode>] [-- <payload>]
|
|
389
|
+
projmux create antigravity {--project <ref> | -p <ref>} [--cwd <path>] [--add-dir <path>]... [--window <ref> | -w <ref>]... [--pane <ref>]... [--selector key=value]... [--create-window] [--name <name>] [--label key=value]... [--placement right|down] [-o <mode>] [-- <payload>]
|
|
390
390
|
projmux create antigravity [--placement right|down] [-o pane-id|none] [-- <payload>]
|
|
391
391
|
```
|
|
392
392
|
|
|
@@ -397,16 +397,16 @@ Output modes (`-o`): `uid`, `name`, `ref`, `metadata`, `json`, `pane-id`, `none`
|
|
|
397
397
|
Delete Projmux resources with an explicit cascade plan
|
|
398
398
|
|
|
399
399
|
```
|
|
400
|
-
projmux delete window [<ref>...] [--project <ref>] [--selector key=value]... [--all] [--dry-run] [--yes]
|
|
401
|
-
projmux delete pane [<ref>...] [--project <ref>] [--window <ref>]... [--all] [--dry-run] [--yes]
|
|
402
|
-
projmux delete agent [<ref>...] [--project <ref>] [--window <ref>]... [--all] [--dry-run] [--yes]
|
|
400
|
+
projmux delete window [<ref>...] [--project <ref> | -p <ref>] [--selector key=value]... [--all] [--dry-run] [--yes]
|
|
401
|
+
projmux delete pane [<ref>...] [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [--all] [--dry-run] [--yes]
|
|
402
|
+
projmux delete agent [<ref>...] [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [--all] [--dry-run] [--yes]
|
|
403
403
|
```
|
|
404
404
|
|
|
405
405
|
Subcommands:
|
|
406
406
|
|
|
407
407
|
| Route | Summary |
|
|
408
408
|
| --- | --- |
|
|
409
|
-
| [`projmux delete window`](#projmux-delete-window) | Delete
|
|
409
|
+
| [`projmux delete window`](#projmux-delete-window) | Delete Registry Windows and every descendant Agent and Pane, killing an exact live tmux mirror when present; no selector inside tmux means the active Window, and --all means every Window in the registry |
|
|
410
410
|
| [`projmux delete pane`](#projmux-delete-pane) | Delete Panes; an Agent-owned current Pane leaves its Agent Offline; no selector inside tmux means the active Pane, and --all means every Pane in the registry |
|
|
411
411
|
| [`projmux delete agent`](#projmux-delete-agent) | Delete Agents and their managed Panes; no selector inside tmux means the active Agent, and --all means every Agent in the registry |
|
|
412
412
|
| [`projmux delete notification`](#projmux-delete-notification) | Delete pending notification rows |
|
|
@@ -416,10 +416,10 @@ Canonical spelling: `projmux delete window`, `projmux delete pane`, `projmux del
|
|
|
416
416
|
|
|
417
417
|
### `projmux delete window`
|
|
418
418
|
|
|
419
|
-
Delete
|
|
419
|
+
Delete Registry Windows and every descendant Agent and Pane, killing an exact live tmux mirror when present; no selector inside tmux means the active Window, and --all means every Window in the registry
|
|
420
420
|
|
|
421
421
|
```
|
|
422
|
-
projmux delete window [<ref>...] [--project <ref>] [--selector key=value]... [--all] [--dry-run] [--yes]
|
|
422
|
+
projmux delete window [<ref>...] [--project <ref> | -p <ref>] [--selector key=value]... [--all] [--dry-run] [--yes]
|
|
423
423
|
```
|
|
424
424
|
|
|
425
425
|
Aliases: `windows`
|
|
@@ -429,7 +429,7 @@ Aliases: `windows`
|
|
|
429
429
|
Delete Panes; an Agent-owned current Pane leaves its Agent Offline; no selector inside tmux means the active Pane, and --all means every Pane in the registry
|
|
430
430
|
|
|
431
431
|
```
|
|
432
|
-
projmux delete pane [<ref>...] [--project <ref>] [--window <ref>]... [--all] [--dry-run] [--yes]
|
|
432
|
+
projmux delete pane [<ref>...] [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [--all] [--dry-run] [--yes]
|
|
433
433
|
```
|
|
434
434
|
|
|
435
435
|
Aliases: `panes`
|
|
@@ -439,7 +439,7 @@ Aliases: `panes`
|
|
|
439
439
|
Delete Agents and their managed Panes; no selector inside tmux means the active Agent, and --all means every Agent in the registry
|
|
440
440
|
|
|
441
441
|
```
|
|
442
|
-
projmux delete agent [<ref>...] [--project <ref>] [--window <ref>]... [--all] [--dry-run] [--yes]
|
|
442
|
+
projmux delete agent [<ref>...] [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [--all] [--dry-run] [--yes]
|
|
443
443
|
```
|
|
444
444
|
|
|
445
445
|
Aliases: `agents`
|
|
@@ -469,10 +469,10 @@ Aliases: `snapshots`
|
|
|
469
469
|
Describe one Projmux resource
|
|
470
470
|
|
|
471
471
|
```
|
|
472
|
-
projmux describe project [<ref>] [-o <mode>]
|
|
473
|
-
projmux describe window [<ref>] [--project <ref>] [-o <mode>]
|
|
474
|
-
projmux describe pane [<ref>] [--project <ref>] [--window <ref>]... [-o <mode>]
|
|
475
|
-
projmux describe agent [<ref>] [--project <ref>] [--window <ref>]... [-o <mode>]
|
|
472
|
+
projmux describe project [<ref>] [--project <ref> | -p <ref>] [-o <mode>]
|
|
473
|
+
projmux describe window [<ref>] [--project <ref> | -p <ref>] [-o <mode>]
|
|
474
|
+
projmux describe pane [<ref>] [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [-o <mode>]
|
|
475
|
+
projmux describe agent [<ref>] [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [-o <mode>]
|
|
476
476
|
```
|
|
477
477
|
|
|
478
478
|
Subcommands:
|
|
@@ -491,7 +491,7 @@ Canonical spelling: `projmux describe project`, `projmux describe window`, `proj
|
|
|
491
491
|
Describe one Project resource; with no selector inside tmux, the active Project
|
|
492
492
|
|
|
493
493
|
```
|
|
494
|
-
projmux describe project
|
|
494
|
+
projmux describe project [<ref>] [--project <ref> | -p <ref>] [-o <mode>]
|
|
495
495
|
```
|
|
496
496
|
|
|
497
497
|
Aliases: `projects`
|
|
@@ -503,7 +503,7 @@ Output modes (`-o`): `uid`, `name`, `ref`, `metadata`, `json`, `none`
|
|
|
503
503
|
Describe one Window resource; with no selector inside tmux, the active Window
|
|
504
504
|
|
|
505
505
|
```
|
|
506
|
-
projmux describe window
|
|
506
|
+
projmux describe window [<ref>] [--project <ref> | -p <ref>] [-o <mode>]
|
|
507
507
|
```
|
|
508
508
|
|
|
509
509
|
Aliases: `windows`
|
|
@@ -515,7 +515,7 @@ Output modes (`-o`): `uid`, `name`, `ref`, `metadata`, `json`, `none`
|
|
|
515
515
|
Describe one Pane resource; with no selector inside tmux, the active Pane
|
|
516
516
|
|
|
517
517
|
```
|
|
518
|
-
projmux describe pane
|
|
518
|
+
projmux describe pane [<ref>] [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [-o <mode>]
|
|
519
519
|
```
|
|
520
520
|
|
|
521
521
|
Aliases: `panes`
|
|
@@ -527,7 +527,7 @@ Output modes (`-o`): `uid`, `name`, `ref`, `metadata`, `json`, `none`
|
|
|
527
527
|
Describe one Agent resource; with no selector inside tmux, the Agent owning the active Pane
|
|
528
528
|
|
|
529
529
|
```
|
|
530
|
-
projmux describe agent
|
|
530
|
+
projmux describe agent [<ref>] [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [-o <mode>]
|
|
531
531
|
```
|
|
532
532
|
|
|
533
533
|
Aliases: `agents`
|
|
@@ -592,8 +592,8 @@ Move the current client to a live resource
|
|
|
592
592
|
|
|
593
593
|
```
|
|
594
594
|
projmux focus project <ref>
|
|
595
|
-
projmux focus window <ref> --project <ref>
|
|
596
|
-
projmux focus pane <ref> --project <ref> --window <ref>
|
|
595
|
+
projmux focus window <ref> {--project <ref> | -p <ref>}
|
|
596
|
+
projmux focus pane <ref> {--project <ref> | -p <ref>} {--window <ref> | -w <ref>}
|
|
597
597
|
```
|
|
598
598
|
|
|
599
599
|
Subcommands:
|
|
@@ -619,7 +619,7 @@ projmux focus project <ref> [--socket <path>] [--client <tty>] [--json]
|
|
|
619
619
|
Move the current client to an already-live Window; never materializes
|
|
620
620
|
|
|
621
621
|
```
|
|
622
|
-
projmux focus window <ref> --project <ref> [--socket <path>] [--client <tty>] [--json]
|
|
622
|
+
projmux focus window <ref> {--project <ref> | -p <ref>} [--socket <path>] [--client <tty>] [--json]
|
|
623
623
|
```
|
|
624
624
|
|
|
625
625
|
### `projmux focus pane`
|
|
@@ -627,7 +627,7 @@ projmux focus window <ref> --project <ref> [--socket <path>] [--client <tty>] [-
|
|
|
627
627
|
Move the current client to an already-live Pane; never materializes
|
|
628
628
|
|
|
629
629
|
```
|
|
630
|
-
projmux focus pane <ref> --project <ref> --window <ref> [--socket <path>] [--json]
|
|
630
|
+
projmux focus pane <ref> {--project <ref> | -p <ref>} {--window <ref> | -w <ref>} [--socket <path>] [--json]
|
|
631
631
|
```
|
|
632
632
|
|
|
633
633
|
## `projmux get`
|
|
@@ -635,12 +635,12 @@ projmux focus pane <ref> --project <ref> --window <ref> [--socket <path>] [--jso
|
|
|
635
635
|
Read Projmux resources by selector
|
|
636
636
|
|
|
637
637
|
```
|
|
638
|
-
projmux get projects [--project <ref>] [--selector key=value]... [-o <mode>]
|
|
639
|
-
projmux get windows [--project <ref>] [--window <ref>]... [--selector key=value]... [--all-projects] [-o <mode>]
|
|
640
|
-
projmux get panes [--project <ref>] [--window <ref>]... [--pane <ref>]... [--selector key=value]... [--all-projects] [-o <mode>]
|
|
641
|
-
projmux get agents [--project <ref>] [--window <ref>]... [--selector key=value]... [--all-projects] [-o <mode>]
|
|
638
|
+
projmux get projects [--project <ref> | -p <ref>] [--selector key=value]... [-o <mode>]
|
|
639
|
+
projmux get windows [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [--selector key=value]... [--all-projects | -A] [-o <mode>]
|
|
640
|
+
projmux get panes [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [--pane <ref>]... [--selector key=value]... [--all-projects | -A] [-o <mode>]
|
|
641
|
+
projmux get agents [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [--selector key=value]... [--all-projects | -A] [-o <mode>]
|
|
642
642
|
projmux get pane --current -o cwd
|
|
643
|
-
projmux get pane [--project <ref>] [--window <ref>]... [--pane <ref>]... [--selector key=value]... [-o <mode>]
|
|
643
|
+
projmux get pane [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [--pane <ref>]... [--selector key=value]... [-o <mode>]
|
|
644
644
|
```
|
|
645
645
|
|
|
646
646
|
Subcommands:
|
|
@@ -662,7 +662,7 @@ Canonical spelling: `projmux get projects`, `projmux get windows`, `projmux get
|
|
|
662
662
|
List Project resources
|
|
663
663
|
|
|
664
664
|
```
|
|
665
|
-
projmux get projects
|
|
665
|
+
projmux get projects [--project <ref> | -p <ref>] [--selector key=value]... [-o <mode>]
|
|
666
666
|
```
|
|
667
667
|
|
|
668
668
|
Aliases: `project`
|
|
@@ -674,7 +674,7 @@ Output modes (`-o`): `uid`, `name`, `ref`, `metadata`, `json`, `none`
|
|
|
674
674
|
List Window resources; inside tmux defaults to the active Project, and --all-projects lists every Project
|
|
675
675
|
|
|
676
676
|
```
|
|
677
|
-
projmux get windows [--project <ref>] [--window <ref>]... [--selector key=value]... [--all-projects] [-o <mode>]
|
|
677
|
+
projmux get windows [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [--selector key=value]... [--all-projects | -A] [-o <mode>]
|
|
678
678
|
```
|
|
679
679
|
|
|
680
680
|
Aliases: `window`
|
|
@@ -686,7 +686,7 @@ Output modes (`-o`): `uid`, `name`, `ref`, `metadata`, `json`, `none`
|
|
|
686
686
|
List Pane resources; inside tmux defaults to the active Project, and --all-projects lists every Project
|
|
687
687
|
|
|
688
688
|
```
|
|
689
|
-
projmux get panes [--project <ref>] [--window <ref>]... [--pane <ref>]... [--selector key=value]... [--all-projects] [-o <mode>]
|
|
689
|
+
projmux get panes [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [--pane <ref>]... [--selector key=value]... [--all-projects | -A] [-o <mode>]
|
|
690
690
|
```
|
|
691
691
|
|
|
692
692
|
Output modes (`-o`): `uid`, `name`, `ref`, `metadata`, `json`, `none`
|
|
@@ -696,7 +696,7 @@ Output modes (`-o`): `uid`, `name`, `ref`, `metadata`, `json`, `none`
|
|
|
696
696
|
List Agent resources; inside tmux defaults to the active Project, and --all-projects lists every Project
|
|
697
697
|
|
|
698
698
|
```
|
|
699
|
-
projmux get agents [--project <ref>] [--window <ref>]... [--selector key=value]... [--all-projects] [-o <mode>]
|
|
699
|
+
projmux get agents [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [--selector key=value]... [--all-projects | -A] [-o <mode>]
|
|
700
700
|
```
|
|
701
701
|
|
|
702
702
|
Aliases: `agent`
|
|
@@ -728,7 +728,7 @@ Aliases: `snapshot`
|
|
|
728
728
|
Read one Pane resource; with no selector inside tmux, the active Pane
|
|
729
729
|
|
|
730
730
|
```
|
|
731
|
-
projmux get pane [--current] [--project <ref>] [--window <ref>]... [--pane <ref>]... [--selector key=value]... [-o <mode>]
|
|
731
|
+
projmux get pane [--current] [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]... [--pane <ref>]... [--selector key=value]... [-o <mode>]
|
|
732
732
|
```
|
|
733
733
|
|
|
734
734
|
Output modes (`-o`): `uid`, `name`, `ref`, `metadata`, `json`, `none`
|
|
@@ -903,7 +903,7 @@ projmux quit [--yes|--force]
|
|
|
903
903
|
Preview or repair Registry and exact tmux resource drift
|
|
904
904
|
|
|
905
905
|
```
|
|
906
|
-
projmux reconcile resources [--dry-run] [--socket <name> | --socket-path <absolute>] [-o json]
|
|
906
|
+
projmux reconcile resources [--dry-run] [--materialize-project <name|uid:uid>] [--socket <name> | --socket-path <absolute>] [-o json]
|
|
907
907
|
```
|
|
908
908
|
|
|
909
909
|
Subcommands:
|
|
@@ -919,7 +919,7 @@ Canonical spelling: `projmux reconcile resources`
|
|
|
919
919
|
Preview or repair safe Registry and tmux UID, owner, and runtime drift on one exact socket
|
|
920
920
|
|
|
921
921
|
```
|
|
922
|
-
projmux reconcile resources [--dry-run] [--socket <name> | --socket-path <absolute>] [-o json]
|
|
922
|
+
projmux reconcile resources [--dry-run] [--materialize-project <name|uid:uid>] [--socket <name> | --socket-path <absolute>] [-o json]
|
|
923
923
|
```
|
|
924
924
|
|
|
925
925
|
## `projmux rebind`
|
|
@@ -927,7 +927,7 @@ projmux reconcile resources [--dry-run] [--socket <name> | --socket-path <absolu
|
|
|
927
927
|
Rebind a Project to a new absolute root without moving files
|
|
928
928
|
|
|
929
929
|
```
|
|
930
|
-
projmux rebind project [<ref>] --root <absolute-path>
|
|
930
|
+
projmux rebind project [<ref>] [--project <ref> | -p <ref>] --root <absolute-path>
|
|
931
931
|
```
|
|
932
932
|
|
|
933
933
|
Subcommands:
|
|
@@ -943,7 +943,7 @@ Canonical spelling: `projmux rebind project`
|
|
|
943
943
|
Rewrite one Project spec.root; no filesystem move, no heuristic uid merge
|
|
944
944
|
|
|
945
945
|
```
|
|
946
|
-
projmux rebind project [<ref>] --root <absolute-path>
|
|
946
|
+
projmux rebind project [<ref>] [--project <ref> | -p <ref>] --root <absolute-path>
|
|
947
947
|
```
|
|
948
948
|
|
|
949
949
|
## `projmux rename`
|
|
@@ -951,10 +951,10 @@ projmux rebind project [<ref>] --root <absolute-path>
|
|
|
951
951
|
Rename a Projmux resource metadata.name
|
|
952
952
|
|
|
953
953
|
```
|
|
954
|
-
projmux rename project [<ref>] --name <name>
|
|
955
|
-
projmux rename window [<ref>] --name <name> [--project <ref>]
|
|
956
|
-
projmux rename pane [<ref>] --name <name> [--project <ref>] [--window <ref>]...
|
|
957
|
-
projmux rename agent [<ref>] --name <name> [--project <ref>] [--window <ref>]...
|
|
954
|
+
projmux rename project [<ref>] [--project <ref> | -p <ref>] --name <name>
|
|
955
|
+
projmux rename window [<ref>] --name <name> [--project <ref> | -p <ref>]
|
|
956
|
+
projmux rename pane [<ref>] --name <name> [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]...
|
|
957
|
+
projmux rename agent [<ref>] --name <name> [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]...
|
|
958
958
|
```
|
|
959
959
|
|
|
960
960
|
Subcommands:
|
|
@@ -973,7 +973,7 @@ Canonical spelling: `projmux rename project`, `projmux rename window`, `projmux
|
|
|
973
973
|
Rename a Projmux Project resource; with no selector inside tmux, the active Project
|
|
974
974
|
|
|
975
975
|
```
|
|
976
|
-
projmux rename project
|
|
976
|
+
projmux rename project [<ref>] [--project <ref> | -p <ref>] --name <name>
|
|
977
977
|
```
|
|
978
978
|
|
|
979
979
|
Aliases: `projects`
|
|
@@ -983,7 +983,7 @@ Aliases: `projects`
|
|
|
983
983
|
Rename a Projmux Window resource; with no selector inside tmux, the active Window
|
|
984
984
|
|
|
985
985
|
```
|
|
986
|
-
projmux rename window
|
|
986
|
+
projmux rename window [<ref>] --name <name> [--project <ref> | -p <ref>]
|
|
987
987
|
```
|
|
988
988
|
|
|
989
989
|
Aliases: `windows`
|
|
@@ -993,7 +993,7 @@ Aliases: `windows`
|
|
|
993
993
|
Rename a Projmux Pane resource; with no selector inside tmux, the active Pane; does not change tmux pane_title
|
|
994
994
|
|
|
995
995
|
```
|
|
996
|
-
projmux rename pane
|
|
996
|
+
projmux rename pane [<ref>] --name <name> [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]...
|
|
997
997
|
```
|
|
998
998
|
|
|
999
999
|
Aliases: `panes`
|
|
@@ -1003,7 +1003,7 @@ Aliases: `panes`
|
|
|
1003
1003
|
Rename an Agent stable resource name without changing its topic, provider, or managed Pane
|
|
1004
1004
|
|
|
1005
1005
|
```
|
|
1006
|
-
projmux rename agent
|
|
1006
|
+
projmux rename agent [<ref>] --name <name> [--project <ref> | -p <ref>] [--window <ref> | -w <ref>]...
|
|
1007
1007
|
```
|
|
1008
1008
|
|
|
1009
1009
|
Aliases: `agents`
|
package/docs/configuration.md
CHANGED
|
@@ -699,10 +699,12 @@ override with `inherit`, `on`, and `off`; `inherit` follows the global value,
|
|
|
699
699
|
while `on` and `off` take precedence. Auto-save only updates the latest
|
|
700
700
|
snapshot. Named snapshots are manual and are never updated by auto-save.
|
|
701
701
|
|
|
702
|
-
Project open from the Alt-1 sidebar defaults to opening a closed project as
|
|
703
|
-
`
|
|
704
|
-
|
|
705
|
-
|
|
702
|
+
Project open from the Alt-1 sidebar defaults to opening a closed project as its
|
|
703
|
+
`Project topology`, which materializes every Registry Window and Window-owned
|
|
704
|
+
shell Pane of that project before the client moves. The optional `Settings >
|
|
705
|
+
Session State > Sidebar startup picker` toggle enables the native sidebar `Start
|
|
706
|
+
project` step. Rows appear as `Latest snapshot`, named snapshot rows, `Project
|
|
707
|
+
topology`, and `Back`. `Latest snapshot`
|
|
706
708
|
is the snapshot auto-save that changes as auto-save runs; named snapshots are
|
|
707
709
|
fixed snapshots. Rows include saved-at date/time metadata when projmux can
|
|
708
710
|
determine it. `Back` returns to the project list without creating, replaying, or
|
|
@@ -161,6 +161,13 @@ at every depth. Unsupported platforms show an unavailable reason, not zero
|
|
|
161
161
|
metrics. PSS, non-Linux collectors, process-list drill-down, history, and
|
|
162
162
|
resource mutation remain outside this contract.
|
|
163
163
|
|
|
164
|
+
The project root exposes only concrete project paths and `No project match` as
|
|
165
|
+
drill-down groups. `ProjectShared` remains a defensive core attribution bucket,
|
|
166
|
+
but it is never projected as a project row, even when a snapshot contains
|
|
167
|
+
ambiguous panes or windows. Those CPU, RSS, and pane aggregates remain included
|
|
168
|
+
in Attributed totals and appear only as a bounded, non-drillable Sample
|
|
169
|
+
diagnostic. They are neither dropped nor reassigned to a concrete project.
|
|
170
|
+
|
|
164
171
|
Host and attributed CPU/memory use the same semantic classifier as the live
|
|
165
172
|
statusbar: CPU is normal below 70%, warning at 70–89.9%, and critical at 90%
|
|
166
173
|
or above; memory is normal below 75%, warning at 75–89.9%, and critical at 90%
|
|
@@ -197,9 +204,9 @@ boundary, so diagnostic values and key hints never share a role. The 80x24
|
|
|
197
204
|
layout retains a navigable list viewport without clipping, border bleed, or a
|
|
198
205
|
second dock divider.
|
|
199
206
|
|
|
200
|
-
Project rows label project paths explicitly
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
207
|
+
Project rows label project paths explicitly, and the unassigned attribution
|
|
208
|
+
bucket keeps its stable core key while displaying `No project match` with a
|
|
209
|
+
bounded explanation. Pane primary identity follows the shared label →
|
|
210
|
+
agent-only AI topic → interactive shell → raw title resolver; pane id,
|
|
204
211
|
process id, and TTY remain labeled secondary details and stable keys are
|
|
205
212
|
unchanged.
|
package/docs/session-restore.md
CHANGED
|
@@ -97,16 +97,23 @@ existing or non-empty live sessions.
|
|
|
97
97
|
Named snapshots may currently be backed by legacy project files in
|
|
98
98
|
`<project>/.projmux/layouts/*.toml`. They reuse the same window, pane, cwd, and
|
|
99
99
|
startup recipe concepts as session snapshots, but the user-facing restore model
|
|
100
|
-
is still `Latest snapshot`, `Named snapshot`, or `
|
|
100
|
+
is still `Latest snapshot`, `Named snapshot`, or `Project topology`. The legacy
|
|
101
101
|
files are imported read-only by Project open
|
|
102
102
|
when building `Named snapshot` candidates; new primary surfaces should describe
|
|
103
103
|
the restore unit as a snapshot, not as a separate layout or preset feature.
|
|
104
104
|
|
|
105
|
-
Project open from the Alt-1 sidebar defaults to opening a closed project as
|
|
106
|
-
`
|
|
105
|
+
Project open from the Alt-1 sidebar defaults to opening a closed project as its
|
|
106
|
+
`Project topology`: the same explicit Registry materialization engine the public
|
|
107
|
+
`reconcile resources --materialize-project` route uses rebuilds every Registry
|
|
108
|
+
Window and Window-owned shell Pane under their existing uids, and the client
|
|
109
|
+
moves only after that converges. A refusal or failure reports the exact stage and
|
|
110
|
+
leaves the client where it was. A directory with no Registry Project, and a
|
|
111
|
+
Project with no Registry Window, still start as a single default session.
|
|
112
|
+
`Settings > Session State > Sidebar startup picker` is an opt-in toggle;
|
|
107
113
|
when it is on, closed project open advances inside the sidebar to the native
|
|
108
114
|
`Start project` step. Rows are ordered `Latest snapshot`, named snapshot rows,
|
|
109
|
-
`
|
|
115
|
+
`Project topology`, then `Back`; a snapshot row stays entirely on the snapshot
|
|
116
|
+
engine, so the two sources are never mixed in one open. `Latest snapshot` is the auto-saved snapshot that
|
|
110
117
|
keeps changing as auto-save runs. `Named snapshot` is a fixed, user-named
|
|
111
118
|
snapshot and is not updated by auto-save. Rows include saved-at date/time
|
|
112
119
|
metadata when available. `Back` returns to the project list without creating,
|
|
@@ -136,7 +143,7 @@ Default `projmux shell` no longer opens a compatibility startup picker and no
|
|
|
136
143
|
longer accepts startup selector flags for snapshot restore. It always
|
|
137
144
|
follows the normal empty attach path after resolving the target app session name
|
|
138
145
|
and startup directory. Use `Settings > Session State > Sidebar startup picker` for
|
|
139
|
-
interactive Latest snapshot / Named snapshot /
|
|
146
|
+
interactive Latest snapshot / Named snapshot / Project topology selection.
|
|
140
147
|
|
|
141
148
|
## Operational diagnostics
|
|
142
149
|
|
package/docs/settings-ia.md
CHANGED
|
@@ -46,8 +46,15 @@ step, never a silent no-op.
|
|
|
46
46
|
calls the canonical `rebind project` route and keeps the same uid. Settings
|
|
47
47
|
performs no heuristic uid merge and no automatic prune.
|
|
48
48
|
- `Project Sidebar [View]` — `Closed Project startup` chooses between using
|
|
49
|
-
the stored Project topology and asking for a Snapshot.
|
|
50
|
-
|
|
49
|
+
the stored Project topology and asking for a Snapshot. `Use Project
|
|
50
|
+
topology` materializes every Registry Window and Window-owned shell Pane of
|
|
51
|
+
that Project under their existing uids and only then moves the client; it is
|
|
52
|
+
not an empty session, and the startup picker names that row `Project
|
|
53
|
+
topology` for the same reason. `Ask for Snapshot or Project topology` adds
|
|
54
|
+
the `Latest snapshot` and `Named snapshot` rows, which stay on the Session
|
|
55
|
+
State snapshot engine — the two sources are never mixed in one open. Neither
|
|
56
|
+
choice resumes an Agent or executes a stored `Pane.spec.command`. The saved
|
|
57
|
+
file keeps its `sidebar-startup-picker` spelling.
|
|
51
58
|
- **AI** — `AI` is a product category, never an addressable resource.
|
|
52
59
|
- `Default launch target [Choice]` — an Agent Provider, a Shell Pane, or
|
|
53
60
|
choose-at-launch. It is a keybinding/picker preference and does not weaken
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "projmux",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.2",
|
|
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.12.
|
|
32
|
-
"@projmux/linux-arm64": "0.12.
|
|
33
|
-
"@projmux/darwin-x64": "0.12.
|
|
34
|
-
"@projmux/darwin-arm64": "0.12.
|
|
31
|
+
"@projmux/linux-x64": "0.12.2",
|
|
32
|
+
"@projmux/linux-arm64": "0.12.2",
|
|
33
|
+
"@projmux/darwin-x64": "0.12.2",
|
|
34
|
+
"@projmux/darwin-arm64": "0.12.2"
|
|
35
35
|
}
|
|
36
36
|
}
|