projmux 0.9.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README-ko.md +89 -72
- package/README.md +21 -14
- package/docs/agent-workflow.md +26 -14
- package/docs/architecture.md +2 -2
- package/docs/cli.md +197 -69
- package/docs/configuration.md +4 -3
- package/docs/globalization.md +11 -9
- package/docs/hooks.md +28 -15
- package/docs/keybindings.md +5 -2
- package/docs/legacy-diagnostics-inventory.md +23 -0
- package/docs/native-picker.md +103 -0
- package/docs/operational-diagnostics.md +215 -8
- package/docs/pr-guideline.md +1 -1
- package/docs/resource-attribution.md +77 -4
- package/docs/session-restore.md +18 -0
- package/docs/settings-ia.md +10 -9
- package/docs/statusbar.md +28 -18
- package/docs/tmux-surface-inventory.md +0 -1
- package/docs/upgrading.md +29 -7
- package/docs/usage-tracking.md +63 -19
- package/package.json +5 -5
- package/docs/native-picker-no-fzf-poc.md +0 -227
- package/docs/native-picker-parity.md +0 -155
- package/docs/picker-ui-plan.md +0 -91
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Legacy diagnostics inventory
|
|
2
|
+
|
|
3
|
+
This is the Phase 6 file/surface inventory. `Keep`, `Deprecate candidate`, and
|
|
4
|
+
`Remove candidate` are review classifications, not runtime changes. Nothing in
|
|
5
|
+
this phase removes, renames, ignores, or changes an environment variable, log,
|
|
6
|
+
CLI, config action, output format, permission, or retention contract.
|
|
7
|
+
|
|
8
|
+
| Surface | Producer / reader files | Current consumer and data boundary | Candidate and rationale | Separate follow-up |
|
|
9
|
+
| --- | --- | --- | --- | --- |
|
|
10
|
+
| `PROJMUX_USAGE_DEBUG` | `internal/app/usagecmd/usage.go`; adapter contract in `internal/core/usage/registry.go` and safe token helper in `internal/core/usage/adapters/claude/claude.go` | `projmux status usage` operator stderr; documented by `AGENTS.md`, `docs/configuration.md`, and `docs/usage-tracking.md`; `internal/app/usagecmd/usage_test.go` fixes the opt-in behavior; adapter errors are otherwise swallowed on the status hot path | **Keep.** Usage adapters are not adopted by the common journal and this opt-in stderr is the only immediate adapter failure consumer. | No removal follow-up. Re-evaluate only with a separately scoped usage diagnostics adoption. |
|
|
11
|
+
| `PROJMUX_SESSIONSTATE_DEBUG` | read/output gate in `internal/app/tmux.go` | Operator/automation stderr for a quiet autosave error; documented in `docs/configuration.md`; tests in `internal/app/tmux_test.go` cover popup environment propagation | **Deprecate candidate.** Phase 3 already records the same quiet autosave failure as a closed common error, but scripts may consume stderr. | Yes: announce deprecation, audit scripts, and remove only in a breaking PR after a compatibility window. |
|
|
12
|
+
| `PROJMUX_FOCUS_DEBUG` | read/output gate in `internal/app/focus.go` | Operator stderr one-line raw target/session/window/pane/socket/client/source/kind; documented in `AGENTS.md`, `docs/cli.md`, `docs/configuration.md`, `docs/operational-diagnostics.md`, and the maintained test list in `docs/agent-workflow.md`; `internal/app/focus_test.go` fixes the byte contract | **Deprecate candidate.** Phase 4 common focus events are safer for support, but the raw routing line remains a distinct local troubleshooting consumer. | Yes: publish safe replacement guidance and remove only through a breaking deprecation roadmap. |
|
|
13
|
+
| `PROJMUX_NATIVE_DEBUG_LOG` | `internal/ui/picker/backend.go` and `colorgrid.go` append native picker actions/query/value/errors; `internal/app/tmux.go` inherits it into popup environments | Developer-selected file path; popup inheritance is covered in `internal/app/tmux_test.go`; no public CLI/support reader, retention bound, or privacy redaction | **Remove candidate.** The opt-in trace can contain user query/value/error text and is not bounded. Current behavior remains intact because a safe bounded replacement and migration notice are outside Phase 6. | Yes: design a bounded private picker trace or common closed events, document migration, then ship removal as breaking. |
|
|
14
|
+
| bounded `ai-ingest.log` | Codex producer `internal/app/ai_ingest_codex.go`; Claude producer `internal/app/ai_ingest_claude.go`; Antigravity producer `internal/app/ai_ingest_antigravity.go`; tmux-bell producer plus shared `appendAIIngestLog`, path, cap, and trim in `internal/app/ai_ingest.go`; common projection in `internal/app/ai_ingest_diagnostics.go` | Detailed CLI reader `internal/app/ai_ingest.go` (`projmux ai ingest log`); count-only support reader `internal/app/diagnostics_report.go`; docs consumers `docs/cli.md`, `docs/hooks.md`, `docs/configuration.md`, `docs/operational-diagnostics.md`, and the maintained test list in `docs/agent-workflow.md`; `internal/app/ai_ingest_test.go`, `internal/app/ai_ingest_diagnostics_test.go`, `internal/app/diagnostics_report_test.go`, and `test/integration/linux-smoke.sh` cover retention/consumer/corrupt/permission behavior | **Deprecate candidate.** Phase 5 common events cover anomalous classification, but intentionally omit normal state/notify/quiet/dedupe detail and all identity. Removing the file now would break the detailed CLI consumer and measured parity. | Yes: define whether detailed normal-state diagnostics remain a product requirement, migrate or retire `ai ingest log` and support counts, announce a compatibility window, then use a breaking PR. |
|
|
15
|
+
|
|
16
|
+
The separate host resource status path is not a legacy debug surface:
|
|
17
|
+
`internal/app/status.go` invokes `internal/systemstatus.Sampler` for
|
|
18
|
+
`projmux status resources`. It owns only host aggregate display/cache behavior,
|
|
19
|
+
not pane/project attribution, and emits zero common resource events. The Phase
|
|
20
|
+
6 Resource Inspector owner is `internal/app/resources.go` →
|
|
21
|
+
`internal/app/resources_collector_linux.go` →
|
|
22
|
+
`internal/integrations/tmux.ListResourcePanes` plus
|
|
23
|
+
`internal/integrations/procfsresources.Collector`.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Native Picker
|
|
2
|
+
|
|
3
|
+
The native picker is the product picker for every interactive selection flow.
|
|
4
|
+
There is no runtime backend selection, saved picker selector, or external
|
|
5
|
+
picker process. `internal/ui/picker` owns the interaction contract and
|
|
6
|
+
`internal/ui/projmuxpicker` owns its visual composition.
|
|
7
|
+
|
|
8
|
+
## Product Contract
|
|
9
|
+
|
|
10
|
+
| Area | Behavior | Primary evidence |
|
|
11
|
+
| --- | --- | --- |
|
|
12
|
+
| Items and results | Structured items keep display labels, stable values, optional search text, multi-line metadata, and action results separate. `internal/ui/pickercompat` maps older internal option/result shapes into this contract; it is not a runtime backend. | `TestPickerOptionsFromCompatPickerMapsCandidatesWhenEntriesAreEmpty`; `TestPickerOptionsFromCompatPickerPreservesTheme` |
|
|
13
|
+
| Search | Lower-case queries are case-insensitive, uppercase queries are case-sensitive, hidden values remain searchable when no explicit search key exists, explicit search-key lists preserve caller order, and simple rows receive fuzzy ranking and match highlighting. | `TestFilterItemsUsesSmartCase`; `TestFilterItemsSearchesHiddenValueWhenNoSearchKey`; `TestFilterItemsPreservesSearchKeyOrder`; `TestFilterItemsRanksBetterMatchesFirst` |
|
|
14
|
+
| Navigation | Up/Down, Ctrl-J/Ctrl-N, and Ctrl-K/Ctrl-P wrap selection; PageUp/PageDown and Home/End clamp or jump; empty lists remain safe. Ctrl-N and Ctrl-P remain real navigation keys unless a caller claims the key as a custom action. | `TestNativeInteractiveSupportsControlNavigationKeys`; `TestNativeInteractiveWrapsPreviousNavigationKeys`; `TestNativeInteractiveWrapsNextNavigationKeys`; `TestNativeInteractiveNavigationKeysAreNoopForEmptyList`; `TestNativeInteractiveJumpNavigationRemainsClamped` |
|
|
15
|
+
| Editing | Left/Right, Ctrl-A/E, Delete, Backspace, Ctrl-U/W, printable input, accept-query mode, and a visible query cursor are supported. | `TestNativeInteractiveEditsTypedQueryAtCursor`; `TestNativeInteractiveSupportsQueryLineEditingKeys`; `TestNativeInteractiveCtrlUDeletesBeforeCursor`; `TestNativeRunnerAcceptsTypedQuery` |
|
|
16
|
+
| Actions | Enter accepts, shared close actions abort, printable/control expect keys return stable action keys, command actions can refresh previews, and mutable actions can update items without restarting the picker. | `TestNativeRunnerUsesSharedCloseActions`; `TestNativeInteractiveSupportsPrintableExpectKeys`; `TestNativeInteractiveRunsCustomActionCommandAndRefreshes`; `TestNativeInteractiveCustomActionMutatesItemsAndRefreshes` |
|
|
17
|
+
| Deferred state | Deferred and event-triggered updates preserve query and selection by value, can repeat, and may explicitly choose a new focus value. | `TestNativeInteractiveDeferredUpdateTriggerRefreshesRepeatedly`; switch and notify sidebar mutable-refresh app tests |
|
|
18
|
+
| Preview | Popup previews use a right split, sidebar previews use a bottom split, control bytes and tabs are normalized before clipping, and preview scrolling/cycling rerenders in place. | `TestNativeInteractiveRendersWidePreviewBesideList`; `TestNativeInteractiveRendersDownPreviewBelowList`; `TestRenderSplitPreviewRowsNormalizesPreviewTabsBeforeTruncating`; `TestNativeInteractiveRendersPreviewOffset` |
|
|
19
|
+
| Mouse | SGR mouse input focuses on primary down, follows drag, accepts on matching release, and scrolls with the wheel. | `TestNativeInteractiveSelectsOnMouseRelease`; `TestNativeInteractiveMouseDragFollowsSelection`; `TestNativeInteractiveSupportsMouseWheelSelection` |
|
|
20
|
+
| Lifecycle | Interactive runs use the alternate screen, synchronized/coalesced frame updates, controlling-TTY fallback, and deterministic reader cleanup. | `TestNativeInteractiveUsesAlternateScreen`; `TestNativeInteractiveWrapsRedrawsInSynchronizedUpdates`; picker/setup lifecycle tests in `docs/agent-workflow.md` |
|
|
21
|
+
|
|
22
|
+
## Rendering And Popup Chrome
|
|
23
|
+
|
|
24
|
+
The renderer owns rounded frames, optional titlebars and chips, search/header
|
|
25
|
+
separators, footer placement, selected-row styling, proportional scrollbars,
|
|
26
|
+
multi-line gaps, preview geometry, ANSI restoration, and terminal-cell width for
|
|
27
|
+
CJK text, emoji, and combining marks. Frame-owned cells inherit the effective
|
|
28
|
+
theme's `surface` and `chrome_foreground` values, including padding after
|
|
29
|
+
embedded resets.
|
|
30
|
+
|
|
31
|
+
Picker popups are always borderless tmux popups (`display-popup -B`) so the
|
|
32
|
+
native renderer owns the visible frame. The popup body receives a per-command
|
|
33
|
+
style derived from the effective theme; no global popup, pane, window, shell,
|
|
34
|
+
or status style is mutated. Project sidebars use a `20%` width with a `40`
|
|
35
|
+
column minimum, notification sidebars use `24%` with a `64` column minimum,
|
|
36
|
+
and both reserve the two statusbar rows when client height is known.
|
|
37
|
+
|
|
38
|
+
Primary evidence includes `TestAppRunTmuxPopupToggleUsesBorderlessNativePopup`,
|
|
39
|
+
`TestAppRunTmuxPopupToggleUsesNativePopupBodyStyleFromGlobalTheme`,
|
|
40
|
+
`TestBuildPopupToggleAppliesNativeBodyStyle`,
|
|
41
|
+
`TestSessionizerSidebarWidthUsesCompactMinimum`,
|
|
42
|
+
`TestNotifySidebarWidthUsesProductContract`, and
|
|
43
|
+
`TestSidebarPopupHeightLeavesStatusbarRows`.
|
|
44
|
+
|
|
45
|
+
## Fuzzy Scoring Provenance
|
|
46
|
+
|
|
47
|
+
The native fuzzy scorer intentionally follows the fzf V2 dynamic-scoring
|
|
48
|
+
algorithm for the maintained reference cases in `internal/ui/picker/backend_test.go`.
|
|
49
|
+
`TestFuzzyScoreMatchesFZFV2ReferenceScores` and
|
|
50
|
+
`TestFuzzyScoreRejectsFZFV2ReferenceNonMatches` are provenance fixtures; keep
|
|
51
|
+
their expected scores stable when changing filtering internals.
|
|
52
|
+
|
|
53
|
+
## Retired Artifact Contract
|
|
54
|
+
|
|
55
|
+
The retired picker selector environment variable and saved selector filename
|
|
56
|
+
are not runtime inputs. Their presence must not cause lookup, file reads,
|
|
57
|
+
warnings, deletion, rewriting, propagation to child popups, or any change to
|
|
58
|
+
the native path. There is deliberately no alias, migration, or stale-value
|
|
59
|
+
cleanup behavior.
|
|
60
|
+
|
|
61
|
+
Coverage is split by boundary:
|
|
62
|
+
|
|
63
|
+
- `TestRunNativePickerOptionDoesNotObserveRetiredBackendArtifacts` guards the
|
|
64
|
+
direct picker path, fails if the retired env name is queried, and verifies a
|
|
65
|
+
stale file is neither deleted nor replaced.
|
|
66
|
+
- `TestAppRunSwitchUsesNativePickerWithoutBackendLookup` guards the ordinary
|
|
67
|
+
switch flow.
|
|
68
|
+
- `TestAppRunTmuxPopupToggleIgnoresRetiredBackendArtifacts` and
|
|
69
|
+
`TestBuildPopupTogglePropagatesNativePickerEnvironmentWithoutRetiredBackend`
|
|
70
|
+
guard popup chrome and child-environment construction.
|
|
71
|
+
- `test/e2e/linux-smoke.sh` launches the ordinary attached-client Settings
|
|
72
|
+
popup with stale env/file values, completes the recorder flow, verifies the
|
|
73
|
+
file inode/content are unchanged, and rejects visible compatibility output.
|
|
74
|
+
|
|
75
|
+
## Removed PoC Coverage Mapping
|
|
76
|
+
|
|
77
|
+
The retired standalone dependency sandbox and focused smoke duplicated product
|
|
78
|
+
coverage or tested a dependency policy that no longer exists. Its valid
|
|
79
|
+
behavior assertions remain covered as follows:
|
|
80
|
+
|
|
81
|
+
| Removed focused assertion | Maintained coverage |
|
|
82
|
+
| --- | --- |
|
|
83
|
+
| Settings and Labs render through the native picker | `TestSettingsUsesNativePicker`; `TestSettingsHubKeepsLabsSectionWithoutRetiredPickerChoices`; ordinary attached-client Settings recorder in `test/e2e/linux-smoke.sh` |
|
|
84
|
+
| Search chrome, smart-case filtering, native frame ownership, and full-height rendering | `TestNativeInteractiveSeparatesSearchHeaderFromList`; `TestFilterItemsUsesSmartCase`; `TestNativeInteractiveRendersBorderFrame`; `TestNativeInteractiveUsesAvailableHeightForSimpleLists` |
|
|
85
|
+
| AI Settings maps a typed selection to the saved mode | `TestAISettingsPickerSetsSelectedMode`; native picker option/result mapping tests |
|
|
86
|
+
| Switch popup/sidebar filtering, selection, preview cycling, and initial focus | `TestAppRunSwitchDefaultsToPopupAndOpensSelectedSession`; `TestSwitchCommandSupportsSidebarUI`; preview cycle and initial-position tests in `internal/app/switch_test.go` |
|
|
87
|
+
| Sessions popup filtering, selection, and preview cycling | `TestAppRunSessionsDefaultsToPopupAndOpensSelectedSession`; session popup preview/cycle tests in `internal/app/session_popup_test.go` |
|
|
88
|
+
| Notification sidebar navigation and mutable actions | `TestNotifySidebarUsesNativePicker`; notify sidebar ack/clear/deferred-refresh app tests |
|
|
89
|
+
| Launch-key close behavior and Ctrl-N/Ctrl-P navigation | `TestNativeInteractiveClosesOnMatchingLaunchCloseKey`; `TestNativeInteractiveSupportsControlNavigationKeys`; empty-list and wrap tests |
|
|
90
|
+
| Mouse selection and alternate-screen restoration | native mouse and lifecycle tests listed above |
|
|
91
|
+
| Generated shell config and the Alt-1 project-sidebar popup path | `TestShellWritesAppConfigAndRunsIsolatedTmux`; `TestAppRunTmuxPopupToggleOpensStandaloneSidebar`; popup frame/body-style tests listed above |
|
|
92
|
+
| Stale selector values do not affect the product | retained and strengthened in the unit/app/e2e negative coverage listed in the previous section |
|
|
93
|
+
|
|
94
|
+
The dependency-absence assertion is now a source-residue property rather than
|
|
95
|
+
a separate container scenario: production code contains no selector, resolver,
|
|
96
|
+
saved-selector access, propagation, or external picker launch path.
|
|
97
|
+
|
|
98
|
+
## Maintenance
|
|
99
|
+
|
|
100
|
+
Update this document and the maintained list in
|
|
101
|
+
[`docs/agent-workflow.md`](agent-workflow.md) whenever picker behavior changes
|
|
102
|
+
coverage level, gains a new product flow, or changes input/render/action
|
|
103
|
+
semantics.
|
|
@@ -2,15 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
Projmux records a small local-only operational journal so command failures and
|
|
4
4
|
state changes can be inspected after the originating process exits. It does
|
|
5
|
-
not upload the journal,
|
|
6
|
-
|
|
5
|
+
not upload the journal, contact an issue tracker, or provide a background
|
|
6
|
+
telemetry service. A support archive is created only by an explicit
|
|
7
|
+
`projmux diagnostics report` invocation and is never transmitted.
|
|
7
8
|
|
|
8
9
|
## Safe event contract
|
|
9
10
|
|
|
10
11
|
Each JSONL record has a closed schema: `at`, `level`, `component`, `event`,
|
|
11
12
|
`result`, `duration_ms`, `run_id`, `version`, `mux_backend`, and optional
|
|
12
13
|
allowlisted `command`, `subcommand`, `kind`, and sanitized `message`. There is
|
|
13
|
-
no generic metadata map.
|
|
14
|
+
no generic metadata map. Runtime lifecycle records add only closed
|
|
15
|
+
`operation` and `code` enums. The allowed operations are session create,
|
|
16
|
+
attach, switch, kill, and tmux apply; codes are stable failure/health
|
|
17
|
+
classifications and never carry routing identity or subprocess details.
|
|
14
18
|
|
|
15
19
|
Command and subcommand names come from static allowlists. Unknown argv values,
|
|
16
20
|
paths, flags, and arguments are dropped. Messages have control/format
|
|
@@ -25,6 +29,158 @@ pane captures/output/title/topic/content, transcripts, raw hook payloads,
|
|
|
25
29
|
configuration secrets, or arbitrary environment values. Phase 0 also does not
|
|
26
30
|
add session/window/pane or other routing identifiers.
|
|
27
31
|
|
|
32
|
+
One explicit state-changing command owns at most one lifecycle pair. Its
|
|
33
|
+
`lifecycle.start` and `lifecycle.outcome` share the process `run_id`, and a
|
|
34
|
+
composite create-then-attach/switch flow keeps the first real mutation as its
|
|
35
|
+
operation instead of recording nested outcomes. Lifecycle ownership replaces
|
|
36
|
+
the generic top-level `command.outcome`; it never duplicates it. Start/outcome
|
|
37
|
+
append failures are ignored and do not change the command result.
|
|
38
|
+
|
|
39
|
+
Session State mutations use one outcome-only `session-state.outcome` record
|
|
40
|
+
per selected attempt. The closed operations are `session-state.save`,
|
|
41
|
+
`session-state.autosave`, `session-state.restore`, and `session-state.delete`;
|
|
42
|
+
an error uses only the matching `.failed` code, `kind=runtime`, and an empty
|
|
43
|
+
message. Optional sources are limited to `manual`, `settings-latest`,
|
|
44
|
+
`settings-named`, `autosave`, `startup-latest`, `startup-named`, and `prune`.
|
|
45
|
+
Successful save and actual startup restore outcomes contain only exact
|
|
46
|
+
non-negative `window_count`, `pane_count`, `shell_recipe_count`,
|
|
47
|
+
`agent_recipe_count`, and `startup_recipe_count` aggregates. Successful delete
|
|
48
|
+
contains only `item_count`; errors contain no counts. Snapshot paths/content,
|
|
49
|
+
project paths, pane cwd/commands, snapshot names, and agent or conversation
|
|
50
|
+
identifiers are never projected.
|
|
51
|
+
|
|
52
|
+
Direct and popup save, Settings latest/named save, direct and Settings delete,
|
|
53
|
+
deduplicated prune delete, and actual latest/named project-startup replay own
|
|
54
|
+
these outcomes. Preview, dry-run, and nested store/replay calls do not.
|
|
55
|
+
Autosave success and disabled, not-due, or fresh no-ops always write zero
|
|
56
|
+
records; a real autosave failure writes exactly one error even when `--quiet`
|
|
57
|
+
preserves its historical successful exit. Session State logical ownership
|
|
58
|
+
suppresses a generic top-level outcome even when journal append fails. An
|
|
59
|
+
actual restore may also produce its runtime lifecycle pair with the same run
|
|
60
|
+
ID; the lifecycle pair and Session State terminal outcome describe different
|
|
61
|
+
contracts and are not duplicates.
|
|
62
|
+
|
|
63
|
+
Notify and focus transitions use the same process `run_id` and add only closed
|
|
64
|
+
`transition`, `disposition`, `provider`, `category`, and `route` enums. Notify
|
|
65
|
+
transitions are `enqueue` and `delivery`; focus uses `request`. Enqueue records
|
|
66
|
+
distinguish queued, stable-ID deduplicated, and failed outcomes. Delivery
|
|
67
|
+
records distinguish delivered, dedupe/visibility/setting suppression, and
|
|
68
|
+
failed outcomes across the external sender hook, WSL Toast and fallback, and
|
|
69
|
+
Linux `notify-send` routes. Focus request records distinguish focused,
|
|
70
|
+
notify-only, session-only, window-only, and failed outcomes. Failure codes are
|
|
71
|
+
closed stage classifications and messages stay empty.
|
|
72
|
+
|
|
73
|
+
Provider and category values are projected through fixed allowlists. Unknown
|
|
74
|
+
values become `other`; arbitrary provider payloads and notification metadata
|
|
75
|
+
cannot extend the event schema. Notification summary/body, tag/group, terminal
|
|
76
|
+
title/topic, paths, queue or routing IDs, UUIDs, and AI/conversation/session
|
|
77
|
+
identifiers are never recorded. The notifier sender owns one terminal delivery
|
|
78
|
+
outcome after fallback selection, so failed intermediate WSL adapters do not
|
|
79
|
+
produce duplicate records when a later route succeeds.
|
|
80
|
+
|
|
81
|
+
One process writes at most one copy of an identical safe notify/focus tuple.
|
|
82
|
+
This fixes repeated stable-ID queue replacement, desktop dedupe, visible-pane
|
|
83
|
+
suppression, and reconcile hot paths to a finite per-run volume; the journal's
|
|
84
|
+
existing size/retention cap remains the cross-process bound. Explicit `notify
|
|
85
|
+
push` and `focus` outcomes logically replace the generic top-level
|
|
86
|
+
`command.outcome`, including when append fails. Secondary automatic enqueue or
|
|
87
|
+
delivery events do not claim an unrelated outer command. A successful focus
|
|
88
|
+
that switches a tmux client may coexist with the shipped runtime
|
|
89
|
+
`session.switch` lifecycle pair under the same run ID: the pair describes the
|
|
90
|
+
tmux mutation, while `focus.transition` describes the request-level result.
|
|
91
|
+
|
|
92
|
+
AI watcher and hook-ingest diagnostics use the same process `run_id` and add
|
|
93
|
+
only closed `provider`, `ai_kind`, `ai_result`, and `failure` enums. The event
|
|
94
|
+
families are `ai.watcher.transition` and `ai.ingest.outcome`. Watcher provider
|
|
95
|
+
is the generic `ai`; ingest providers are `codex`, `claude`, `antigravity`, or
|
|
96
|
+
`tmux-bell`. Each provider accepts only its own closed semantic-kind catalog;
|
|
97
|
+
for example, `tmux-bell` can only emit `bell`, while watcher events can only use
|
|
98
|
+
the generic `ai` provider and `watcher` kind. Provider event names are projected
|
|
99
|
+
into semantic kinds such as `prompt`, `permission`, `stop`, `notification`,
|
|
100
|
+
`tool`, `session`, `compact`, `subagent`, `teammate`, `statusline`, `invocation`,
|
|
101
|
+
`lifecycle`, `bell`, `payload`, or `unknown`. A raw or future event name can
|
|
102
|
+
therefore be diagnosed as `unknown` but can never extend the journal schema.
|
|
103
|
+
|
|
104
|
+
One watcher process emits at most one `started` transition, one terminal
|
|
105
|
+
`pane-gone` or `hook-active` transition, and one copy of each distinct safe
|
|
106
|
+
failure tuple. The existing observable launch seam uses only
|
|
107
|
+
`watcher-launch-failed`; status application remains the pre-existing
|
|
108
|
+
best-effort operation and does not claim to expose swallowed tmux write errors.
|
|
109
|
+
The terminal watcher event logically replaces its generic top-level outcome,
|
|
110
|
+
including when append fails.
|
|
111
|
+
The polling loop does not record snapshots, observed titles, captures, pane
|
|
112
|
+
state, or a record per iteration.
|
|
113
|
+
|
|
114
|
+
Hook ingest projects only anomalies: invalid/read/oversized payloads, unmatched
|
|
115
|
+
or invalid targets, unsupported event classification, and terminal route
|
|
116
|
+
failure. Route failures are limited to the observable bell queue/store and
|
|
117
|
+
Antigravity explicit-response seams. Identical safe anomaly tuples are
|
|
118
|
+
coalesced per process. Successful state, notification, quiet, and bell-dedupe
|
|
119
|
+
traffic emits zero common AI events. Notify enqueue/delivery remains owned by
|
|
120
|
+
the Phase 4 notify recorder, so ingest does not add a second AI success outcome
|
|
121
|
+
or claim a secondary notify outcome. An ingest failure owns the top-level error
|
|
122
|
+
logically before its best-effort append, preventing a duplicate generic
|
|
123
|
+
`command.outcome`.
|
|
124
|
+
|
|
125
|
+
The common AI event never contains the raw hook payload or event name, prompt,
|
|
126
|
+
transcript, tool name/input/output, notification summary/body, pane content,
|
|
127
|
+
cwd/path/command/title/topic, tmux target, queue ID, provider conversation or
|
|
128
|
+
session identifier, UUID, or arbitrary reason/error string. `failure` is a
|
|
129
|
+
stage enum, not `error.Error()`.
|
|
130
|
+
|
|
131
|
+
Resource attribution diagnostics use `component=resource` and the single
|
|
132
|
+
`resource.sampler.outcome` family. The Resource Inspector lifecycle is the
|
|
133
|
+
only writer: its Linux collector owns tmux inventory, project-root discovery,
|
|
134
|
+
and procfs attribution, while its refresh gate owns derived staleness. The
|
|
135
|
+
closed `source` values are `sampler`, `tmux-inventory`, `project-discovery`,
|
|
136
|
+
and `refresh`; the closed `resource_result` values are `unavailable`,
|
|
137
|
+
`partial`, `stale`, `error`, and `scan-budget-exceeded`. `failure` is limited
|
|
138
|
+
to the matching safe stage enum. Impossible source/result/failure combinations
|
|
139
|
+
are rejected.
|
|
140
|
+
|
|
141
|
+
The lifecycle's existing overlap and trigger-drop counters remain UI-only
|
|
142
|
+
refresh feedback and do not create an operational event by themselves. When
|
|
143
|
+
the retained last-complete sample crosses the stale boundary, the refresh
|
|
144
|
+
owner records the single coalesced `stale` transition instead.
|
|
145
|
+
|
|
146
|
+
Normal warming/ready samples, periodic samples, successful automatic/manual
|
|
147
|
+
refreshes, and the separate host-only `projmux status resources` sampler emit
|
|
148
|
+
zero common resource events. The two-second Resource Inspector lifecycle budget
|
|
149
|
+
measures inventory, discovery, and procfs collection together. Tmux inventory
|
|
150
|
+
and procfs observe its context directly. Project discovery does not currently
|
|
151
|
+
accept a context, so an overrun is classified as budget-exceeded when discovery
|
|
152
|
+
returns rather than being preempted; making that seam cancellable is a separate
|
|
153
|
+
follow-up. Budget exhaustion preserves the established unavailable UI/CLI
|
|
154
|
+
result and adds only the safe budget tuple. A persistent identical anomaly
|
|
155
|
+
emits once. Recovery is silent and resets that transition, so a later re-entry
|
|
156
|
+
emits once again. Journal append failure does not affect snapshot selection,
|
|
157
|
+
popup refresh, stdout/stderr, or exit status.
|
|
158
|
+
|
|
159
|
+
No resource event contains CPU or memory values, PID/process counts, process
|
|
160
|
+
command/cwd/title, project/session/window/pane identifiers, socket/TTY,
|
|
161
|
+
attribution details, snapshot status text, arbitrary errors, paths, UUIDs, or
|
|
162
|
+
privacy seeds. Partial and stale outcomes are info-level and remain in the
|
|
163
|
+
private local journal only. Unavailable, collection/inventory/discovery error,
|
|
164
|
+
and scan-budget outcomes are error-level, so the explicit support report may
|
|
165
|
+
include their closed enums after hashing run/version correlation. The report's
|
|
166
|
+
existing error-only projection omits partial/stale and never exports metrics or
|
|
167
|
+
identity.
|
|
168
|
+
|
|
169
|
+
The diagnostics package exposes a typed `ReadRuntimeHealth` projection for
|
|
170
|
+
read-only Doctor consumers. It reports the fixed `tmux` backend, latest
|
|
171
|
+
socket/apply state, and a bounded tail/count of safe failures using only
|
|
172
|
+
`Store.ReadOnly`; it does not create, chmod, lock, truncate, apply, restart, or
|
|
173
|
+
repair anything. Doctor schema 2 consumes that seam for its `logs` findings
|
|
174
|
+
and adds one fixed-argv, one-second `tmux -L projmux show-options` probe for
|
|
175
|
+
actual socket/config health. The probe neither generates nor applies config.
|
|
176
|
+
Its captured output is capped at 4 KiB. Doctor reads only a pre-existing
|
|
177
|
+
regular generated config (at most 1 MiB) without following symlinks, and the
|
|
178
|
+
shared read-only journal seam rejects non-regular inputs and files above 5 MiB.
|
|
179
|
+
These conditions degrade to typed findings rather than blocking or repairing
|
|
180
|
+
the source. Windows ACL privacy is reported as unverified because `os.FileMode`
|
|
181
|
+
cannot prove it; a separate finding preserves the metadata-only writability
|
|
182
|
+
result, and Doctor does not modify ACLs.
|
|
183
|
+
|
|
28
184
|
## Storage and retention
|
|
29
185
|
|
|
30
186
|
The path is
|
|
@@ -54,9 +210,13 @@ arm`, `attention clear`, `attention window`, `tmux autosave-session-state`, and
|
|
|
54
210
|
to the journal; an error from any of them still records exactly one safe error
|
|
55
211
|
outcome. Explicit user mutations such as `attention toggle` retain their
|
|
56
212
|
state-changing success record. Direct top-level help and explicit preview-only intents (`upgrade
|
|
57
|
-
--dry-run`, `update apply --dry-run`,
|
|
58
|
-
|
|
59
|
-
|
|
213
|
+
--dry-run`, `update apply --dry-run`, AI integration dry-runs, and the
|
|
214
|
+
currently preview-only session restore) are also read-only. Doctor is a stricter
|
|
215
|
+
boundary: successes and errors never append to this journal, so diagnostics do
|
|
216
|
+
not make its filesystem contract self-defeating. Support report success and
|
|
217
|
+
errors likewise never append; its strict reader shares the viewer's tolerant
|
|
218
|
+
decoder but never creates/locks/chmods/repairs/truncates the source journal.
|
|
219
|
+
Multi-mode commands such as AI status/topic,
|
|
60
220
|
terminal apply, snapshot delete, update check, and welcome popup inspect only
|
|
61
221
|
allowlisted mode/flag names; boolean `=false` values retain mutation-capable
|
|
62
222
|
classification, and no flag values are ever recorded. Help-looking tokens
|
|
@@ -76,5 +236,52 @@ viewer read is excluded from success logging, so inspection does not create a
|
|
|
76
236
|
recursion loop.
|
|
77
237
|
|
|
78
238
|
The older bounded `ai-ingest.log` and subsystem-specific `PROJMUX_*_DEBUG`
|
|
79
|
-
surfaces retain their current paths, formats, and behavior.
|
|
80
|
-
|
|
239
|
+
surfaces retain their current paths, formats, and behavior. Phase 6 deliberately
|
|
240
|
+
keeps the legacy producer and both existing consumers: `projmux ai ingest log`
|
|
241
|
+
still reads the legacy JSONL bytes, and `diagnostics report` still emits its
|
|
242
|
+
allowlisted source/result count summary. Legacy append failure remains
|
|
243
|
+
best-effort and independent of common-journal append failure.
|
|
244
|
+
|
|
245
|
+
The measured migration parity is:
|
|
246
|
+
|
|
247
|
+
| Legacy `ai-ingest.log` result | Common operational projection |
|
|
248
|
+
| --- | --- |
|
|
249
|
+
| parse error with no classified event | `payload / failed / payload-invalid` |
|
|
250
|
+
| bell queue/store or Antigravity response route error | allowlisted semantic kind / `failed / route-failed` |
|
|
251
|
+
| no matching pane | allowlisted semantic kind / `ignored / target-unmatched` |
|
|
252
|
+
| pane-not-found bell target | `bell / ignored / target-unmatched` |
|
|
253
|
+
| unknown event recorded as quiet | `unknown / ignored / unsupported-event` |
|
|
254
|
+
| normal `state`, `notify`, known `quiet`, or `deduped` | zero common AI events; existing state/notify owner remains authoritative |
|
|
255
|
+
| stdin read or payload-size rejection before the legacy append seam | common-only `payload-read` or `payload-oversized`; no legacy row existed |
|
|
256
|
+
| blank `ai ingest bell` CLI target rejected before the legacy append seam | common-only `bell / ignored / target-invalid`; exit semantics unchanged |
|
|
257
|
+
|
|
258
|
+
This is a dual-run migration seam, not a deprecation. Operators who need the
|
|
259
|
+
legacy detailed local view can keep using `ai ingest log`; support archives
|
|
260
|
+
remain count-only for that file. The common journal is the safe correlated
|
|
261
|
+
source for watcher lifecycle and anomalous ingest classification. The file is
|
|
262
|
+
a documented **Deprecate candidate**, not deprecated behavior in this release:
|
|
263
|
+
common diagnostics cover anomalies but not the legacy detailed normal-state
|
|
264
|
+
consumer. Any deprecation/removal requires a separate breaking roadmap with
|
|
265
|
+
consumer migration.
|
|
266
|
+
|
|
267
|
+
`PROJMUX_FOCUS_DEBUG` remains available with its existing one-line byte
|
|
268
|
+
contract. Focus diagnostics share its request classification seam, but do not
|
|
269
|
+
copy the debug line's raw target, session/window/pane, socket, client, source,
|
|
270
|
+
or kind values into the journal. It is a documented **Deprecate candidate**
|
|
271
|
+
because the common focus transition is the safe support path; its raw routing
|
|
272
|
+
byte contract remains unchanged until a separate breaking deprecation.
|
|
273
|
+
|
|
274
|
+
The complete file/surface inventory and decisions are maintained in
|
|
275
|
+
[legacy-diagnostics-inventory.md](legacy-diagnostics-inventory.md). These are
|
|
276
|
+
candidates only; Phase 6 removes, renames, ignores, or changes none of them.
|
|
277
|
+
|
|
278
|
+
## Explicit support report
|
|
279
|
+
|
|
280
|
+
`projmux diagnostics report [--output <path>]` previews and then atomically
|
|
281
|
+
publishes a private local `tar.gz`; see [cli.md](cli.md#diagnostics). The
|
|
282
|
+
manifest records report schema version 2, `default-hash-v1` redaction, every
|
|
283
|
+
included entry, and stable missing/corrupt/permission omission reasons. Doctor
|
|
284
|
+
JSON schema version 2 and the bounded operations decoder are reused rather than
|
|
285
|
+
duplicated. AI ingest contributes count-only allowlisted source/result rows,
|
|
286
|
+
never raw legacy lines. Existing output files survive collisions and partial
|
|
287
|
+
temporary archives are removed.
|
package/docs/pr-guideline.md
CHANGED
|
@@ -24,7 +24,7 @@ feat(ai): add codex split picker keybinding
|
|
|
24
24
|
fix(ai): prepend agent bin dir to PATH so node-managed CLIs find node
|
|
25
25
|
docs(readme): drop Releases and Configuration sections
|
|
26
26
|
chore: bump release-please manifest to 0.3.0
|
|
27
|
-
refactor(picker):
|
|
27
|
+
refactor(picker): simplify native picker bootstrap code
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
Rules:
|
|
@@ -48,6 +48,13 @@ maps, SQLite, protobuf, or remote telemetry.
|
|
|
48
48
|
- Snapshot state is `warming`, `ready`, `partial`, or `unavailable`. Bounded
|
|
49
49
|
diagnostics contain scan duration and sampled/skipped/race/permission counts,
|
|
50
50
|
plus identity/delta quality counts; they contain no user payload.
|
|
51
|
+
- The interactive lifecycle has a two-second total budget matching its
|
|
52
|
+
non-overlapping cadence. Tmux inventory and procfs observe the context
|
|
53
|
+
directly. Project discovery is included in elapsed-budget classification but
|
|
54
|
+
its current interface is not cancellable, so an overrun is recognized only
|
|
55
|
+
when discovery returns. Budget exhaustion remains an unavailable snapshot;
|
|
56
|
+
it never exposes a partially mutating result. Context-aware project discovery
|
|
57
|
+
is a separate follow-up.
|
|
51
58
|
|
|
52
59
|
## Measurements
|
|
53
60
|
|
|
@@ -90,11 +97,18 @@ The opt-in read-only test below observes an existing socket and emits counts
|
|
|
90
97
|
only. It neither captures pane content nor reads process command lines.
|
|
91
98
|
|
|
92
99
|
```text
|
|
93
|
-
PROJMUX_RESOURCE_TMUX_SOCKET=projmux
|
|
100
|
+
PROJMUX_RESOURCE_TMUX_SOCKET=projmux \
|
|
101
|
+
PROJMUX_RESOURCE_EXPECT_PROJECT_ROOT=/path/to/project go test \
|
|
94
102
|
-run TestResourceAttributionRealTmuxReadOnlySmoke -v \
|
|
95
103
|
./internal/integrations/tmux
|
|
96
104
|
```
|
|
97
105
|
|
|
106
|
+
When `PROJMUX_RESOURCE_EXPECT_PROJECT_ROOT` is set, the smoke additionally
|
|
107
|
+
requires at least one blank explicit anchor to resolve from its pane current
|
|
108
|
+
path and requires the resulting project bucket to contain a pane. Output stays
|
|
109
|
+
bounded to the expected project path and aggregate counts; it does not emit
|
|
110
|
+
session names, pane content, prompts, transcripts, or process command lines.
|
|
111
|
+
|
|
98
112
|
2026-08-12 result: `panes=8`, `pane_pid_eq_sid=8`, `missing_pids=0`,
|
|
99
113
|
`attributed_processes=13`, `escaped_boundary=0`, `sampled=474`, `skipped=0`,
|
|
100
114
|
`race=0`, `permission=0`, `status=ready`. A separate tmux format-only count
|
|
@@ -119,6 +133,18 @@ PROJMUX_RESOURCE_TRANSIENT_SMOKE=1 go test \
|
|
|
119
133
|
The pane shell remained attributed while its real `setsid` child was counted
|
|
120
134
|
at the escaped/Other boundary, without reading the child command line.
|
|
121
135
|
|
|
136
|
+
The current-path fallback itself has a separate isolated real-tmux smoke. It
|
|
137
|
+
starts with inherited `TMUX`/`TMUX_PANE` removed, uses a dedicated
|
|
138
|
+
`TMUX_TMPDIR` plus `-L` socket, verifies the actual socket path is below that
|
|
139
|
+
temporary root before exact cleanup, and confirms the blank tmux project
|
|
140
|
+
option remains blank after in-memory attribution:
|
|
141
|
+
|
|
142
|
+
```text
|
|
143
|
+
PROJMUX_RESOURCE_PROJECT_FALLBACK_SMOKE=1 go test \
|
|
144
|
+
-run TestResourceProjectFallbackTransientSmoke -v \
|
|
145
|
+
./internal/integrations/tmux
|
|
146
|
+
```
|
|
147
|
+
|
|
122
148
|
## Phase 1 inspector
|
|
123
149
|
|
|
124
150
|
The popup retains warming/partial/unavailable and overage states, renders RSS
|
|
@@ -127,6 +153,53 @@ samples when it closes. Its non-overlapping default cadence is two seconds;
|
|
|
127
153
|
Ctrl-R shares the same scan gate. Selection and query survive refresh by stable
|
|
128
154
|
row identity, while a vanished row clamps to the nearest valid neighbor.
|
|
129
155
|
Display labels use label → agent topic → known interactive shell → raw title,
|
|
130
|
-
but those values never become ownership keys.
|
|
131
|
-
|
|
132
|
-
|
|
156
|
+
but those values never become ownership keys. Pane rows and detail reuse that
|
|
157
|
+
identity plus the tmux current command, PID/SID, pane id, and TTY; pane rows
|
|
158
|
+
show attributed process counts while project/window rows retain pane counts.
|
|
159
|
+
Right/Enter move forward, Left moves back (and is a root no-op), and Esc closes
|
|
160
|
+
at every depth. Unsupported platforms show an unavailable reason, not zero
|
|
161
|
+
metrics. PSS, non-Linux collectors, process-list drill-down, history, and
|
|
162
|
+
resource mutation remain outside this contract.
|
|
163
|
+
|
|
164
|
+
Host and attributed CPU/memory use the same semantic classifier as the live
|
|
165
|
+
statusbar: CPU is normal below 70%, warning at 70–89.9%, and critical at 90%
|
|
166
|
+
or above; memory is normal below 75%, warning at 75–89.9%, and critical at 90%
|
|
167
|
+
or above. Values retain the resolved semantic role but omit visible severity
|
|
168
|
+
words. Unknown is rendered as `--`, never as zero; Sample lifecycle and
|
|
169
|
+
freshness remain explicit text.
|
|
170
|
+
|
|
171
|
+
The first paint is a non-actionable warming surface. Completed samples report
|
|
172
|
+
age and fresh/stale state; partial and overage callouts stay bounded to counts
|
|
173
|
+
and aggregate values. Empty and gone scopes are read-only and explain what the
|
|
174
|
+
latest complete sample can no longer open. Automatic refresh runs every two
|
|
175
|
+
seconds; Ctrl-R reports in-progress state while retaining the last complete
|
|
176
|
+
sample. Both paths preserve scope, breadcrumb, query, selection, and the row
|
|
177
|
+
order last computed by Tab. The default order is Name; Tab computes CPU,
|
|
178
|
+
Memory, or Name once from the current sample, while later refreshes update row
|
|
179
|
+
values without silently moving focus. Native synchronized frame diffs repaint
|
|
180
|
+
only changed rows and update state/footer chrome together.
|
|
181
|
+
|
|
182
|
+
The Resource Inspector lifecycle projects only unavailable, partial, stale,
|
|
183
|
+
collection/inventory/discovery error, and scan-budget transitions into the
|
|
184
|
+
private bounded operations journal. A persistent identical transition is
|
|
185
|
+
coalesced until silent recovery; normal samples and refreshes emit nothing.
|
|
186
|
+
The statusbar's separate host-only sampler also emits nothing. Resource events
|
|
187
|
+
never contain the metrics, PID/process data, tmux/project identity, paths,
|
|
188
|
+
titles, commands, snapshot reasons, or arbitrary error strings described by
|
|
189
|
+
this UI model. See [operational-diagnostics.md](operational-diagnostics.md).
|
|
190
|
+
|
|
191
|
+
The live summary is a fixed five-row bottom dock below the search/list surface:
|
|
192
|
+
one renderer-owned theme-aware divider, then Host, Attributed, Coverage, and
|
|
193
|
+
Sample. It does not scroll or filter with rows. Coverage owns the non-drillable
|
|
194
|
+
Other or current-scope empty/gone explanation; bounded partial/overage details
|
|
195
|
+
stay on Sample. The action footer remains below the dock with its own chrome
|
|
196
|
+
boundary, so diagnostic values and key hints never share a role. The 80x24
|
|
197
|
+
layout retains a navigable list viewport without clipping, border bleed, or a
|
|
198
|
+
second dock divider.
|
|
199
|
+
|
|
200
|
+
Project rows label project paths explicitly. The two attribution buckets keep
|
|
201
|
+
their stable core keys but display `No project match` and `Multiple project
|
|
202
|
+
matches` with bounded explanations. Pane primary identity follows the shared
|
|
203
|
+
label → agent-only AI topic → interactive shell → raw title resolver; pane id,
|
|
204
|
+
process id, and TTY remain labeled secondary details and stable keys are
|
|
205
|
+
unchanged.
|
package/docs/session-restore.md
CHANGED
|
@@ -137,3 +137,21 @@ longer accepts startup selector flags for session-state restore. It always
|
|
|
137
137
|
follows the normal empty attach path after resolving the target app session name
|
|
138
138
|
and startup directory. Use `Settings > Session State > Sidebar startup picker` for
|
|
139
139
|
interactive Latest snapshot / Named snapshot / Empty session selection.
|
|
140
|
+
|
|
141
|
+
## Operational diagnostics
|
|
142
|
+
|
|
143
|
+
Selected Session State mutations leave one local, best-effort terminal outcome
|
|
144
|
+
in the bounded operational journal. Manual and popup save, Project Settings
|
|
145
|
+
latest/named save, manual/Settings/prune delete, and actual project-startup
|
|
146
|
+
latest/named replay are covered. Restore preview and `--dry-run` remain
|
|
147
|
+
read-only. Successful autosave, disabled/not-due/fresh autosave no-ops, and
|
|
148
|
+
nested snapshot store/replay calls do not write an outcome; an actual autosave
|
|
149
|
+
failure writes one safe error even under `--quiet`.
|
|
150
|
+
|
|
151
|
+
The outcome contains only a closed operation/source and aggregate window,
|
|
152
|
+
pane, recipe, or deleted-item counts. It never contains a snapshot or project
|
|
153
|
+
path, snapshot content/name, pane cwd/command, agent resume/conversation/session
|
|
154
|
+
ID, or arbitrary metadata. Diagnostics append failure never changes save,
|
|
155
|
+
restore, delete, or quiet-autosave behavior. See
|
|
156
|
+
[operational-diagnostics.md](operational-diagnostics.md) for the complete event
|
|
157
|
+
schema and retention/privacy contract.
|
package/docs/settings-ia.md
CHANGED
|
@@ -71,11 +71,11 @@ view-first layout:
|
|
|
71
71
|
desktop AI notification collapse window. It stores integer seconds and shows
|
|
72
72
|
the effective source; `PROJMUX_TMUX_NOTIFY_DEDUPE_SECONDS` remains the top
|
|
73
73
|
override. The tmux bell fallback keeps its fixed 5 second window.
|
|
74
|
-
- `Settings > Notifications > Delivery sources` shows Codex
|
|
75
|
-
tmux producer diagnostics, the effective desktop sender
|
|
76
|
-
copyable install/remove/dry-run commands. Settings copies
|
|
77
|
-
it does not install or remove external notify wiring. The
|
|
78
|
-
source is intentionally omitted from Settings.
|
|
74
|
+
- `Settings > Notifications > Delivery sources` shows Codex, Claude,
|
|
75
|
+
Antigravity, and tmux producer diagnostics, the effective desktop sender
|
|
76
|
+
override state, and copyable install/remove/dry-run commands. Settings copies
|
|
77
|
+
command text only; it does not install or remove external notify wiring. The
|
|
78
|
+
legacy Codex notify source is intentionally omitted from Settings.
|
|
79
79
|
- `Settings > Notifications > Hook quiet policy` shows Codex/Claude hook
|
|
80
80
|
runtime action values and writes only
|
|
81
81
|
`${XDG_CONFIG_HOME:-$HOME/.config}/projmux/ai-hook-actions.json`. It does not
|
|
@@ -85,8 +85,8 @@ view-first layout:
|
|
|
85
85
|
`${XDG_CONFIG_HOME:-$HOME/.config}/projmux/sidebar-startup-picker`.
|
|
86
86
|
- `Settings > Labs` contains only Live system resources and Project Hooks.
|
|
87
87
|
Keybindings live at `Settings > Keybindings`; Labs has no visible or hidden
|
|
88
|
-
keybindings redirect.
|
|
89
|
-
render picker source
|
|
88
|
+
keybindings redirect. The native picker is the product picker, so Labs does
|
|
89
|
+
not render picker source information.
|
|
90
90
|
- `Settings > Labs > Live system resources` is a direct global on/off toggle
|
|
91
91
|
for the macOS/Linux/WSL lower-status-row `CPU N% MEM N%` segment. It defaults
|
|
92
92
|
off, updates live tmux state when toggled, and renders unavailable on
|
|
@@ -97,7 +97,8 @@ view-first layout:
|
|
|
97
97
|
- `Settings > Labs > Project Hooks` is overview-first. The Labs root opens the
|
|
98
98
|
overview, and the on/off mutation rows live one level deeper.
|
|
99
99
|
- `Settings > AI Settings` is view-first. The root contains `Default split
|
|
100
|
-
mode
|
|
100
|
+
mode`, `Enabled agents`, and `Resume picker`; the default-mode detail contains
|
|
101
|
+
the `Claude`, `Codex`, `Antigravity`, `Shell`, and `Selective` choices.
|
|
101
102
|
- `Settings > Project > Project recipe` is the functional label for
|
|
102
103
|
`.projmux/config.toml`. Search still matches `config.toml` as an alias.
|
|
103
104
|
- `Settings > Project > Project recipe` is view-first. The root contains section
|
|
@@ -117,7 +118,7 @@ view-first layout:
|
|
|
117
118
|
visible as warnings and fall back to `en-US`.
|
|
118
119
|
- Global root descriptions keep ownership explicit: Appearance owns language,
|
|
119
120
|
AI badge style, and status/notification icon decoration; Theme owns presets,
|
|
120
|
-
color tokens
|
|
121
|
+
and color tokens. About describes only the surface it retains.
|
|
121
122
|
- `Settings > About` is intentionally compact: Version, Source, update
|
|
122
123
|
status/actions (including Latest, Update state, Installer, and Release notes
|
|
123
124
|
when available), Welcome, and Quit. It does not reproduce static key,
|