dsh-tui
其他 活跃维护

dsh-tui

lyuwen/dsh-tui

提供终端可视化操作入口,支持点选配置工作流参数、实时追踪任务执行状态,无需记忆复杂指令,部署轻量,适配各类主流终端环境。

0
Stars 标星
0
Forks 分支
0
Watchers 关注
0
Open Issues
TypeScript
主要语言
None
开源协议
183 KB
仓库大小
28 天前
最后推送
一键安装扩展 / 插件指令
dsh plugin --profile web add github:lyuwen/dsh-tui
git clone https://github.com/lyuwen/dsh-tui.git
git clone git@github.com:lyuwen/dsh-tui.git
README.md main

dsh-tui

A lightweight terminal user interface for DeepSeek Harness (DSH). The TUI
is a thin frontend client: it connects to a running DSH backend over the
same HTTP/WebSocket protocol the Web UI uses, normalizes backend events into a
small client-side model, and renders them in the terminal. The backend stays
the single source of truth — the TUI never runs agents, tools, sandboxes, or
models itself.

       Browser                    Terminal
          │                          │
          ▼                          ▼
      DSH Backend  ◄── HTTP RPC + WebSocket ──►  dsh-tui

Features

  • Attach to any existing DSH session and resume it later
  • Live streaming: assistant text, reasoning (collapsible), tool cards,
    run state, session titles, token usage
  • Interactive approvals and user questions answered through the backend
  • Interrupt the current run (Esc)
  • Session picker, new-session creation, command palette
  • Reconnect with bounded backoff; dedup by backend identifiers
  • Offline replay of captured event traces for development and regression tests

Requirements

  • Node.js ≥ 20.18 (Node 22+ runs the TypeScript sources directly)
  • A running DSH server: dsh web (default http://127.0.0.1:3080)

Usage

npm install
npm run build          # compile to dist/

# Attach to an existing session
node dist/cli.js --session <session-id>

# Create a fresh session in the current directory and attach
node dist/cli.js --new

# Point at a non-default server
node dist/cli.js --server http://127.0.0.1:8080 --session <id>

# No session argument → session picker on startup
node dist/cli.js

# Offline replay of a captured trace
node dist/cli.js --replay fixtures/pong-session.jsonl --speed 2

The npm bin is dsh-tui; after npm link (or installing the package) the
commands above become dsh-tui --session <id>.

Keys

Key Action
Enter send — next-step delivery while the agent is running (» prompt), native queue when idle
Ctrl+Enter steer — cancel the current step, continue with your message
Ctrl+Shift+Enter backlog — queue as its own turn after the current one
Shift+Enter new line in the composer (multiline input)
Esc interrupt the current run
Ctrl+C / Ctrl+D quit (press twice to force)
Tab / Shift+Tab expand/collapse tools
Ctrl+T toggle reasoning visibility
Ctrl+O toggle latest tool output
Ctrl+P command palette
Ctrl+R session picker
PgUp / PgDn / Home / End scroll conversation
y / n allow / deny a permission request
1-9 + Enter answer a question

The three send modes follow the same semantics as the web UI's
queue-steer-button: Enter while running delivers the message with the next
agent step (session.prompt steer mode), Ctrl+Enter aborts the current step
first and then delivers, and Ctrl+Shift+Enter puts the message in the
whole-turn backlog.

Slash commands: typing / in the composer shows matching commands inline
(also available via Ctrl+P): /new, /sessions, /stats, /models,
/config, /permission, /reconnect, /reasoning, /tools, /clear,
/help, /quit. Any other /… text is forwarded to the backend's own
slash-command registry (e.g. /compact, /goal, /permission <preset>).

  • /stats — detailed session statistics from the live projections: turns,
    steps, LLM time, tool-call time, average TTFT, decode time, output tokens,
    throughput (TGS), input tokens (uncached + cache read), cache hit rate, and
    context pressure.
  • /models — browse provider groups and models; Enter applies, r cycles
    the reasoning effort (session.selectModel).
  • /config — read-only view of the deployment settings namespaces
    (settings.describe).
  • /permission — shows the current sandbox permission and the available
    presets; Enter applies through the backend /permission command.

Architecture

src/
├── cli.ts               CLI entry (args, TUI bootstrap, wiring)
├── test-client.ts       headless smoke client (Milestone B)
├── client/
│   ├── types.ts         normalized TUI event model (HarnessEvent, …)
│   ├── protocol.ts      wire envelopes: /api RPC, respond, event streams
│   ├── events.ts        raw frame → HarnessEvent normalization (once)
│   ├── harness-client.ts  stable client boundary (interface)
│   ├── dsh-client.ts    concrete DSH client (HTTP + WebSocket + reconnect)
│   └── reconnect.ts     bounded-backoff helpers
├── state/
│   ├── state.ts         DshTuiState
│   ├── reducer.ts       pure reduceHarnessEvent / reduceUiAction
│   ├── fold.ts          history folding (shares reducer semantics)
│   └── store.ts         tiny observable store
├── components/          Pi-based rendering: app, header, conversation,
│                        message, tool-call, interaction, composer, status-line,
│                        session-picker, command-palette, help
└── testing/
    └── replay-client.ts offline trace replay client

Design rules (from the implementation plan):

  1. The TUI depends only on the HarnessClient boundary — never on transport,
    wire schemas, Cordis internals, or backend implementation details.
  2. All backend-specific interpretation lives in client/events.ts
    (normalize exactly once).
  3. The state reducer is pure and unit-tested; rendering consumes state, not
    wire messages.
  4. Interactions are backend-authoritative: an approval is only settled when the
    backend confirms it (approval/resolved / question/resolved frames).
  5. Backend message/tool ids are preserved for dedup and reconnect.

Development

npm run typecheck
npm test                # 46 unit + integration tests
npm run test:client     # headless smoke client against a live server
npm run dev -- --replay fixtures/interaction.jsonl   # live TUI on a fixture

Captured fixtures live in fixtures/:

  • live-trace.jsonl — 1336 frames captured from a live mux stream
  • pong-session.jsonl — a complete small run (user → stream → answer)
  • interaction.jsonl — approval + question lifecycle (requested → resolved)
  • interaction-pending.jsonl — approvals/questions left pending

Documentation

Non-goals (MVP)

No embedded terminal emulator, file explorer, diff editor, workspace
management, model configuration, sandbox lifecycle, multi-session panes, local
trajectory persistence, or direct LLM calls. The TUI is a client; the backend
does the work.

License

MIT