codsh
A terminal coding agent · composed on dsh

codsh

The interaction design of today's best agent CLIs, rebuilt as one surface — and put on top of a runtime you already have.

codsh-cli on npm zero-dependency launcher MIT
install
$ 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.

A session that is its own space real capture
██████╗ ██████╗ ██████╗ ███████╗██╗ ██╗ ██╔════╝██╔═══██╗██╔══██╗██╔════╝██║ ██║ ██║ ██║ ██║██║ ██║███████╗███████║ ██║ ██║ ██║██║ ██║╚════██║██╔══██║ ╚██████╗╚██████╔╝██████╔╝███████║██║ ██║ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ✻ 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.

01 — See it

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.

Tool calls as cards, with their diffs real capture
┃ › 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.

A block says what it is under the pointer real capture
┃ › 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.

One click opens the one block real capture
┃ › 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.

Todos that stay in view real capture
┃ › 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.

Markdown, rendered rather than echoed real capture
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.

Plan mode tints the box real capture
██████╗ ██████╗ ██████╗ ███████╗██╗ ██╗ ██╔════╝██╔═══██╗██╔══██╗██╔════╝██║ ██║ ██║ ██║ ██║██║ ██║███████╗███████║ ██║ ██║ ██║██║ ██║╚════██║██╔══██║ ╚██████╗╚██████╔╝██████╔╝███████║██║ ██║ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ✻ 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.

02 — The surface

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.

clickCtrl+O

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.

Ctrl+T/todos

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.

Off a TTY it degrades rather than breaks. In a pipe or a script the same surface becomes a line reader: selections become typed answers, lists replace widgets, and nothing draws.
03 — /ship

One sentence to shipped.

/ship drives an idea from 0 to 1 with exactly two approvals and nothing else to babysit.

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

in the box
 /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.

04 — Install & run

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 --continue

Pick up the most recent session in this workspace.

codsh -p "task"

One-shot print mode, for scripts and pipes.

DEEPSEEK_API_KEY

The model key, read from the environment or a .env file.

DSH_BIN

Which dsh to launch, when you do not want the one on PATH.

DSH_HOME

Where profiles live; ~/.dsh by default.

CODSH_CLIPBOARD

osc52, system, or off — narrows how a selection reaches your clipboard.

CODSH_BUNDLE_SPEC

Pin the runtime the launcher registers, instead of the version it pairs with.

CODSH_VISION_BASE_URL

An OpenAI-compatible multimodal endpoint that describes pasted images for the text-only model.

CODSH_VISION_MODEL

The vision model to ask, e.g. glm-4v or a local llava.

CODSH_VISION_API_KEY

Bearer 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:

without the launcher
$ dsh plugin --profile code add codsh-bundle
$ dsh --profile code
05 — Develop

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.

development
$ 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.

codsh never forks the harness. Upstream changes go to deepseek-harness as ordinary pull requests. Keeping in step with its releases is automated: 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.