dsh-TUI

1.8kStars78Forks56Issues0Watchers

DeepSeek Harness is a Claude

Language
TypeScript
License
MIT
Branch
main
claude-codecoding-agentdeepseekdeepseek-harnessdsh-plugininkreactterminal

Install

$ dsh plugin --profile web add github:ccch1mneyyy/dsh-TUI

Run the command above in your terminal to install this plugin via the dsh CLI. You can switch Profile in the top-right corner. New to dsh? Read the beginner tutorial

One-Line Pitch

dsh-TUI is a Claude Code-style terminal interaction frontend for DeepSeek Harness. As a Cordis bundle plugin mounted on dsh-base, it reuses official Agent, model, session, and tool services to provide users with streaming Markdown conversations, /resume//new/model switching, double-click Esc for history traversal, and fullscreen alt-screen rendering.

Core Features

  • Provides streaming Markdown, structured tool cards, command and file completion, @ file references (anywhere completion, images sent as persistent attachments), history search, message selection, and supports both inline and alt-screen rendering modes
  • Displays real-time work progress, segmented context usage, TPS, cache hit rate, inference level, input/output tokens, and Git/session information in the status bar
  • Complete session workflow: /resume session browser, /new new session, /compact compact, /export Markdown export, /btw side question, model switching, and double-click empty input Esc for time travel via session fork
  • Integrates DSH official capabilities: Agent preset roster (/preset), Skills (/audit /bug /review etc.), MCP (/mcp), Goals, Todos, sub-agents, and ask_user_question questionnaires
  • Event-driven projection, differential terminal output, message virtualization, replay merging, and bounded缓存 for long sessions to prevent rendering and memory from growing infinitely with the session
  • /theme built-in auto/light/dark/dark-ansi four themes and supports ~/.dsh-tui/themes/<name>.json customization, /lang Chinese/English interface switching, all through Cordis configuration + persistence + env three-level override

Technical Implementation

  • Language: TypeScript (ESM, "type": "module", tsc compiled to lib/types/)
  • Key Dependencies: react@^19.2.0, react-reconciler@^0.33.0, @deepseek-ai/cordis@^4.0.1, @deepseek-ai/dsh-agent@^0.1.0-rc.6
  • Architecture Pattern: Single Cordis plugin name: 'dsh-tui', via dsh.bundle.patch → ./cordis.patch.yml overriding dsh-base default lines (disabling host layer tools/planning/compaction/skills, etc., taken over by Agent preset roster), official @deepseek-ai/* imports concentrated within src/dsh-adapter/ boundary, rendering based on ported Ink+Yoga (differential output, terminal capability detection, ConPTY compatible path)
  • Entry Files: src/index.ts (re-export shim) → src/dsh-adapter/index.ts (Config Schema + apply) → src/dsh-adapter/plugin.tsx (runtime implementation), bin entry is bin/dsh-tui.js (one-click detection of dsh/pnpm and self-bootstrapping profile)

Use Cases

When you want to use DSH as a "daily development conversation partner"—continuous multi-round dialogue in the terminal, need to see visualization of thinking and tool calls, can随时回查或回溯历史会话, don't want to be interrupted by web pages—dsh-TUI provides the Claude Code familiar interaction experience. At the same time, it shares session/event true source with the official web client, so sessions opened in TUI can also be viewed on the web.

Prerequisites & Compatibility

DependencyMinimum VersionDescription
DeepSeek Harness0.1.0-rc.6+Determined by @deepseek-ai/dsh-* locked in package.json#peerDependencies
Node.js^22.19.0 || >=24.0.0package.json#engines.node; CI uses 24
pnpm10+ (recommended 11+)Package installation within profile handled by pnpm; pnpm 9 transitive dependencies not promoted will exit immediately (issue #60)
PlatformmacOS / Windows / LinuxCross-platform; Windows uses dsh-tui.cmd, clipboard reads PowerShell, sandbox unavailable on Windows so falls back to danger-full-access
Native ModulesNoneAll JS/TS dependencies, no node-gyp build required
Peer Dependencies@deepseek-ai/cordis ^4.0.1 and full set of @deepseek-ai/dsh-* ^0.1.0-rc.6Provided by host DSH; uninstalling please ensure host version alignment
Required CredentialsDEEPSEEK_API_KEY (add DEEPSEEK_BASE_URL for custom endpoint)See cordis.patch.yml:28-30

Installation

dsh plugin --profile web add github:ccch1mneyyy/dsh-TUI

Configuration Options

All tunable parameters of dsh-TUI are concentrated in the Config Schema (src/dsh-adapter/index.ts:87). In $DSH_HOME/profiles/dsh-tui/cordis.patch.yml, replace the entire config block of the dsh-tui line; one-line change for overall modification; common items are as follows:

ConfigTypeDescriptionDefault
sessionIdstringExisting session ID to restore on startup; empty creates new sessionNot set
providerstringLLM routing name; only considered explicit routing when configured with modelHarness agentDefaultModel
modelstringStartup model; /model switches via session fork and writes back to persistenceHarness agentDefaultModel
cwdstringSession-side working directory (Agent meta, @ completion, /resume filtering, status bar); explicit absolute path recommendedGit worktree root of startup directory
workspacestringWorkspace target resolved at startup: local absolute path, file:// URI, or plugin-registered URINot set
effortstringInference level actually effective per request (deepseek only off/high/max, illegal silently falls back)max
activitybooleanWhether to show real-time work status linetrue
activityFramesstringWork status animation presets (claude/moon/comet/dots/random)claude
contextBarbooleanWhether to show segmented context progress bar below input boxtrue
fullscreenbooleantrue uses alternate screen + mouse selection; false uses inlinefalse
langen | zhInterface language (overridden by DSH_TUI_LANG)zh
presetstringNew session Agent preset (standard/code/minimal/cordis/liangshen)Persisted or standard
diffLayoutauto | split | unifiedFile editing diff display method (auto selects by terminal width)auto
modesarrayAtomic combinations for Shift+Tab session mode cycling (plan/sandbox/approval)Built-in three defaults → plan → full

Theme/language/debug switches not directly exposed by Config go through environment variables (priority: env > config > persistence > default):

Environment VariableDescription
DSH_TUI_LANGLock interface language en/zh
DSH_TUI_THEMELock built-in or custom theme, takes priority over persisted choice
DSH_TUI_PERSONAOverride Agent persona (defaults to You are a coding agent. if not set)
DSH_TUI_PRESETOverride new session default Agent preset
DSH_TUI_DISABLE_MOUSETemporarily disable mouse capture in fullscreen mode
DSH_TUI_SESSION_ROOTOverride JSONL session root directory
DSH_TUI_RESUME_SESSIONResume specified session on startup (launcher usually sets this for you)
DSH_TUI_WORKSPACE_TARGETStartup workspace triggered by dsh-tui <target>
DSH_TUI_WORKSPACEWorking directory used by Windows dsh-tui.cmd
DSH_TUI_DEBUGEnable stderr debug logging (don't log to stdout, it breaks the UI)
DSH_TUI_RENDER_LOGSpecify file path for raw ANSI frames for forensics (includes visible content, use with caution)
DEEPSEEK_API_KEY / DEEPSEEK_BASE_URLModel credentials and custom endpoint
DSH_PERMISSION_MODEOverride sandbox policy on non-Windows platforms (workspace-write/danger-full-access)

Legacy names CC_TUI_* and DSH_CC_* are no longer effective from this version (launcher will warn each time), the only exception is resume writing dual paths (both DSH_TUI_RESUME_SESSION and DSH_CC_RESUME_SESSION set at the same time).

FAQ

Q: I'm using pnpm 9, it exits back to shell immediately after startup with almost no error message.

A: This is typical manifestation of issue #60: pnpm 9 when installing profile does not promote transitive dependency dsh-working-activity to a location the loader can resolve, module resolution failure causes the entire plugin tree to be reclaimed, TUI after resume exits directly after showing the prompt. Upgrade pnpm to 10 or 11: npm install -g pnpm@latest && dsh plugin --profile dsh-tui add @deepseek-harness-tui/dsh-tui@latest.

Q: Launcher reports "Cannot start: profile runs v..., but launcher is v...".

A: This is reverse mismatch protection for issue #183: when global launcher is one minor version newer than packages in profile, CLI will apply launcher's bundle patch to older packages, subpath exports may not resolve, module resolution will crash. Align both: dsh plugin --profile dsh-tui add @deepseek-harness-tui/dsh-tui@<launcher version> (or both upgrade to @latest).

Q: After /model selects another model, I want to go back to the original conversation line.

A: Model switching in TUI continues via session fork, does not modify history. Old session stays fully in /resume list; selection itself persists in ~/.dsh-tui/model.json, used by next /new and restart.

Q: Installed but version seems unchanged?

A: Without @latest, pnpm resolves according to version range already recorded in profile package.json (like ^0.1.4), will stay on old mainline. Explicitly specify: dsh plugin --profile dsh-tui add @deepseek-harness-tui/dsh-tui@latest, then check top-right corner of header for vX.Y.Z to verify.

Q: Status bar work status line shows two / doesn't show.

A: Duplication is mostly due to another dsh-working-activity added in profile (both README and docs/getting-started.md warn against duplicate add). Remove duplicate bundle configuration in profile, keep only the working-activity line auto-inserted by this package patch. If not showing, check if dsh-tui activity: true in cordis.yml was overwritten, /activity choice accidentally turned off, or use DSH_TUI_DEBUG=1 dsh --profile dsh-tui to check stderr.

Q: Will uninstalling the plugin lose session data / change DSH core?

A: No. dsh-TUI is pure plugin mount (README.md:21), does not modify DSH core; uninstall is restore. Theme/language/preset preferences remain in ~/.dsh-tui/, can be manually deleted if needed. Session logs still in $DSH_HOME/sessions/ (profile) or ~/.dsh-tui/sessions/ (bare cordis.yml) original paths.

Q: Why doesn't pasting images on Windows send as image blocks like the documentation says?

A: Windows uses PowerShell Get-Clipboard to read clipboard. When clipboard is locked by other programs, it retries first, and if still locked eventually silently degrades to temp file path insertion (not embedded base64); Finder multi-file copy on macOS has no stable AppleScript reading method, falls back to text/image. These are all "known limitations" listed in README and architecture docs.

Q: Terminal doesn't support alt-screen or want to disable mouse?

A: Set dsh-tui fullscreen: false in cordis.patch.yml, or one-time startup use DSH_TUI_DISABLE_MOUSE=1 dsh --profile dsh-tui to temporarily disable mouse. Terminal.app (macOS built-in) consumes combinations, please continue using Ctrl+<key> in it (iterm2/kitty/WezTerm/ghostty etc. support ).

Learning Curve

Beginner — default config can start directly; enter configuration reference when you want to tune themes, Agent presets, MCP, approval policies.

Known Issues & Limitations

  • No usable sandbox backend on Windows: profile defaults to danger-full-access on Windows with approval policy never; before running in untrusted repo please check actual patch and DSH_PERMISSION_MODE settings (docs/architecture.md:110-111 / cordis.patch.yml:134).
  • /model continues via session fork: not in-place replacement; old session stays in /resume list (docs/architecture.md:122-123 / README.md:225-228).
  • Ctrl+V clipboard dispatches by platform: Windows uses PowerShell Get-Clipboard (falls back silently after retry if locked), macOS uses osascript/pbpaste (Finder multi-file copy has no stable AppleScript method), Linux probes wl-paste/xclip/xsel in order (all unavailable errors); clipboard bitmaps inserted as temp file paths not embedded as image blocks (README.md:229-234).
  • Plugin context injected into system prompt not shown independently: merged into context progress bar statistics (docs/architecture.md:121-122 / README.md:225).
  • Exit path doesn't wait for Agent async persistence: process exit concludes, persistence plugin as fallback (README.md:235 / docs/architecture.md:129).
  • /vim, /connect, /hooks are placeholder commands: When no equivalent mechanism on DSH side, gives clear explanation instead of silent (README.md:240-241 / docs/architecture.md:133).
  • Bare cordis.yml startup has no /permission preset switching: Only profile combinations have (default permission-presets line of dsh-base mounted) (README.md:236-239 / docs/architecture.md:131-132).
  • Legacy name environment variable compatibility: Old CC_TUI_* and DSH_CC_* no longer effective (launcher warns each time when set), the only exception is resume writes dual paths (both DSH_TUI_RESUME_SESSION and DSH_CC_RESUME_SESSION set ensures old launcher works) (docs/getting-started.md:79-92 / src/utils/paths.ts:58-68).
  • Data directory migration only copies not moves: On first startup if ~/.dsh-cc exists but ~/.dsh-tui doesn't, copies entire to new directory and prompts one line; old directory left for you to manually delete after confirming new directory works (docs/getting-started.md:88-90 / docs/architecture.md:96-98).
  • sessionHistory still compatible with old path ~/.dsh-cc/resume.txt: Marked TODO: drop the legacy path once pre-rename users migrate at src/sessionHistory.ts:14, current version needs to keep dual-write fallback.
  • Ink rendering layer has open TODOs: Ported Ink submodule has TODOs at src/ink/screen.ts:805 (SpacerHead cell handling when soft wrap not implemented) and src/ink/render-to-screen.ts:172 (cell conversion pending extraction to common helper), will follow up after code stabilizes.