@agi-fans/dsh-tui 0.20.0 → 0.22.0
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/lib/CHANGELOG.md +249 -3
- package/lib/chrome/box.d.ts +47 -16
- package/lib/chrome/box.js +172 -130
- package/lib/chrome/box.js.map +1 -1
- package/lib/chrome/code-highlight.d.ts +15 -0
- package/lib/chrome/code-highlight.js +60 -4
- package/lib/chrome/code-highlight.js.map +1 -1
- package/lib/chrome/command-output.d.ts +29 -2
- package/lib/chrome/command-output.js +100 -4
- package/lib/chrome/command-output.js.map +1 -1
- package/lib/chrome/main-screen-renderer.d.ts +18 -0
- package/lib/chrome/main-screen-renderer.js +58 -5
- package/lib/chrome/main-screen-renderer.js.map +1 -1
- package/lib/chrome/markdown.js +30 -10
- package/lib/chrome/markdown.js.map +1 -1
- package/lib/chrome/relative-time.d.ts +17 -0
- package/lib/chrome/relative-time.js +36 -0
- package/lib/chrome/relative-time.js.map +1 -1
- package/lib/chrome/renderer.d.ts +9 -0
- package/lib/chrome/renderer.js +1 -1
- package/lib/chrome/renderer.js.map +1 -1
- package/lib/chrome/secret-mask.d.ts +35 -0
- package/lib/chrome/secret-mask.js +180 -0
- package/lib/chrome/secret-mask.js.map +1 -0
- package/lib/chrome/status-config.d.ts +161 -51
- package/lib/chrome/status-config.js +237 -126
- package/lib/chrome/status-config.js.map +1 -1
- package/lib/chrome/status-line.d.ts +3 -2
- package/lib/chrome/status-line.js +105 -63
- package/lib/chrome/status-line.js.map +1 -1
- package/lib/chrome/terminal-colors.d.ts +85 -0
- package/lib/chrome/terminal-colors.js +230 -0
- package/lib/chrome/terminal-colors.js.map +1 -0
- package/lib/chrome/terminal-images.d.ts +9 -1
- package/lib/chrome/terminal-images.js +27 -4
- package/lib/chrome/terminal-images.js.map +1 -1
- package/lib/chrome/theme.d.ts +32 -9
- package/lib/chrome/theme.js +616 -520
- package/lib/chrome/theme.js.map +1 -1
- package/lib/chrome/tool-args.d.ts +1 -1
- package/lib/chrome/tool-args.js +3 -1
- package/lib/chrome/tool-args.js.map +1 -1
- package/lib/chrome/tool-renderers.d.ts +2 -0
- package/lib/chrome/tool-renderers.js +69 -3
- package/lib/chrome/tool-renderers.js.map +1 -1
- package/lib/chrome/tools-list.d.ts +1 -4
- package/lib/chrome/tools-list.js +1 -41
- package/lib/chrome/tools-list.js.map +1 -1
- package/lib/chrome/welcome-tips.d.ts +20 -7
- package/lib/chrome/welcome-tips.js +22 -41
- package/lib/chrome/welcome-tips.js.map +1 -1
- package/lib/commands/auth-ids.d.ts +25 -0
- package/lib/commands/auth-ids.js +27 -0
- package/lib/commands/auth-ids.js.map +1 -0
- package/lib/commands/auth-input.d.ts +34 -0
- package/lib/commands/auth-input.js +96 -0
- package/lib/commands/auth-input.js.map +1 -0
- package/lib/commands/auth-providers.d.ts +39 -0
- package/lib/commands/auth-providers.js +125 -0
- package/lib/commands/auth-providers.js.map +1 -0
- package/lib/commands/auth.d.ts +16 -22
- package/lib/commands/auth.js +346 -299
- package/lib/commands/auth.js.map +1 -1
- package/lib/commands/btw.d.ts +27 -0
- package/lib/commands/btw.js +59 -0
- package/lib/commands/btw.js.map +1 -0
- package/lib/commands/diff.js +30 -5
- package/lib/commands/diff.js.map +1 -1
- package/lib/commands/export.d.ts +1 -1
- package/lib/commands/export.js +5 -3
- package/lib/commands/export.js.map +1 -1
- package/lib/commands/files.d.ts +17 -1
- package/lib/commands/files.js +69 -61
- package/lib/commands/files.js.map +1 -1
- package/lib/commands/integrations.js +18 -6
- package/lib/commands/integrations.js.map +1 -1
- package/lib/commands/jobs.d.ts +19 -4
- package/lib/commands/jobs.js +50 -7
- package/lib/commands/jobs.js.map +1 -1
- package/lib/commands/model.js +109 -76
- package/lib/commands/model.js.map +1 -1
- package/lib/commands/permission.js +46 -13
- package/lib/commands/permission.js.map +1 -1
- package/lib/commands/plugins.js +196 -42
- package/lib/commands/plugins.js.map +1 -1
- package/lib/commands/schedule.d.ts +29 -0
- package/lib/commands/schedule.js +228 -0
- package/lib/commands/schedule.js.map +1 -0
- package/lib/commands/session-configuration.d.ts +1 -1
- package/lib/commands/session-configuration.js +29 -28
- package/lib/commands/session-configuration.js.map +1 -1
- package/lib/commands/session.js +75 -80
- package/lib/commands/session.js.map +1 -1
- package/lib/commands/terminal.d.ts +24 -4
- package/lib/commands/terminal.js +38 -94
- package/lib/commands/terminal.js.map +1 -1
- package/lib/commands/trajectory.js +4 -1
- package/lib/commands/trajectory.js.map +1 -1
- package/lib/definition.d.ts +150 -11
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/input/actions.d.ts +51 -0
- package/lib/input/actions.js +120 -0
- package/lib/input/actions.js.map +1 -0
- package/lib/input/editor-discovery.js +2 -2
- package/lib/input/editor-discovery.js.map +1 -1
- package/lib/input/editor.d.ts +0 -10
- package/lib/input/editor.js +11 -9
- package/lib/input/editor.js.map +1 -1
- package/lib/input/image-paste.d.ts +19 -1
- package/lib/input/image-paste.js +82 -1
- package/lib/input/image-paste.js.map +1 -1
- package/lib/input/keybindings-config.d.ts +15 -4
- package/lib/input/keybindings-config.js +57 -35
- package/lib/input/keybindings-config.js.map +1 -1
- package/lib/input/keys.d.ts +18 -0
- package/lib/input/keys.js +48 -3
- package/lib/input/keys.js.map +1 -1
- package/lib/input/wheel-scroll.d.ts +46 -0
- package/lib/input/wheel-scroll.js +69 -0
- package/lib/input/wheel-scroll.js.map +1 -0
- package/lib/prompt-intents.d.ts +182 -0
- package/lib/prompt-intents.js +127 -0
- package/lib/prompt-intents.js.map +1 -0
- package/lib/runtime/agent-profile.d.ts +5 -0
- package/lib/runtime/agent-profile.js +12 -0
- package/lib/runtime/agent-profile.js.map +1 -1
- package/lib/runtime/approval-rules.d.ts +59 -0
- package/lib/runtime/approval-rules.js +179 -0
- package/lib/runtime/approval-rules.js.map +1 -0
- package/lib/runtime/btw-policy.d.ts +7 -0
- package/lib/runtime/btw-policy.js +18 -0
- package/lib/runtime/btw-policy.js.map +1 -0
- package/lib/runtime/btw.d.ts +47 -0
- package/lib/runtime/btw.js +200 -0
- package/lib/runtime/btw.js.map +1 -0
- package/lib/runtime/cancellable.d.ts +75 -0
- package/lib/runtime/cancellable.js +76 -0
- package/lib/runtime/cancellable.js.map +1 -0
- package/lib/runtime/composer-images.js +5 -4
- package/lib/runtime/composer-images.js.map +1 -1
- package/lib/runtime/composer-shell.d.ts +30 -0
- package/lib/runtime/composer-shell.js +150 -0
- package/lib/runtime/composer-shell.js.map +1 -0
- package/lib/runtime/file-recovery-local.d.ts +73 -0
- package/lib/runtime/file-recovery-local.js +351 -0
- package/lib/runtime/file-recovery-local.js.map +1 -0
- package/lib/runtime/file-recovery-recording.d.ts +23 -0
- package/lib/runtime/file-recovery-recording.js +131 -0
- package/lib/runtime/file-recovery-recording.js.map +1 -0
- package/lib/runtime/file-recovery-review.d.ts +3 -0
- package/lib/runtime/file-recovery-review.js +130 -0
- package/lib/runtime/file-recovery-review.js.map +1 -0
- package/lib/runtime/file-recovery-store.d.ts +83 -0
- package/lib/runtime/file-recovery-store.js +329 -0
- package/lib/runtime/file-recovery-store.js.map +1 -0
- package/lib/runtime/file-recovery-worker.d.ts +22 -0
- package/lib/runtime/file-recovery-worker.js +153 -0
- package/lib/runtime/file-recovery-worker.js.map +1 -0
- package/lib/runtime/file-review.d.ts +6 -3
- package/lib/runtime/file-review.js +44 -7
- package/lib/runtime/file-review.js.map +1 -1
- package/lib/runtime/herdr-agent.d.ts +4 -13
- package/lib/runtime/herdr-agent.js +19 -63
- package/lib/runtime/herdr-agent.js.map +1 -1
- package/lib/runtime/plain-tui.d.ts +2 -0
- package/lib/runtime/plain-tui.js +7 -1
- package/lib/runtime/plain-tui.js.map +1 -1
- package/lib/runtime/plugin-settings.d.ts +25 -2
- package/lib/runtime/plugin-settings.js +329 -31
- package/lib/runtime/plugin-settings.js.map +1 -1
- package/lib/runtime/provider-local.d.ts +81 -24
- package/lib/runtime/provider-local.js +1807 -608
- package/lib/runtime/provider-local.js.map +1 -1
- package/lib/runtime/runner.js +52 -12
- package/lib/runtime/runner.js.map +1 -1
- package/lib/runtime/session-archive.d.ts +6 -0
- package/lib/runtime/session-archive.js +129 -3
- package/lib/runtime/session-archive.js.map +1 -1
- package/lib/runtime/session-runtime.js +1 -1
- package/lib/runtime/session-runtime.js.map +1 -1
- package/lib/runtime/settings-preferences.d.ts +5 -0
- package/lib/runtime/settings-preferences.js +34 -0
- package/lib/runtime/settings-preferences.js.map +1 -0
- package/lib/runtime/startup-notices.js +2 -0
- package/lib/runtime/startup-notices.js.map +1 -1
- package/lib/runtime/terminal-modes.d.ts +47 -0
- package/lib/runtime/terminal-modes.js +86 -0
- package/lib/runtime/terminal-modes.js.map +1 -0
- package/lib/runtime/terminal-notifications.d.ts +3 -5
- package/lib/runtime/terminal-notifications.js +4 -8
- package/lib/runtime/terminal-notifications.js.map +1 -1
- package/lib/runtime/terminal-probe.d.ts +36 -0
- package/lib/runtime/terminal-probe.js +37 -0
- package/lib/runtime/terminal-probe.js.map +1 -0
- package/lib/runtime/terminal-session.d.ts +57 -0
- package/lib/runtime/terminal-session.js +164 -0
- package/lib/runtime/terminal-session.js.map +1 -0
- package/lib/runtime/terminal-state.d.ts +29 -0
- package/lib/runtime/terminal-state.js +62 -0
- package/lib/runtime/terminal-state.js.map +1 -0
- package/lib/runtime/tool-presentation.js +50 -14
- package/lib/runtime/tool-presentation.js.map +1 -1
- package/lib/session/external-agents.d.ts +5 -0
- package/lib/session/external-agents.js +27 -0
- package/lib/session/external-agents.js.map +1 -0
- package/lib/session/feature-toggles.d.ts +1 -1
- package/lib/session/feature-toggles.js +1 -1
- package/lib/session/interaction-adapter.d.ts +1 -6
- package/lib/session/interaction-adapter.js +95 -18
- package/lib/session/interaction-adapter.js.map +1 -1
- package/lib/session/message-queue.js +1 -1
- package/lib/session/message-queue.js.map +1 -1
- package/lib/session/model-readiness.d.ts +16 -0
- package/lib/session/model-readiness.js +43 -0
- package/lib/session/model-readiness.js.map +1 -0
- package/lib/session/package-metadata.d.ts +8 -0
- package/lib/session/package-metadata.js +8 -0
- package/lib/session/package-metadata.js.map +1 -1
- package/lib/session/project-context.d.ts +5 -0
- package/lib/session/project-context.js +36 -0
- package/lib/session/project-context.js.map +1 -1
- package/lib/session/session-controller.d.ts +10 -13
- package/lib/session/session-controller.js +183 -98
- package/lib/session/session-controller.js.map +1 -1
- package/lib/session/session-library.js +2 -0
- package/lib/session/session-library.js.map +1 -1
- package/lib/session/session-tree.d.ts +3 -0
- package/lib/session/session-tree.js +3 -1
- package/lib/session/session-tree.js.map +1 -1
- package/lib/session/subagent-roster.d.ts +2 -1
- package/lib/session/subagent-roster.js +24 -3
- package/lib/session/subagent-roster.js.map +1 -1
- package/lib/session/subagent-tracker.d.ts +6 -2
- package/lib/session/subagent-tracker.js +49 -2
- package/lib/session/subagent-tracker.js.map +1 -1
- package/lib/session/tui-settings.d.ts +47 -13
- package/lib/session/tui-settings.js +76 -34
- package/lib/session/tui-settings.js.map +1 -1
- package/lib/session/working-directory.d.ts +4 -0
- package/lib/session/working-directory.js +4 -0
- package/lib/session/working-directory.js.map +1 -0
- package/lib/session/worktrees.d.ts +13 -0
- package/lib/session/worktrees.js +49 -0
- package/lib/session/worktrees.js.map +1 -0
- package/lib/views/approval-rule.d.ts +3 -0
- package/lib/views/approval-rule.js +4 -0
- package/lib/views/approval-rule.js.map +1 -0
- package/lib/views/at-complete.d.ts +8 -0
- package/lib/views/at-complete.js +64 -2
- package/lib/views/at-complete.js.map +1 -1
- package/lib/views/autocomplete.d.ts +22 -2
- package/lib/views/autocomplete.js +70 -40
- package/lib/views/autocomplete.js.map +1 -1
- package/lib/views/copy-targets.d.ts +13 -14
- package/lib/views/copy-targets.js +42 -54
- package/lib/views/copy-targets.js.map +1 -1
- package/lib/views/document-reader.js +18 -5
- package/lib/views/document-reader.js.map +1 -1
- package/lib/views/event-views.d.ts +1 -1
- package/lib/views/event-views.js +60 -6
- package/lib/views/event-views.js.map +1 -1
- package/lib/views/file-actions.d.ts +12 -0
- package/lib/views/file-actions.js +72 -0
- package/lib/views/file-actions.js.map +1 -0
- package/lib/views/history-search.js +15 -21
- package/lib/views/history-search.js.map +1 -1
- package/lib/views/hotkeys.d.ts +8 -1
- package/lib/views/hotkeys.js +53 -26
- package/lib/views/hotkeys.js.map +1 -1
- package/lib/views/list-navigation.d.ts +62 -0
- package/lib/views/list-navigation.js +73 -0
- package/lib/views/list-navigation.js.map +1 -0
- package/lib/views/list-view.d.ts +99 -0
- package/lib/views/list-view.js +165 -0
- package/lib/views/list-view.js.map +1 -0
- package/lib/views/prompt-selector.d.ts +34 -4
- package/lib/views/prompt-selector.js +270 -134
- package/lib/views/prompt-selector.js.map +1 -1
- package/lib/views/session-files.d.ts +1 -2
- package/lib/views/session-files.js +1 -11
- package/lib/views/session-files.js.map +1 -1
- package/lib/views/settings-list.d.ts +51 -10
- package/lib/views/settings-list.js +267 -315
- package/lib/views/settings-list.js.map +1 -1
- package/lib/views/trajectory-timeline.d.ts +72 -0
- package/lib/views/trajectory-timeline.js +133 -0
- package/lib/views/trajectory-timeline.js.map +1 -0
- package/lib/views/trajectory.d.ts +15 -4
- package/lib/views/trajectory.js +557 -123
- package/lib/views/trajectory.js.map +1 -1
- package/lib/views/transcript-export.js +9 -0
- package/lib/views/transcript-export.js.map +1 -1
- package/lib/views/transcript-render.d.ts +97 -25
- package/lib/views/transcript-render.js +542 -170
- package/lib/views/transcript-render.js.map +1 -1
- package/lib/views/transcript-search.d.ts +39 -6
- package/lib/views/transcript-search.js +46 -11
- package/lib/views/transcript-search.js.map +1 -1
- package/lib/views/transcript-types.d.ts +63 -5
- package/lib/views/transcript-types.js +23 -11
- package/lib/views/transcript-types.js.map +1 -1
- package/package.json +95 -65
- package/lib/commands/loop.d.ts +0 -52
- package/lib/commands/loop.js +0 -307
- package/lib/commands/loop.js.map +0 -1
- package/lib/commands/steer.d.ts +0 -5
- package/lib/commands/steer.js +0 -24
- package/lib/commands/steer.js.map +0 -1
- package/lib/runtime/terminal-reader.d.ts +0 -11
- package/lib/runtime/terminal-reader.js +0 -87
- package/lib/runtime/terminal-reader.js.map +0 -1
- package/lib/views/agent-hub.d.ts +0 -32
- package/lib/views/agent-hub.js +0 -206
- package/lib/views/agent-hub.js.map +0 -1
- package/lib/views/copy-selector.d.ts +0 -51
- package/lib/views/copy-selector.js +0 -139
- package/lib/views/copy-selector.js.map +0 -1
|
@@ -1,83 +1,193 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Status-line customization shared by settings, persistence, and rendering.
|
|
3
|
+
*
|
|
4
|
+
* The footer is two rows of fixed copy. This module owns *which* parts of those
|
|
5
|
+
* rows appear and how much of each telemetry group is shown — nothing more.
|
|
6
|
+
*
|
|
7
|
+
* There used to be a layout engine here: twelve independently placed items, each
|
|
8
|
+
* with its own colour, its own column, and two levels of ordering, plus a legacy
|
|
9
|
+
* `metrics` colour slot for groups that had no colour of their own. That is a
|
|
10
|
+
* page of settings for a two-line footer, and it asked the reader to decide
|
|
11
|
+
* things the footer could decide better. The reader now picks a density, and can
|
|
12
|
+
* turn individual telemetry groups off when a terminal is narrow or a metric is
|
|
13
|
+
* not interesting to them.
|
|
14
|
+
*
|
|
3
15
|
* @module @agi-fans/dsh-tui/status-config
|
|
4
16
|
*/
|
|
5
17
|
import type { VolatileSnapshot } from '@deepseek-ai/cordis';
|
|
6
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* Telemetry groups on the second line, in the order they are shown.
|
|
20
|
+
*
|
|
21
|
+
* The order is fixed and follows the priority stated in `AGENTS.md`: cache,
|
|
22
|
+
* tokens, and latency first because they say how the turn is going; durations
|
|
23
|
+
* second; turn and step counts last, because they are the least actionable.
|
|
24
|
+
*/
|
|
7
25
|
export declare const STATUS_GROUP_IDS: readonly ["context", "cache", "tokens", "speed", "durations", "counts"];
|
|
8
26
|
export type StatusGroupId = (typeof STATUS_GROUP_IDS)[number];
|
|
9
27
|
/** First-line pieces: model, reasoning effort, workspace path, Git branch, and session title. */
|
|
10
28
|
export declare const STATUS_META_IDS: readonly ["model", "effort", "path", "git", "session"];
|
|
11
29
|
export type StatusMetaId = (typeof STATUS_META_IDS)[number];
|
|
12
|
-
/** Every
|
|
30
|
+
/** Every part of the footer a reader can show or hide. */
|
|
13
31
|
export declare const STATUS_ITEM_IDS: readonly ["model", "effort", "path", "git", "session", "context", "cache", "tokens", "speed", "durations", "counts"];
|
|
14
32
|
export type StatusItemId = (typeof STATUS_ITEM_IDS)[number];
|
|
15
33
|
export declare const STATUS_LABEL_STYLES: readonly ["compact", "full"];
|
|
16
34
|
export type StatusLabelStyle = (typeof STATUS_LABEL_STYLES)[number];
|
|
35
|
+
/** How context occupancy is written, which is a rendering choice, not a layout one. */
|
|
17
36
|
export declare const STATUS_CONTEXT_STYLES: readonly ["percent", "bar", "tokens", "detailed"];
|
|
18
37
|
export type StatusContextStyle = (typeof STATUS_CONTEXT_STYLES)[number];
|
|
19
38
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
39
|
+
* How much the footer says.
|
|
40
|
+
*
|
|
41
|
+
* A density is the whole vocabulary now: three whole-footer shapes a reader can
|
|
42
|
+
* recognize, instead of twelve items they have to assemble. Individual groups
|
|
43
|
+
* can still be hidden on top of one, which is the one per-item decision that
|
|
44
|
+
* survives — "I do not care about this number" is real, "put this number on the
|
|
45
|
+
* left in accent green" is chrome nobody asked for.
|
|
46
|
+
*/
|
|
47
|
+
export declare const STATUS_DENSITIES: readonly ["minimal", "standard", "verbose"];
|
|
48
|
+
export type StatusDensity = (typeof STATUS_DENSITIES)[number];
|
|
49
|
+
/**
|
|
50
|
+
* Which telemetry row each group is drawn on.
|
|
51
|
+
*
|
|
52
|
+
* Two rows exist so the widest density can state everything without dropping
|
|
53
|
+
* anything: the first row is the window and the turn in flight, the second is
|
|
54
|
+
* what the session has accumulated. `minimal` and `standard` only fill the first
|
|
55
|
+
* row, so their footer stays two lines; the row is a property of the group, not
|
|
56
|
+
* of the density, so nothing moves between rows when the density changes.
|
|
57
|
+
*/
|
|
58
|
+
export declare const STATUS_ROWS: readonly (readonly StatusGroupId[])[];
|
|
59
|
+
/**
|
|
60
|
+
* Groups drawn against the left edge of their row.
|
|
61
|
+
*
|
|
62
|
+
* A row answers two questions from opposite edges, and each side keeps its
|
|
63
|
+
* meaning down the footer: occupancy and the time already spent read on the
|
|
64
|
+
* left, throughput and the count of work done on the right.
|
|
65
|
+
*/
|
|
66
|
+
export declare const STATUS_LEFT_GROUPS: readonly StatusGroupId[];
|
|
67
|
+
/** Which telemetry row a group is drawn on; 0 is the row under the composer. */
|
|
68
|
+
export declare function statusGroupRow(id: StatusGroupId): number;
|
|
69
|
+
/** Which side of its row a group is drawn on. */
|
|
70
|
+
export declare function statusGroupSide(id: StatusGroupId): 'left' | 'right';
|
|
71
|
+
/** Which groups each density shows, in footer order. */
|
|
72
|
+
export declare const DENSITY_GROUPS: Readonly<Record<StatusDensity, readonly StatusGroupId[]>>;
|
|
73
|
+
/** Which first-line pieces each density shows. */
|
|
74
|
+
export declare const DENSITY_META: Readonly<Record<StatusDensity, readonly StatusMetaId[]>>;
|
|
75
|
+
/** The label style each density defaults to. */
|
|
76
|
+
export declare const DENSITY_LABELS: Readonly<Record<StatusDensity, StatusLabelStyle>>;
|
|
77
|
+
/** The context representation each density defaults to. */
|
|
78
|
+
export declare const DENSITY_CONTEXT: Readonly<Record<StatusDensity, StatusContextStyle>>;
|
|
79
|
+
export declare const DEFAULT_STATUS_DENSITY: StatusDensity;
|
|
80
|
+
/**
|
|
81
|
+
* Stored status-line input.
|
|
82
|
+
*
|
|
83
|
+
* `density` is the whole user-facing decision. `meta` and `groups` are narrowings
|
|
84
|
+
* on top of it: a reader who turned a number off keeps it off across densities,
|
|
85
|
+
* because hiding something is a statement about the number, not about the layout.
|
|
22
86
|
*/
|
|
23
|
-
export declare const STATUS_COLOR_SLOTS: readonly ["model", "effort", "path", "git", "session", "context", "cache", "tokens", "speed", "durations", "counts", "metrics"];
|
|
24
|
-
export type StatusColorSlot = (typeof STATUS_COLOR_SLOTS)[number];
|
|
25
|
-
/** Theme tokens offered for a status item. `default` keeps the built-in hierarchy. */
|
|
26
|
-
export declare const STATUS_COLOR_TOKENS: readonly ["default", "text", "muted", "accent", "success", "warning", "border", "label"];
|
|
27
|
-
export type StatusColorToken = (typeof STATUS_COLOR_TOKENS)[number];
|
|
28
|
-
/** Footer column an item can occupy. */
|
|
29
|
-
export declare const STATUS_SIDES: readonly ["left", "right"];
|
|
30
|
-
export type StatusSide = (typeof STATUS_SIDES)[number];
|
|
31
|
-
export declare const DEFAULT_STATUS_SIDES: Record<StatusItemId, StatusSide>;
|
|
32
|
-
/** Per-item color choices. Omitted items keep their built-in tone. */
|
|
33
|
-
export type StatusBarColors = Partial<Record<StatusColorSlot, StatusColorToken>>;
|
|
34
|
-
/** User-owned status-line layout. Missing `groups`/`meta` are hidden; `order` retains their slots. */
|
|
35
87
|
export interface StatusBarConfig {
|
|
88
|
+
density: StatusDensity;
|
|
89
|
+
/**
|
|
90
|
+
* Whether the second line is drawn at all.
|
|
91
|
+
*
|
|
92
|
+
* Kept as its own field rather than expressed as "every group hidden": hiding
|
|
93
|
+
* all of them and calling that off would forget what to bring back when the
|
|
94
|
+
* reader turns telemetry on again.
|
|
95
|
+
*/
|
|
96
|
+
enabled?: boolean;
|
|
97
|
+
/** Pieces the reader hid, on top of what the density shows. */
|
|
98
|
+
hidden: StatusItemId[];
|
|
99
|
+
/**
|
|
100
|
+
* Pieces the reader added beyond what the density shows.
|
|
101
|
+
*
|
|
102
|
+
* Without this, a part the density omits could not be turned on at all: `Space`
|
|
103
|
+
* on it was a no-op, while the row still said `hidden` — a control that looked
|
|
104
|
+
* broken. Positive and negative narrowing are both deltas from the density, so
|
|
105
|
+
* changing the density still changes everything the reader has not overruled.
|
|
106
|
+
*/
|
|
107
|
+
shown: StatusItemId[];
|
|
108
|
+
}
|
|
109
|
+
/** A status-line document, including every field earlier releases wrote. */
|
|
110
|
+
export type StatusBarInput = Partial<VolatileSnapshot<StatusBarConfig>> & {
|
|
111
|
+
/** Earlier releases spelled the whole layout out; read only while migrating. */
|
|
112
|
+
enabled?: boolean;
|
|
113
|
+
labels?: StatusLabelStyle;
|
|
114
|
+
contextStyle?: StatusContextStyle;
|
|
115
|
+
groups?: readonly StatusGroupId[];
|
|
116
|
+
order?: readonly StatusGroupId[];
|
|
117
|
+
meta?: readonly StatusMetaId[];
|
|
118
|
+
metaOrder?: readonly StatusMetaId[];
|
|
119
|
+
colors?: Readonly<Record<string, string>>;
|
|
120
|
+
sides?: Readonly<Record<string, string>>;
|
|
121
|
+
};
|
|
122
|
+
/** What the renderer consumes: the density expanded, with narrowings applied. */
|
|
123
|
+
export interface ResolvedStatusBarConfig {
|
|
124
|
+
density: StatusDensity;
|
|
125
|
+
/** False when the reader hid the whole second line. */
|
|
36
126
|
enabled: boolean;
|
|
37
127
|
labels: StatusLabelStyle;
|
|
38
|
-
/** Context occupancy representation; omitted preferences default to percent. */
|
|
39
|
-
contextStyle?: StatusContextStyle;
|
|
40
|
-
groups: StatusGroupId[];
|
|
41
|
-
/** Complete visual order, including hidden groups. Absent in legacy settings. */
|
|
42
|
-
order?: StatusGroupId[];
|
|
43
|
-
/** Visible first-line items. Absent means every meta item is shown. */
|
|
44
|
-
meta?: StatusMetaId[];
|
|
45
|
-
/** Complete first-line order, including hidden meta items. */
|
|
46
|
-
metaOrder?: StatusMetaId[];
|
|
47
|
-
/** Optional per-item colors for the two-line footer. */
|
|
48
|
-
colors?: StatusBarColors;
|
|
49
|
-
/** Optional left/right column for each item. */
|
|
50
|
-
sides?: Partial<Record<StatusItemId, StatusSide>>;
|
|
51
|
-
}
|
|
52
|
-
/** Stored status-line input: a settings document value or a frozen config snapshot. */
|
|
53
|
-
export type StatusBarInput = Partial<VolatileSnapshot<StatusBarConfig>>;
|
|
54
|
-
/** Normalized layout always carries complete orders, colors, and columns. */
|
|
55
|
-
export interface ResolvedStatusBarConfig extends StatusBarConfig {
|
|
56
128
|
contextStyle: StatusContextStyle;
|
|
57
|
-
order
|
|
129
|
+
/** Visible telemetry groups, in fixed footer order. */
|
|
130
|
+
groups: StatusGroupId[];
|
|
131
|
+
/** Visible first-line pieces, in fixed footer order. */
|
|
58
132
|
meta: StatusMetaId[];
|
|
59
|
-
metaOrder: StatusMetaId[];
|
|
60
|
-
colors: Required<StatusBarColors>;
|
|
61
|
-
sides: Record<StatusItemId, StatusSide>;
|
|
62
133
|
}
|
|
63
|
-
/**
|
|
134
|
+
/** Earlier releases stored a three-value `statusPreset` beside the layout. */
|
|
64
135
|
export declare const STATUS_PRESETS: readonly ["minimal", "compact", "full"];
|
|
65
136
|
export type StatusPreset = (typeof STATUS_PRESETS)[number];
|
|
137
|
+
/** Everything shown at the shipped density. */
|
|
66
138
|
export declare const DEFAULT_STATUS_GROUPS: readonly StatusGroupId[];
|
|
67
|
-
/**
|
|
68
|
-
* Session title is offered but off by default: adding it to the first line
|
|
69
|
-
* would push narrow terminals into degradation sooner. The terminal window
|
|
70
|
-
* title carries it unconditionally.
|
|
71
|
-
*/
|
|
72
139
|
export declare const DEFAULT_STATUS_META: readonly StatusMetaId[];
|
|
73
|
-
export declare const DEFAULT_STATUS_COLORS: Required<StatusBarColors>;
|
|
74
|
-
/** Return a fresh default so callers can safely replace its group list. */
|
|
75
|
-
export declare function defaultStatusBarConfig(): ResolvedStatusBarConfig;
|
|
76
|
-
export declare function isStatusMetaId(value: unknown): value is StatusMetaId;
|
|
77
140
|
export declare function isStatusItemId(value: unknown): value is StatusItemId;
|
|
78
|
-
export declare function
|
|
141
|
+
export declare function isStatusMetaId(value: unknown): value is StatusMetaId;
|
|
142
|
+
export declare function isStatusGroupId(value: unknown): value is StatusGroupId;
|
|
79
143
|
/**
|
|
80
|
-
* Normalize persisted input at the single configuration seam.
|
|
81
|
-
*
|
|
144
|
+
* Normalize persisted input at the single configuration seam.
|
|
145
|
+
*
|
|
146
|
+
* A document written by an earlier release described its layout item by item.
|
|
147
|
+
* Rather than fail it or resurrect the engine, the shape it asked for is reduced
|
|
148
|
+
* to the nearest density: what was visible decides the narrowing, and the retired
|
|
149
|
+
* per-item colour and column choices are dropped, because both shipped palettes
|
|
150
|
+
* already paint them the right way.
|
|
82
151
|
*/
|
|
83
152
|
export declare function resolveStatusBarConfig(config?: StatusBarInput, legacyPreset?: StatusPreset): ResolvedStatusBarConfig;
|
|
153
|
+
/**
|
|
154
|
+
* What a stored document asks to hide, relative to its density.
|
|
155
|
+
*
|
|
156
|
+
* Exported because writing the document back needs the same reading: a caller
|
|
157
|
+
* that reconstructed the narrowing from the *rendered* footer instead would turn
|
|
158
|
+
* every part its density happens to omit into a permanent hiding, and changing
|
|
159
|
+
* the density afterwards would no longer restore them.
|
|
160
|
+
*/
|
|
161
|
+
export declare function statusNarrowing(config: StatusBarInput | undefined, density: StatusDensity): StatusItemId[];
|
|
162
|
+
/** What a stored document adds beyond its density. */
|
|
163
|
+
export declare function statusAdditions(config: StatusBarInput | undefined): StatusItemId[];
|
|
164
|
+
/**
|
|
165
|
+
* True when a document has already been expanded.
|
|
166
|
+
*
|
|
167
|
+
* `resolveStatusBarConfig` is idempotent only if it can tell the two shapes
|
|
168
|
+
* apart: an expanded config carries `groups`/`meta`, which a stored document
|
|
169
|
+
* never does. Without this the renderer re-resolved its own input and silently
|
|
170
|
+
* dropped every narrowing, so a hidden group came back.
|
|
171
|
+
*/
|
|
172
|
+
export declare function isResolvedStatusBarConfig(config: ResolvedStatusBarConfig | StatusBarInput): config is ResolvedStatusBarConfig;
|
|
173
|
+
/**
|
|
174
|
+
* The document a resolved config came from.
|
|
175
|
+
*
|
|
176
|
+
* Visibility cannot say which of two reasons a part is missing: the reader hid
|
|
177
|
+
* it, or the density never included it. Rebuilding the document from what the
|
|
178
|
+
* footer shows therefore has to keep them apart — a part the density omits must
|
|
179
|
+
* stay out of `hidden`, or raising the density would silently do nothing — and it
|
|
180
|
+
* is the only way a caller that holds the resolved form (the provider holds the
|
|
181
|
+
* footer it is drawing) can hand the document back without losing a choice.
|
|
182
|
+
*/
|
|
183
|
+
export declare function statusBarDocument(config: ResolvedStatusBarConfig): StatusBarConfig;
|
|
184
|
+
/** True when the footer shows this part at the current narrowing. */
|
|
185
|
+
export declare function statusItemVisible(config: ResolvedStatusBarConfig, id: StatusItemId): boolean;
|
|
186
|
+
/**
|
|
187
|
+
* The same document with one part turned on or off.
|
|
188
|
+
*
|
|
189
|
+
* Both directions are deltas from the density, so a part the density omits can
|
|
190
|
+
* be added and a part it includes can be removed, without either one rewriting
|
|
191
|
+
* the other's state.
|
|
192
|
+
*/
|
|
193
|
+
export declare function toggleStatusItem(config: StatusBarConfig, id: StatusItemId): StatusBarConfig;
|
|
@@ -1,159 +1,270 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Status-line customization shared by settings, persistence, and rendering.
|
|
3
|
+
*
|
|
4
|
+
* The footer is two rows of fixed copy. This module owns *which* parts of those
|
|
5
|
+
* rows appear and how much of each telemetry group is shown — nothing more.
|
|
6
|
+
*
|
|
7
|
+
* There used to be a layout engine here: twelve independently placed items, each
|
|
8
|
+
* with its own colour, its own column, and two levels of ordering, plus a legacy
|
|
9
|
+
* `metrics` colour slot for groups that had no colour of their own. That is a
|
|
10
|
+
* page of settings for a two-line footer, and it asked the reader to decide
|
|
11
|
+
* things the footer could decide better. The reader now picks a density, and can
|
|
12
|
+
* turn individual telemetry groups off when a terminal is narrow or a metric is
|
|
13
|
+
* not interesting to them.
|
|
14
|
+
*
|
|
3
15
|
* @module @agi-fans/dsh-tui/status-config
|
|
4
16
|
*/
|
|
5
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* Telemetry groups on the second line, in the order they are shown.
|
|
19
|
+
*
|
|
20
|
+
* The order is fixed and follows the priority stated in `AGENTS.md`: cache,
|
|
21
|
+
* tokens, and latency first because they say how the turn is going; durations
|
|
22
|
+
* second; turn and step counts last, because they are the least actionable.
|
|
23
|
+
*/
|
|
6
24
|
export const STATUS_GROUP_IDS = ['context', 'cache', 'tokens', 'speed', 'durations', 'counts'];
|
|
7
25
|
/** First-line pieces: model, reasoning effort, workspace path, Git branch, and session title. */
|
|
8
26
|
export const STATUS_META_IDS = ['model', 'effort', 'path', 'git', 'session'];
|
|
9
|
-
/** Every
|
|
27
|
+
/** Every part of the footer a reader can show or hide. */
|
|
10
28
|
export const STATUS_ITEM_IDS = [...STATUS_META_IDS, ...STATUS_GROUP_IDS];
|
|
11
29
|
export const STATUS_LABEL_STYLES = ['compact', 'full'];
|
|
30
|
+
/** How context occupancy is written, which is a rendering choice, not a layout one. */
|
|
12
31
|
export const STATUS_CONTEXT_STYLES = ['percent', 'bar', 'tokens', 'detailed'];
|
|
13
32
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
33
|
+
* How much the footer says.
|
|
34
|
+
*
|
|
35
|
+
* A density is the whole vocabulary now: three whole-footer shapes a reader can
|
|
36
|
+
* recognize, instead of twelve items they have to assemble. Individual groups
|
|
37
|
+
* can still be hidden on top of one, which is the one per-item decision that
|
|
38
|
+
* survives — "I do not care about this number" is real, "put this number on the
|
|
39
|
+
* left in accent green" is chrome nobody asked for.
|
|
16
40
|
*/
|
|
17
|
-
export const
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
context
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
speed: 'left',
|
|
32
|
-
durations: 'right',
|
|
33
|
-
counts: 'right',
|
|
34
|
-
};
|
|
35
|
-
/** Legacy value accepted while existing settings documents migrate. */
|
|
36
|
-
export const STATUS_PRESETS = ['minimal', 'compact', 'full'];
|
|
37
|
-
export const DEFAULT_STATUS_GROUPS = STATUS_GROUP_IDS;
|
|
41
|
+
export const STATUS_DENSITIES = ['minimal', 'standard', 'verbose'];
|
|
42
|
+
/**
|
|
43
|
+
* Which telemetry row each group is drawn on.
|
|
44
|
+
*
|
|
45
|
+
* Two rows exist so the widest density can state everything without dropping
|
|
46
|
+
* anything: the first row is the window and the turn in flight, the second is
|
|
47
|
+
* what the session has accumulated. `minimal` and `standard` only fill the first
|
|
48
|
+
* row, so their footer stays two lines; the row is a property of the group, not
|
|
49
|
+
* of the density, so nothing moves between rows when the density changes.
|
|
50
|
+
*/
|
|
51
|
+
export const STATUS_ROWS = [
|
|
52
|
+
['context', 'cache', 'tokens', 'speed'],
|
|
53
|
+
['durations', 'counts'],
|
|
54
|
+
];
|
|
38
55
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
56
|
+
* Groups drawn against the left edge of their row.
|
|
57
|
+
*
|
|
58
|
+
* A row answers two questions from opposite edges, and each side keeps its
|
|
59
|
+
* meaning down the footer: occupancy and the time already spent read on the
|
|
60
|
+
* left, throughput and the count of work done on the right.
|
|
42
61
|
*/
|
|
43
|
-
export const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
62
|
+
export const STATUS_LEFT_GROUPS = ['context', 'cache', 'durations'];
|
|
63
|
+
/** Which telemetry row a group is drawn on; 0 is the row under the composer. */
|
|
64
|
+
export function statusGroupRow(id) {
|
|
65
|
+
const row = STATUS_ROWS.findIndex(groups => groups.includes(id));
|
|
66
|
+
return row < 0 ? 0 : row;
|
|
67
|
+
}
|
|
68
|
+
/** Which side of its row a group is drawn on. */
|
|
69
|
+
export function statusGroupSide(id) {
|
|
70
|
+
return STATUS_LEFT_GROUPS.includes(id) ? 'left' : 'right';
|
|
71
|
+
}
|
|
72
|
+
/** Which groups each density shows, in footer order. */
|
|
73
|
+
export const DENSITY_GROUPS = {
|
|
74
|
+
/** Occupancy only: how full the window is and how much of it came from cache. */
|
|
75
|
+
minimal: ['context', 'cache'],
|
|
76
|
+
/** Adds latency — the first number that says a turn feels slow rather than long. */
|
|
77
|
+
standard: ['context', 'cache', 'speed'],
|
|
78
|
+
/** Every group, with full labels and the detailed context form. */
|
|
79
|
+
verbose: [...STATUS_GROUP_IDS],
|
|
57
80
|
};
|
|
58
|
-
/**
|
|
59
|
-
export
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
81
|
+
/** Which first-line pieces each density shows. */
|
|
82
|
+
export const DENSITY_META = {
|
|
83
|
+
/** Where the model is and where the work is; the footer's original two facts. */
|
|
84
|
+
minimal: ['model', 'path'],
|
|
85
|
+
standard: ['model', 'effort', 'path', 'git'],
|
|
86
|
+
/** `session` joins at the widest setting; the terminal title shows it anyway. */
|
|
87
|
+
verbose: ['model', 'effort', 'path', 'git', 'session'],
|
|
88
|
+
};
|
|
89
|
+
/** The label style each density defaults to. */
|
|
90
|
+
export const DENSITY_LABELS = {
|
|
91
|
+
minimal: 'compact',
|
|
92
|
+
standard: 'compact',
|
|
93
|
+
verbose: 'full',
|
|
94
|
+
};
|
|
95
|
+
/** The context representation each density defaults to. */
|
|
96
|
+
export const DENSITY_CONTEXT = {
|
|
97
|
+
minimal: 'percent',
|
|
98
|
+
standard: 'percent',
|
|
99
|
+
verbose: 'detailed',
|
|
100
|
+
};
|
|
101
|
+
export const DEFAULT_STATUS_DENSITY = 'standard';
|
|
102
|
+
/** Earlier releases stored a three-value `statusPreset` beside the layout. */
|
|
103
|
+
export const STATUS_PRESETS = ['minimal', 'compact', 'full'];
|
|
104
|
+
/** Everything shown at the shipped density. */
|
|
105
|
+
export const DEFAULT_STATUS_GROUPS = DENSITY_GROUPS[DEFAULT_STATUS_DENSITY];
|
|
106
|
+
export const DEFAULT_STATUS_META = DENSITY_META[DEFAULT_STATUS_DENSITY];
|
|
107
|
+
function isStatusDensity(value) {
|
|
108
|
+
return typeof value === 'string' && STATUS_DENSITIES.includes(value);
|
|
73
109
|
}
|
|
74
|
-
function
|
|
75
|
-
return typeof value === 'string' &&
|
|
110
|
+
export function isStatusItemId(value) {
|
|
111
|
+
return typeof value === 'string' && STATUS_ITEM_IDS.includes(value);
|
|
76
112
|
}
|
|
77
113
|
export function isStatusMetaId(value) {
|
|
78
114
|
return typeof value === 'string' && STATUS_META_IDS.includes(value);
|
|
79
115
|
}
|
|
80
|
-
export function
|
|
81
|
-
return typeof value === 'string' &&
|
|
116
|
+
export function isStatusGroupId(value) {
|
|
117
|
+
return typeof value === 'string' && STATUS_GROUP_IDS.includes(value);
|
|
82
118
|
}
|
|
83
|
-
|
|
84
|
-
|
|
119
|
+
/**
|
|
120
|
+
* Map a retired `statusPreset` onto a density.
|
|
121
|
+
*
|
|
122
|
+
* `minimal` meant "no second line"; that is now `minimal` density with telemetry
|
|
123
|
+
* hidden, which is the same footer the reader had. `full` meant long labels,
|
|
124
|
+
* which is what `verbose` says.
|
|
125
|
+
*/
|
|
126
|
+
function densityFromPreset(preset) {
|
|
127
|
+
if (preset === 'minimal')
|
|
128
|
+
return { density: 'minimal', enabled: false };
|
|
129
|
+
if (preset === 'full')
|
|
130
|
+
return { density: 'verbose', enabled: true };
|
|
131
|
+
return { density: DEFAULT_STATUS_DENSITY, enabled: true };
|
|
85
132
|
}
|
|
86
|
-
|
|
87
|
-
|
|
133
|
+
/**
|
|
134
|
+
* Normalize persisted input at the single configuration seam.
|
|
135
|
+
*
|
|
136
|
+
* A document written by an earlier release described its layout item by item.
|
|
137
|
+
* Rather than fail it or resurrect the engine, the shape it asked for is reduced
|
|
138
|
+
* to the nearest density: what was visible decides the narrowing, and the retired
|
|
139
|
+
* per-item colour and column choices are dropped, because both shipped palettes
|
|
140
|
+
* already paint them the right way.
|
|
141
|
+
*/
|
|
142
|
+
export function resolveStatusBarConfig(config, legacyPreset) {
|
|
143
|
+
const fallback = densityFromPreset(legacyPreset);
|
|
144
|
+
if (config === undefined)
|
|
145
|
+
return expand(fallback.density, { enabled: fallback.enabled, hidden: [] });
|
|
146
|
+
const density = isStatusDensity(config.density) ? config.density : fallback.density;
|
|
147
|
+
/**
|
|
148
|
+
* A legacy document listed what it wanted shown; a current one lists what it
|
|
149
|
+
* wants hidden. Both cannot be read from `density`: the schema defaults that
|
|
150
|
+
* field, so an old document arrives here already looking current, while the
|
|
151
|
+
* layout arrays only exist on an old one.
|
|
152
|
+
*/
|
|
153
|
+
const enabled = typeof config.enabled === 'boolean' ? config.enabled : fallback.enabled;
|
|
154
|
+
return expand(density, { enabled, hidden: statusNarrowing(config, density), shown: statusAdditions(config) });
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* What a stored document asks to hide, relative to its density.
|
|
158
|
+
*
|
|
159
|
+
* Exported because writing the document back needs the same reading: a caller
|
|
160
|
+
* that reconstructed the narrowing from the *rendered* footer instead would turn
|
|
161
|
+
* every part its density happens to omit into a permanent hiding, and changing
|
|
162
|
+
* the density afterwards would no longer restore them.
|
|
163
|
+
*/
|
|
164
|
+
export function statusNarrowing(config, density) {
|
|
165
|
+
if (config === undefined)
|
|
166
|
+
return [];
|
|
167
|
+
const legacyLayout = config.groups !== undefined || config.meta !== undefined
|
|
168
|
+
|| config.order !== undefined || config.metaOrder !== undefined;
|
|
169
|
+
return legacyLayout
|
|
170
|
+
? legacyHidden(config, density)
|
|
171
|
+
: [...new Set((config.hidden ?? []).filter(isStatusItemId))];
|
|
88
172
|
}
|
|
89
|
-
|
|
90
|
-
|
|
173
|
+
/** What a stored document adds beyond its density. */
|
|
174
|
+
export function statusAdditions(config) {
|
|
175
|
+
return [...new Set((config?.shown ?? []).filter(isStatusItemId))];
|
|
91
176
|
}
|
|
92
|
-
|
|
93
|
-
|
|
177
|
+
/** What an earlier release's explicit lists hid, expressed as a narrowing. */
|
|
178
|
+
function legacyHidden(config, density) {
|
|
179
|
+
const shownGroups = config.groups === undefined ? DENSITY_GROUPS[density] : config.groups;
|
|
180
|
+
const shownMeta = config.meta === undefined ? DENSITY_META[density] : config.meta;
|
|
181
|
+
const hidden = [];
|
|
182
|
+
for (const id of STATUS_GROUP_IDS)
|
|
183
|
+
if (!shownGroups.includes(id))
|
|
184
|
+
hidden.push(id);
|
|
185
|
+
for (const id of STATUS_META_IDS)
|
|
186
|
+
if (!shownMeta.includes(id))
|
|
187
|
+
hidden.push(id);
|
|
188
|
+
return hidden;
|
|
94
189
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
190
|
+
/**
|
|
191
|
+
* True when a document has already been expanded.
|
|
192
|
+
*
|
|
193
|
+
* `resolveStatusBarConfig` is idempotent only if it can tell the two shapes
|
|
194
|
+
* apart: an expanded config carries `groups`/`meta`, which a stored document
|
|
195
|
+
* never does. Without this the renderer re-resolved its own input and silently
|
|
196
|
+
* dropped every narrowing, so a hidden group came back.
|
|
197
|
+
*/
|
|
198
|
+
export function isResolvedStatusBarConfig(config) {
|
|
199
|
+
return Array.isArray(config.groups)
|
|
200
|
+
&& Array.isArray(config.meta)
|
|
201
|
+
&& typeof config.enabled === 'boolean';
|
|
202
|
+
}
|
|
203
|
+
/** Expand one density plus its deltas into the renderer's view. */
|
|
204
|
+
function expand(density, options) {
|
|
205
|
+
const hidden = new Set(options.hidden);
|
|
206
|
+
const shown = new Set(options.shown ?? []);
|
|
207
|
+
// Catalog order, so a part the reader added sits where its family sits rather
|
|
208
|
+
// than at the end of the row where it would move every time it is toggled.
|
|
209
|
+
const visible = (catalog, base) => catalog.filter(id => (base.includes(id) || shown.has(id)) && !hidden.has(id));
|
|
210
|
+
return {
|
|
211
|
+
density,
|
|
212
|
+
enabled: options.enabled,
|
|
213
|
+
labels: DENSITY_LABELS[density],
|
|
214
|
+
contextStyle: DENSITY_CONTEXT[density],
|
|
215
|
+
groups: visible(STATUS_GROUP_IDS, DENSITY_GROUPS[density]),
|
|
216
|
+
meta: visible(STATUS_META_IDS, DENSITY_META[density]),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* The document a resolved config came from.
|
|
221
|
+
*
|
|
222
|
+
* Visibility cannot say which of two reasons a part is missing: the reader hid
|
|
223
|
+
* it, or the density never included it. Rebuilding the document from what the
|
|
224
|
+
* footer shows therefore has to keep them apart — a part the density omits must
|
|
225
|
+
* stay out of `hidden`, or raising the density would silently do nothing — and it
|
|
226
|
+
* is the only way a caller that holds the resolved form (the provider holds the
|
|
227
|
+
* footer it is drawing) can hand the document back without losing a choice.
|
|
228
|
+
*/
|
|
229
|
+
export function statusBarDocument(config) {
|
|
230
|
+
const densityHas = (id) => isStatusMetaId(id) ? DENSITY_META[config.density].includes(id) : DENSITY_GROUPS[config.density].includes(id);
|
|
231
|
+
const hidden = [];
|
|
232
|
+
const shown = [];
|
|
99
233
|
for (const id of STATUS_ITEM_IDS) {
|
|
100
|
-
const
|
|
101
|
-
if (
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const ordered = [...new Set(preferred.filter((id) => ids.includes(id)))];
|
|
108
|
-
return [...ordered, ...ids.filter(id => !ordered.includes(id))];
|
|
109
|
-
}
|
|
110
|
-
function resolveStatusColors(colors) {
|
|
111
|
-
const resolved = { ...DEFAULT_STATUS_COLORS };
|
|
112
|
-
if (colors === undefined)
|
|
113
|
-
return resolved;
|
|
114
|
-
for (const slot of STATUS_COLOR_SLOTS) {
|
|
115
|
-
const token = colors[slot];
|
|
116
|
-
if (isStatusColorToken(token))
|
|
117
|
-
resolved[slot] = token;
|
|
118
|
-
}
|
|
119
|
-
const legacyMetrics = resolved.metrics;
|
|
120
|
-
if (legacyMetrics !== 'default') {
|
|
121
|
-
for (const group of STATUS_GROUP_IDS) {
|
|
122
|
-
if (colors[group] === undefined)
|
|
123
|
-
resolved[group] = legacyMetrics;
|
|
124
|
-
}
|
|
234
|
+
const visible = statusItemVisible(config, id);
|
|
235
|
+
if (visible === densityHas(id))
|
|
236
|
+
continue;
|
|
237
|
+
if (visible)
|
|
238
|
+
shown.push(id);
|
|
239
|
+
else
|
|
240
|
+
hidden.push(id);
|
|
125
241
|
}
|
|
126
|
-
return
|
|
242
|
+
return { density: config.density, hidden, shown, enabled: config.enabled };
|
|
243
|
+
}
|
|
244
|
+
/** True when the footer shows this part at the current narrowing. */
|
|
245
|
+
export function statusItemVisible(config, id) {
|
|
246
|
+
return isStatusMetaId(id) ? config.meta.includes(id) : config.groups.includes(id);
|
|
127
247
|
}
|
|
128
248
|
/**
|
|
129
|
-
*
|
|
130
|
-
*
|
|
249
|
+
* The same document with one part turned on or off.
|
|
250
|
+
*
|
|
251
|
+
* Both directions are deltas from the density, so a part the density omits can
|
|
252
|
+
* be added and a part it includes can be removed, without either one rewriting
|
|
253
|
+
* the other's state.
|
|
131
254
|
*/
|
|
132
|
-
export function
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
255
|
+
export function toggleStatusItem(config, id) {
|
|
256
|
+
const density = isStatusDensity(config.density) ? config.density : DEFAULT_STATUS_DENSITY;
|
|
257
|
+
const hidden = new Set((config.hidden ?? []).filter(isStatusItemId));
|
|
258
|
+
const shown = new Set((config.shown ?? []).filter(isStatusItemId));
|
|
259
|
+
const visible = statusItemVisible(expand(density, { enabled: true, hidden: [...hidden], shown: [...shown] }), id);
|
|
260
|
+
if (visible) {
|
|
261
|
+
hidden.add(id);
|
|
262
|
+
shown.delete(id);
|
|
140
263
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
: [...new Set(config.meta.filter(isStatusMetaId))];
|
|
147
|
-
return {
|
|
148
|
-
enabled: config.enabled ?? true,
|
|
149
|
-
labels: isStatusLabelStyle(config.labels) ? config.labels : 'compact',
|
|
150
|
-
contextStyle: STATUS_CONTEXT_STYLES.includes(config.contextStyle) ? config.contextStyle : 'percent',
|
|
151
|
-
groups,
|
|
152
|
-
order: completeOrder(STATUS_GROUP_IDS, config.order === undefined ? groups : config.order),
|
|
153
|
-
meta,
|
|
154
|
-
metaOrder: completeOrder(STATUS_META_IDS, config.metaOrder === undefined ? meta : config.metaOrder),
|
|
155
|
-
colors: resolveStatusColors(config.colors),
|
|
156
|
-
sides: resolveStatusSides(config.sides),
|
|
157
|
-
};
|
|
264
|
+
else {
|
|
265
|
+
shown.add(id);
|
|
266
|
+
hidden.delete(id);
|
|
267
|
+
}
|
|
268
|
+
return { ...config, hidden: [...hidden], shown: [...shown] };
|
|
158
269
|
}
|
|
159
270
|
//# sourceMappingURL=status-config.js.map
|