@deepseek-harness-tui/dsh-tui 0.8.3 → 0.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -10
- package/bin/dsh-tui.js +50 -11
- package/dsh-ecosystem-spec/protocols/profile-definitions.d.ts +13 -13
- package/dsh-ecosystem-spec/protocols/profile-definitions.js +59 -59
- package/dsh-ecosystem-spec/protocols/tui-channel-http.d.ts +15 -15
- package/dsh-ecosystem-spec/protocols/tui-channel-http.js +32 -32
- package/dsh-ecosystem-spec/protocols/tui-channel.d.ts +59 -59
- package/dsh-ecosystem-spec/protocols/tui-channel.js +166 -166
- package/dsh-ecosystem-spec/protocols/tui-contributions.d.ts +42 -42
- package/dsh-ecosystem-spec/protocols/tui-contributions.js +143 -143
- package/dsh-ecosystem-spec/registry/README.md +14 -14
- package/dsh-ecosystem-spec/registry/host-descriptor.tui.example.json +56 -56
- package/dsh-ecosystem-spec/registry/permissions-0.1.json +13 -13
- package/dsh-ecosystem-spec/registry/registry-0.15.json +149 -149
- package/lib/types/activityPrefs.d.ts +10 -0
- package/lib/types/activityPrefs.d.ts.map +1 -1
- package/lib/types/activityPrefs.js +17 -0
- package/lib/types/commands.d.ts.map +1 -1
- package/lib/types/commands.js +1 -0
- package/lib/types/components/LogoV2.d.ts +4 -1
- package/lib/types/components/LogoV2.d.ts.map +1 -1
- package/lib/types/components/LogoV2.js +8 -3
- package/lib/types/components/MessageList.d.ts +4 -1
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +4 -4
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +1 -3
- package/lib/types/components/SplitDiffView.d.ts +3 -1
- package/lib/types/components/SplitDiffView.d.ts.map +1 -1
- package/lib/types/components/SplitDiffView.js +12 -5
- package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
- package/lib/types/components/StreamingMarkdown.js +10 -2
- package/lib/types/components/TipsPanel.d.ts +14 -0
- package/lib/types/components/TipsPanel.d.ts.map +1 -0
- package/lib/types/components/TipsPanel.js +37 -0
- package/lib/types/components/activityFrames.d.ts +7 -28
- package/lib/types/components/activityFrames.d.ts.map +1 -1
- package/lib/types/components/activityFrames.js +7 -84
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantThinkingMessage.js +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts +4 -1
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +14 -3
- package/lib/types/dsh-adapter/channel.d.ts +17 -0
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +169 -33
- package/lib/types/dsh-adapter/index.d.ts +5 -0
- package/lib/types/dsh-adapter/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/index.js +19 -0
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +176 -4
- package/lib/types/dsh-adapter/settings-sections.d.ts +13 -0
- package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
- package/lib/types/dsh-adapter/settings-sections.js +31 -6
- package/lib/types/effortPrefs.d.ts +7 -6
- package/lib/types/effortPrefs.d.ts.map +1 -1
- package/lib/types/effortPrefs.js +7 -6
- package/lib/types/i18n.d.ts +42 -14
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +11 -4
- package/lib/types/ink/ink.d.ts +10 -0
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +35 -1
- package/lib/types/ink/parse-keypress.d.ts.map +1 -1
- package/lib/types/ink/parse-keypress.js +15 -0
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +44 -7
- package/lib/types/screens/Settings.d.ts.map +1 -1
- package/lib/types/screens/Settings.js +109 -50
- package/lib/types/screens/StatusLine.d.ts +8 -0
- package/lib/types/screens/StatusLine.d.ts.map +1 -1
- package/lib/types/screens/StatusLine.js +65 -42
- package/lib/types/settings-sections.d.ts +1 -1
- package/lib/types/settings-sections.d.ts.map +1 -1
- package/lib/types/tips.d.ts +30 -0
- package/lib/types/tips.d.ts.map +1 -0
- package/lib/types/tips.js +575 -0
- package/lib/types/tuiDisplayPrefs.d.ts +47 -0
- package/lib/types/tuiDisplayPrefs.d.ts.map +1 -0
- package/lib/types/tuiDisplayPrefs.js +60 -0
- package/node_modules/@dsh-std/command/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/command/LICENSE +21 -21
- package/node_modules/@dsh-std/command/README.md +26 -26
- package/node_modules/@dsh-std/command/README.zh.md +28 -28
- package/node_modules/@dsh-std/command/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/command/package.json +22 -22
- package/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/connection/LICENSE +21 -21
- package/node_modules/@dsh-std/connection/README.md +42 -42
- package/node_modules/@dsh-std/connection/README.zh.md +42 -42
- package/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
- package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
- package/node_modules/@dsh-std/connection/package.json +20 -20
- package/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/core/LICENSE +21 -21
- package/node_modules/@dsh-std/core/README.md +13 -13
- package/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/core/package.json +21 -21
- package/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -9
- package/node_modules/@dsh-std/manifest/LICENSE +21 -21
- package/node_modules/@dsh-std/manifest/README.md +5 -5
- package/node_modules/@dsh-std/manifest/README.zh.md +5 -5
- package/node_modules/@dsh-std/manifest/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/manifest/package.json +20 -20
- package/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -144
- package/node_modules/@dsh-std/messages/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/messages/LICENSE +21 -21
- package/node_modules/@dsh-std/messages/README.md +5 -5
- package/node_modules/@dsh-std/messages/README.zh.md +7 -7
- package/node_modules/@dsh-std/messages/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/messages/package.json +20 -20
- package/node_modules/@dsh-std/messages/schema/message-observer-envelope-0.15.schema.json +54 -54
- package/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -9
- package/node_modules/@dsh-std/presentation/LICENSE +21 -21
- package/node_modules/@dsh-std/presentation/README.md +27 -27
- package/node_modules/@dsh-std/presentation/README.zh.md +29 -29
- package/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -1
- package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/presentation/package.json +25 -25
- package/node_modules/@dsh-std/storage/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/storage/LICENSE +21 -21
- package/node_modules/@dsh-std/storage/README.md +5 -5
- package/node_modules/@dsh-std/storage/README.zh.md +7 -7
- package/node_modules/@dsh-std/storage/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/storage/package.json +20 -20
- package/node_modules/@dsh-std/storage/schema/local-storage-0.15.schema.json +56 -56
- package/package.json +8 -3
- package/presets/liangshen/.dsh-tui-managed.json +1 -1
- package/presets/liangshen/agent.cordis.yml +7 -5
- package/presets/liangshen/custom-bash.mjs +184 -9
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/LICENSE +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.md +42 -42
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.zh.md +42 -42
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +20 -20
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -9
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/LICENSE +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.md +5 -5
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.zh.md +5 -5
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +20 -20
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -144
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -9
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/LICENSE +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +27 -27
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +29 -29
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +25 -25
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/LICENSE +21 -21
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.md +42 -42
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.zh.md +42 -42
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +20 -20
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +21 -21
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Settings.d.ts","sourceRoot":"","sources":["../../../src/screens/Settings.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAUzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;
|
|
1
|
+
{"version":3,"file":"Settings.d.ts","sourceRoot":"","sources":["../../../src/screens/Settings.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAUzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AA+CxD;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CAAC,EACvB,OAAO,EACP,OAAO,GACR,EAAE;IACD,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB,GAAG,KAAK,CAAC,SAAS,CA0ZlB"}
|
|
@@ -46,6 +46,7 @@ export function Settings({ channel, onClose, }) {
|
|
|
46
46
|
const [sections, setSections] = React.useState(() => channel.settingsSections());
|
|
47
47
|
const [mode, setMode] = React.useState('list');
|
|
48
48
|
const [editing, setEditing] = React.useState(null);
|
|
49
|
+
const [activeGroup, setActiveGroup] = React.useState(null);
|
|
49
50
|
const [focusIndex, setFocusIndex] = React.useState(0);
|
|
50
51
|
const [notice, setNotice] = React.useState(undefined);
|
|
51
52
|
/** Configured status of every secret field's credential ref. */
|
|
@@ -100,8 +101,26 @@ export function Settings({ channel, onClose, }) {
|
|
|
100
101
|
};
|
|
101
102
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
102
103
|
}, [host, sections, secretProbe]);
|
|
103
|
-
|
|
104
|
-
const
|
|
104
|
+
const activeSection = activeGroup === null ? undefined : sections.find(section => section.ns === activeGroup.ns);
|
|
105
|
+
const activeGroupSpec = activeSection?.groups?.find(group => group.id === activeGroup?.id);
|
|
106
|
+
React.useEffect(() => {
|
|
107
|
+
if (activeGroup !== null && activeGroupSpec === undefined) {
|
|
108
|
+
setActiveGroup(null);
|
|
109
|
+
setFocusIndex(0);
|
|
110
|
+
setWindowStart(0);
|
|
111
|
+
}
|
|
112
|
+
}, [activeGroup, activeGroupSpec]);
|
|
113
|
+
/** Focusable rows in display order for the current page. */
|
|
114
|
+
const focusable = activeSection !== undefined && activeGroupSpec !== undefined
|
|
115
|
+
? activeSection.fields
|
|
116
|
+
.filter(field => field.group === activeGroupSpec.id)
|
|
117
|
+
.map(field => ({ kind: 'field', ns: activeSection.ns, field }))
|
|
118
|
+
: sections.flatMap(section => [
|
|
119
|
+
...section.fields
|
|
120
|
+
.filter(field => field.group === undefined)
|
|
121
|
+
.map(field => ({ kind: 'field', ns: section.ns, field })),
|
|
122
|
+
...(section.groups ?? []).map(group => ({ kind: 'group', ns: section.ns, group })),
|
|
123
|
+
]);
|
|
105
124
|
const effFocus = Math.min(focusIndex, Math.max(0, focusable.length - 1));
|
|
106
125
|
const focused = focusable.length === 0 ? undefined : focusable[effFocus];
|
|
107
126
|
const focusedForm = focused === undefined ? undefined : forms.get(focused.ns);
|
|
@@ -173,6 +192,12 @@ export function Settings({ channel, onClose, }) {
|
|
|
173
192
|
setFocusIndex(Math.min(Math.max(0, focusable.length - 1), effFocus + 1));
|
|
174
193
|
}
|
|
175
194
|
else if (isPlainReturn(key) && focused !== undefined) {
|
|
195
|
+
if (focused.kind === 'group') {
|
|
196
|
+
setActiveGroup({ ns: focused.ns, id: focused.group.id });
|
|
197
|
+
setFocusIndex(0);
|
|
198
|
+
setWindowStart(0);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
176
201
|
// A save in flight owns the section's drafts; starting an edit mid-write
|
|
177
202
|
// is exactly the lost-draft race the staged model exists to prevent.
|
|
178
203
|
if (focusedForm === undefined || !focusedForm.available || focusedForm.saving)
|
|
@@ -196,11 +221,17 @@ export function Settings({ channel, onClose, }) {
|
|
|
196
221
|
bump();
|
|
197
222
|
}
|
|
198
223
|
else if (key.escape) {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
224
|
+
if (activeGroupSpec !== undefined) {
|
|
225
|
+
// Group navigation never settles drafts; the root page owns discard/exit.
|
|
226
|
+
setActiveGroup(null);
|
|
227
|
+
setFocusIndex(0);
|
|
228
|
+
setWindowStart(0);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
// At the root, Esc backs out one layer at a time: staged drafts first —
|
|
232
|
+
// ANY dirty section, not just the focused one — then the screen itself.
|
|
233
|
+
// A save in flight cannot be undone from here; let it settle instead of
|
|
234
|
+
// discarding around it.
|
|
204
235
|
const dirty = [...forms.values()].filter(form => form.shell().dirty);
|
|
205
236
|
if (dirty.length > 0) {
|
|
206
237
|
if (dirty.some(form => form.saving))
|
|
@@ -219,7 +250,7 @@ export function Settings({ channel, onClose, }) {
|
|
|
219
250
|
const ns = section.ns;
|
|
220
251
|
const form = forms.get(ns);
|
|
221
252
|
const state = form?.field(field) ?? { text: '', overridden: false, invalid: false };
|
|
222
|
-
const isFocused = focused
|
|
253
|
+
const isFocused = focused?.kind === 'field' && focused.ns === ns && focused.field === field;
|
|
223
254
|
const isEditing = isFocused && mode === 'edit' && editing !== null;
|
|
224
255
|
const label = pick(field.label, field.descriptions);
|
|
225
256
|
const hint = field.hint !== undefined ? pick(field.hint, field.hintDescriptions) : undefined;
|
|
@@ -248,58 +279,82 @@ export function Settings({ channel, onClose, }) {
|
|
|
248
279
|
return (_jsxs(Box, { children: [_jsx(Text, { color: isFocused ? 'suggestion' : undefined, children: isFocused ? '❯ ' : ' ' }), _jsx(Text, { bold: isFocused, children: label }), _jsx(Box, { flexGrow: 1 }), state.invalid && _jsxs(Text, { color: "error", children: [t('settings-field-invalid'), " "] }), state.overridden && _jsxs(Text, { dimColor: true, children: ["[", t('settings-badge-override'), "] "] }), form?.isStaged(field) === true && !isEditing && _jsx(Text, { color: "suggestion", children: "* " }), _jsx(Text, { color: isEditing || isFocused ? 'suggestion' : undefined, dimColor: !isFocused && !isEditing && state.text === '', children: value }), hint !== undefined && isFocused && (_jsxs(Text, { dimColor: true, children: ['\n ', hint] }))] }));
|
|
249
280
|
};
|
|
250
281
|
// ── Layout: a flat entry list with accounted line heights, windowed so the
|
|
251
|
-
// focused
|
|
282
|
+
// focused row is always on screen no matter how long the current page gets. ─
|
|
252
283
|
const entries = [];
|
|
253
284
|
let focusCursor = 0;
|
|
254
|
-
|
|
255
|
-
const
|
|
256
|
-
const
|
|
257
|
-
|
|
285
|
+
const addField = (section, field) => {
|
|
286
|
+
const isFocused = focused?.kind === 'field' && focused.ns === section.ns && focused.field === field;
|
|
287
|
+
const index = focusCursor;
|
|
288
|
+
focusCursor += 1;
|
|
258
289
|
entries.push({
|
|
259
|
-
key: `
|
|
260
|
-
lines:
|
|
261
|
-
|
|
290
|
+
key: `field:${section.ns}:${field.path.join('.')}`,
|
|
291
|
+
lines: field.hint !== undefined && isFocused ? 2 : 1,
|
|
292
|
+
focus: index,
|
|
293
|
+
node: renderField(section, field),
|
|
262
294
|
});
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
295
|
+
};
|
|
296
|
+
if (activeSection !== undefined && activeGroupSpec !== undefined) {
|
|
297
|
+
const groupFields = activeSection.fields.filter(field => field.group === activeGroupSpec.id);
|
|
298
|
+
for (const field of groupFields)
|
|
299
|
+
addField(activeSection, field);
|
|
300
|
+
if (groupFields.length === 0) {
|
|
301
|
+
entries.push({ key: 'group:empty', lines: 1, node: _jsx(Text, { dimColor: true, children: t('settings-group-empty') }) });
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
sections.forEach((section, sectionIndex) => {
|
|
306
|
+
const form = forms.get(section.ns);
|
|
307
|
+
const view = form?.namespace;
|
|
308
|
+
const shell = form?.shell();
|
|
268
309
|
entries.push({
|
|
269
|
-
key: `
|
|
270
|
-
lines:
|
|
271
|
-
|
|
272
|
-
node: renderField(section, field),
|
|
310
|
+
key: `section:${section.ns}`,
|
|
311
|
+
lines: sectionIndex === 0 ? 1 : 2,
|
|
312
|
+
node: (_jsxs(Box, { flexDirection: "column", children: [sectionIndex > 0 && _jsx(Text, { children: " " }), _jsxs(Box, { children: [_jsx(Text, { bold: true, color: "permission", children: pick(section.title, section.descriptions) }), _jsxs(Text, { dimColor: true, children: [" (", section.ns, ")"] }), view?.applies === 'restart' && _jsxs(Text, { color: "warning", children: [" [", t('settings-badge-restart'), "]"] }), view === undefined && _jsxs(Text, { color: "warning", children: [" [", t('settings-section-unavailable'), "]"] }), shell?.dirty === true && _jsxs(Text, { color: "suggestion", children: [" [", t('settings-badge-dirty'), "]"] }), shell?.saving === true && _jsxs(Text, { dimColor: true, children: [" [", t('settings-badge-saving'), "]"] }), shell?.failed === true && _jsxs(Text, { color: "error", children: [" [", t('settings-badge-failed'), "]"] })] })] })),
|
|
273
313
|
});
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
314
|
+
for (const field of section.fields) {
|
|
315
|
+
if (field.group === undefined)
|
|
316
|
+
addField(section, field);
|
|
317
|
+
}
|
|
318
|
+
for (const group of section.groups ?? []) {
|
|
319
|
+
const isFocused = focused?.kind === 'group' && focused.ns === section.ns && focused.group === group;
|
|
320
|
+
const index = focusCursor;
|
|
321
|
+
focusCursor += 1;
|
|
322
|
+
entries.push({
|
|
323
|
+
key: `group:${section.ns}:${group.id}`,
|
|
324
|
+
lines: 1,
|
|
325
|
+
focus: index,
|
|
326
|
+
node: (_jsxs(Box, { children: [_jsx(Text, { color: isFocused ? 'suggestion' : undefined, children: isFocused ? '❯ ' : ' ' }), _jsx(Text, { bold: isFocused, children: pick(group.title, group.descriptions) }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { color: isFocused ? 'suggestion' : undefined, children: "\u203A" })] })),
|
|
327
|
+
});
|
|
328
|
+
}
|
|
283
329
|
});
|
|
284
|
-
|
|
330
|
+
const registeredNs = new Set(sections.map(section => section.ns));
|
|
331
|
+
const readonlyNamespaces = namespaces.filter(entry => !registeredNs.has(entry.ns));
|
|
332
|
+
if (readonlyNamespaces.length > 0) {
|
|
333
|
+
entries.push({
|
|
334
|
+
key: 'readonly:heading',
|
|
335
|
+
lines: 2,
|
|
336
|
+
node: (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { children: " " }), _jsx(Text, { bold: true, dimColor: true, children: t('settings-readonly-heading') })] })),
|
|
337
|
+
});
|
|
338
|
+
for (const entry of readonlyNamespaces) {
|
|
339
|
+
entries.push({
|
|
340
|
+
key: `readonly:${entry.ns}`,
|
|
341
|
+
lines: 1,
|
|
342
|
+
node: (_jsxs(Box, { children: [_jsxs(Text, { children: [' ', entry.ns] }), entry.applies === 'restart' && _jsxs(Text, { color: "warning", children: [" [", t('settings-badge-restart'), "]"] }), _jsxs(Text, { dimColor: true, children: [' ', valuePreview(entry.value, 60)] })] })),
|
|
343
|
+
});
|
|
344
|
+
}
|
|
285
345
|
entries.push({
|
|
286
|
-
key:
|
|
346
|
+
key: 'readonly:hint',
|
|
287
347
|
lines: 1,
|
|
288
|
-
node:
|
|
348
|
+
node: _jsxs(Text, { dimColor: true, children: [' ', t('settings-readonly-hint', { path: '~/.dsh/settings.yaml' })] }),
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
if (sections.length === 0 && readonlyNamespaces.length === 0) {
|
|
352
|
+
entries.push({
|
|
353
|
+
key: 'empty',
|
|
354
|
+
lines: 1,
|
|
355
|
+
node: _jsx(Text, { dimColor: true, children: t('settings-empty') }),
|
|
289
356
|
});
|
|
290
357
|
}
|
|
291
|
-
entries.push({
|
|
292
|
-
key: 'readonly:hint',
|
|
293
|
-
lines: 1,
|
|
294
|
-
node: _jsxs(Text, { dimColor: true, children: [' ', t('settings-readonly-hint', { path: '~/.dsh/settings.yaml' })] }),
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
if (sections.length === 0 && readonlyNamespaces.length === 0) {
|
|
298
|
-
entries.push({
|
|
299
|
-
key: 'empty',
|
|
300
|
-
lines: 1,
|
|
301
|
-
node: _jsx(Text, { dimColor: true, children: t('settings-empty') }),
|
|
302
|
-
});
|
|
303
358
|
}
|
|
304
359
|
// Focus-follow window: keep the focused entry fully inside the viewport.
|
|
305
360
|
let totalLines = 0;
|
|
@@ -329,5 +384,9 @@ export function Settings({ channel, onClose, }) {
|
|
|
329
384
|
entryOffset += entry.lines;
|
|
330
385
|
return start >= windowStart && start + entry.lines <= windowStart + viewport;
|
|
331
386
|
});
|
|
332
|
-
|
|
387
|
+
const title = activeSection !== undefined && activeGroupSpec !== undefined
|
|
388
|
+
? `${t('settings-title')} › ${pick(activeSection.title, activeSection.descriptions)} › ${pick(activeGroupSpec.title, activeGroupSpec.descriptions)}`
|
|
389
|
+
: t('settings-title');
|
|
390
|
+
const navigationHint = activeGroupSpec === undefined ? t('settings-hint-list') : t('settings-hint-group');
|
|
391
|
+
return (_jsxs(Box, { flexDirection: "column", width: columns, height: rows, children: [_jsxs(Box, { children: [_jsx(Text, { bold: true, children: title }), _jsx(Box, { flexGrow: 1 }), host === undefined && _jsx(Text, { color: "warning", children: t('settings-unavailable') })] }), _jsx(Divider, {}), visible.map(entry => (_jsx(React.Fragment, { children: entry.node }, entry.key))), _jsx(Box, { flexGrow: 1 }), notice !== undefined && (_jsx(Text, { color: notice.tone === 'error' ? 'error' : 'success', children: notice.text })), _jsx(Divider, {}), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: mode === 'edit' ? t('settings-hint-edit') : navigationHint }) })] }));
|
|
333
392
|
}
|
|
@@ -28,4 +28,12 @@ export declare function StatusLine({ channel, selectionActive, helpOpen, wake, }
|
|
|
28
28
|
tick: number;
|
|
29
29
|
};
|
|
30
30
|
}): React.JSX.Element;
|
|
31
|
+
type UsageSnapshot = {
|
|
32
|
+
input: number;
|
|
33
|
+
cacheRead: number;
|
|
34
|
+
cacheWrite: number;
|
|
35
|
+
};
|
|
36
|
+
/** Return the prompt-cache hit rate, or nothing when usage is unavailable. */
|
|
37
|
+
export declare function formatCacheHitRate(usage: UsageSnapshot | undefined): string | undefined;
|
|
38
|
+
export {};
|
|
31
39
|
//# sourceMappingURL=StatusLine.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StatusLine.d.ts","sourceRoot":"","sources":["../../../src/screens/StatusLine.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAGxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAQvD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,eAAuB,EACvB,QAAgB,EAChB,IAAI,GACL,EAAE;IACD,OAAO,EAAE,OAAO,CAAA;IAChB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CACvD,
|
|
1
|
+
{"version":3,"file":"StatusLine.d.ts","sourceRoot":"","sources":["../../../src/screens/StatusLine.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAGxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAQvD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,eAAuB,EACvB,QAAgB,EAChB,IAAI,GACL,EAAE;IACD,OAAO,EAAE,OAAO,CAAA;IAChB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CACvD,qBAsPA;AAED,KAAK,aAAa,GAAG;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAKvF"}
|
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Box, Text, useTerminalSize, useTheme } from '../ui.js';
|
|
3
3
|
import { formatTokens } from '../cc/format.js';
|
|
4
4
|
import { t } from '../i18n.js';
|
|
5
|
+
import { formatContextUsage, normalizeStatusBar } from '../tuiDisplayPrefs.js';
|
|
5
6
|
import { Byline } from '../components/design-system/Byline.js';
|
|
6
7
|
import { ActivityLine, contextPressurePct } from '../components/ActivityLine.js';
|
|
7
8
|
import { modeDisplayName } from '../sessionModes.js';
|
|
@@ -18,30 +19,32 @@ import { renderContextBar, renderTpsGauge, renderTpsSparkline, speedColor, } fro
|
|
|
18
19
|
export function StatusLine({ channel, selectionActive = false, helpOpen = false, wake, }) {
|
|
19
20
|
const { columns } = useTerminalSize();
|
|
20
21
|
const [themeName] = useTheme();
|
|
22
|
+
const statusBar = normalizeStatusBar(channel.statusBar);
|
|
21
23
|
const usage = channel.lastUsage;
|
|
24
|
+
const contextUsed = usage === undefined
|
|
25
|
+
? undefined
|
|
26
|
+
: usage.input + usage.cacheRead + usage.cacheWrite;
|
|
22
27
|
const contextParts = [];
|
|
23
|
-
|
|
24
|
-
// mode (index 0); sage while a plan-declaring mode is in force.
|
|
25
|
-
if (channel.modeIndex > 0) {
|
|
26
|
-
contextParts.push(_jsx(Text, { color: channel.mode.plan === true ? 'planMode' : 'warning', children: modeDisplayName(channel.mode) }, "mode"));
|
|
27
|
-
}
|
|
28
|
-
if (channel.reasoningEffort !== undefined) {
|
|
28
|
+
if (statusBar.thinking && channel.reasoningEffort !== undefined) {
|
|
29
29
|
contextParts.push(_jsx(Text, { color: "inactiveShimmer", children: channel.reasoningEffort }, "effort"));
|
|
30
30
|
}
|
|
31
|
-
if (
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
if (statusBar.mode && channel.modeIndex > 0) {
|
|
32
|
+
contextParts.push(_jsx(Text, { color: channel.mode.plan === true ? 'planMode' : 'warning', children: modeDisplayName(channel.mode) }, "mode"));
|
|
33
|
+
}
|
|
34
|
+
const formattedContext = statusBar.contextUsage
|
|
35
|
+
? formatContextUsage(contextUsed, channel.contextWindow, statusBar.compact)
|
|
36
|
+
: undefined;
|
|
37
|
+
const contextUsagePart = formattedContext === undefined
|
|
38
|
+
? undefined
|
|
39
|
+
: (_jsxs(Text, { color: "inactiveShimmer", children: [_jsx(Text, { dimColor: true, children: "ctx " }), formattedContext] }, "context"));
|
|
40
|
+
if (statusBar.cache) {
|
|
41
|
+
const cacheRate = formatCacheHitRate(usage);
|
|
42
|
+
if (cacheRate !== undefined) {
|
|
43
|
+
contextParts.push(_jsxs(Text, { color: "inactiveShimmer", children: [_jsx(Text, { dimColor: true, children: t('status-cache-label') }), cacheRate] }, "cache"));
|
|
44
|
+
}
|
|
38
45
|
}
|
|
39
|
-
// TPS readout sits right after the model so a crowded footer truncates
|
|
40
|
-
// the trailing fields (tokens/think/cache), never the speedometer. One
|
|
41
|
-
// number only: the live value (gauge while streaming, sparkline of past
|
|
42
|
-
// turns once samples exist) — no μ/p95 clutter.
|
|
43
46
|
const tpsParts = [];
|
|
44
|
-
if (channel.tps !== undefined) {
|
|
47
|
+
if (statusBar.tps && channel.tps !== undefined) {
|
|
45
48
|
if (channel.working && channel.tpsSamples.length === 0) {
|
|
46
49
|
tpsParts.push(_jsxs(Text, { children: [renderTpsGauge(channel.tps, channel.tps), ' ', _jsxs(Text, { dimColor: true, children: [Math.round(channel.tps), " tps"] })] }, "tps"));
|
|
47
50
|
}
|
|
@@ -55,57 +58,77 @@ export function StatusLine({ channel, selectionActive = false, helpOpen = false,
|
|
|
55
58
|
tpsParts.push(_jsxs(Text, { dimColor: true, children: [Math.round(channel.tps), " t/s"] }, "tps"));
|
|
56
59
|
}
|
|
57
60
|
}
|
|
58
|
-
// Left group: every field sits at soft white (inactiveShimmer) instead of
|
|
59
|
-
// the previous uniform dim grey — readable against dark terminals.
|
|
60
61
|
const leftParts = [
|
|
61
|
-
|
|
62
|
+
...(statusBar.model
|
|
63
|
+
? [_jsx(Text, { color: "inactiveShimmer", children: channel.model }, "model")]
|
|
64
|
+
: []),
|
|
62
65
|
...tpsParts,
|
|
63
66
|
...contextParts,
|
|
64
|
-
|
|
67
|
+
...(statusBar.tokens
|
|
68
|
+
? [
|
|
69
|
+
_jsxs(Text, { color: "inactiveShimmer", children: [formatTokens(channel.tokens.input), "\u2192", formatTokens(channel.tokens.output)] }, "tokens"),
|
|
70
|
+
]
|
|
71
|
+
: []),
|
|
65
72
|
];
|
|
66
|
-
// Right group: git branch in muted steel blue, cwd a soft white, the
|
|
67
|
-
// session title dimmest (it truncates first anyway).
|
|
68
73
|
const rightParts = [
|
|
69
|
-
...(channel.gitBranch
|
|
74
|
+
...(statusBar.gitBranch && channel.gitBranch
|
|
70
75
|
? [
|
|
71
76
|
_jsx(Text, { color: "professionalBlue", children: channel.gitBranch }, "git"),
|
|
72
77
|
]
|
|
73
78
|
: []),
|
|
74
|
-
|
|
75
|
-
|
|
79
|
+
...(statusBar.cwd
|
|
80
|
+
? [
|
|
81
|
+
_jsx(Text, { color: "inactiveShimmer", children: statusBar.compact ? basename(channel.displayCwd) : channel.displayCwd }, "cwd"),
|
|
82
|
+
]
|
|
83
|
+
: []),
|
|
84
|
+
...(statusBar.sessionTitle && channel.sessionTitle
|
|
76
85
|
? [
|
|
77
86
|
_jsx(Text, { dimColor: true, children: channel.sessionTitle }, "title"),
|
|
78
87
|
]
|
|
79
88
|
: []),
|
|
80
89
|
];
|
|
81
|
-
// Row 3: the mode hint — and, while idle, the working-activity turn
|
|
82
|
-
// summary (the live working line itself moves to the spinner slot above
|
|
83
|
-
// the input while a turn runs, so the two never duplicate).
|
|
84
90
|
const hint = selectionActive
|
|
85
|
-
? '
|
|
91
|
+
? t('statusline-hint-select')
|
|
86
92
|
: channel.working
|
|
87
|
-
? '
|
|
88
|
-
: !helpOpen
|
|
89
|
-
? '
|
|
93
|
+
? t('statusline-hint-working')
|
|
94
|
+
: statusBar.shortcutHint && !helpOpen
|
|
95
|
+
? t('statusline-hint-shortcuts')
|
|
90
96
|
: '';
|
|
91
97
|
const activity = channel.workingActivity;
|
|
92
|
-
const showActivity =
|
|
98
|
+
const showActivity = statusBar.activity &&
|
|
99
|
+
!channel.working &&
|
|
93
100
|
activity !== undefined &&
|
|
94
101
|
activity.line !== '' &&
|
|
95
102
|
activity.phase !== 'idle';
|
|
103
|
+
const showTrajectory = statusBar.trajectory && wake !== undefined;
|
|
96
104
|
const barWidth = columns - 4;
|
|
97
105
|
let bar = null;
|
|
98
|
-
// Theme-aware free segment: the light palette's near-white fill (#E8E8E8)
|
|
99
|
-
// reads as a glaring white band on dark terminals — swap it for a deep
|
|
100
|
-
// blue-gray there while keeping the light palette as-is (dark-ansi carries
|
|
101
|
-
// `ansi:` color names, so map by theme name rather than palette tokens).
|
|
102
106
|
const barColors = themeName === 'light'
|
|
103
107
|
? undefined
|
|
104
108
|
: { freeFill: '#2E3440', freeText: '#8D95A6' };
|
|
105
|
-
if (
|
|
106
|
-
|
|
109
|
+
if (statusBar.contextBar &&
|
|
110
|
+
channel.contextBarEnabled &&
|
|
111
|
+
barWidth >= 14 &&
|
|
112
|
+
usage !== undefined &&
|
|
113
|
+
channel.contextWindow !== undefined) {
|
|
114
|
+
bar = renderContextBar(channel.contextSegments, contextUsed ?? 0, channel.contextWindow, barWidth, barColors);
|
|
107
115
|
}
|
|
108
|
-
|
|
116
|
+
const compactLeftParts = [...leftParts, ...rightParts];
|
|
117
|
+
const fullLeftParts = contextUsagePart === undefined
|
|
118
|
+
? leftParts
|
|
119
|
+
: [...leftParts, contextUsagePart];
|
|
120
|
+
const hasStatusFields = compactLeftParts.length > 0 || contextUsagePart !== undefined;
|
|
121
|
+
const showSupplementalRow = hint !== '' || showActivity || showTrajectory;
|
|
122
|
+
return (_jsx(Box, { paddingX: 1, width: columns, flexShrink: 0, children: _jsxs(Box, { flexDirection: "column", width: "100%", children: [bar ? _jsx(Text, { children: bar }) : null, hasStatusFields ? statusBar.compact ? (_jsxs(Box, { flexDirection: "row", justifyContent: "space-between", gap: 2, children: [_jsx(Box, { flexGrow: 1, flexShrink: 1, children: _jsx(Text, { wrap: "truncate", children: _jsx(Byline, { children: compactLeftParts }) }) }), contextUsagePart ? (_jsx(Box, { flexShrink: 0, children: _jsx(Text, { wrap: "truncate", children: _jsx(Byline, { children: [contextUsagePart] }) }) })) : null] })) : (_jsxs(Box, { flexDirection: "row", justifyContent: "space-between", gap: 2, children: [_jsx(Box, { flexGrow: 1, flexShrink: 1, children: _jsx(Text, { wrap: "truncate", children: _jsx(Byline, { children: fullLeftParts }) }) }), _jsx(Box, { justifyContent: "flex-end", flexShrink: 2, children: _jsx(Text, { wrap: "truncate", children: _jsx(Byline, { children: rightParts }) }) })] })) : null, showSupplementalRow ? _jsxs(Box, { height: 1, overflow: "hidden", flexDirection: "row", justifyContent: "space-between", gap: 2, children: [_jsxs(Box, { flexDirection: "row", flexGrow: 1, justifyContent: showActivity && hint ? 'space-between' : 'flex-start', gap: 2, children: [showActivity && activity !== undefined ? (_jsx(ActivityLine, { activity: activity, activityFrames: channel.activityFrames, warnPct: contextPressurePct(usage, channel.contextWindow), warnDanger: (contextPressurePct(usage, channel.contextWindow) ?? 0) >= 95 })) : hint ? (_jsx(Text, { color: "inactiveShimmer", children: hint })) : null, showActivity && hint ? (_jsx(Text, { color: "inactiveShimmer", wrap: "truncate", children: hint })) : null] }), showTrajectory && wake !== undefined ? (_jsx(MiniWake, { band: wake.band, hint: wake.hint, tick: wake.tick })) : null] }) : null] }) }));
|
|
123
|
+
}
|
|
124
|
+
/** Return the prompt-cache hit rate, or nothing when usage is unavailable. */
|
|
125
|
+
export function formatCacheHitRate(usage) {
|
|
126
|
+
if (usage === undefined)
|
|
127
|
+
return undefined;
|
|
128
|
+
const total = usage.input + usage.cacheRead + usage.cacheWrite;
|
|
129
|
+
if (!Number.isFinite(total) || total <= 0)
|
|
130
|
+
return undefined;
|
|
131
|
+
return `${((usage.cacheRead / total) * 100).toFixed(1)}%`;
|
|
109
132
|
}
|
|
110
133
|
function basename(path) {
|
|
111
134
|
const parts = path.split(/[\\/]/);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { name, TuiSettingsSectionsRuntime } from './dsh-adapter/settings-sections.js';
|
|
2
|
-
export type { TuiSettingsFieldKind, TuiSettingsFieldOption, TuiSettingsFieldWrite, TuiSettingsField, TuiSettingsSection, } from './dsh-adapter/settings-sections.js';
|
|
2
|
+
export type { TuiSettingsFieldKind, TuiSettingsFieldOption, TuiSettingsGroup, TuiSettingsFieldWrite, TuiSettingsField, TuiSettingsSection, } from './dsh-adapter/settings-sections.js';
|
|
3
3
|
export { default } from './dsh-adapter/settings-sections.js';
|
|
4
4
|
//# sourceMappingURL=settings-sections.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-sections.d.ts","sourceRoot":"","sources":["../../src/settings-sections.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAA;AACrF,YAAY,EACV,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,oCAAoC,CAAA"}
|
|
1
|
+
{"version":3,"file":"settings-sections.d.ts","sourceRoot":"","sources":["../../src/settings-sections.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAA;AACrF,YAAY,EACV,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,oCAAoC,CAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 精简 Tips 池 —— 启动首屏轮换(LogoV2)与 `/tips` 命令面板共用。
|
|
3
|
+
*
|
|
4
|
+
* 设计约定:
|
|
5
|
+
* - 每条 tip 一句话,中文 ≤ 约 60 字符、英文 ≤ 约 100 字符,首屏单行可读
|
|
6
|
+
* (窄终端自动截断);
|
|
7
|
+
* - 文案只讲"用户能立刻用上"的操作,不讲实现细节;
|
|
8
|
+
* - id 稳定(面板按 id 去重/排序),group 用于 `/tips` 面板分组展示;
|
|
9
|
+
* - 与 docs/user-guide.md 同源:文档是详版,这里是精版,覆盖全部功能面。
|
|
10
|
+
*/
|
|
11
|
+
export type TipGroup = 'keys' | 'commands' | 'workflow' | 'display' | 'pitfalls';
|
|
12
|
+
export interface Tip {
|
|
13
|
+
id: string;
|
|
14
|
+
group: TipGroup;
|
|
15
|
+
zh: string;
|
|
16
|
+
en: string;
|
|
17
|
+
}
|
|
18
|
+
export declare const TIP_GROUP_LABELS: Record<TipGroup, {
|
|
19
|
+
zh: string;
|
|
20
|
+
en: string;
|
|
21
|
+
}>;
|
|
22
|
+
export declare const TIPS: readonly Tip[];
|
|
23
|
+
/**
|
|
24
|
+
* 启动随机轮换选择:每次启动随机取一条,让首屏每次都有新鲜感。
|
|
25
|
+
* random 可注入以便测试固定(默认 Math.random)。
|
|
26
|
+
*/
|
|
27
|
+
export declare function pickRandomTip(random?: () => number): Tip;
|
|
28
|
+
/** 按分组取 tips(/tips 面板展示用,保持 TIPS 内顺序)。 */
|
|
29
|
+
export declare function tipsByGroup(group: TipGroup): Tip[];
|
|
30
|
+
//# sourceMappingURL=tips.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tips.d.ts","sourceRoot":"","sources":["../../src/tips.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAA;AAEhF,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,QAAQ,CAAA;IACf,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;CACX;AAED,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,QAAQ,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAMzE,CAAA;AAED,eAAO,MAAM,IAAI,EAAE,SAAS,GAAG,EAsiB9B,CAAA;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,GAAE,MAAM,MAAoB,GAAG,GAAG,CAErE;AAED,0CAA0C;AAC1C,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,GAAG,EAAE,CAElD"}
|