An interactive terminal runner for DeepSeek Harness in the style of Claude Code / Codex CLI: a long-lived REPL that creates (or resumes) one persisted agent, streams its durable session events into the terminal, answers approval prompts inline, and exposes slash verbs. No web, no HTTP host, no browser — just the terminal.
# interactive REPL (creates a session, or resumes the latest for this directory)
dsh --profile tui
# one-shot pipeline mode (no TTY): pipe a task in, get the answer on stdout
echo "run the tests" | dsh --profile tui --fresh| Flag | Meaning |
|---|---|
--workspace <dir> |
Working directory for the agent (default: the launching directory) |
--session <id> |
Resume a specific persisted session instead of the latest |
--model <provider/model> |
Override the default model for this boot |
--permission <mode> |
read-only | workspace-write | danger-full-access |
--fresh |
Start a brand-new session instead of resuming the latest |
--no-intro |
Skip the intro banner |
-h, --help |
Show this command's help |
Booting without --fresh resumes the newest persisted session whose workspace
matches the launching directory, and prints a recap of its last turn.
/help /quit /exit /new /sessions /resume /rename /workspace
/plan /model /reasoning /providers /models /apikey /permission
/clear /status /print
/sessionslists persisted sessions for this workspace./resume <id>resumes a specific session mid-run./rename <title>names the current session./workspace [<dir>]shows the workspace, or switches to another directory./plan [on|off]toggles plan mode (the agent plans, then submits the plan for review)./modeland/reasoningswitch the active model/effort./providersand/models [<provider>]browse the configured model catalog./apikey [<key>]stores the DeepSeek key (blank shows its source) the same way the Web "Models" page does./permissionchanges the approval mode for the session./new,/quit, and/exitstart fresh or leave the session.
The harness also ships its own scheduled commands (/compact, /goal,
/feedback, …); any it registers are exposed automatically and get picked up
by Tab completion. Prompt-time features from the Web UI are mirrored too: the
agent's live task list is pinned in a side panel while it works, the model can
pause and ask you a multiple-choice question (answered inline in the TUI), and
tool approvals are rendered as inline y/n prompts.
npm run build # tsc -p tsconfig.build.json
node scripts/deploy.mjs # copy bundle into ~/.dsh/profiles node_modulesDeploy installs the bundle under $DSH_HOME/profiles/node_modules so
dsh --profile tui picks it up.
scripts/mock-llm.mjs serves an OpenAI-compatible SSE endpoint that plays a
scripted 4-step tour — write a task list, run bash, ask the user a
multiple-choice question, then answer — so the whole loop (tools → task list →
question → answer) can be exercised end to end.
# non-escalated: tool runs without prompting
node scripts/mock-llm.mjs
# escalated: the bash tool asks for approval (answer y/n in the TUI)
MOCK_ESCALATE=1 node scripts/mock-llm.mjsPoint the profile's model config at it, e.g. in ~/.dsh/settings.yaml:
llm-deepseek:
baseURL: http://127.0.0.1:8899
agent-default-model:
provider: deepseek-official
model: deepseek-v4-flashThen run with a dummy key: DEEPSEEK_API_KEY=sk-dummy dsh --profile tui --fresh.
npm run smoke runs a self-contained end-to-end check: it boots (or reuses)
the mock, runs the profile in one-shot piped mode against a fresh temp
workspace, and asserts the tour completes with the expected answer.
The profile speaks the OpenAI chat-completions wire format, so a compatible
relay can stand in for the DeepSeek API. From ~/.dsh/settings.yaml:
llm-deepseek:
baseURL: https://<host>/<deployment>/relay/v1 # adapter appends /chat/completions
maxTokens: 16000 # keep under the relay's output cap
models: # optional: catalog surfaced by /models
- id: DeepSeek-V4-Flash-0731
name: DeepSeek-V4-Flash-0731
agent-default-model:
provider: deepseek-official
model: DeepSeek-V4-Flash-0731Then boot with a model id the relay actually serves:
DEEPSEEK_API_KEY=<relay-token> dsh --profile tui --model DeepSeek-V4-Flash-0731Gotchas: the baseURL must include the path prefix before /chat/completions
(the DeepSeek adapter always appends it); relay max_tokens caps are typically
lower than the CLI default of 256k, so keep maxTokens under the cap; and the
persisted model selection can override agent-default-model, so prefer
--model or /model to pick the serving model.
dsh-tui is an ordinary Cordis plugin bundle over dsh-base:
src/startup.ts— the app'scommandercommand; providestuiStartupconfig only after flags parse, so--helpnever boots the loop.src/index.ts— theClidriver: boots (create or resume) an agent, streams session events, answersapproval/requestprompts, dispatches verbs.src/terminal.ts— raw/alternate-screen TTY renderer (prompt, status line, history, tab completion).src/render.ts— streams assistant text, tool-call descriptions, and turn summaries into the terminal.
Interactive runs never watch or reload their composition (hmr is disabled for
the profile).