codsh▍
The interaction design of today's best agent CLIs, rebuilt as one surface — and put on top of a runtime you already have.
$ npm install -g @deepseek-ai/dsh codsh-cli # have dsh already? npm i -g codsh-cli $ codsh
Everything under the surface — the agent loop, tools, sessions, sandboxing, model adapters — is the released DeepSeek Harness packages from npm, installed once per machine. codsh adds two small things on top: the launcher, and a bundle carrying the TTY surface and a coding preset.
██████╗ ██████╗ ██████╗ ███████╗██╗ ██╗
██╔════╝██╔═══██╗██╔══██╗██╔════╝██║ ██║
██║ ██║ ██║██║ ██║███████╗███████║
██║ ██║ ██║██║ ██║╚════██║██╔══██║
╚██████╗╚██████╔╝██████╔╝███████║██║ ██║
╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝
✻ Welcome to codsh · cli-mock · code-cli
~/.cache/codsh/showcase
session session-6610af68-744c-4499-98c7-d9bb135d6891
/help for commands · Tab completes · ⇧Tab plan mode · ESC interrupts · /exit leav
…
╭─────────────────────────────────────────────────────────────────────────────────╮
│ › Ask anything · / for commands · @ for files · ⇧Tab plan mode │
╰─────────────────────────────────────────────────────────────────────────────────╯
cli-mock · code-cli · workspace-write · 0 tokens · ~/.cache/codsh/showcase
Captured from the packed binary by the e2e harness.
Every terminal below is a real one.
Not a mockup. Each frame was captured from the packed binary by the end-to-end harness, replayed through a terminal emulator, and written into this page with its colours intact.
A screenshot nobody checked is a promise nobody kept, so the site is
generated the way the tests are: drive the real thing, keep the frame.
Rerun it with pnpm run site:screens. A screen’s empty middle
is shortened so the card stays a readable height — nothing else is touched.
┃ › create the note
│ ● Write note.txt
│ + CODE_CLI_ROUND_TRIP
CODE_CLI_CALL_OK via cli-mock
╭─────────────────────────────────────────────────────────────────────────────────╮
│ › Ask anything · / for commands · @ for files · ⇧Tab plan mode │
╰─────────────────────────────────────────────────────────────────────────────────╯
⠋ working 0.0s · ESC to interrupt
cli-mock · code-cli · workspace-write · 26 tokens · ~/.cache/codsh/showcase
Every call renders through its presenter — a title, a status, and a diff — under a rule down the block’s left edge.
┃ › think it over
✻ thought for 0.0s · +2 lines (click or Ctrl+O expands)
CODE_CLI_ANSWER after thinking
0.0s · 14 tokens
╭─────────────────────────────────────────────────────────────────────────────────╮
│ › Ask anything · / for commands · @ for files · ⇧Tab plan mode │
╰─────────────────────────────────────────────────────────────────────────────────╯
thinking · 4 lines · click to expand
cli-mock · code-cli · workspace-write · 14 tokens · ~/.cache/codsh/showcase
Resting on a fold underlines its head row and names it below the box — what a click will do, before it lands.
┃ › think it over
✻ thought for 0.0s
CODE_CLI_THINKING about the request
weighing the options carefully
CODE_CLI_ANSWER after thinking
0.0s · 14 tokens
╭─────────────────────────────────────────────────────────────────────────────────╮
│ › Ask anything · / for commands · @ for files · ⇧Tab plan mode │
╰─────────────────────────────────────────────────────────────────────────────────╯
cli-mock · code-cli · workspace-write · 14 tokens · ~/.cache/codsh/showcase
A click opens the block it lands on and a click anywhere inside folds it back; Ctrl+O still swaps every one at once.
┃ › plan the work
│ ● Update todo list
│ todos 1/3 · 1 in progress · 1 open
│ ✔ read the code
│ ▶ write the fix
│ ○ run the tests
│ Updated todo list: 1 pending, 1 in progress, 1 completed.
CODE_CLI_CALL_OK via cli-mock
0.1s · 26 tokens
╭─────────────────────────────────────────────────────────────────────────────────╮
│ › Ask anything · / for commands · @ for files · ⇧Tab plan mode │
╰─────────────────────────────────────────────────────────────────────────────────╯
todos 1/3 · 1 in progress · 1 open · Ctrl+T closes
✔ read the code
▶ write the fix
○ run the tests
cli-mock · code-cli · workspace-write · 26 tokens · ~/.cache/codsh/showcase
A pinned row holds the agent’s list over the status row instead of scrolling away with the write; Ctrl+T opens it whole.
Prose with bold, em, inline_code, and a link (https://x.dev).
An identifier like some_helper_name must survive intact.
• screen.ts: the viewport module
• second bullet
• third bullet keeps the answer long
• fourth bullet keeps the answer long
• fifth bullet keeps the answer long
• sixth bullet keeps the answer long
• seventh bullet keeps the answer long
• eighth bullet: past the fold threshold at any test width
╭────────┬────────────────────────────────────────────────────────────────────────╮
│ 维度 │ 内容 │
├────────┼────────────────────────────────────────────────────────────────────────┤
│ 一句话 │ 一个很长的中文单元格内容,用来强制表格在任何终端宽度下都必须在单元格内 │
│ │ 部换行。一个很长的中文单元格内容,用来强制表格在任何终端宽度下都必须在 │
│ │ 单元格内部换行。一个很长的中文单元格内容,用来强制表格在任何终端宽度下 │
│ │ 都必须在单元格内部换行。 │
├────────┼────────────────────────────────────────────────────────────────────────┤
│ 命令 │ codsh │
╰────────┴────────────────────────────────────────────────────────────────────────╯
│ a quoted line
ts
const answer = "text" // a comment
CODE_CLI_CALL_STREAM_DONE
╭─────────────────────────────────────────────────────────────────────────────────╮
│ › Ask anything · / for commands · @ for files · ⇧Tab plan mode │
╰─────────────────────────────────────────────────────────────────────────────────╯
⠋ working 0.0s · ESC to interrupt
cli-mock · code-cli · workspace-write · 0 tokens · ~/.cache/codsh/showcase
Tables get real columns, code gets highlighted, and emphasis markers are consumed instead of printed.
██████╗ ██████╗ ██████╗ ███████╗██╗ ██╗
██╔════╝██╔═══██╗██╔══██╗██╔════╝██║ ██║
██║ ██║ ██║██║ ██║███████╗███████║
██║ ██║ ██║██║ ██║╚════██║██╔══██║
╚██████╗╚██████╔╝██████╔╝███████║██║ ██║
╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝
✻ Welcome to codsh · cli-mock · code-cli
~/.cache/codsh/showcase
session session-e81f2247-9dbd-4e1e-afc1-efc009a5578d
/help for commands · Tab completes · ⇧Tab plan mode · ESC interrupts · /exit leav
…
▲ plan mode — exploring only; no files will change until you approve a plan
╭─────────────────────────────────────────────────────────────────────────────────╮
│ › Ask anything · / for commands · @ for files · ⇧Tab plan mode │
╰─────────────────────────────────────────────────────────────────────────────────╯
cli-mock · code-cli · workspace-write · plan · 0 tokens · ~/.cache/codsh/showcase
Shift-Tab toggles plan mode, and the frame carries it so the next submission’s effect is visible mid-thought.
A session that is its own space.
codsh takes the alternate screen, so your shell's scrollback is untouched and waiting when you leave.
The transcript is yours to move in
It scrolls in a buffer the session owns — wheel, page keys, ⇧↑ ⇧↓ — under an input box that never leaves the bottom. Scrolled back, the viewport says how far, and new output accumulates without yanking you to it.
Folds answer the mouse
Long finished blocks — thinking, tool output, answers past a screenful — collapse to their head lines once you move on. Click one to open just that block, click anywhere inside to fold it back, or swap every one at once.
A block says what it is
Rest the pointer on a fold and its head row underlines while the
chrome names it — thinking · 42 lines · click to expand.
What a click will do is known before it lands, and a block taller
than the screen still tells you which one you are in.
Todos that stay in view
When the agent writes a list, a pinned row holds it over the status row — progress, the item in flight, or what comes next — instead of scrolling away with the write.
Select to copy
Drag, and the selection is on your clipboard the moment you release — through OSC 52 and the platform clipboard both. A selection that sweeps across a block's left rule copies the text without it.
An input box that owns the keyboard
Multi-line editing (⇧Enter on kitty-protocol terminals,
Alt+Enter everywhere), history across sessions, and
completion for commands, arguments and @-mentioned files
as you type.
Streaming rendering
Markdown with code highlighting and real table columns, reasoning
dim under ✻ thinking, and tool calls as presenter-driven
cards with diffs.
Decisions as selections
Approvals, questions, /model and /resume are
arrow-key widgets. Plan mode toggles on ⇧Tab and tints the
box frame, so the next submission's effect is visible mid-thought.
Session flow
/clear starts fresh in place, /resume picks
from recorded sessions, Esc Esc recalls your
last message to edit, and !cmd runs in your shell with
the outcome injected as context — no turn spent.
One sentence to shipped.
/ship drives an idea from 0 to 1 with exactly two approvals
and nothing else to babysit.
-
Interview
The agent reads your repo first, then asks one focused question at a time — users, success criteria, scope, non-goals, constraints, edge cases — until answers stop changing the design. A pasted mockup or screenshot is requirements material.
-
Spec — gate 1
The agreed design lands as a file in your repo. Every acceptance criterion names the exact command that proves it, and a
Status:line makes the file resumable. You confirm it. -
Plan — gate 2
Ordered milestones, the tests each one adds, and the commands that prove the whole thing. You approve it — and the plan is then written into the spec as checkboxes, with the proof commands run once to record the baseline before any code. A suite that was already red surfaces here, not under the diff.
-
Landing
From here it is autonomous, with the spec file — not the conversation — as the working memory: re-read before each milestone, checkbox ticked and a commit made when it turns green. Small plans run in-session under the todo list; large ones run a bounded fresh-agent Ralph loop that stops and reports rather than spin past two rounds of no progress.
-
Done means verified
Every criterion is checked by running its own command and reading the real output — after a Ralph loop, the session re-runs them all itself — then a report listing criterion, command, and what it printed.
› /ship let long diffs open in a pager instead of scrolling past
Run it bare and it first offers to resume any unfinished spec it finds — interruptions lose nothing — then asks for the sentence. Mid-flight decision changes go back into the spec file, so the file on disk always states what is being built.
Two packages, one dsh.
codsh-cli is a zero-dependency launcher, a few kilobytes. It
never bundles the runtime, so a machine carries exactly one dsh however
many tools sit on it.
The launcher finds your dsh, registers the
codsh-bundle
runtime into a dsh code profile on first run — the packaged
code-cli preset installs itself on first boot — and every
later run boots straight into the prompt. codsh is exactly
dsh --profile code; flags after it reach the app.
codsh --resume <id>Reopen a recorded session, replaying its history as the same folds.
codsh --continuePick up the most recent session in this workspace.
codsh -p "task"One-shot print mode, for scripts and pipes.
DEEPSEEK_API_KEYThe model key, read from the environment or a .env file.
DSH_BINWhich dsh to launch, when you do not want the one on PATH.
DSH_HOMEWhere profiles live; ~/.dsh by default.
CODSH_CLIPBOARDosc52, system, or off — narrows how a selection reaches your clipboard.
CODSH_BUNDLE_SPECPin the runtime the launcher registers, instead of the version it pairs with.
CODSH_VISION_BASE_URLAn OpenAI-compatible multimodal endpoint that describes pasted images for the text-only model.
CODSH_VISION_MODELThe vision model to ask, e.g. glm-4v or a local llava.
CODSH_VISION_API_KEYBearer token for the vision endpoint; leave unset for endpoints that need none.
Prefer no launcher at all? The two lines it wraps work directly, with any profile name:
$ dsh plugin --profile code add codsh-bundle $ dsh --profile code
Seconds per iteration.
pnpm run dev keeps a repo-local dsh home in
.dev-home: the first run does a real profile install of the
packed tree, and every later run copies the fresh build over it — so
edits reach the running surface in seconds.
$ pnpm install $ pnpm run dev # build → sync → boot $ MOCK=markdown pnpm run dev # keyless, against the e2e mock model $ pnpm test # unit suites $ pnpm run test:e2e # packs, installs, drives the real binary
The e2e suites test the published artefact: npm pack's output
goes into a real profile, booted by the dsh launcher from npm against a
keyless mock model. What passes there is what a user installs — and it is
the same harness that captured the frames on this page.
pnpm run sync:dsh moves every range to the newest
published version, re-verifies the plugin composition, and proves the
tree still builds and passes.