@deepseek-harness-tui/dsh-tui 0.11.2 → 0.12.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.
Files changed (168) hide show
  1. package/README.md +21 -5
  2. package/bin/dsh-tui.js +30 -3
  3. package/cordis.patch.yml +24 -5
  4. package/guide/dsh-tui-guide/SKILL.md +37 -0
  5. package/guide/dsh-tui-guide/configuration.en.md +410 -0
  6. package/guide/dsh-tui-guide/configuration.md +349 -0
  7. package/guide/dsh-tui-guide/getting-started.en.md +398 -0
  8. package/guide/dsh-tui-guide/getting-started.md +397 -0
  9. package/guide/dsh-tui-guide/interaction.en.md +674 -0
  10. package/guide/dsh-tui-guide/interaction.md +747 -0
  11. package/guide/dsh-tui-guide/migrate.en.md +166 -0
  12. package/guide/dsh-tui-guide/migrate.md +132 -0
  13. package/guide/dsh-tui-guide/plugins.en.md +68 -0
  14. package/guide/dsh-tui-guide/plugins.md +56 -0
  15. package/guide/dsh-tui-guide/themes.en.md +192 -0
  16. package/guide/dsh-tui-guide/themes.md +185 -0
  17. package/guide/dsh-tui-guide/user-guide.en.md +608 -0
  18. package/guide/dsh-tui-guide/user-guide.md +586 -0
  19. package/guide/dsh-tui-guide/vscode.en.md +301 -0
  20. package/guide/dsh-tui-guide/vscode.md +272 -0
  21. package/lib/settings.json +5 -5
  22. package/lib/types/adapter/channel/ui-policy.d.ts +3 -2
  23. package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
  24. package/lib/types/adapter/channel/ui-policy.js +4 -0
  25. package/lib/types/adapter/ports/channel-settings.d.ts +2 -1
  26. package/lib/types/adapter/ports/channel-settings.d.ts.map +1 -1
  27. package/lib/types/adapter/ports/channel-ui.d.ts +29 -2
  28. package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
  29. package/lib/types/adapter/ports/channel-view.d.ts +43 -9
  30. package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
  31. package/lib/types/components/Chat/JobCard.d.ts +9 -0
  32. package/lib/types/components/Chat/JobCard.d.ts.map +1 -1
  33. package/lib/types/components/Chat/JobCard.js +42 -15
  34. package/lib/types/components/Chat/SubagentMessage.js +6 -6
  35. package/lib/types/components/JobsPanel.d.ts.map +1 -1
  36. package/lib/types/components/JobsPanel.js +80 -33
  37. package/lib/types/components/MessageList.js +3 -3
  38. package/lib/types/components/PresetPicker.d.ts +4 -0
  39. package/lib/types/components/PresetPicker.d.ts.map +1 -1
  40. package/lib/types/components/PresetPicker.js +5 -1
  41. package/lib/types/components/PromptInput.d.ts.map +1 -1
  42. package/lib/types/components/PromptInput.js +12 -1
  43. package/lib/types/components/StarPrompt.d.ts +6 -0
  44. package/lib/types/components/StarPrompt.d.ts.map +1 -1
  45. package/lib/types/components/StarPrompt.js +45 -0
  46. package/lib/types/components/SubagentCard.d.ts.map +1 -1
  47. package/lib/types/components/SubagentCard.js +8 -8
  48. package/lib/types/components/SubagentDetailScene.d.ts.map +1 -1
  49. package/lib/types/components/SubagentDetailScene.js +108 -10
  50. package/lib/types/components/WhaleGirl.d.ts +6 -0
  51. package/lib/types/components/WhaleGirl.d.ts.map +1 -1
  52. package/lib/types/components/WhaleGirl.js +18 -0
  53. package/lib/types/components/messages/AssistantThinkingMessage.js +4 -4
  54. package/lib/types/components/trajectory/MiniWake.d.ts +11 -1
  55. package/lib/types/components/trajectory/MiniWake.d.ts.map +1 -1
  56. package/lib/types/components/trajectory/MiniWake.js +9 -3
  57. package/lib/types/dsh-adapter/channel/external-commands.d.ts.map +1 -1
  58. package/lib/types/dsh-adapter/channel/external-commands.js +8 -2
  59. package/lib/types/dsh-adapter/channel/job-projection.d.ts +1 -0
  60. package/lib/types/dsh-adapter/channel/job-projection.d.ts.map +1 -1
  61. package/lib/types/dsh-adapter/channel/job-projection.js +88 -3
  62. package/lib/types/dsh-adapter/channel/mode-actions.d.ts +13 -0
  63. package/lib/types/dsh-adapter/channel/mode-actions.d.ts.map +1 -1
  64. package/lib/types/dsh-adapter/channel/mode-actions.js +48 -7
  65. package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts.map +1 -1
  66. package/lib/types/dsh-adapter/channel/mode-permission-actions.js +25 -9
  67. package/lib/types/dsh-adapter/channel/preferences.d.ts +1 -1
  68. package/lib/types/dsh-adapter/channel/preferences.d.ts.map +1 -1
  69. package/lib/types/dsh-adapter/channel/preferences.js +17 -7
  70. package/lib/types/dsh-adapter/channel/state.d.ts +4 -2
  71. package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
  72. package/lib/types/dsh-adapter/channel/state.js +1 -1
  73. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -1
  74. package/lib/types/dsh-adapter/channel/subagent-projection.js +5 -0
  75. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  76. package/lib/types/dsh-adapter/channel.js +16 -1
  77. package/lib/types/dsh-adapter/contract.d.ts +5 -4
  78. package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
  79. package/lib/types/dsh-adapter/contract.js +9 -3
  80. package/lib/types/dsh-adapter/jobs.d.ts +82 -16
  81. package/lib/types/dsh-adapter/jobs.d.ts.map +1 -1
  82. package/lib/types/dsh-adapter/jobs.js +104 -9
  83. package/lib/types/dsh-adapter/oauth/bonus.d.ts +27 -0
  84. package/lib/types/dsh-adapter/oauth/bonus.d.ts.map +1 -0
  85. package/lib/types/dsh-adapter/oauth/bonus.js +69 -0
  86. package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/command.d.ts +2 -1
  87. package/lib/types/dsh-adapter/oauth/command.d.ts.map +1 -0
  88. package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/command.js +7 -4
  89. package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/credentials.d.ts +13 -10
  90. package/lib/types/dsh-adapter/oauth/credentials.d.ts.map +1 -0
  91. package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/credentials.js +61 -23
  92. package/lib/types/dsh-adapter/oauth/deepseek.d.ts +39 -0
  93. package/lib/types/dsh-adapter/oauth/deepseek.d.ts.map +1 -0
  94. package/lib/types/dsh-adapter/oauth/deepseek.js +189 -0
  95. package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/index.d.ts +24 -16
  96. package/lib/types/dsh-adapter/oauth/index.d.ts.map +1 -0
  97. package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/index.js +34 -20
  98. package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/interaction.d.ts +14 -12
  99. package/lib/types/dsh-adapter/oauth/interaction.d.ts.map +1 -0
  100. package/lib/types/dsh-adapter/oauth/interaction.js +283 -0
  101. package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/opener.d.ts +2 -1
  102. package/lib/types/dsh-adapter/oauth/opener.d.ts.map +1 -0
  103. package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/opener.js +1 -1
  104. package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/pi-ai.d.ts +10 -3
  105. package/lib/types/dsh-adapter/oauth/pi-ai.d.ts.map +1 -0
  106. package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/pi-ai.js +8 -3
  107. package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/profiles.d.ts +6 -3
  108. package/lib/types/dsh-adapter/oauth/profiles.d.ts.map +1 -0
  109. package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/profiles.js +11 -3
  110. package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/service.d.ts +14 -7
  111. package/lib/types/dsh-adapter/oauth/service.d.ts.map +1 -0
  112. package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/service.js +82 -17
  113. package/lib/types/dsh-adapter/plugin.d.ts +8 -1
  114. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  115. package/lib/types/dsh-adapter/plugin.js +72 -12
  116. package/lib/types/dsh-adapter/presets.d.ts +6 -4
  117. package/lib/types/dsh-adapter/presets.d.ts.map +1 -1
  118. package/lib/types/dsh-adapter/presets.js +6 -4
  119. package/lib/types/dsh-adapter/providerWizard.d.ts.map +1 -1
  120. package/lib/types/dsh-adapter/providerWizard.js +6 -2
  121. package/lib/types/dsh-adapter/subagents.d.ts +1 -0
  122. package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
  123. package/lib/types/dsh-adapter/subagents.js +10 -1
  124. package/lib/types/i18n.d.ts +174 -18
  125. package/lib/types/i18n.d.ts.map +1 -1
  126. package/lib/types/i18n.js +53 -11
  127. package/lib/types/ink/components/App.d.ts.map +1 -1
  128. package/lib/types/ink/components/App.js +10 -1
  129. package/lib/types/ink/parse-keypress.d.ts +35 -0
  130. package/lib/types/ink/parse-keypress.d.ts.map +1 -1
  131. package/lib/types/ink/parse-keypress.js +611 -83
  132. package/lib/types/ink/terminal-querier.d.ts +25 -0
  133. package/lib/types/ink/terminal-querier.d.ts.map +1 -1
  134. package/lib/types/ink/terminal-querier.js +42 -0
  135. package/lib/types/ink/update-overflow-guard.d.ts +24 -0
  136. package/lib/types/ink/update-overflow-guard.d.ts.map +1 -1
  137. package/lib/types/ink/update-overflow-guard.js +25 -3
  138. package/lib/types/minimalUiMode.d.ts +19 -0
  139. package/lib/types/minimalUiMode.d.ts.map +1 -0
  140. package/lib/types/minimalUiMode.js +23 -0
  141. package/lib/types/oauth.d.ts +5 -10
  142. package/lib/types/oauth.d.ts.map +1 -1
  143. package/lib/types/oauth.js +5 -10
  144. package/lib/types/screens/Chat.d.ts +4 -1
  145. package/lib/types/screens/Chat.d.ts.map +1 -1
  146. package/lib/types/screens/Chat.js +27 -7
  147. package/lib/types/screens/StatusLine.d.ts +4 -0
  148. package/lib/types/screens/StatusLine.d.ts.map +1 -1
  149. package/lib/types/screens/StatusLine.js +12 -12
  150. package/lib/types/settings/definitions.js +4 -4
  151. package/lib/types/tips.d.ts.map +1 -1
  152. package/lib/types/tips.js +10 -4
  153. package/lib/types/update.js +2 -2
  154. package/lib/types/utils/pastedImagePath.d.ts +8 -0
  155. package/lib/types/utils/pastedImagePath.d.ts.map +1 -1
  156. package/lib/types/utils/pastedImagePath.js +29 -5
  157. package/package.json +111 -100
  158. package/presets/liangshen/agent.cordis.yml +4 -1
  159. package/presets/liangshen/preset.yml +1 -1
  160. package/lib/types/minimalMode.d.ts +0 -13
  161. package/lib/types/minimalMode.d.ts.map +0 -1
  162. package/lib/types/minimalMode.js +0 -17
  163. package/node_modules/@deepseek-harness-tui/dsh-auth/LICENSE +0 -21
  164. package/node_modules/@deepseek-harness-tui/dsh-auth/README.md +0 -143
  165. package/node_modules/@deepseek-harness-tui/dsh-auth/cordis.patch.yml +0 -11
  166. package/node_modules/@deepseek-harness-tui/dsh-auth/dsh-plugin.json +0 -44
  167. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/interaction.js +0 -193
  168. package/node_modules/@deepseek-harness-tui/dsh-auth/package.json +0 -69
@@ -0,0 +1,608 @@
1
+ # dsh-TUI User Guide
2
+
3
+ [Documentation index](README.md) · [中文](user-guide.md)
4
+
5
+ > A user manual for day-to-day use: launch, keys, commands, session workflow, UI indicators, and tips.
6
+
7
+ ## Table of contents
8
+
9
+ - [1. Quick start](#1-quick-start)
10
+ - [2. Keymap quick reference](#2-keymap-quick-reference)
11
+ - [3. Command reference](#3-command-reference)
12
+ - [4. Session workflow](#4-session-workflow)
13
+ - [5. UI and status bar](#5-ui-and-status-bar)
14
+ - [6. Model / preset / theme / language](#6-model--preset--theme--language)
15
+ - [7. Tips](#7-tips)
16
+
17
+ ## 1. Quick start
18
+
19
+ ### 1.1 Install and launch
20
+
21
+ ```sh
22
+ # Install the CLI + this plugin (the plugin ships its own dsh-tui command)
23
+ npm install -g @deepseek-ai/dsh @deepseek-harness-tui/dsh-tui
24
+
25
+ # Start (first run auto-initializes the dsh-tui profile, needs pnpm)
26
+ dsh-tui
27
+ ```
28
+
29
+ - `dsh-tui --resume`: resume the last session. On Windows you can also use `dsh-tui.cmd` from the repo (equivalent).
30
+ - `dsh-tui safe`: safe mode — read-only environment view, lists profile plugins, suggests fixes, and can create a clean rescue profile (see §5.5).
31
+ - `dsh --profile dsh-tui`: manual launch, equivalent to `dsh-tui` (`/update` only works this way).
32
+ - The `deepseek-official` route needs `DEEPSEEK_API_KEY`; on DSH 0.2.0-rc.1+ the standard profile can use the separate `deepseek-account` browser-authorization route. Other supported subscriptions use built-in OAuth sign-in. Run `/doctor` to check the environment.
33
+ - Primary verified dsh engine version: `0.2.0-rc.2`. See `ADAPTER.md` for compatibility lines; versions outside that list show a drift note and the command to align on the logo page.
34
+ - If the logo page shows a ⚠ version-drift warning, align the dsh engine:
35
+ `npm i -g @deepseek-ai/dsh@<版本>`
36
+
37
+ ### 1.2 What you see on first launch
38
+
39
+ 1. **Pixel whale header** (~3.4 s intro animation, then frozen): `✦ dsh-TUI` version,
40
+ `DEEPSEEK / HARNESS` big text, current model and effort, working directory, and a
41
+ **startup hint** (`/model` · `/help` · `Tab`). Narrow terminals climb down a ladder (see 5.1).
42
+ When the dsh engine is out of the verified range, a **⚠ version-drift warning**
43
+ appears with the align command.
44
+ 2. **Bottom status bar**: working-status row, context bar, TPS gauge, and other live
45
+ indicators (see [5. UI and status bar](#5-ui-and-status-bar)).
46
+ 3. **Startup hint line**: one fixed line under the logo:
47
+ `提示:<随机小技巧> · /tips 更多技巧` — changes each launch.
48
+ `/tips` opens the full tips panel (`↑/↓` scroll, `Esc` close).
49
+ 4. **First normal launch** (no `--resume`, no workspace, no prompt) enters the
50
+ **session manager** to pick a workspace. `~/.dsh-tui/home.json` records "seen"
51
+ so later launches go straight to chat. Open it any time with `/resume`, `/home`,
52
+ `/agentview`, `/bg`, or `⌸` at the start of the input line.
53
+ 5. Type `/` for the command menu, `?` for the shortcut help.
54
+
55
+ ### 1.3 Core mental model
56
+
57
+ - Every command supports **Tab completion** (for commands with arguments,
58
+ type `/命令 ` first, then Tab).
59
+ - Non-command input is a normal message. **Unknown commands are sent to the model as plain messages**.
60
+
61
+ ## 2. Keymap quick reference
62
+
63
+ > In the tables, `Ctrl` on macOS can usually be swapped for `⌘` (`⌘V` `⌘O` `⌘R` `⌘T` `⌘L` `⌘Enter`);
64
+ > `Ctrl+C`/`Ctrl+D` stay `Ctrl`.
65
+ > `⌘` needs the extended keyboard protocol (see §5.4). Terminal.app: use Ctrl.
66
+
67
+ ### 2.1 Send and deliver (three behaviors while the model is working)
68
+
69
+ | Key | Action |
70
+ |---|---|
71
+ | `Enter` | idle = send; **model working = steer** (inject a next-step boundary, no interrupt); menu open = confirm selection |
72
+ | `Tab` | complete `/` command or `@` file; **model working = follow-up** (queue after the current turn) |
73
+ | `Ctrl+Enter` (⌘Enter) | interrupt the current turn and send the input now |
74
+ | `Shift+Enter` / `Ctrl+J` | newline (`Option+Enter` is the mac Terminal.app fallback) |
75
+ | `Alt+Up` | bring the last unhandled message back to the input for editing (no interrupt) |
76
+ | `Esc` (working + pending) | interrupt the turn and re-send the pending message now |
77
+ | `/btw …` while working | Enter runs it directly (side question never interrupts the main turn) |
78
+
79
+ ### 2.2 Interrupt / exit / system
80
+
81
+ | Key | Action |
82
+ |---|---|
83
+ | `Ctrl+C` | working = interrupt; if the interrupt won't settle, press again = force quit; idle with input = clear input; idle empty input = double-press exit (3 s window) |
84
+ | `Ctrl+D` | working = interrupt (press again if it won't settle = force quit); idle = double-press exit |
85
+ | `Ctrl+L` (⌘L) | clear screen and force redraw |
86
+ | `Ctrl+O` (⌘O) | expand/collapse details (full thinking, tool args and output) |
87
+ | `Ctrl+E` | in input = cursor to line end; in transcript = expand/collapse hidden old messages |
88
+ | `Ctrl+P` | toggle the loaded-context panel at startup (works when the panel is on screen) |
89
+ | `?` | empty input = open shortcut/command help menu |
90
+
91
+ ### 2.3 Search
92
+
93
+ | Key | Action |
94
+ |---|---|
95
+ | `Ctrl+R` (⌘R) | history search; press again or `↓` for next match; `Enter` fills the input |
96
+ | `/` (transcript) | full-transcript search; `n` / `N` jump (only in Ctrl+O expanded state) |
97
+
98
+ ### 2.4 Input editing
99
+
100
+ | Key | Action |
101
+ |---|---|
102
+ | `←` / `→` | move the cursor by character (with a selection, collapse to that edge) |
103
+ | `Ctrl+←` / `Ctrl+→` (⌘←/→) | jump by word |
104
+ | `Home` / `End`, `Ctrl+E` | logical line start / end (`Ctrl+A` now opens the subagent panel, see §2.7) |
105
+ | `Ctrl+U` / `Ctrl+K` | delete before the cursor (to line start) / after the cursor (to line end) |
106
+ | `Ctrl+W` | delete the previous word |
107
+ | `Backspace` / `Delete` | delete previous / next character; **with a selection, delete the whole selection** |
108
+ | `↑` / `↓` | move between lines when multi-line; browse input history when single-line (last 200 entries, kept across restarts) |
109
+ | `Ctrl+V` (⌘V) / `Alt+V` | paste: text / file path (images auto `@`-referenced) / clipboard bitmap (`[Image #N]` attachment); use `Alt+V` when the terminal swallows `Ctrl+V` |
110
+ | `Ctrl+G` | edit the input in the `$VISUAL`/`$EDITOR` external editor (`:cq` keeps the draft; prompts you to configure when unset) |
111
+ | `Ctrl+Shift+E` (⌘⇧E) | open the **full-screen draft editor** (or click `⛶` at the end of the input line): line numbers, current line highlighted, `Enter` newline, `Ctrl+Enter` send, `Esc` collapse (draft kept); off at `/settings → 全屏草稿编辑` |
112
+ | long draft auto-fold | pasting a block **≥6 lines or ≥600 chars** folds into a `▸ N 行・M 字` chip: click the chip or `▾` to toggle; `Enter` always submits the full text |
113
+ | `/vim` | **vim editing mode toggle** (per-session, not persisted): shows an `INSERT` badge, `Esc` to `NORMAL`, `i/I/a/A/o/O` back to INSERT. NORMAL keys below |
114
+ | typing | **replaces the whole selection when one exists** (like a standard editor), cursor lands after the inserted text |
115
+ | right-click / `Ctrl+Shift+V` | terminal-native paste (newlines inserted as-is) |
116
+ | `Esc` (input) | closes layer by layer: help → **image preview** → command menu → file menu (only the current `@` token) → **clear selection if any (text stays)** → re-send interrupt → clear input → double-press = time-travel |
117
+ | double-press `Esc` (empty input) | **time-travel rewind** (press twice within 3 s) |
118
+
119
+ **vim NORMAL keys**: move `h/l` `j/k` `0/^/$` `w/b`;
120
+ delete `x/X` `dd`/`d$`/`d0`/`d^`/`dw`; `u` undo, `Enter` send.
121
+ Unrecognized keys are ignored, `Esc` does nothing, clear with `Ctrl+C`/`dd`.
122
+
123
+ ### 2.5 Navigation / modes
124
+
125
+ | Key | Action |
126
+ |---|---|
127
+ | `Shift+Tab` | cycle session mode (default → plan → full access); mounted third-party permission presets follow in registry order at the end of the cycle |
128
+ | `Shift+↑` | message selection mode (`↑/↓` move, `Enter` expand one, `Esc` exit) |
129
+ | `Ctrl+T` (⌘T) | open the trace scene (same as `/trace`) |
130
+ | `Alt+S` | one-key star (same as `/star`; the splash's star line is clickable too). Remappable in `/settings`; a short "the whale girl catches the star" celebration plays on success. Replay it any time with `DSH_TUI_STAR_MODAL=1 dsh-tui`; preview the splash star line with `DSH_TUI_STAR_LINE=1 dsh-tui` (preview env vars, ledger untouched) |
131
+
132
+ ### 2.6 Mouse (fullscreen mode; drag/double-click/triple-click select-and-copy)
133
+
134
+ | Action | Effect |
135
+ |---|---|
136
+ | left-drag | select text, **copy on release** (OSC 52 + system clipboard tools as fallback), auto-clear the selection |
137
+ | double-click / triple-click | select word / line, copy immediately |
138
+ | wheel | scroll the message list (±3 rows/notch); **with a text selection, pan the selection with the content** |
139
+ | in the input box | drag / Shift+click / double-click build a selection; `Backspace`/`Delete` delete it, typing replaces, `←/→` collapse, `Esc` clears only the selection, `Ctrl+C` copies it |
140
+ | `Esc` | clear the selection (no copy) |
141
+ | single-click | message row = expand/collapse · hyperlink = open browser · 「加载更早消息」/StickyHeader/「↓ N new」= load/jump |
142
+ | hover truncated content | hover ~600 ms to show full content in a popover; no popover while dragging a selection |
143
+ | keyboard selection extend | with a selection, `Shift+←/→/↑/↓/Home/End` extends/shrinks (wraps across lines) |
144
+
145
+ ### 2.7 Per-scene keys
146
+
147
+ **Questionnaire (model ask_user_question)**
148
+
149
+ - `↑/↓` select, `Space` multi-select, `Tab` jump to custom answer, `Enter` submit; `←/→` switch question (no submit, draft kept); `Ctrl+V` paste, `Ctrl+K` fold.
150
+ - `Esc` back from question 2 onward, cancel the whole batch on question 1; `Ctrl+C` cancel on any question. On the input row, `←/→` move the caret first and switch questions only at the text edge.
151
+
152
+ **Plan review**
153
+
154
+ - `↑/↓` move, `1`/`2` quick pick; typing = fill feedback (`Ctrl+V` paste, `Enter` submit); `Esc` interrupt; **approve must have no feedback**.
155
+
156
+ **Tool approval**
157
+
158
+ - `↑/↓` move, `1` allow (this time only), `2` deny, `Enter` submit; `Esc`/`Ctrl+C` deny.
159
+
160
+ **Session manager** (`/resume`, `/home`, `/agentview`, `/bg`, `⌸` at the input line start — the same screen)
161
+
162
+ - Layout: left workspace column, right session column; ≥84 columns side-by-side, narrower hides the workspace column.
163
+ - Switch column `←/→`; move `↑/↓`/`PgUp`/`PgDn`; **typing = live filter** (by title/dir/branch/model).
164
+ - Enter `Enter` (row 0 = new session in that workspace); new `Ctrl+Enter`/`Ctrl+N`; stop background session `Ctrl+X`.
165
+ - `Ctrl+L` reload · `Enter` on the rail opens the action menu · `Esc` close hint → clear filter → leave.
166
+ - Source tabs: when Claude Code / Codex / Grok Build / zcode have conversations on this machine, tabs appear on the right of the title row; switch with `Tab`/`Shift+Tab` or a click.
167
+ On a source tab `Enter`/click imports just that conversation and opens it (one imported before opens directly); a missing working directory is reported and nothing is imported; `Ctrl+L` rescans the source.
168
+ - Mouse: click a session row = enter, click `★`/`☆` = toggle pin only, right-click a workspace row = action menu.
169
+ - Empty input + `←` (or `/bg`) = send to background and open this screen, session keeps running.
170
+
171
+ Switching sessions just parks the current one — the running turn keeps going.
172
+ A session taken by another terminal shows red with `占用 pid <pid>`
173
+ and can't be entered; it recovers after that terminal exits.
174
+ Fixed items live in `~/.dsh-tui/session-pins.json`.
175
+ The workspace menu has four items: edit / new here / rename / remove from list (**removes the entry only**, directory and session log stay).
176
+
177
+ **Image preview** (open by clicking `[Image #N]` in the input or a thumbnail in the transcript)
178
+
179
+ - `←/→` previous / next; bottom-button zoom: `适应`/`100%`/`200%`/`400%`/`800%`;
180
+ drag or wheel to pan.
181
+ - `Esc`/`Ctrl+C`/`Enter` or click outside to close.
182
+ - The bottom 「打开原图」opens the original file in the system viewer.
183
+
184
+ **IDE selection** (VS Code companion extension `dsh-tui-vscode`, needs ≥ 0.7.0)
185
+
186
+ - Select code in the editor → a `⧉ N lines selected` badge appears **live** under the input, and the selected lines are **auto-attached** to context on submit.
187
+ - The transcript shows a 「⧉ Selected N lines from <相对路径>」
188
+ indicator line (text from the editor, unsaved changes included).
189
+ - No IDE installed/connected → skipped automatically, nothing else affected (see [vscode.md](vscode.md)).
190
+
191
+ **History search (Ctrl+R)**
192
+ `↑/↓` select · press `Ctrl+R` again or `↓` for next · `Enter` fill · `Esc`/`Ctrl+C`/`Ctrl+D` cancel
193
+
194
+ **Trace scene (Ctrl+T / /trace)**
195
+ - `↑/↓`/`PgUp`/`PgDn` move · `←/→` (or `h`) switch timeline/hotspot · `g`/`G` top/bottom · `q`/`Esc` exit
196
+ - `[`/`]` jump failure · `{`/`}` jump turn · `m` cycle projection · `Enter` expand details (`j`/`k` page) · hotspot `t` sort
197
+ - `/` query line (prefixes `tool:` `kind:` `turn:` `err:` `run:` `>10s` `tok>1k`)
198
+
199
+ **/settings panel**
200
+ `↑/↓` move · `Enter` expand/toggle/edit · `←/→` cycle a field that has options (booleans still only respond to `Enter`) ·
201
+ changes save automatically, `Esc` exits
202
+
203
+ **/btw panel**
204
+ `↑/↓` scroll · `Space`/`Enter`/`Esc` close · `c` copy answer · `Esc` cancels while waiting
205
+
206
+ **/effort slider**
207
+ `←/→` adjust live (Esc does not revert) · `Enter`/`Esc` done
208
+
209
+ **@ file completion**
210
+ `@` triggers anywhere in the message · `↑/↓` move · `Tab`/`Enter` accept · directories drill down ·
211
+ `Esc` closes only the current token menu
212
+ - **Two query modes**: path-like input (`@src/` `@./` `@~/` `@D:\`) lists only that directory;
213
+ plain fragments use **fuzzy subsequence match** (`@ink` hits `src/ink/Box.js`).
214
+ - Image paths auto-become `[Image #N]` attachments.
215
+
216
+ **Subagent panel (Ctrl+A)**
217
+ `↑/↓` browse · `Enter` view details · `Esc` close; details page `←/→` page, `X` interrupts while running; subagents render as live card rows. The panel mirrors every child this session dispatched — `subagent`/`send_message` runs, continuable re-dispatches (each new run resets the row), and workflow/ralph members — and re-folds durable discovery facts from the session log on resume, so restarting no longer blanks it. Historical rows without live timing show a `⚪` state instead of a fake duration.
218
+
219
+ **Double-press Esc time-travel (rewind)**
220
+ List `↑/↓` + `Enter` to confirm · confirm page `Enter` rewind / `Esc` back · only `Esc` responds while a plugin decision is pending
221
+
222
+ ## 3. Command reference
223
+
224
+ The command menu = built-in commands (50) + DSH registry commands (`/plan` `/goal` etc.) + the skill catalog
225
+ (completion only, hidden from the `/help` menu). `/lang` switches the UI and command descriptions between English and Chinese.
226
+
227
+ ### 3.1 Session
228
+
229
+ | Command | Args | Effect |
230
+ |---|---|---|
231
+ | `/new` | none | start a new session (no confirmation; the old session stays under `/resume`) |
232
+ | `/resume` | none | open the **session manager** (workspace + session columns, live filter, pins, cross-workspace): switching just parks the session, the running turn keeps going |
233
+ | `/home` / `/agentview` / `/bg` | none | the same session manager (`/home`=workspace view · `/agentview`=hosted session state · `/bg`=send to background and open, alias `/background`) |
234
+ | `/tree` | none | session fork tree: hover to preview, click to rewind / fork / switch branch |
235
+ | `/fork` | none | copy the current session into a resumable clone (original unaffected) |
236
+ | `/restart` | none | restart the process and resume this session (rejected mid-turn, `Ctrl+C` first) |
237
+ | `/rename` | `<新名称>` | rename the current session (no arg shows the current title and usage) |
238
+ | `/recap` | none | recent-activity summary (one line) + suggested title; press `a` or click to apply the title. With `dsh-tui.recapOnOpen` (default on), opening/resuming a session auto-shows a divider + `回顾:` summary line at the bottom; hover to view actions, click to expand, gone after the next message |
239
+ | `/workspace` | `resume` / `rename <名称>` / `open <路径或URI>` | manage workspaces; `open` accepts an absolute path, file URI, or plugin scheme |
240
+ | `/clear` | none | clear the current session view (reset expand/selection state) |
241
+ | `/compact` | none | compact session history (prompts when nothing to compact) |
242
+ | `/export` | none | export the session as Markdown to the working directory |
243
+ | `/btw` | `<问题>` | side question: single turn, no tools, doesn't interrupt the main turn, not written to history |
244
+ | `/trace` | none | open the trace scene (same as `Ctrl+T`) |
245
+ | `/rewind` | none | rewind selector (same as double-press Esc on empty input) |
246
+ | `/exit` (alias `/quit` `/q`) | none | exit dsh-tui |
247
+
248
+ ### 3.2 Status and diagnostics
249
+
250
+ | Command | Args | Effect |
251
+ |---|---|---|
252
+ | `/context` | none | loaded-context detail (instructions/runtime context/skills/tools etc.) |
253
+ | `/status` | none | model+effort, working/idle, session id, dir+git branch, token, cache hit rate, context percentage, session title |
254
+ | `/cost` | none | token usage + cache hit rate + a session estimate (subagent usage included) split into main/subagent; unofficial or unlisted models show tokens only and are marked unpriced (**an estimate — the platform bill is authoritative**) |
255
+ | `/balance` | none | DeepSeek official account balance (free read-only API): summary line + hover detail (same session-estimate split: main/subagent/unpriced), click refresh, `×` close |
256
+ | `/config` | none | config sources: `cordis.patch.yml` path, launch method, model routing |
257
+ | `/doctor` | none | environment check |
258
+ | `/migrate` | `[agent] [--dry-run]` | import conversation history from other coding agents (claude-code/codex/omp/zcode/grok-build); runs in a child process — see [Session migration](migrate.en.md) |
259
+ | `/init` | none | create `AGENTS.md` in the working directory (created / exists / failed) |
260
+ | `/agents` | none | subagent list for this session |
261
+ | `/jobs` | none | background-task panel: status/runtime/exit-code tracking, `↑/↓` select, `k` stop; while open, `Esc` **closes only the panel** and won't interrupt the turn (close the panel first, then `Ctrl+C`) |
262
+ | `/settings` | none | open the plugin settings editor (namespace read/edit) |
263
+ | `/help` | none | shortcut + command help menu (`?` entry) |
264
+
265
+ ### 3.3 Model / display
266
+
267
+ | Command | Args | Effect |
268
+ |---|---|---|
269
+ | `/model` | none | model selector; **switching = fork the session** (history kept, only routing changes; a session nobody has typed into records no branch, keeping automatic titles for its first prompt), choice persisted to `~/.dsh-tui/model.json` |
270
+ | `/effort` | `status` / `<id>` | reasoning effort: no-arg slider (`←/→` adjust); `status` current level; `<id>` set directly. Persisted to `~/.dsh-tui/effort.json`; new-session start level follows /settings `effortDefault` (§5.3) |
271
+ | `/thinking` | none | extended-thinking display toggle (thinking expands item by item while streaming) |
272
+ | `/tokens` | none | token usage + context percentage |
273
+ | `/activity` | `frames <名>` / `status` | working-status animation: no-arg selector, `frames <名>` sets directly (includes `random`), default `moon8`. Persisted to `~/.dsh-tui/working-activity.json` |
274
+ | `/preset` | `<id>` / `status` | agent preset: `standard` / `ptc` (old 0.1.1 name `code`) / `minimal` / `cordis` / **Liangshen mode `liangshen`**; **cannot switch an already-started session**. Persisted to `~/.dsh-tui/agent-preset.json` |
275
+ | `/theme` | `<名字>` / `status` | theme: no-arg selector; `<名字>` switch directly; `status` current theme (auto appends the OSC 11 result). Persisted to `~/.dsh-tui/theme.json` |
276
+ | `/color` | no-arg / `<名>` / `status` / `reset` | session accent color: no-arg opens the palette (`↑/↓` pick, `Enter` apply); `<名>` set directly; `reset` back to default. Colors `red/orange/yellow/green/blue/purple/pink/cyan`, saved per session |
277
+ | `/lang` | `en` / `zh` / `status` | hot-switch UI language. Priority: `DSH_TUI_LANG` > profile config (legacy: settings.yaml user layer > cordis.yml) > persisted |
278
+ | `/vim` | none | **vim editing mode toggle** (see §2.4): input switches to vim keys, per-session, not persisted |
279
+
280
+ ### 3.4 Account / policy / extensions
281
+
282
+ | Command | Args | Effect |
283
+ |---|---|---|
284
+ | `/provider` | none | interactive model-provider wizard (add / edit / delete; standard-profile account sign-in includes DeepSeek on DSH 0.2.0-rc.1+, plus ChatGPT/Codex / Claude / Grok and, when supported by host pi-ai, OpenAI direct / Meta Muse) |
285
+ | `/auth` | `status` / `login [provider]` / `logout <provider>` | inspect account status, sign in, or sign out (`deepseek-account` for DeepSeek; `openai-codex` / `anthropic` / `xai` for pi-ai subscriptions; newer pi-ai also `openai` / `meta`) |
286
+ | `/login` | none | credential status (source, store writability, base URL; account states are listed when the OAuth module is mounted) |
287
+ | `/logout` | none | logout notes (env source: delete the variable and restart) |
288
+ | `/permission` | none / `<preset>` / `status` | view/switch permission preset and policy (no arg opens the selector) |
289
+ | `/add-dir` | none | file-policy scope notes (rooted at the working directory) |
290
+ | `/hooks` | none | placeholder: notes when DSH hooks aren't mounted in the composition |
291
+ | `/mcp` | none | MCP connection state (tools grouped as `mcp__服务器__工具`); shows a `cordis.patch.yml` snippet when unconfigured |
292
+ | `/skills` | none | skill-catalog selector (name+source+blurb); Enter fills a direct-call skill as `/name ` |
293
+ | `/plugins` | `check <dsh-plugin.json 路径>` | plugin diagnostics: trust banner + host descriptor + authorization matrix + ledger; `check` validates a manifest and reports compatibility |
294
+ | `/update` | none | update the TUI and auto-restart to resume the session (only via `dsh --profile`; rejected mid-turn) |
295
+ | `/terminal-setup` | none | terminal setup advice (Windows Terminal ≥110 columns, paste keys) |
296
+
297
+ ### 3.5 Skills
298
+
299
+ dsh-TUI ships no generic skills; `/skills` browses skills DSH discovers, and a direct-call skill joins the command menu as `/name` (see §4.8).
300
+
301
+ ### 3.6 Placeholder commands
302
+
303
+ `/connect`: placeholder — DSH has no remote-connection mechanism yet.
304
+
305
+ ### 3.7 Registry commands (from the DSH ecosystem, merged into the `/` menu)
306
+
307
+ | Command | Effect |
308
+ |---|---|
309
+ | `/plan` | `[off\|message]` plan mode; `/plan off` exits |
310
+ | `/goal` | set/view the session goal |
311
+ | `/feedback` | submit usage feedback |
312
+ | `/permission` | view/switch presets from the DSH `permissionPresets` registry (third-party presets in registry order) |
313
+
314
+ > These commands come from the DSH command registry; this repo only merges them into the menu, completes, and dispatches.
315
+
316
+ ## 4. Session workflow
317
+
318
+ ### 4.1 Session lifecycle
319
+
320
+ | Action | Command/Key | Notes |
321
+ |---|---|---|
322
+ | New | `/new` | no confirmation — the old session is persisted, always reachable via `/resume`; also clears the resume marker |
323
+ | Resume | `/resume` (same as `/home` `/agentview` `/bg` and `⌸` at the input line start) | the three-in-one **session manager**: `←/→` switch column, type to filter, `Enter` enter, `Ctrl+N` new, `Ctrl+X` stop background session, `★`/`☆` pin. Switching just parks the session, the turn keeps running; a session taken by another terminal shows red and can't be entered (see §2.7) |
324
+ | Rename | `/rename <标题>` | rename immediately and persist (writes a session/title event, readable back in the session manager) |
325
+ | Compact | `/compact` | trigger DSH compaction manually; **rejected mid-turn**; unavailable under minimal preset; the compaction point renders as a Divider summary row |
326
+ | Export | `/export` | export Markdown from the full session log (thinking and tool-call sections), file `dsh-tui-export-<时间戳>.md` in the current session cwd |
327
+ | Clear | `/clear` | clears the view only, never the session log |
328
+ | Stop | session manager `Ctrl+X` | stop the **background** session under the cursor; the session the current terminal is using can't be stopped (exit the whole TUI with `/exit` or double-press `Ctrl+C`) |
329
+ | Exit | `/exit` (or `/quit` `/q`) | double-press `Ctrl+C` or `Ctrl+D` also exits when idle; mid-work, press `Ctrl+C`/`Ctrl+D` again to force quit when the interrupt won't settle |
330
+
331
+ Command-line resume: `dsh-tui --resume` (last session) / `dsh-tui --resume <id>` (specific session).
332
+ `-c` / `--continue` are equivalent.
333
+
334
+ ### 4.2 Time-travel rewind (double-press Esc)
335
+
336
+ **Double-press `Esc` on empty input** (or `/rewind`) opens the rewind selector:
337
+
338
+ 1. The selector lists **your own messages** (newest first), `↑/↓` + `Enter` to pick.
339
+ 2. If the model is working: cancel the turn and wait for it to settle (up to 30 s).
340
+ 3. The boundary is **before the turn** that message belongs to; **can't rewind past the first message**.
341
+ 4. The system forks a new session and replays history to the rewind point, **puts the original message back in the input** for editing and resend.
342
+ 5. The rewind branch stays in the `/resume` list, keeps the current model routing + the session's own preset.
343
+
344
+ ### 4.3 Message delivery semantics (while the model is working)
345
+
346
+ Keys are in §2.1:
347
+ - `Enter` = **steer** (inject a next-step boundary, no interrupt)
348
+ - `Tab` = **follow-up** (queue after the turn)
349
+ - `Ctrl+Enter` = **interrupt** (interrupt and send)
350
+ - `Alt+Up` bring the last unhandled message back
351
+ - `↑` recalling a message that is still queued also withdraws that queued entry (same as `Alt+Up`, so the same text is not sent twice); once the running turn claimed it, only a notice appears
352
+ - `Esc` (with pending) interrupt and re-send
353
+ - `/btw …` side question never interrupts the main turn
354
+
355
+ ### 4.4 Side question /btw
356
+
357
+ `/btw <问题>`: one no-tool, single-turn answer reusing the current context,
358
+ **not written to history, no token counted**.
359
+ Panel `↑/↓` scroll · `c` copy · `Esc` close.
360
+
361
+ ### 4.5 Trace scene (Ctrl+T / /trace)
362
+
363
+ Full-screen view of the whole session timeline (doesn't pollute scrollback); keys are in §2.7.
364
+
365
+ ### 4.6 Model switching and presets
366
+
367
+ - `/model`: selector. **Switching = fork the session** (history kept, only routing changes, the old session stays in `/resume`);
368
+ persisted to `~/.dsh-tui/model.json`.
369
+ - Switching is rejected mid-turn.
370
+ - `/preset` options: `standard` (default full features), `ptc`, `minimal` (the kernel's Minimal preset: one persistent-shell tool only, no compaction, no plan mode),
371
+ `cordis`, `liangshen` (Liangshen mode).
372
+ **A session that already has messages can't switch** (blank-only): the choice only becomes the default for the next `/new`.
373
+ This is a **kernel agent preset** deciding which tools the model can use; `/settings → Minimal UI` (极简界面) on the display side is unrelated.
374
+ - Cycle session mode with `Shift+Tab`: default (workspace-write + approval) → plan (read-only) →
375
+ full (danger-full-access).
376
+ - Third-party permission presets follow in registry order at the end.
377
+ - **After approving a plan or `/plan off`, sandbox and approval policy return to the pre-plan state**.
378
+
379
+ ### 4.7 Questionnaires and approvals
380
+
381
+ Keys are in §2.7. Key points:
382
+ - Questionnaire **last line is a free-input line** (typing submits together with the option label).
383
+ - Plan review **approve must have no feedback text**.
384
+ - When an approval and a questionnaire hang at once, **approval wins**.
385
+ - A background-session approval is tagged `来自后台会话 <会话 id 前 8 位>`.
386
+
387
+ ### 4.8 Skills / registry / Goals-Todos
388
+
389
+ - `/skills` browses the skill catalog; a direct-call skill joins the command menu as `/name` (dsh-TUI ships no generic skills).
390
+ - `/plan` `/goal` `/feedback` `/permission` come from the DSH registry, merged into the `/` menu.
391
+ - **Goals/Todos panel appears automatically**: when the model writes a goal/todo, it renders above the input
392
+ (🎯 goal + phase badge + tree todo), no action needed.
393
+
394
+ ### 4.9 MCP / Workspace / other
395
+
396
+ - `/mcp`: lists `mcp__服务器__工具` grouped by server;
397
+ shows a `cordis.patch.yml` snippet when unconfigured.
398
+ - `/workspace`: `resume` / `rename <名>` / `open <路径|file:// URI>`
399
+ (open and start a new session).
400
+ - `dsh-tui <路径>` also accepts a workspace target.
401
+ - `/doctor` check: Node/platform, API key, model routing, cwd, context window, session storage, plugin host.
402
+ - `/provider` interactive wizard to manage model providers: add / edit / delete.
403
+ - The standard profile's built-in OAuth module offers **subscription sign-in** (ChatGPT/Codex / Claude / Grok; OpenAI direct / Meta Muse on newer pi-ai, no API key); `/auth login <provider>` also signs in, and `/auth logout <provider>` removes the stored OAuth credential.
404
+ - DSH 0.2.0-rc.1+ delegates DeepSeek account browser authorization to the Host: run `/auth login deepseek-account`, then select the separate `deepseek-account` route with `/model`; `/auth logout deepseek-account` delegates sign-out to the Host. It does not change the `deepseek-official` API key.
405
+ - Non-env-variable API keys are written to `~/.dsh/.credentials.yaml` (0600), and the UI shows only `••••••`; pi-ai subscription OAuth credentials instead live in `$DSH_HOME/dsh-auth/credentials.json` (`~/.dsh/dsh-auth/credentials.json` when DSH_HOME is unset). The Host credential service owns DeepSeek account grants; they are not written to that OAuth file.
406
+ - Custom endpoints need route name, API key, baseURL, and protocol (`openai-completions` / `openai-responses` /
407
+ `anthropic-messages`).
408
+ - After add/edit, run `/model` to switch to the new route.
409
+ - `/init` creates AGENTS.md; `/agents` subagent list; `/login` `/logout` credential management.
410
+ - `/permission` `/add-dir` permission notes; `/hooks` `/vim` `/connect` are placeholders.
411
+
412
+ ## 5. UI and status bar
413
+
414
+ An empty session shows the whale logo area at the top (scrolls away with the conversation):
415
+
416
+ - **Intro animation** (~3.4 s, three picked each launch, `/deepseek` egg re-rolls): classic / heart / sleep.
417
+ - **Welcome idle animation** (`whaleIdle`, default on): fin, blink, tail wag, sleeps with Z after 10 s idle; **click to show a heart and wake it**.
418
+ - **Maid portrait** (`whaleGirl`, default off): swaps the header's pixel whale for the author-drawn maid — FIRST as a **real raster** through the terminal image protocols (Kitty/Sixel); terminals without graphics support fall back to the character-art maid. **Click her** and she turns into the "happy" portrait for a few seconds, then eases back on her own; the first agent task freezes her (no more reactions).
419
+ - After the first agent task, it freezes to a static frame (`/new` re-enters the welcome period).
420
+ - Text column right of the whale: `✦ dsh-TUI v版本号` →
421
+ `DEEPSEEK / HARNESS` big text (bold glyphs, both rows the same width, one blank row between) →
422
+ current model + effort → working directory → startup hint line.
423
+ - The big-text face rotates by **local date** (eight faces: bold / square / bevel / wide / dot /
424
+ stencil / classic / slab): the same day always shows the same one, independent of launch time.
425
+ To keep one face, pick it in `/settings → Splash font` (`splashFont`) — choosing a specific face
426
+ pins it, choosing `Daily rotation` (the default) restores the rotation; it applies immediately.
427
+ - Out of the verified range, a **⚠ version-drift warning** appears (with the align command).
428
+ - Centered tagline under the whale: `探索未至之境!`.
429
+ - Narrow terminals climb down a ladder on the **content-area** width: **≥ 97 columns** whale + big
430
+ text; **55–96** the big text alone (the whale goes first); **40–54** the whale alone; **< 40** a
431
+ single plain `DeepSeek Harness` line. The thresholds follow the face width (97 columns is the
432
+ 6-column faces; the widest, `wide`, needs 113, and the 5-column `classic`/`slab` fit at 96).
433
+ - Pixel whale art and idle behavior ported from [dsh-ui-whale](https://github.com/lhh010/dsh-ui-whale) (author
434
+ [@lhh010](https://github.com/lhh010)), with thanks.
435
+
436
+ **Long single-line fold** (default on)
437
+
438
+ - Text with **a single line over 1000 chars** folds into
439
+ `… 已折叠 N 字符(点击或 ctrl+o 展开)` marker.
440
+ - Expand: **click the line** (tool card: click the card) to unfold, click again to fold; keyboard `Ctrl+O`.
441
+ - Thinking lines don't fold.
442
+
443
+ ### 5.2 Bottom status bar (three rows under the input)
444
+
445
+ **Row 1 — context segment bar** (`/settings → statusBar.contextBar`, default on)
446
+
447
+ - Colored by content type (system / prompt / assistant / thinking / tools).
448
+ - The only text on the bar is the right-edge reading `13k/64k 19.5%` (narrow screens show only `19.5%`).
449
+ - The reading colors by usage: <80% gray-blue, **≥80% amber, ≥95% red**.
450
+ - Hover the whole bar for the legend: color block + name + token count (narrow screens shorten the names).
451
+
452
+ **Row 2 — status field row** (each field toggled separately, see `/settings`)
453
+ - left group: model → TPS → thinking → mode → ctx → cache hit rate → tokens (`1.2k→340` input→output) →
454
+ cost (`≈¥0.05 谷`, **a session estimate** that includes subagent usage, priced per
455
+ each agent's model × peak/idle × cache components; hover splits main ¥ / subagent ¥ / unpriced N tok;
456
+ unofficial or unlisted models show tokens only and are marked unpriced;
457
+ **the platform bill is authoritative**)
458
+ - right group: git branch → working directory (basename only in compact mode) → session title → short session ID (`#` + first 8 chars, for `--resume`)
459
+ - `statusBar.compact` merges the two sides into one row.
460
+ - Default on: compact, model, thinking, cwd, contextUsage, cache, cost, goal, contextBar.
461
+ - Default off: tokens, tps, gitBranch, sessionTitle, sessionId, mode, activity, trajectory.
462
+
463
+ **Row 3 — hints / working activity + mini trace bar**
464
+ - Idle shows `? for shortcuts`, running `esc to interrupt`, selecting `esc to return to input`.
465
+ - Idle also shows the working-activity animation (`statusBar.activity` on), context ≥80% amber, ≥95% red.
466
+ - Right-side **mini trace bar MiniWake** (`statusBar.trajectory`, default off): session projected as density glyphs, color per channel, failures red;
467
+ degrades/hides on narrow screens.
468
+
469
+ **TPS gauge** (`statusBar.tps`, default off): streaming shows a live gauge + `N tps`, after the turn a sparkline;
470
+ speed **≥50 green / ≥20 yellow / <20 red**.
471
+
472
+ ### 5.3 The /settings editor
473
+
474
+ `/settings` opens the plugin settings editor; **changes save automatically**, `Esc` exits directly.
475
+ On 0.1.7 the dsh-tui block writes to the active profile's `cordis.patch.yml`; older hosts use the settings.yaml user layer. Most settings apply live; fullscreen and image-preview need `/restart`.
476
+ Common items below, full list on the /settings screen. Most topics (**Appearance**, **Splash**, **Conversation**, **Rendering**) lay their fields right on the root page under small headers — no subpage round-trip to tweak them; only the genuinely block-like domains — **Formula**, **Status bar**, **Shortcuts** — keep a subpage behind one root-page row:
477
+
478
+ | Field | Notes |
479
+ |---|---|
480
+ | lang | UI language zh/en (locked when DSH_TUI_LANG is pinned) |
481
+ | fullscreen | fullscreen mode (default on); takes effect after `/restart` |
482
+ | minimal | Minimal UI (default off): hide the header splash, emoji glyphs and decorative colors, and trim the footer to model + cwd; code highlight and tool colors stay. **An interface switch** with no effect on model capability — do not confuse it with the kernel Minimal agent preset in `/preset` |
483
+ | terminalImages | terminal image preview (default on, needs terminal support); takes effect after `/restart`. Off shows text only and skips preview decode, sending images to the model is unaffected |
484
+ | imageBacking | image backing (default `transparent`, same **Rendering** topic as the row above): what sits behind chat photos and illustrations. Transparent paints only the pixels of the image itself — the terminal background or wallpaper shows at anti-aliased edges and transparent corners; Terminal colour composites onto the terminal background for smooth soft edges. Applies immediately |
485
+ | whale | pixel whale header (default on); three intro animations picked per launch (classic/heart/sleep), `/deepseek` egg re-rolls |
486
+ | whaleIdle | whale welcome idle animation (default on): fin/tail/blink, sleeps with Z after 10 s idle; click for a heart. Freezes after the first task |
487
+ | splashFont | big-text face on the header splash: Daily rotation (default, changes with the local date) / bold / square / bevel / wide / dot matrix / stencil / thin (classic) / slab. Picking a face pins it; picking Daily rotation restores the rotation. Applies immediately |
488
+ | whaleGirl | maid portrait (default off): swaps the header's pixel whale for the author-drawn maid as a **real raster** (Kitty/Sixel); falls back to the pixel whale without graphics support |
489
+ | diffLayout | Edit/Write diff layout: auto (two columns ≥110 cols) / split / unified |
490
+ | thinkingFold | thinking block: preview (2-3 line preview + folded when settled) / full (expanded to end of turn) |
491
+ | effortDefault | default reasoning effort: auto / off / low / high / max. Start level for new sessions (details below) |
492
+ | smoothStreaming | smooth streaming output (default on): replies/thinking/tool-card text reveal at ~30fps; replay/history always direct |
493
+ | toolBackground | tool-card background emphasis: none / subtle / strong |
494
+ | mermaidDiagrams | Mermaid diagrams (default on): ```` ```mermaid ```` blocks render as character diagrams, forming while streaming; too-wide or unsupported types keep source with the required columns. Applies immediately |
495
+ | mathRendering | LaTeX math (default `auto`; lives on the **Formula** subpage of `/settings`): how `$…$` / `\(…\)` inline and `$$…$$` / `\[…\]` / bare display-environment (`\begin{align}` …) block formulas in replies show. `auto` uses the best available renderer (today Unicode text, with fractions and limits stacked in blocks), `image` typesets formulas with MathJax as terminal images when the terminal has graphics — the Kitty graphics protocol (Kitty, Ghostty, WezTerm, iTerm2…) or Sixel (Windows Terminal 1.22+, xterm, foot, WezTerm) — in the theme's text color (block formulas up to 16 rows; inline formulas as one-row images when a single row can hold them legibly; still-streaming formulas, dimmed thinking, terminals without graphics, formulas too small on one row, and any render failure fall back to Unicode), `unicode` pins Unicode text, `source` keeps the TeX. Unsupported, still-streaming, or too-wide formulas keep their source (a too-wide block first falls back to one line). Prices (`$5`), shell variables (`$HOME`), and `$` in code are left alone. The older `latexMath: false` still means `source`. **Click a formula image** to open the preview card: it re-typesets at twice the cell size, zooms 100–800%, pans, closes on `Esc` or a click outside, and titles itself with the formula's TeX. On Sixel the formulas carry **no backing** (only their strokes), so the terminal background or wallpaper shows through. Illustrations that ship with their own transparent margins — the `whaleGirl` raster — float the same way; photographs, screenshots, and images inside cards still composite onto a colour, because Sixel cannot express soft alpha. Applies immediately |
496
+ | mathImageScale | formula image size (default `auto`; same **Formula** subpage), used with LaTeX math → Image: `auto` matches the body text, `large` / `xlarge` set **display** formulas bigger. Terminal images are drawn one device pixel per pixel, so "bigger" literally means more pixels per stroke — the only sharpness lever there is. Inline formulas are unaffected (they must fit one row). Applies immediately |
497
+ | scrollGutter | transcript gutter: timeline (turn timeline, default) / scrollbar (proportional) / hidden. Applies immediately |
498
+ | pageMargin | page margin: inset from all four terminal edges. Presets none / slim / normal (default) / roomy, or custom `NxM` (details below). Applies immediately |
499
+ | foldTerminalCommand | fold terminal commands (default off): multi-line commands on terminal cards (Bash/PowerShell) fold to first line + count; `Ctrl+O` or click to expand |
500
+ | expandEditor | full-screen draft editor (default on): `⛶` at the input line end or `Ctrl+Shift+E` expands to a full-screen editor; `Ctrl+Enter` send, `Esc` collapse (draft kept); off hides both entries |
501
+ | statusBar.* | all status-bar toggles above (compact/model/thinking/cwd/contextUsage/cache/tokens/cost/tps/gitBranch/sessionTitle/sessionId/mode/contextBar/activity/trajectory; statusBar.sessionId is the bottom-bar display toggle, unrelated to cordis startup sessionId) |
502
+
503
+ **effortDefault**: when the model lacks that level, drop one level and show a notice; priority settings user layer > cordis `effort` >
504
+ last `/effort` (effort.json) > model default.
505
+
506
+ **scrollGutter**: the scrollbar track can be dragged directly; `Shift`/`Alt`/`Ctrl`+drag is still text selection.
507
+
508
+ **pageMargin**: custom `NxM` = `N` columns left/right, `M` rows top/bottom (cap 8x4); only `N` means 1 row top/bottom.
509
+
510
+ Namespaces not declared as TUI blocks are listed read-only; edit the profile config by hand (`~/.dsh/settings.yaml` on older hosts).
511
+ These settings are **not in /settings**, edit `$DSH_HOME/profiles/dsh-tui/cordis.patch.yml`:
512
+ provider / model / cwd / preset / workspace / sessionId / modes,
513
+ plus the startup-level `effort` key.
514
+
515
+ ### 5.4 Terminal requirements
516
+
517
+ - Interactive TTY required; Windows Terminal recommended (≥110 columns, monospace, TrueColor).
518
+ - macOS `⌘` modifier needs the extended keyboard protocol (iTerm2 / kitty / WezTerm / ghostty / tmux).
519
+ - Terminal.app: use Ctrl.
520
+ - VS Code: install the companion extension `dsh-tui-vscode` (gets the **IDE selection channel**, needs ≥ 0.7.0).
521
+ - Or run `dsh-tui` directly in the integrated terminal.
522
+ - **Images**: thumbnails and full preview need Kitty graphics or Sixel (auto-detected, Kitty preferred).
523
+ - `DSH_TUI_IMAGE_PROTOCOL=auto|kitty|sixel|none` overrides the protocol.
524
+ - `DSH_TUI_DISABLE_TERMINAL_IMAGES=1` forces preview off.
525
+ - tmux/screen, non-TTY, and accessibility mode show text only; sending images to the model is unaffected.
526
+ - **Pasting clipboard images (Ctrl+V / Alt+V)**: on Linux one of `wl-paste` (wl-clipboard), `xclip` or `xsel` is required.
527
+ - WSL: WSLg exposes a Windows bitmap as `image/bmp`; dsh-tui converts it to PNG before attaching.
528
+ - When those tools find nothing, it falls back to `powershell.exe` (needs Windows interop) to read the
529
+ Windows clipboard: screenshots, files copied in Explorer, and text.
530
+ - Environment check: `/doctor`.
531
+
532
+ ### 5.5 Safe mode and rescue profile (`dsh-tui safe`)
533
+
534
+ When dsh exits unexpectedly, safe mode gives a **read-only** environment diagnosis, profile plugin list, and fix guidance.
535
+
536
+ - **Two entry points**: run `dsh-tui safe` manually; or follow the on-screen prompt after a non-zero dsh exit (non-interactive envs just print a line).
537
+ - **Read-only scope**: diagnosis/list/guidance change no state.
538
+ - Exception: retry normal startup, or create/reuse a blank rescue profile (writes only `$DSH_HOME/profiles/dsh-tui-safe/`).
539
+ - **The rescue profile must prove clean first** (no third-party plugins, no `cordis.patch.yml` entries), else it refuses and prints how to handle it.
540
+ - **Non-interactive**: `dsh-tui safe --rescue` only reports the verdict (ready exits 0, refused exits 1).
541
+ - **Run the fix commands yourself** (safe mode only lists them):
542
+ - `dsh plugin --profile dsh-tui remove <第三方插件>` remove suspicious plugins.
543
+ - `dsh plugin --profile dsh-tui add @deepseek-harness-tui/dsh-tui@<版本>`
544
+ reinstall to align.
545
+ - `dsh-tui doctor` environment diagnosis.
546
+
547
+ ## 6. Model / preset / theme / language
548
+
549
+ | Item | Command | Notes |
550
+ |---|---|---|
551
+ | Model | `/model` | selector; **switching = fork the session** (history kept, routing only); persisted to `~/.dsh-tui/model.json`, reused on restart and `/new`. Never chosen → built-in default (currently `deepseek-flash`) |
552
+ | Reasoning effort | `/effort` | slider (`←/→` live) or `/effort <id>`; `/effort status` for current; new-session default in /settings → default reasoning effort |
553
+ | Agent preset | `/preset` | `standard` / `ptc` (old 0.1.1 name `code`) / `minimal` / `cordis` / **Liangshen mode `liangshen`**; **can't switch an already-started session** |
554
+ | Theme | `/theme` | `auto` (OSC 11 follows terminal background) / `light` / `dark` / `dark-ansi`; `/theme <名>` direct; `/theme status` for the result |
555
+ | Custom theme | manual | `~/.dsh-tui/themes/<名>.json`, `{base, colors}` format, hot-swap on select; naming it `auto` gets shadowed by the built-in |
556
+ | Language | `/lang` | `en` / `zh` hot switch; priority `DSH_TUI_LANG` > profile config (legacy: settings.yaml user layer > cordis.yml) > persisted |
557
+ | Status animation | `/activity` | selector or `/activity frames <名>`; default `moon8`, `random` randomizes |
558
+
559
+ **Theme priority**: `DSH_TUI_THEME` > `~/.dsh-tui/theme.json` > OSC 11 terminal-background detection > dark fallback.
560
+
561
+ **~/.dsh-tui/ preference files** (all best-effort, fall back on bad files):
562
+
563
+ - `theme.json`, `model.json`, `agent-preset.json`, `effort.json`, `working-activity.json`, `lang.json`,
564
+ `trajectory.json`, `resume.txt` / `last-used.json`, `themes/<名>.json`
565
+
566
+ **Common environment variables**:
567
+
568
+ - `DSH_TUI_LANG`, `DSH_TUI_THEME`, `DSH_TUI_PRESET`, `DSH_TUI_PERSONA`
569
+ - `DSH_TUI_DISABLE_MOUSE`, `DSH_TUI_DISABLE_TERMINAL_IMAGES`, `DSH_TUI_IMAGE_PROTOCOL`,
570
+ `DSH_TUI_ACCESSIBILITY` (accessibility: no animation/graphics preview)
571
+ - `DSH_TUI_RESUME_SESSION`, `DSH_TUI_WORKSPACE_TARGET`, `DSH_TUI_SESSION_ROOT`, `DSH_TUI_DEBUG`,
572
+ `DSH_TUI_RENDER_LOG` (frame capture)
573
+ - `DEEPSEEK_API_KEY`, `DEEPSEEK_BASE_URL`, `VISUAL`/`EDITOR` (`Ctrl+G` external editor),
574
+ `DSH_PERMISSION_MODE`
575
+
576
+ ## 7. Tips
577
+
578
+ **Getting started**
579
+
580
+ 1. `?` for shortcuts, `/` for commands — both have Tab completion.
581
+ 2. Not sure the environment is right? Run `/doctor`; for the whole session, `/status`.
582
+ 3. Switch UI language `/lang en|zh`, applies immediately and persists.
583
+
584
+ **Efficiency**
585
+
586
+ 4. Three deliveries while the model works: `Enter` inject a next step, `Tab` queue, `Ctrl+Enter` interrupt and send.
587
+ 5. `Alt+Up` brings the last unhandled message back to edit and resend, no retyping.
588
+ 6. A quick question without interrupting the main turn or writing history:
589
+ `/btw <问题>`.
590
+ 7. Made a mistake? **Double-press `Esc` on empty input to rewind** (or `/rewind`), edit and resend.
591
+ 8. `@` completes files anywhere in the message, `@src/a.ts#L12-14` cites a precise line range.
592
+ 9. `Ctrl+A` subagent panel: `Enter` for details, `X` to interrupt a running subagent.
593
+ 10. `Ctrl+O` expand/collapse details; `Ctrl+T` for the trace (`[`/`]` jump failure, `/` field query).
594
+
595
+ **Troubleshooting**
596
+
597
+ 11. Context pressure ≥80% turns amber, ≥95% red — time to `/compact` (unavailable under minimal preset).
598
+ 12. Session manager (`/resume`, `/home`, `/agentview`, `/bg`, or `⌸` at the input line start):
599
+ type to filter, `★` pin, `Ctrl+X` stop a background session; switching just parks it.
600
+ 13. Mid-turn, `/compact`, `/model`, `/restart` are rejected — `Ctrl+C` first or wait for the turn to end.
601
+ 14. `/model` switch = fork (history kept), persisted and reused on restart and `/new`.
602
+
603
+ **Ask the manual**
604
+
605
+ 15. Not sure how a feature works? **Ask the AI in the session** — the manual ships with the package
606
+ and the answer cites its source; to force a manual lookup, type `/dsh-tui-guide <question>`.
607
+ Manual text is only read into context when asked, so it costs nothing while idle. (Launching
608
+ `dsh --profile dsh-tui` directly, bypassing the `dst`/`dsh-tui` launcher, skips the manual.)