@deepseek-harness-tui/dsh-tui 0.8.4 → 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.
Files changed (174) hide show
  1. package/bin/dsh-tui.js +0 -0
  2. package/dsh-ecosystem-spec/protocols/profile-definitions.d.ts +13 -13
  3. package/dsh-ecosystem-spec/protocols/profile-definitions.js +59 -59
  4. package/dsh-ecosystem-spec/protocols/tui-channel-http.d.ts +15 -15
  5. package/dsh-ecosystem-spec/protocols/tui-channel-http.js +32 -32
  6. package/dsh-ecosystem-spec/protocols/tui-channel.d.ts +59 -59
  7. package/dsh-ecosystem-spec/protocols/tui-channel.js +166 -166
  8. package/dsh-ecosystem-spec/protocols/tui-contributions.d.ts +42 -42
  9. package/dsh-ecosystem-spec/protocols/tui-contributions.js +143 -143
  10. package/dsh-ecosystem-spec/registry/README.md +14 -14
  11. package/dsh-ecosystem-spec/registry/host-descriptor.tui.example.json +56 -56
  12. package/dsh-ecosystem-spec/registry/permissions-0.1.json +13 -13
  13. package/dsh-ecosystem-spec/registry/registry-0.15.json +149 -149
  14. package/lib/types/activityPrefs.d.ts +10 -0
  15. package/lib/types/activityPrefs.d.ts.map +1 -1
  16. package/lib/types/activityPrefs.js +17 -0
  17. package/lib/types/components/MessageList.d.ts +4 -1
  18. package/lib/types/components/MessageList.d.ts.map +1 -1
  19. package/lib/types/components/MessageList.js +4 -4
  20. package/lib/types/components/SplitDiffView.d.ts +3 -1
  21. package/lib/types/components/SplitDiffView.d.ts.map +1 -1
  22. package/lib/types/components/SplitDiffView.js +12 -5
  23. package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
  24. package/lib/types/components/StreamingMarkdown.js +10 -2
  25. package/lib/types/components/activityFrames.d.ts +7 -28
  26. package/lib/types/components/activityFrames.d.ts.map +1 -1
  27. package/lib/types/components/activityFrames.js +7 -94
  28. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  29. package/lib/types/components/messages/AssistantThinkingMessage.js +1 -1
  30. package/lib/types/components/messages/AssistantToolUseMessage.d.ts +4 -1
  31. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  32. package/lib/types/components/messages/AssistantToolUseMessage.js +14 -3
  33. package/lib/types/dsh-adapter/channel.d.ts +17 -0
  34. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  35. package/lib/types/dsh-adapter/channel.js +161 -19
  36. package/lib/types/dsh-adapter/index.d.ts +5 -0
  37. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  38. package/lib/types/dsh-adapter/index.js +19 -0
  39. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  40. package/lib/types/dsh-adapter/plugin.js +176 -4
  41. package/lib/types/dsh-adapter/settings-sections.d.ts +13 -0
  42. package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
  43. package/lib/types/dsh-adapter/settings-sections.js +31 -6
  44. package/lib/types/ink/ink.d.ts +9 -0
  45. package/lib/types/ink/ink.d.ts.map +1 -1
  46. package/lib/types/ink/ink.js +24 -1
  47. package/lib/types/screens/Chat.d.ts.map +1 -1
  48. package/lib/types/screens/Chat.js +34 -4
  49. package/lib/types/screens/Settings.d.ts.map +1 -1
  50. package/lib/types/screens/Settings.js +109 -50
  51. package/lib/types/screens/StatusLine.d.ts +8 -0
  52. package/lib/types/screens/StatusLine.d.ts.map +1 -1
  53. package/lib/types/screens/StatusLine.js +62 -39
  54. package/lib/types/settings-sections.d.ts +1 -1
  55. package/lib/types/settings-sections.d.ts.map +1 -1
  56. package/lib/types/tips.js +2 -2
  57. package/lib/types/tuiDisplayPrefs.d.ts +47 -0
  58. package/lib/types/tuiDisplayPrefs.d.ts.map +1 -0
  59. package/lib/types/tuiDisplayPrefs.js +60 -0
  60. package/node_modules/@dsh-std/command/CHANGELOG.md +8 -8
  61. package/node_modules/@dsh-std/command/LICENSE +21 -21
  62. package/node_modules/@dsh-std/command/README.md +26 -26
  63. package/node_modules/@dsh-std/command/README.zh.md +28 -28
  64. package/node_modules/@dsh-std/command/lib/index.js.map +1 -1
  65. package/node_modules/@dsh-std/command/package.json +22 -22
  66. package/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
  67. package/node_modules/@dsh-std/connection/LICENSE +21 -21
  68. package/node_modules/@dsh-std/connection/README.md +42 -42
  69. package/node_modules/@dsh-std/connection/README.zh.md +42 -42
  70. package/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
  71. package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  72. package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
  73. package/node_modules/@dsh-std/connection/package.json +20 -20
  74. package/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  75. package/node_modules/@dsh-std/core/LICENSE +21 -21
  76. package/node_modules/@dsh-std/core/README.md +13 -13
  77. package/node_modules/@dsh-std/core/README.zh.md +13 -13
  78. package/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  79. package/node_modules/@dsh-std/core/package.json +21 -21
  80. package/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -9
  81. package/node_modules/@dsh-std/manifest/LICENSE +21 -21
  82. package/node_modules/@dsh-std/manifest/README.md +5 -5
  83. package/node_modules/@dsh-std/manifest/README.zh.md +5 -5
  84. package/node_modules/@dsh-std/manifest/lib/index.js.map +1 -1
  85. package/node_modules/@dsh-std/manifest/package.json +20 -20
  86. package/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -144
  87. package/node_modules/@dsh-std/messages/CHANGELOG.md +8 -8
  88. package/node_modules/@dsh-std/messages/LICENSE +21 -21
  89. package/node_modules/@dsh-std/messages/README.md +5 -5
  90. package/node_modules/@dsh-std/messages/README.zh.md +7 -7
  91. package/node_modules/@dsh-std/messages/lib/index.js.map +1 -1
  92. package/node_modules/@dsh-std/messages/package.json +20 -20
  93. package/node_modules/@dsh-std/messages/schema/message-observer-envelope-0.15.schema.json +54 -54
  94. package/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -9
  95. package/node_modules/@dsh-std/presentation/LICENSE +21 -21
  96. package/node_modules/@dsh-std/presentation/README.md +27 -27
  97. package/node_modules/@dsh-std/presentation/README.zh.md +29 -29
  98. package/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -1
  99. package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
  100. package/node_modules/@dsh-std/presentation/package.json +25 -25
  101. package/node_modules/@dsh-std/storage/CHANGELOG.md +8 -8
  102. package/node_modules/@dsh-std/storage/LICENSE +21 -21
  103. package/node_modules/@dsh-std/storage/README.md +5 -5
  104. package/node_modules/@dsh-std/storage/README.zh.md +7 -7
  105. package/node_modules/@dsh-std/storage/lib/index.js.map +1 -1
  106. package/node_modules/@dsh-std/storage/package.json +20 -20
  107. package/node_modules/@dsh-std/storage/schema/local-storage-0.15.schema.json +56 -56
  108. package/package.json +6 -3
  109. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
  110. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/LICENSE +21 -21
  111. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.md +42 -42
  112. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.zh.md +42 -42
  113. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
  114. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  115. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
  116. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +20 -20
  117. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  118. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/LICENSE +21 -21
  119. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.md +13 -13
  120. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.zh.md +13 -13
  121. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  122. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +21 -21
  123. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -9
  124. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/LICENSE +21 -21
  125. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.md +5 -5
  126. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.zh.md +5 -5
  127. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js.map +1 -1
  128. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +20 -20
  129. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -144
  130. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -9
  131. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/LICENSE +21 -21
  132. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +27 -27
  133. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +29 -29
  134. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -1
  135. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
  136. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +25 -25
  137. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  138. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/LICENSE +21 -21
  139. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.md +13 -13
  140. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.zh.md +13 -13
  141. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  142. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +21 -21
  143. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  144. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/LICENSE +21 -21
  145. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.md +13 -13
  146. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.zh.md +13 -13
  147. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  148. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +21 -21
  149. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  150. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/LICENSE +21 -21
  151. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.md +13 -13
  152. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.zh.md +13 -13
  153. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  154. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +21 -21
  155. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
  156. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/LICENSE +21 -21
  157. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.md +42 -42
  158. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.zh.md +42 -42
  159. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
  160. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  161. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
  162. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +20 -20
  163. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  164. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/LICENSE +21 -21
  165. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.md +13 -13
  166. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.zh.md +13 -13
  167. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  168. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +21 -21
  169. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  170. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/LICENSE +21 -21
  171. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.md +13 -13
  172. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.zh.md +13 -13
  173. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  174. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +21 -21
@@ -88,12 +88,30 @@ function registerSection(runtime, section, owner) {
88
88
  throw new TypeError(`invalid TUI settings-section namespace: ${section.ns}`);
89
89
  if (state.sections.has(ns))
90
90
  throw new Error(`TUI settings section "${ns}" is already registered`);
91
- const normalized = Object.freeze({
92
- ...section,
93
- ns,
94
- descriptions: section.descriptions === undefined ? undefined : Object.freeze({ ...section.descriptions }),
95
- fields: Object.freeze(section.fields.map(field => Object.freeze({
91
+ const groupIds = new Set();
92
+ const groups = section.groups === undefined
93
+ ? undefined
94
+ : Object.freeze(section.groups.map(group => {
95
+ const id = group.id.trim();
96
+ if (!/^[a-z][a-z0-9_-]*$/u.test(id))
97
+ throw new TypeError(`invalid TUI settings group id: ${group.id}`);
98
+ if (groupIds.has(id))
99
+ throw new Error(`TUI settings group "${id}" is already declared in section "${ns}"`);
100
+ groupIds.add(id);
101
+ return Object.freeze({
102
+ ...group,
103
+ id,
104
+ descriptions: group.descriptions === undefined ? undefined : Object.freeze({ ...group.descriptions }),
105
+ });
106
+ }));
107
+ const fields = Object.freeze(section.fields.map(field => {
108
+ const group = field.group?.trim();
109
+ if (group !== undefined && !groupIds.has(group)) {
110
+ throw new TypeError(`TUI settings field "${field.path.join('.')}" references unknown group "${field.group}" in section "${ns}"`);
111
+ }
112
+ return Object.freeze({
96
113
  ...field,
114
+ group,
97
115
  path: Object.freeze([...field.path]),
98
116
  descriptions: field.descriptions === undefined ? undefined : Object.freeze({ ...field.descriptions }),
99
117
  hintDescriptions: field.hintDescriptions === undefined ? undefined : Object.freeze({ ...field.hintDescriptions }),
@@ -101,7 +119,14 @@ function registerSection(runtime, section, owner) {
101
119
  ? undefined
102
120
  : Object.freeze(field.options.map(option => Object.freeze({ ...option, descriptions: option.descriptions === undefined ? undefined : Object.freeze({ ...option.descriptions }) }))),
103
121
  secret: field.secret === undefined ? undefined : Object.freeze({ ...field.secret }),
104
- }))),
122
+ });
123
+ }));
124
+ const normalized = Object.freeze({
125
+ ...section,
126
+ ns,
127
+ descriptions: section.descriptions === undefined ? undefined : Object.freeze({ ...section.descriptions }),
128
+ groups,
129
+ fields,
105
130
  });
106
131
  state.sections.set(ns, normalized);
107
132
  if (owner !== undefined)
@@ -113,6 +113,15 @@ export default class Ink {
113
113
  * unchanged cells don't need repainting. Scrollback is preserved.
114
114
  */
115
115
  forceRedraw(): void;
116
+ /**
117
+ * Establish a genuinely fresh terminal page: clear both the visible screen
118
+ * and native scrollback, reset frame correspondence, then redraw the current
119
+ * React tree. This is intentionally stronger than Ctrl+L/forceRedraw(),
120
+ * which preserves history; use it only at a destructive UI boundary such as
121
+ * `/new`, where showing the previous conversation above the new session is
122
+ * misleading.
123
+ */
124
+ clearScrollbackAndRedraw(): void;
116
125
  /**
117
126
  * Mark the previous frame as untrustworthy for blit, forcing the next
118
127
  * render to do a full-damage diff instead of the per-node fast path.
@@ -1 +1 @@
1
- {"version":3,"file":"ink.d.ts","sourceRoot":"","sources":["../../../src/ink/ink.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ink.d.ts","sourceRoot":"","sources":["../../../src/ink/ink.tsx"],"names":[],"mappings":"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"}
@@ -32,7 +32,7 @@ import { CharPool, cellAt, createScreen, HyperlinkPool, isEmptyCellAt, migrateSc
32
32
  import { applySearchHighlight } from './searchHighlight.js';
33
33
  import { applySelectionOverlay, captureScrolledRows, clearSelection, createSelectionState, extendSelection, findPlainTextUrlAt, getSelectedText, hasSelection, moveFocus, selectLineAt, selectWordAt, shiftAnchor, shiftSelection, shiftSelectionForFollow, startSelection, updateSelection } from './selection.js';
34
34
  import { isDecstbmSafe, SYNC_OUTPUT_SUPPORTED, supportsExtendedKeys, supportsWin32InputMode, writeDiffToTerminal } from './terminal.js';
35
- import { CURSOR_HOME, cursorMove, cursorPosition, DISABLE_KITTY_KEYBOARD, DISABLE_MODIFY_OTHER_KEYS, DISABLE_WIN32_INPUT_MODE, ENABLE_KITTY_KEYBOARD, ENABLE_MODIFY_OTHER_KEYS, ENABLE_WIN32_INPUT_MODE, ERASE_SCREEN, SGR_RESET } from './termio/csi.js';
35
+ import { CURSOR_HOME, cursorMove, cursorPosition, DISABLE_KITTY_KEYBOARD, DISABLE_MODIFY_OTHER_KEYS, DISABLE_WIN32_INPUT_MODE, ENABLE_KITTY_KEYBOARD, ENABLE_MODIFY_OTHER_KEYS, ENABLE_WIN32_INPUT_MODE, ERASE_SCREEN, ERASE_SCROLLBACK, SGR_RESET } from './termio/csi.js';
36
36
  import { DBP, DFE, DISABLE_MOUSE_TRACKING, ENABLE_MOUSE_TRACKING, ENTER_ALT_SCREEN, EXIT_ALT_SCREEN, SHOW_CURSOR } from './termio/dec.js';
37
37
  import { CLEAR_ITERM2_PROGRESS, CLEAR_TAB_STATUS, setClipboard, supportsTabStatus, wrapForMultiplexer } from './termio/osc.js';
38
38
  import { TerminalWriteProvider } from './useTerminalNotification.js';
@@ -874,6 +874,29 @@ export default class Ink {
874
874
  }
875
875
  this.onRender();
876
876
  }
877
+ /**
878
+ * Establish a genuinely fresh terminal page: clear both the visible screen
879
+ * and native scrollback, reset frame correspondence, then redraw the current
880
+ * React tree. This is intentionally stronger than Ctrl+L/forceRedraw(),
881
+ * which preserves history; use it only at a destructive UI boundary such as
882
+ * `/new`, where showing the previous conversation above the new session is
883
+ * misleading.
884
+ */
885
+ clearScrollbackAndRedraw() {
886
+ if (!this.options.stdout.isTTY || this.isUnmounted || this.isPaused)
887
+ return;
888
+ // Keep 3J outside synchronized output. Windows Terminal can relocate the
889
+ // viewport when erase-buffer commands execute inside BSU/ESU.
890
+ this.options.stdout.write(SGR_RESET + ERASE_SCROLLBACK + ERASE_SCREEN + CURSOR_HOME);
891
+ if (this.altScreenActive) {
892
+ this.resetFramesForAltScreen();
893
+ }
894
+ else {
895
+ this.repaint();
896
+ this.prevFrameContaminated = true;
897
+ }
898
+ this.onRender();
899
+ }
877
900
  /**
878
901
  * Mark the previous frame as untrustworthy for blit, forcing the next
879
902
  * render to do a full-damage diff instead of the per-node fast path.
@@ -1 +1 @@
1
- {"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/screens/Chat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AASzB,OAAO,EAAqB,KAAK,OAAO,EAAsE,MAAM,2BAA2B,CAAA;AAC/I,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAGlE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAyI3D,wBAAgB,IAAI,CAAC,EACnB,OAAO,EACP,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,MAAM,EACN,QAAQ,EACR,UAAkB,EAClB,cAAc,EAAE,kBAAkB,GACnC,EAAE;IACD,OAAO,EAAE,OAAO,CAAA;IAChB,aAAa,EAAE,aAAa,CAAA;IAC5B;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,cAAc,CAAA;IACjC,oEAAoE;IACpE,eAAe,CAAC,EAAE,cAAc,CAAA;IAChC,iDAAiD;IACjD,kBAAkB,CAAC,EAAE,eAAe,CAAA;IACpC,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB,qBAkmEA"}
1
+ {"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/screens/Chat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AASzB,OAAO,EAAqB,KAAK,OAAO,EAAsE,MAAM,2BAA2B,CAAA;AAC/I,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAGlE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAyI3D,wBAAgB,IAAI,CAAC,EACnB,OAAO,EACP,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,MAAM,EACN,QAAQ,EACR,UAAkB,EAClB,cAAc,EAAE,kBAAkB,GACnC,EAAE;IACD,OAAO,EAAE,OAAO,CAAA;IAChB,aAAa,EAAE,aAAa,CAAA;IAC5B;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,cAAc,CAAA;IACjC,oEAAoE;IACpE,eAAe,CAAC,EAAE,cAAc,CAAA;IAChC,iDAAiD;IACjD,kBAAkB,CAAC,EAAE,eAAe,CAAA;IACpC,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB,qBAioEA"}
@@ -298,6 +298,18 @@ export function Chat({ channel, questionStore, approvalStore, extensionDialogs,
298
298
  const loadedContextVisible = channel.rows.length === 0 && channel.loadedContext !== undefined;
299
299
  /** Startup context panel: collapsed by default, toggled with Ctrl+P. */
300
300
  const [loadedContextOpen, setLoadedContextOpen] = React.useState(false);
301
+ /**
302
+ * The context panel changes the height of the main-screen transcript by a
303
+ * large amount. In inline mode that invalidates the renderer's previous
304
+ * scrollback/layout correspondence; asking it to repaint from the physical
305
+ * viewport prevents the collapsed frame from reusing stale blank cells.
306
+ */
307
+ const toggleLoadedContext = React.useCallback(() => {
308
+ setLoadedContextOpen(previous => !previous);
309
+ const ink = instances.get(process.stdout) ?? instances.values().next().value;
310
+ ink?.invalidatePrevFrame();
311
+ ink?.reanchorViewport();
312
+ }, []);
301
313
  /** `/` transcript search (less-style incsearch, ported from CC's REPL). */
302
314
  const [searchOpen, setSearchOpen] = React.useState(false);
303
315
  const [searchQuery, setSearchQuery] = React.useState('');
@@ -659,8 +671,26 @@ export function Chat({ channel, questionStore, approvalStore, extensionDialogs,
659
671
  // non-destructive — no CC-style "press /new again" confirmation.
660
672
  setHelpOpen(false);
661
673
  void channel.newSession().then((ok) => {
662
- if (ok)
663
- channel.notify(t('new-session-started'));
674
+ if (!ok)
675
+ return;
676
+ // A new session is a fresh terminal page, not merely an emptied
677
+ // transcript. Reset view-local state, return the ScrollBox to the
678
+ // top, then clear native scrollback and repaint the whale homepage.
679
+ setExpanded(false);
680
+ setExpandedRows(new Set());
681
+ setSelectedId(null);
682
+ setSelectionActive(false);
683
+ setShowAllMessages(false);
684
+ setLoadedContextOpen(false);
685
+ handle?.scrollTo(0);
686
+ channel.notify(t('new-session-started'));
687
+ const ink = instances.get(process.stdout) ?? instances.values().next().value;
688
+ // Wait one task so React commits the empty transcript/homepage tree;
689
+ // clearing before that would immediately repaint the old session.
690
+ setTimeout(() => {
691
+ handle?.scrollTo(0);
692
+ ink?.clearScrollbackAndRedraw();
693
+ }, 0);
664
694
  });
665
695
  return true;
666
696
  }
@@ -1824,7 +1854,7 @@ export function Chat({ channel, questionStore, approvalStore, extensionDialogs,
1824
1854
  // Ctrl+P toggles the startup loaded-context panel while it is on
1825
1855
  // screen (transcript still empty); once rows take over and the
1826
1856
  // panel disappears the key has nothing left to do.
1827
- setLoadedContextOpen(previous => !previous);
1857
+ toggleLoadedContext();
1828
1858
  return;
1829
1859
  }
1830
1860
  if (isMod(key) && input === 'r' && !helpOpen) {
@@ -2014,7 +2044,7 @@ export function Chat({ channel, questionStore, approvalStore, extensionDialogs,
2014
2044
  seekRow(lastUser.id);
2015
2045
  else
2016
2046
  handle?.scrollToBottom();
2017
- } })), _jsxs(ScrollBox, { ref: setHandle, flexDirection: "column", flexGrow: 1, flexShrink: 1, stickyScroll: true, children: [_jsx(LogoHeader, { model: channel.model, effort: channel.reasoningEffort, cwd: channel.displayCwd }), loadedContextVisible && (_jsx(LoadedContextPanel, { context: channel.loadedContext, open: loadedContextOpen, onToggle: () => { setLoadedContextOpen(previous => !previous); } })), _jsx(MessageList, { rows: channel.rows, failureHintRowId: failureHintRowId, failureHint: t('traj-hint-failure', { key: `${modLabel}t` }), expanded: expanded, expandedRows: expandedRows, selectedId: selectionActive ? selectedId : null, onToggleRow: toggleRowExpanded, model: channel.model, diffLayout: channel.diffLayout, thinkingFold: channel.thinkingFold, showAll: showAllMessages, thinkingVisible: thinkingVisible, onToggleAll: () => { setShowAllMessages(previous => !previous); }, onLoadOlder: () => channel.loadOlder(), registerRowRef: registerRowRef, scrollHandle: handle, forceMountRowId: forceMountRowId, newSinceRowId: isSticky ? null : lastSeenRowIdRef.current, onUnseenCount: setUnseenCount })] }), _jsxs(Box, { flexDirection: "column", flexShrink: 0, children: [showPill && (_jsx(NewMessagesPill, { count: unseenCount, onClick: () => handle?.scrollToBottom() })), channel.working &&
2047
+ } })), _jsxs(ScrollBox, { ref: setHandle, flexDirection: "column", flexGrow: 1, flexShrink: 1, stickyScroll: true, children: [_jsx(LogoHeader, { model: channel.model, effort: channel.reasoningEffort, cwd: channel.displayCwd }), loadedContextVisible && (_jsx(LoadedContextPanel, { context: channel.loadedContext, open: loadedContextOpen, onToggle: toggleLoadedContext })), _jsx(MessageList, { rows: channel.rows, failureHintRowId: failureHintRowId, failureHint: t('traj-hint-failure', { key: `${modLabel}t` }), expanded: expanded, expandedRows: expandedRows, selectedId: selectionActive ? selectedId : null, onToggleRow: toggleRowExpanded, model: channel.model, diffLayout: channel.diffLayout, thinkingFold: channel.thinkingFold, toolBackground: channel.toolBackground, showAll: showAllMessages, thinkingVisible: thinkingVisible, onToggleAll: () => { setShowAllMessages(previous => !previous); }, onLoadOlder: () => channel.loadOlder(), registerRowRef: registerRowRef, scrollHandle: handle, forceMountRowId: forceMountRowId, newSinceRowId: isSticky ? null : lastSeenRowIdRef.current, onUnseenCount: setUnseenCount })] }), _jsxs(Box, { flexDirection: "column", flexShrink: 0, children: [showPill && (_jsx(NewMessagesPill, { count: unseenCount, onClick: () => handle?.scrollToBottom() })), channel.working &&
2018
2048
  (channel.activityEnabled &&
2019
2049
  channel.workingActivity !== undefined &&
2020
2050
  channel.workingActivity.line !== '' &&
@@ -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;AA2CxD;;;;;;;;;;;;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,CA0VlB"}
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
- /** Focusable rows in display order: every field of every section. */
104
- const focusable = sections.flatMap(section => section.fields.map(field => ({ ns: section.ns, field })));
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
- // Esc backs out one layer at a time: staged drafts first — ANY dirty
200
- // section, not just the focused one, so leaving never silently drops
201
- // an edit made two sections ago — the screen second. A save in flight
202
- // cannot be undone from here; let it settle instead of discarding
203
- // around it.
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 !== undefined && focused.ns === ns && focused.field === field;
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 field is always on screen no matter how long the list gets. ────
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
- sections.forEach((section, sectionIndex) => {
255
- const form = forms.get(section.ns);
256
- const view = form?.namespace;
257
- const shell = form?.shell();
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: `section:${section.ns}`,
260
- lines: sectionIndex === 0 ? 1 : 2,
261
- 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'), "]"] })] })] })),
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
- for (const field of section.fields) {
264
- const isFocused = focused !== undefined && focused.ns === section.ns && focused.field === field;
265
- const hasHint = field.hint !== undefined && isFocused;
266
- const index = focusCursor;
267
- focusCursor += 1;
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: `field:${section.ns}:${field.path.join('.')}`,
270
- lines: hasHint ? 2 : 1,
271
- focus: index,
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
- const registeredNs = new Set(sections.map(section => section.ns));
277
- const readonlyNamespaces = namespaces.filter(entry => !registeredNs.has(entry.ns));
278
- if (readonlyNamespaces.length > 0) {
279
- entries.push({
280
- key: 'readonly:heading',
281
- lines: 2,
282
- node: (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { children: " " }), _jsx(Text, { bold: true, dimColor: true, children: t('settings-readonly-heading') })] })),
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
- for (const entry of readonlyNamespaces) {
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: `readonly:${entry.ns}`,
346
+ key: 'readonly:hint',
287
347
  lines: 1,
288
- 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)] })] })),
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
- return (_jsxs(Box, { flexDirection: "column", width: columns, height: rows, children: [_jsxs(Box, { children: [_jsx(Text, { bold: true, children: t('settings-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') : t('settings-hint-list') }) })] }));
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,qBA2MA"}
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"}