@agi-fans/dsh-tui 0.21.0 → 0.23.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/LICENSE +26 -0
- package/lib/CHANGELOG.md +356 -1
- package/lib/chrome/box.d.ts +32 -18
- package/lib/chrome/box.js +131 -132
- package/lib/chrome/box.js.map +1 -1
- package/lib/chrome/code-highlight.d.ts +15 -0
- package/lib/chrome/code-highlight.js +61 -5
- package/lib/chrome/code-highlight.js.map +1 -1
- package/lib/chrome/command-output.d.ts +28 -2
- package/lib/chrome/command-output.js +106 -4
- package/lib/chrome/command-output.js.map +1 -1
- package/lib/chrome/goal-bar.js +1 -1
- package/lib/chrome/goal-bar.js.map +1 -1
- package/lib/chrome/main-screen-renderer.d.ts +16 -0
- package/lib/chrome/main-screen-renderer.js +57 -8
- package/lib/chrome/main-screen-renderer.js.map +1 -1
- package/lib/chrome/markdown.d.ts +3 -3
- package/lib/chrome/markdown.js +101 -32
- package/lib/chrome/markdown.js.map +1 -1
- package/lib/chrome/md-style.d.ts +5 -2
- package/lib/chrome/md-style.js +13 -4
- package/lib/chrome/md-style.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 +37 -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 +6 -5
- package/lib/chrome/status-line.js +110 -68
- 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 +38 -10
- package/lib/chrome/theme.js +537 -542
- package/lib/chrome/theme.js.map +1 -1
- package/lib/chrome/tool-renderers.js +69 -13
- 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/commands/auth-account.d.ts +9 -0
- package/lib/commands/auth-account.js +202 -0
- package/lib/commands/auth-account.js.map +1 -0
- 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 +12 -20
- package/lib/commands/auth.js +264 -627
- package/lib/commands/auth.js.map +1 -1
- package/lib/commands/btw.d.ts +13 -1
- package/lib/commands/btw.js +37 -104
- package/lib/commands/btw.js.map +1 -1
- package/lib/commands/diff.js +23 -112
- package/lib/commands/diff.js.map +1 -1
- package/lib/commands/export.d.ts +0 -1
- package/lib/commands/export.js +98 -57
- package/lib/commands/export.js.map +1 -1
- package/lib/commands/files.d.ts +17 -1
- package/lib/commands/files.js +68 -114
- package/lib/commands/files.js.map +1 -1
- package/lib/commands/integrations.d.ts +12 -1
- package/lib/commands/integrations.js +120 -23
- package/lib/commands/integrations.js.map +1 -1
- package/lib/commands/jobs-browser.d.ts +3 -0
- package/lib/commands/jobs-browser.js +152 -0
- package/lib/commands/jobs-browser.js.map +1 -0
- package/lib/commands/jobs.d.ts +12 -8
- package/lib/commands/jobs.js +65 -14
- package/lib/commands/jobs.js.map +1 -1
- package/lib/commands/model.d.ts +3 -0
- package/lib/commands/model.js +223 -114
- package/lib/commands/model.js.map +1 -1
- package/lib/commands/open-external.d.ts +2 -0
- package/lib/commands/open-external.js +19 -0
- package/lib/commands/open-external.js.map +1 -0
- package/lib/commands/permission.js +70 -60
- package/lib/commands/permission.js.map +1 -1
- package/lib/commands/plugins.js +427 -68
- package/lib/commands/plugins.js.map +1 -1
- package/lib/commands/schedule-catalog.d.ts +12 -0
- package/lib/commands/schedule-catalog.js +41 -0
- package/lib/commands/schedule-catalog.js.map +1 -0
- package/lib/commands/schedule-history.d.ts +4 -0
- package/lib/commands/schedule-history.js +62 -0
- package/lib/commands/schedule-history.js.map +1 -0
- package/lib/commands/schedule.d.ts +16 -9
- package/lib/commands/schedule.js +226 -162
- package/lib/commands/schedule.js.map +1 -1
- package/lib/commands/session-configuration.d.ts +3 -0
- package/lib/commands/session-configuration.js +58 -32
- package/lib/commands/session-configuration.js.map +1 -1
- package/lib/commands/session.js +118 -97
- package/lib/commands/session.js.map +1 -1
- package/lib/commands/terminal.d.ts +14 -8
- package/lib/commands/terminal.js +32 -185
- 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 +226 -29
- package/lib/definition.js.map +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/input/actions.d.ts +51 -0
- package/lib/input/actions.js +123 -0
- package/lib/input/actions.js.map +1 -0
- package/lib/input/composer-files.d.ts +2 -0
- package/lib/input/composer-files.js +13 -3
- package/lib/input/composer-files.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 +12 -1
- package/lib/input/image-paste.js +86 -1
- package/lib/input/image-paste.js.map +1 -1
- package/lib/input/key-test.d.ts +5 -0
- package/lib/input/key-test.js +19 -0
- package/lib/input/key-test.js.map +1 -0
- package/lib/input/keybindings-config.d.ts +12 -5
- package/lib/input/keybindings-config.js +30 -57
- package/lib/input/keybindings-config.js.map +1 -1
- package/lib/input/keys.d.ts +18 -0
- package/lib/input/keys.js +42 -4
- 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/locale/index.d.ts +6 -0
- package/lib/locale/index.js +32 -0
- package/lib/locale/index.js.map +1 -0
- package/lib/locale/prompt.d.ts +4 -0
- package/lib/locale/prompt.js +24 -0
- package/lib/locale/prompt.js.map +1 -0
- package/lib/locale/zh.d.ts +1114 -0
- package/lib/locale/zh.js +1115 -0
- package/lib/locale/zh.js.map +1 -0
- package/lib/prompt-intents.d.ts +186 -0
- package/lib/prompt-intents.js +131 -0
- package/lib/prompt-intents.js.map +1 -0
- package/lib/runtime/account-settings.d.ts +18 -0
- package/lib/runtime/account-settings.js +241 -0
- package/lib/runtime/account-settings.js.map +1 -0
- package/lib/runtime/agent-profile.d.ts +3 -3
- package/lib/runtime/agent-profile.js +4 -4
- package/lib/runtime/agent-profile.js.map +1 -1
- package/lib/runtime/btw-policy.js +2 -1
- package/lib/runtime/btw-policy.js.map +1 -1
- package/lib/runtime/btw.js +1 -2
- package/lib/runtime/btw.js.map +1 -1
- 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.d.ts +2 -2
- package/lib/runtime/composer-images.js +7 -6
- package/lib/runtime/composer-images.js.map +1 -1
- package/lib/runtime/composer-shell.d.ts +17 -2
- package/lib/runtime/composer-shell.js +133 -41
- package/lib/runtime/composer-shell.js.map +1 -1
- package/lib/runtime/file-browser.d.ts +19 -0
- package/lib/runtime/file-browser.js +291 -0
- package/lib/runtime/file-browser.js.map +1 -0
- package/lib/runtime/file-recovery-review.d.ts +0 -1
- package/lib/runtime/file-recovery-review.js +29 -30
- package/lib/runtime/file-recovery-review.js.map +1 -1
- package/lib/runtime/file-recovery-store.js +5 -1
- package/lib/runtime/file-recovery-store.js.map +1 -1
- package/lib/runtime/file-review.d.ts +6 -9
- package/lib/runtime/file-review.js +92 -8
- package/lib/runtime/file-review.js.map +1 -1
- package/lib/runtime/help-reader.d.ts +12 -0
- package/lib/runtime/help-reader.js +50 -0
- package/lib/runtime/help-reader.js.map +1 -0
- package/lib/runtime/hook-settings.d.ts +2 -2
- package/lib/runtime/human-interaction.js +1 -1
- package/lib/runtime/human-interaction.js.map +1 -1
- package/lib/runtime/model-catalog-editor.d.ts +12 -0
- package/lib/runtime/model-catalog-editor.js +215 -0
- package/lib/runtime/model-catalog-editor.js.map +1 -0
- package/lib/runtime/model-settings.d.ts +11 -0
- package/lib/runtime/model-settings.js +404 -0
- package/lib/runtime/model-settings.js.map +1 -0
- 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 +4 -1
- package/lib/runtime/plugin-settings.js +170 -92
- package/lib/runtime/plugin-settings.js.map +1 -1
- package/lib/runtime/prompt-browser.d.ts +9 -0
- package/lib/runtime/prompt-browser.js +19 -0
- package/lib/runtime/prompt-browser.js.map +1 -0
- package/lib/runtime/provider-local.d.ts +80 -38
- package/lib/runtime/provider-local.js +2280 -683
- package/lib/runtime/provider-local.js.map +1 -1
- package/lib/runtime/reference-reader.d.ts +15 -0
- package/lib/runtime/reference-reader.js +78 -0
- package/lib/runtime/reference-reader.js.map +1 -0
- package/lib/runtime/runner.js +42 -39
- package/lib/runtime/runner.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-draft.d.ts +21 -0
- package/lib/runtime/settings-draft.js +166 -0
- package/lib/runtime/settings-draft.js.map +1 -0
- package/lib/runtime/settings-preferences.js +1 -1
- package/lib/runtime/settings-preferences.js.map +1 -1
- package/lib/runtime/startup-notices.d.ts +0 -1
- package/lib/runtime/startup-notices.js +35 -4
- package/lib/runtime/startup-notices.js.map +1 -1
- package/lib/runtime/subagent-model-selection.js +2 -1
- package/lib/runtime/subagent-model-selection.js.map +1 -1
- package/lib/runtime/subagent-settings.d.ts +14 -0
- package/lib/runtime/subagent-settings.js +288 -0
- package/lib/runtime/subagent-settings.js.map +1 -0
- 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 +6 -5
- package/lib/runtime/terminal-notifications.js +17 -16
- package/lib/runtime/terminal-notifications.js.map +1 -1
- package/lib/runtime/terminal-probe.d.ts +38 -0
- package/lib/runtime/terminal-probe.js +46 -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/tool-presentation.js.map +1 -1
- package/lib/runtime/tool-reader.d.ts +5 -0
- package/lib/runtime/tool-reader.js +27 -0
- package/lib/runtime/tool-reader.js.map +1 -0
- package/lib/runtime/web-settings.d.ts +14 -0
- package/lib/runtime/web-settings.js +339 -0
- package/lib/runtime/web-settings.js.map +1 -0
- package/lib/session/command-attachments.d.ts +17 -0
- package/lib/session/command-attachments.js +50 -0
- package/lib/session/command-attachments.js.map +1 -0
- package/lib/session/context-diagnostics.d.ts +16 -0
- package/lib/session/context-diagnostics.js +15 -0
- package/lib/session/context-diagnostics.js.map +1 -1
- package/lib/session/external-agents.d.ts +3 -1
- package/lib/session/external-agents.js +35 -10
- package/lib/session/external-agents.js.map +1 -1
- package/lib/session/generation-continuation.d.ts +11 -0
- package/lib/session/generation-continuation.js +34 -0
- package/lib/session/generation-continuation.js.map +1 -0
- package/lib/session/goal-controls.d.ts +5 -0
- package/lib/session/goal-controls.js +81 -0
- package/lib/session/goal-controls.js.map +1 -0
- package/lib/session/interaction-adapter.d.ts +7 -3
- package/lib/session/interaction-adapter.js +125 -54
- package/lib/session/interaction-adapter.js.map +1 -1
- package/lib/session/message-queue.d.ts +2 -0
- package/lib/session/message-queue.js +102 -17
- package/lib/session/message-queue.js.map +1 -1
- 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/pending-inputs.d.ts +30 -0
- package/lib/session/pending-inputs.js +183 -0
- package/lib/session/pending-inputs.js.map +1 -0
- package/lib/session/session-configuration.js +1 -1
- package/lib/session/session-configuration.js.map +1 -1
- package/lib/session/session-controller.d.ts +42 -24
- package/lib/session/session-controller.js +534 -106
- package/lib/session/session-controller.js.map +1 -1
- package/lib/session/session-tree.d.ts +2 -0
- package/lib/session/session-tree.js +2 -0
- package/lib/session/session-tree.js.map +1 -1
- package/lib/session/subagent-roster.d.ts +1 -0
- package/lib/session/subagent-roster.js +16 -5
- package/lib/session/subagent-roster.js.map +1 -1
- package/lib/session/subagent-tracker.d.ts +2 -0
- package/lib/session/subagent-tracker.js +18 -0
- package/lib/session/subagent-tracker.js.map +1 -1
- package/lib/session/tui-settings.d.ts +48 -15
- package/lib/session/tui-settings.js +75 -34
- package/lib/session/tui-settings.js.map +1 -1
- package/lib/session/workflow-projection.d.ts +2 -1
- package/lib/session/workflow-projection.js +34 -4
- package/lib/session/workflow-projection.js.map +1 -1
- package/lib/views/autocomplete.d.ts +28 -9
- package/lib/views/autocomplete.js +90 -70
- package/lib/views/autocomplete.js.map +1 -1
- package/lib/views/context-overview.d.ts +4 -0
- package/lib/views/context-overview.js +43 -0
- package/lib/views/context-overview.js.map +1 -0
- package/lib/views/copy-targets.d.ts +18 -15
- package/lib/views/copy-targets.js +35 -60
- package/lib/views/copy-targets.js.map +1 -1
- package/lib/views/document-reader.d.ts +10 -1
- package/lib/views/document-reader.js +76 -9
- package/lib/views/document-reader.js.map +1 -1
- package/lib/views/event-views.js +71 -17
- package/lib/views/event-views.js.map +1 -1
- package/lib/views/file-actions.js +21 -0
- package/lib/views/file-actions.js.map +1 -1
- package/lib/views/file-browser.d.ts +98 -0
- package/lib/views/file-browser.js +120 -0
- package/lib/views/file-browser.js.map +1 -0
- package/lib/views/history-search.js +19 -25
- package/lib/views/history-search.js.map +1 -1
- package/lib/views/hotkey-format.d.ts +3 -2
- package/lib/views/hotkey-format.js +4 -3
- package/lib/views/hotkey-format.js.map +1 -1
- package/lib/views/hotkeys.d.ts +7 -1
- package/lib/views/hotkeys.js +59 -37
- 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 +170 -0
- package/lib/views/list-view.js.map +1 -0
- package/lib/views/prompt-selector.d.ts +54 -4
- package/lib/views/prompt-selector.js +349 -162
- 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 +16 -9
- package/lib/views/settings-list.js +171 -315
- package/lib/views/settings-list.js.map +1 -1
- package/lib/views/tool-actions.d.ts +16 -0
- package/lib/views/tool-actions.js +29 -0
- package/lib/views/tool-actions.js.map +1 -0
- package/lib/views/trajectory-timeline.d.ts +71 -0
- package/lib/views/trajectory-timeline.js +143 -0
- package/lib/views/trajectory-timeline.js.map +1 -0
- package/lib/views/trajectory.d.ts +36 -4
- package/lib/views/trajectory.js +842 -190
- package/lib/views/trajectory.js.map +1 -1
- package/lib/views/transcript-render.d.ts +132 -38
- package/lib/views/transcript-render.js +792 -260
- 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 +64 -5
- package/lib/views/transcript-types.js +23 -11
- package/lib/views/transcript-types.js.map +1 -1
- package/lib/views/workflow.d.ts +16 -0
- package/lib/views/workflow.js +42 -0
- package/lib/views/workflow.js.map +1 -0
- package/package.json +74 -90
- package/lib/chrome/welcome-tips.d.ts +0 -11
- package/lib/chrome/welcome-tips.js +0 -44
- package/lib/chrome/welcome-tips.js.map +0 -1
- package/lib/commands/advisor.d.ts +0 -15
- package/lib/commands/advisor.js +0 -200
- package/lib/commands/advisor.js.map +0 -1
- 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/rate.d.ts +0 -33
- package/lib/commands/rate.js +0 -212
- package/lib/commands/rate.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/commands/worktree.d.ts +0 -5
- package/lib/commands/worktree.js +0 -103
- package/lib/commands/worktree.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/session/steering.d.ts +0 -3
- package/lib/session/steering.js +0 -9
- package/lib/session/steering.js.map +0 -1
- package/lib/views/agent-hub.d.ts +0 -32
- package/lib/views/agent-hub.js +0 -209
- package/lib/views/agent-hub.js.map +0 -1
- package/lib/views/copy-selector.d.ts +0 -54
- package/lib/views/copy-selector.js +0 -170
- package/lib/views/copy-selector.js.map +0 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential masking for drawn user text.
|
|
3
|
+
*
|
|
4
|
+
* A terminal is shown to other people: a screen share, a recording, a screenshot
|
|
5
|
+
* pasted into an issue. When someone sends an API key by accident, the transcript
|
|
6
|
+
* is the copy that outlives the mistake. This masks a recognized credential's
|
|
7
|
+
* tail in what is drawn and nothing else — the stored message, the copy action
|
|
8
|
+
* and the model input keep the original characters, so the key still works and
|
|
9
|
+
* `Ctrl+C` on the selection still gives the reader what they sent.
|
|
10
|
+
*
|
|
11
|
+
* Recognition follows published formats only, the same rule the Harness client
|
|
12
|
+
* uses: a provider key or token after its fixed prefix, a JSON Web Token, and a
|
|
13
|
+
* private key block. Free-form passwords and `name=value` assignments have no
|
|
14
|
+
* published format, so they stay plain — guessing would mask ordinary prose and
|
|
15
|
+
* teach the reader to distrust the mask.
|
|
16
|
+
*
|
|
17
|
+
* @module @agi-fans/dsh-tui/chrome/secret-mask
|
|
18
|
+
*/
|
|
19
|
+
/** One credential range found in the text, as offsets. */
|
|
20
|
+
interface Range {
|
|
21
|
+
start: number;
|
|
22
|
+
end: number;
|
|
23
|
+
/** A key block keeps its BEGIN line and any END line readable. */
|
|
24
|
+
block?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** Every credential range in `text`, in order and never overlapping. */
|
|
27
|
+
export declare function findSecrets(text: string): readonly Range[];
|
|
28
|
+
/**
|
|
29
|
+
* Mask every recognized credential in `text`.
|
|
30
|
+
*
|
|
31
|
+
* Returns the text unchanged when nothing matched, so a caller can compare by
|
|
32
|
+
* identity to know whether the drawn form differs from the stored one.
|
|
33
|
+
*/
|
|
34
|
+
export declare function maskSecrets(text: string): string;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential masking for drawn user text.
|
|
3
|
+
*
|
|
4
|
+
* A terminal is shown to other people: a screen share, a recording, a screenshot
|
|
5
|
+
* pasted into an issue. When someone sends an API key by accident, the transcript
|
|
6
|
+
* is the copy that outlives the mistake. This masks a recognized credential's
|
|
7
|
+
* tail in what is drawn and nothing else — the stored message, the copy action
|
|
8
|
+
* and the model input keep the original characters, so the key still works and
|
|
9
|
+
* `Ctrl+C` on the selection still gives the reader what they sent.
|
|
10
|
+
*
|
|
11
|
+
* Recognition follows published formats only, the same rule the Harness client
|
|
12
|
+
* uses: a provider key or token after its fixed prefix, a JSON Web Token, and a
|
|
13
|
+
* private key block. Free-form passwords and `name=value` assignments have no
|
|
14
|
+
* published format, so they stay plain — guessing would mask ordinary prose and
|
|
15
|
+
* teach the reader to distrust the mask.
|
|
16
|
+
*
|
|
17
|
+
* @module @agi-fans/dsh-tui/chrome/secret-mask
|
|
18
|
+
*/
|
|
19
|
+
/** What replaces each hidden character. */
|
|
20
|
+
const MASK = '*';
|
|
21
|
+
/** Characters of a prefixed key left readable: the provider prefix and little else. */
|
|
22
|
+
const VISIBLE_PREFIX = 8;
|
|
23
|
+
/**
|
|
24
|
+
* The formats worth recognizing in a terminal.
|
|
25
|
+
*
|
|
26
|
+
* `sk-` requires a digit and twenty characters because they are the model keys
|
|
27
|
+
* people paste by accident; without both, a hyphenated identifier reads as a
|
|
28
|
+
* credential. Cloud key ids are bounded because their length is fixed by format.
|
|
29
|
+
*/
|
|
30
|
+
const RUN_FORMATS = [
|
|
31
|
+
{ literal: 'sk-', min: 20, digit: true },
|
|
32
|
+
{ literal: 'AIza', min: 35 },
|
|
33
|
+
{ literal: 'ghp_', min: 36 },
|
|
34
|
+
{ literal: 'gho_', min: 36 },
|
|
35
|
+
{ literal: 'ghu_', min: 36 },
|
|
36
|
+
{ literal: 'ghs_', min: 36 },
|
|
37
|
+
{ literal: 'ghr_', min: 36 },
|
|
38
|
+
{ literal: 'github_pat_', min: 22 },
|
|
39
|
+
{ literal: 'glpat-', min: 20 },
|
|
40
|
+
{ literal: 'npm_', min: 36 },
|
|
41
|
+
{ literal: 'hf_', min: 30 },
|
|
42
|
+
{ literal: 'AKIA', min: 16, max: 16 },
|
|
43
|
+
{ literal: 'ASIA', min: 16, max: 16 },
|
|
44
|
+
{ literal: 'LTAI', min: 12, max: 20 },
|
|
45
|
+
{ literal: 'AKID', min: 28, max: 36 },
|
|
46
|
+
{ literal: 'xoxa-', min: 10 },
|
|
47
|
+
{ literal: 'xoxb-', min: 10 },
|
|
48
|
+
{ literal: 'xoxp-', min: 10 },
|
|
49
|
+
{ literal: 'xoxr-', min: 10 },
|
|
50
|
+
{ literal: 'xoxs-', min: 10 },
|
|
51
|
+
{ literal: 'sk_live_', min: 16 },
|
|
52
|
+
{ literal: 'sk_test_', min: 16 },
|
|
53
|
+
{ literal: 'rk_live_', min: 16 },
|
|
54
|
+
{ literal: 'rk_test_', min: 16 },
|
|
55
|
+
{ literal: 'whsec_', min: 24 },
|
|
56
|
+
];
|
|
57
|
+
const KEY_BLOCK_BEGIN = '-----BEGIN ';
|
|
58
|
+
const KEY_BLOCK_END = '-----END';
|
|
59
|
+
const JWT_PREFIX = 'eyJ';
|
|
60
|
+
/** Characters a key or token run may contain. */
|
|
61
|
+
function isKeyChar(code) {
|
|
62
|
+
return (code >= 0x30 && code <= 0x39)
|
|
63
|
+
|| (code >= 0x41 && code <= 0x5a)
|
|
64
|
+
|| (code >= 0x61 && code <= 0x7a)
|
|
65
|
+
|| code === 0x5f || code === 0x2d;
|
|
66
|
+
}
|
|
67
|
+
function runEnd(text, from) {
|
|
68
|
+
let at = from;
|
|
69
|
+
while (at < text.length && isKeyChar(text.charCodeAt(at)))
|
|
70
|
+
at += 1;
|
|
71
|
+
return at;
|
|
72
|
+
}
|
|
73
|
+
function hasDigit(text, start, end) {
|
|
74
|
+
for (let at = start; at < end; at += 1) {
|
|
75
|
+
const code = text.charCodeAt(at);
|
|
76
|
+
if (code >= 0x30 && code <= 0x39)
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
/** The prefixed key or token starting at `start`, when the literal and run both validate. */
|
|
82
|
+
function prefixedAt(text, start) {
|
|
83
|
+
for (const format of RUN_FORMATS) {
|
|
84
|
+
if (!text.startsWith(format.literal, start))
|
|
85
|
+
continue;
|
|
86
|
+
const runStart = start + format.literal.length;
|
|
87
|
+
const end = runEnd(text, runStart);
|
|
88
|
+
const length = end - runStart;
|
|
89
|
+
if (length < format.min)
|
|
90
|
+
continue;
|
|
91
|
+
if (format.max !== undefined && length > format.max)
|
|
92
|
+
continue;
|
|
93
|
+
if (format.digit === true && !hasDigit(text, runStart, end))
|
|
94
|
+
continue;
|
|
95
|
+
return { start, end };
|
|
96
|
+
}
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
/** A JSON Web Token: three base64url runs joined by dots, starting with the header prefix. */
|
|
100
|
+
function jwtAt(text, start) {
|
|
101
|
+
if (!text.startsWith(JWT_PREFIX, start))
|
|
102
|
+
return undefined;
|
|
103
|
+
const headerEnd = runEnd(text, start);
|
|
104
|
+
if (text[headerEnd] !== '.' || !text.startsWith('.eyJ', headerEnd))
|
|
105
|
+
return undefined;
|
|
106
|
+
const payloadEnd = runEnd(text, headerEnd + 1);
|
|
107
|
+
if (text[payloadEnd] !== '.')
|
|
108
|
+
return undefined;
|
|
109
|
+
const end = runEnd(text, payloadEnd + 1);
|
|
110
|
+
return end > payloadEnd + 1 ? { start, end } : undefined;
|
|
111
|
+
}
|
|
112
|
+
/** A private key block, from its BEGIN line through the END line when one is present. */
|
|
113
|
+
function keyBlockAt(text, start) {
|
|
114
|
+
if (!text.startsWith(KEY_BLOCK_BEGIN, start))
|
|
115
|
+
return undefined;
|
|
116
|
+
const lineEnd = text.indexOf('\n', start);
|
|
117
|
+
if (lineEnd === -1)
|
|
118
|
+
return undefined;
|
|
119
|
+
const endAt = text.indexOf('\n' + KEY_BLOCK_END, lineEnd);
|
|
120
|
+
return { start, end: endAt === -1 ? text.length : endAt, block: true };
|
|
121
|
+
}
|
|
122
|
+
/** Every credential range in `text`, in order and never overlapping. */
|
|
123
|
+
export function findSecrets(text) {
|
|
124
|
+
const found = [];
|
|
125
|
+
let at = 0;
|
|
126
|
+
while (at < text.length) {
|
|
127
|
+
const next = keyBlockAt(text, at) ?? prefixedAt(text, at) ?? jwtAt(text, at);
|
|
128
|
+
if (next === undefined) {
|
|
129
|
+
at += 1;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
found.push(next);
|
|
133
|
+
at = next.end;
|
|
134
|
+
}
|
|
135
|
+
return found;
|
|
136
|
+
}
|
|
137
|
+
/** The drawn form of a key block: its BEGIN line, a mask per body line, its END line. */
|
|
138
|
+
function maskBlock(text, range) {
|
|
139
|
+
const bodyStart = text.indexOf('\n', range.start);
|
|
140
|
+
if (bodyStart === -1)
|
|
141
|
+
return text.slice(range.start, range.start + VISIBLE_PREFIX).padEnd(range.end - range.start, MASK);
|
|
142
|
+
// Lines and their breaks stay in place so a block does not change the height of
|
|
143
|
+
// what the reader already scrolled past.
|
|
144
|
+
let out = text.slice(range.start, bodyStart + 1);
|
|
145
|
+
for (let at = bodyStart + 1; at <= range.end; at += 1) {
|
|
146
|
+
const code = text.charCodeAt(at);
|
|
147
|
+
if (at === range.end)
|
|
148
|
+
return out;
|
|
149
|
+
if (code === 10)
|
|
150
|
+
out += '\n';
|
|
151
|
+
else if (code === 13)
|
|
152
|
+
out += '\r';
|
|
153
|
+
else
|
|
154
|
+
out += MASK;
|
|
155
|
+
}
|
|
156
|
+
return out;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Mask every recognized credential in `text`.
|
|
160
|
+
*
|
|
161
|
+
* Returns the text unchanged when nothing matched, so a caller can compare by
|
|
162
|
+
* identity to know whether the drawn form differs from the stored one.
|
|
163
|
+
*/
|
|
164
|
+
export function maskSecrets(text) {
|
|
165
|
+
const ranges = findSecrets(text);
|
|
166
|
+
if (ranges.length === 0)
|
|
167
|
+
return text;
|
|
168
|
+
let out = '';
|
|
169
|
+
let at = 0;
|
|
170
|
+
for (const range of ranges) {
|
|
171
|
+
out += text.slice(at, range.start);
|
|
172
|
+
out += range.block === true
|
|
173
|
+
? maskBlock(text, range)
|
|
174
|
+
: text.slice(range.start, range.start + VISIBLE_PREFIX)
|
|
175
|
+
.padEnd(range.end - range.start, MASK);
|
|
176
|
+
at = range.end;
|
|
177
|
+
}
|
|
178
|
+
return out + text.slice(at);
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=secret-mask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-mask.js","sourceRoot":"","sources":["../../src/chrome/secret-mask.ts"],"names":[],"mappings":"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"}
|
|
@@ -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;
|