dsh-oc-tui 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -11
- package/docs//347/224/250/346/210/267/346/211/213/345/206/214.md +417 -401
- package/lib/index.js +510 -89
- package/lib/metrics.js +295 -47
- package/lib/rewind.js +272 -0
- package/lib/term.js +20 -11
- package/lib/ui.js +688 -94
- package/lib/util.js +362 -290
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ Published on **npm** as [`dsh-oc-tui`](https://www.npmjs.com/package/dsh-oc-tui)
|
|
|
24
24
|
- [Slash commands](#slash-commands)
|
|
25
25
|
- [Interactive prompts](#interactive-prompts)
|
|
26
26
|
- [Thinking intensity](#thinking-intensity)
|
|
27
|
-
- [
|
|
27
|
+
- [Session stats and the context meter](#session-stats-and-the-context-meter)
|
|
28
28
|
- [Settings](#settings)
|
|
29
29
|
- [In-app updates](#in-app-updates)
|
|
30
30
|
- [How it works](#how-it-works)
|
|
@@ -43,8 +43,9 @@ Published on **npm** as [`dsh-oc-tui`](https://www.npmjs.com/package/dsh-oc-tui)
|
|
|
43
43
|
| **Tool activity** | Tool cards with a one-line summary (`read src/app.ts`, `run npm test`), flowing spinners while running, and markdown-rendered results. |
|
|
44
44
|
| **Interactive questions** | The model can pause and ask you — option lists, multi-select, free text, and a scrollable plan review — all inline in the terminal. See [Interactive prompts](#interactive-prompts). |
|
|
45
45
|
| **Inline approvals** | `approval/request` prompts are answered with `y` / `n` without leaving the UI. |
|
|
46
|
-
| **
|
|
47
|
-
| **
|
|
46
|
+
| **Session stats** | One stats strip above the composer — turns/steps, LLM and tool wall time, average TTFT, decode throughput, cache-hit rate, and billed input/output tokens — folded from durable events. See [Session stats and the context meter](#session-stats-and-the-context-meter). |
|
|
47
|
+
| **Stats window** | Click the strip or the context meter, or type `/stats`, for the full session-statistics and token-usage breakdown. |
|
|
48
|
+
| **Context meter** | Live context occupancy (`ctx ▓▓░░ 32K/128K 25%`), with the system/tools/messages composition in the same window. |
|
|
48
49
|
| **Thinking intensity** | `Tab` cycles the current model's real reasoning levels; `Ctrl+E` opens a slider. The level is applied per request and persisted. |
|
|
49
50
|
| **Shared settings** | The same host settings namespaces the Web UI uses — general, sessions, per-provider model configuration, credentials — persisted to `$DSH_HOME/settings.yaml`. |
|
|
50
51
|
| **In-app updates** | Detect and switch versions of `@deepseek-ai/dsh` and `dsh-oc-tui` from inside the TUI, with Windows-safe deferred installs. |
|
|
@@ -197,17 +198,22 @@ It prefers the `dsh` on `PATH` and falls back to `npx --yes @deepseek-ai/dsh`. I
|
|
|
197
198
|
| `Up` / `Down` | Move the caret across a multi-line prompt; on the first/last row, step through input history. |
|
|
198
199
|
| `Left` / `Right` | Move the caret within the input box. |
|
|
199
200
|
| `PgUp` / `PgDn` | Scroll the transcript. |
|
|
200
|
-
| `Esc` | Close the
|
|
201
|
+
| `Esc` | Close the session stats window, the thinking slider, or help; cancel an approval; cancel a running turn; clear the prompt you are typing. |
|
|
202
|
+
| `Esc Esc` | Idle with an empty prompt: open the rewind picker. |
|
|
201
203
|
| `y` / `n` | Answer an inline approval prompt. |
|
|
202
204
|
|
|
203
205
|
**Mouse.** The wheel scrolls the transcript (or the Settings window while it is open). Hold the left button and drag across the transcript to select text, then press the right button to copy the selection.
|
|
204
206
|
|
|
205
207
|
### Slash commands
|
|
206
208
|
|
|
207
|
-
Built in: `/help` `/settings` `/new` `/resume <id>` `/model <id>` `/provider <route>` `/clear` `/cancel` `/quit` (`/exit` also works).
|
|
209
|
+
Built in: `/help` `/settings` `/new` `/resume <id>` `/model <id>` `/provider <route>` `/rewind` `/stats` `/clear` `/cancel` `/quit` (`/exit` also works).
|
|
210
|
+
|
|
211
|
+
**Rewind.** `Esc Esc` (or `/rewind`) lists the prompts of the live session. Restoring the **conversation** forks a new session from the events before the chosen prompt — the parent session is left untouched on disk, exactly as the harness's own `session/fork` does — and the picker lands on the most recent prompt, so `Enter` twice rewinds the last turn. `/rewind <n|last> [conversation|code|both]` runs it without the picker. The fork starts with an **empty inbox**: a cut before a turn also cuts the inbox claim that turn performed, so anything the parent had queued — including the prompt you rewound away from — is not delivered again; it stays in the parent's log, and the result line says `dropped N inherited pending input` when there was any. Restoring **files** is best-effort and fenced: it needs a git worktree (anywhere else the rewind reports `files not restored (not a git worktree)` and changes nothing), it rewrites tracked files from `HEAD` without touching the index, and it removes an untracked file only when the transcript's first recorded write to that path is at or after the rewind point. Everything it overwrites or deletes is copied to `$DSH_HOME/rewind-backups/<sessionId>/<timestamp>/` first, and the result line names that directory. Because the log stores no file contents, a tracked file returns to its last commit, not to its exact state at the rewind point.
|
|
208
212
|
|
|
209
213
|
Harness commands — `/compact`, `/goal`, `/plan`, … — are forwarded to `ctx.commands` and run without a model turn. They need a live session: on the title screen the TUI answers `/<name>: start a session first` instead of dropping the command silently.
|
|
210
214
|
|
|
215
|
+
`/stats` is the TUI's own command: it toggles the [session stats window](#session-stats-and-the-context-meter) and, like the harness commands, needs a live session.
|
|
216
|
+
|
|
211
217
|
### Interactive prompts
|
|
212
218
|
|
|
213
219
|
**Approvals.** When a tool needs permission, the composer area shows `Approval · <tool> · y allow / n deny`. `y` allows once, `n` rejects, `Esc` cancels. The plugin also honours the effective permission preset, so an auto-approving preset does not prompt at all.
|
|
@@ -240,11 +246,23 @@ The effective level sits on the composer's top-right border as the bare level na
|
|
|
240
246
|
|
|
241
247
|
The choice is applied to the session's requests through the `agent/request` waterfall and stored in `agent-default-model.reasoningEffort`.
|
|
242
248
|
|
|
243
|
-
###
|
|
249
|
+
### Session stats and the context meter
|
|
250
|
+
|
|
251
|
+
The row above the composer is the **session stats strip**, the TUI's counterpart of the web chat's stats line: the same figures in the same order, separated by `│`:
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
▤ 1 turn · 2 steps│LLM 1.3s · tools 1.2s│TTFT avg 400ms · 20.0 tok/s│cache 55%│in 110 · out 30
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
- `turns` / `steps` count **closed steps** (`step/end`), so failed, cancelled, and max-tokens steps count too. `LLM` is `step/start` → assembled reply; `tools` pairs `tool/call` → `tool/result`.
|
|
258
|
+
- `TTFT avg` is the per-step average time to first token; `tok/s` is decode throughput (first token → assembled reply over the reported output tokens).
|
|
259
|
+
- `cache` is the prompt-side cache-hit share (cache reads over all billed input); `in` / `out` are the session's billed input and output tokens.
|
|
260
|
+
- A narrow terminal drops trailing groups **whole** and marks the elision with `│…` rather than cutting a figure in half; the window always carries the complete set.
|
|
261
|
+
- A session with no closed step and no billed tokens hides the strip entirely and gives the row back to the transcript.
|
|
244
262
|
|
|
245
|
-
The
|
|
263
|
+
The whole strip is a click target. Clicking it — or the context meter at the right end of the status row (`ctx ▓▓░░ 32K/128K 25%`), or typing `/stats` — opens the **session stats window**; click again, click elsewhere, or press `Esc` to close. The window breaks the same line into labelled rows (`usage` / `duration` / `speed` / `tokens` / `cache`) and adds the context-occupancy reading with its heuristic composition — system prompt, tools, and messages — matching the Web UI's ContextMeter dialog.
|
|
246
264
|
|
|
247
|
-
|
|
265
|
+
Figures come from the same sources as the Web UI, projection-first with the plugin's own fold as the fallback: `tokenUsage`, `contextPressure`, and `contextBreakdown` are mounted by `dsh-base`'s token-meter row, while `sessionStats` is mounted only by the web app bundle — so the TUI folds the durable `step` / `chunk` / `message` / `tool` events by the same rules. A missing projection falls back for that figure alone, and a figure nobody can supply stays hidden instead of printing a zero.
|
|
248
266
|
|
|
249
267
|
### Settings
|
|
250
268
|
|
|
@@ -362,12 +380,12 @@ More detail, in Chinese: [docs/用户手册.md](docs/用户手册.md).
|
|
|
362
380
|
|
|
363
381
|
## Known limitations
|
|
364
382
|
|
|
365
|
-
- IME composition
|
|
383
|
+
- IME composition is not exposed by the zero-dependency terminal engine yet. Pasted images are: a bracketed paste of raw image bytes, a `data:image/...;base64,...` URL, a local image path, or an image URL becomes a `[Image N]` attachment, and pasting text nothing recognizes asks the terminal for its clipboard (OSC 52).
|
|
366
384
|
- The plugin does not hot-reload: the profile's HMR root is the profile directory, so a running TUI keeps the copy it booted with.
|
|
367
385
|
- `dsh tui` as a bare subcommand needs a shell alias — the stock launcher hardcodes only `web` and `plugin`.
|
|
368
386
|
- Harness slash commands need a live session; on the title screen the TUI tells you to start one first.
|
|
369
387
|
- Deferring a question with `Esc` does not cancel the tool call — it delegates, and with no other answerer the tool call fails. Per-question skip (as the Web UI composer offers) is not implemented.
|
|
370
|
-
- `--resume`, Settings → Manage sessions,
|
|
388
|
+
- `--resume`, Settings → Manage sessions, the context meter, and the stats strip depend on services mounted by `@deepseek-ai/dsh-base` (`sessionQuery`, `sessionProjections`); a hand-built profile must provide them. The `sessionStats` projection is a web-app-layer row, so the TUI folds those figures from the session log itself when no profile mounts it.
|
|
371
389
|
- The deferred dsh install on Windows waits for the TUI that scheduled it, not for every dsh process on the machine — close other TUI windows (and `dsh web`) before it runs.
|
|
372
390
|
|
|
373
391
|
## Layout
|
|
@@ -377,7 +395,7 @@ lib/index.js plugin entry: agents, events, input, commands, approvals, u
|
|
|
377
395
|
lib/startup.js command-line provider (tuiStartup service)
|
|
378
396
|
lib/term.js terminal engine (raw mode, screen, key decoding)
|
|
379
397
|
lib/ui.js responsive view model + renderer (includes the question modal)
|
|
380
|
-
lib/metrics.js
|
|
398
|
+
lib/metrics.js whole-session stats + token usage fold (web stats strip / tokenUsage port)
|
|
381
399
|
lib/interrupt.js Ctrl+C lifecycle state
|
|
382
400
|
lib/web-settings.js shared WebUI settings projection
|
|
383
401
|
lib/updates.js in-app update manager (npm registry + installs)
|