codsh
终端编码 agent · 组合在 dsh 之上

codsh

把当今最好的几个 agent CLI 的交互设计重做成一个界面—— 再把它架在你已经有的运行时上。

npm 上的 codsh-cli 零依赖启动器 MIT
安装
$ npm install -g @deepseek-ai/dsh codsh-cli
  # 已有 dsh?只需 npm i -g codsh-cli
$ codsh

界面之下的一切——agent 循环、工具、会话、沙箱、模型适配器——都是 npm 上 已发布的 DeepSeek Harness 包,一台机器只装一份。codsh 只在上面加两个小东西:启动器, 以及携带 TTY 界面与编码 preset 的 bundle。

会话是自己的空间 真实抓取
██████╗ ██████╗ ██████╗ ███████╗██╗ ██╗ ██╔════╝██╔═══██╗██╔══██╗██╔════╝██║ ██║ ██║ ██║ ██║██║ ██║███████╗███████║ ██║ ██║ ██║██║ ██║╚════██║██╔══██║ ╚██████╗╚██████╔╝██████╔╝███████║██║ ██║ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ✻ 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

由 e2e harness 从打包后的真实二进制抓取。

01 — 看一眼

下面每一个终端都是真的。

不是效果图。每一帧都由 e2e 测试驱动打包后的真实二进制抓取, 经终端模拟器重放,再连颜色一起写进这个页面。

没人核对过的截图,等于没人守住的承诺——所以这个站点是按测试的方式生成的: 驱动真实的东西,留下那一帧。重新生成只需 pnpm run site:screens。 屏幕中间的空白被缩短,好让卡片保持可读的高度——除此之外没有任何改动。

工具调用渲染为卡片,带 diff 真实抓取
┃ › 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

每次调用都经由它的 presenter 渲染——标题、状态、diff——左侧还有一道标出块边界的竖线。

鼠标停在哪一块,它就说自己是什么 真实抓取
┃ › 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

停在折叠块上时,其首行加下划线,输入框下方报出它是什么——点下去会发生什么,点之前就知道。

一次点击只开一块 真实抓取
┃ › 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

点一下展开落点那一块,在块内任意处再点一下收起;Ctrl+O 依然一次开合全部。

todo 常驻可见 真实抓取
┃ › 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

一行常驻读数把 agent 的清单钉在状态行之上,不随那次写入滚走;Ctrl+T 展开为完整清单。

Markdown 是渲染,不是回显 真实抓取
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

表格排出真正的列,代码带高亮,强调标记被吃掉而不是打印出来。

Plan 模式为输入框着色 真实抓取
██████╗ ██████╗ ██████╗ ███████╗██╗ ██╗ ██╔════╝██╔═══██╗██╔══██╗██╔════╝██║ ██║ ██║ ██║ ██║██║ ██║███████╗███████║ ██║ ██║ ██║██║ ██║╚════██║██╔══██║ ╚██████╗╚██████╔╝██████╔╝███████║██║ ██║ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ✻ 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 切换 plan 模式,边框承载这个状态——下一次提交会做什么,思考途中一眼可见。

02 — 界面

会话是自己的空间。

codsh 进入备用屏幕,你的 shell 滚回历史原封不动、退出即在那里等着你。

transcript 由你自己走

它在会话自有的缓冲里滚动——滚轮、翻页键、⇧↑ ⇧↓—— 输入框钉在底部从不移动。向上翻阅时视口会标注离尾部多远, 新输出继续累积而不把你拽回去。

折叠块听鼠标的

超过一屏的已完成块——思考、工具输出、长回答——在你继续往下走时 折叠成头几行。点一下只展开那一块,在块内任意处再点一下收起, 也可以一次开合全部。

点击Ctrl+O

块会说自己是什么

鼠标停在折叠块上,它的首行加下划线,同时 chrome 报出它是什么—— thinking · 42 lines · click to expand。点下去会发生什么, 点之前就知道;块比屏幕还高时,你也知道自己正处在哪一段。

todo 常驻可见

agent 写下清单后,一行常驻读数把它钉在状态行之上——进度、 正在做的那一项,或者下一项该做什么——不会随那次写入一起滚走。

Ctrl+T/todos

框选即复制

拖动,松手那一刻内容就在剪贴板上——OSC 52 与平台剪贴板双通道。 框选跨过块左侧的竖线时,复制出来的是正文,不带那道线。

接管键盘的输入框

多行编辑(支持 kitty 键盘协议的终端用 ⇧Enter, 其余终端 Alt+Enter)、跨会话历史, 命令、参数与 @ 文件提及的补全随输入自动打开。

流式渲染

Markdown 带代码高亮与真正的表格列,推理模型的思考在 ✻ thinking 下暗色显示,工具调用按 presenter 驱动的 卡片渲染(含 diff)。

决定用选择

审批、提问、/model/resume 都是方向键组件。 ⇧Tab 切换 plan 模式并为输入框着色——下一次提交会做什么, 思考途中一眼可见。

会话流

/clear 原地开新会话,/resume 从会话列表里选, 连按两次 Esc 召回上一条消息编辑,!cmd 在你自己的 shell 里运行并把结果注入为上下文——不花回合。

非 TTY 环境下是降级,不是罢工。在管道或脚本里,同一界面变成行读取器: 选择变为键入回答、组件变为列表、不绘制任何东西。
03 — /ship

一句话到落地。

/ship 用恰好两次确认、再无其他看护,把一个想法从 0 推到 1。

  1. 访谈

    agent 先通读你的仓库,再一次只问一个问题——用户、成功标准、范围、非目标、约束、边界情况——直到回答不再改变设计。随命令粘贴的 mockup 或截图就是需求材料。

  2. Spec — 关口 1

    商定的设计落成仓库里的一个文件。每条验收标准都写明证明它的精确命令,Status: 行让文件可续跑。由你确认。

  3. 计划 — 关口 2

    有序的里程碑、每个里程碑添加的测试,以及证明整件事的命令。由你批准——批准后计划以复选框形式写进 spec 文件,并在写任何代码之前先把证明命令跑一遍记录基线。本来就红的测试在这道关口暴露,而不是压在 diff 底下。

  4. 落地

    此后全程自主,spec 文件——而非对话——是工作记忆:每个里程碑开始前重读、变绿即打钩并提交一次。小计划在会话内按 todo 清单走;大计划跑有界的 fresh-agent Ralph 循环,连续两轮无进展即停下汇报而不是空转。

  5. 完成即已验证

    每条标准都以跑它自带的命令、读真实输出来验证——Ralph 循环返回后由会话亲自全部重跑——然后按“标准、命令、实际输出”逐条汇报。

在输入框里
 /ship 让超长 diff 用分页器打开而不是刷屏滚过

不带参数运行会先提议续跑任何未完成的 spec——中断不丢任何东西—— 然后才问你那句话。中途改变的决定先写回 spec 文件, 磁盘上的文件永远说明正在构建什么。

04 — 安装与运行

两个包,一份 dsh。

codsh-cli 是一个零依赖启动器,只有几十 KB。它从不捆绑运行时, 所以一台机器无论装多少工具,都只有一份 dsh。

启动器自动找到你的 dsh,首次运行把 codsh-bundle 运行时注册进 dsh 的 code profile——自带的 code-cli preset 会在首次启动时自动安装——之后每次运行 直接进入提示符。codsh 严格等价于 dsh --profile code,其后的参数直达应用。

codsh --resume <id>

重开一个已记录的会话,历史以同样的折叠形态重放。

codsh --continue

接上当前工作区最近的那个会话。

codsh -p "任务"

一次性 print 模式,面向脚本与管道。

DEEPSEEK_API_KEY

模型密钥,从环境变量或 .env 读取。

DSH_BIN

指定启动哪个 dsh,当你不想用 PATH 上那个时。

DSH_HOME

profile 存放位置,默认 ~/.dsh

CODSH_CLIPBOARD

osc52systemoff——收窄选中内容进剪贴板的通道。

CODSH_BUNDLE_SPEC

钉住启动器注册的运行时版本,而不用它默认配对的那个。

CODSH_VISION_BASE_URL

任意 OpenAI 兼容的多模态端点,替纯文本模型描述粘贴的图片。

CODSH_VISION_MODEL

要询问的视觉模型,如 glm-4v 或本地 llava

CODSH_VISION_API_KEY

视觉端点的 Bearer token;端点无需鉴权时留空。

完全不想要启动器?它包装的那两行可以直接用,profile 名任取:

不用启动器
$ dsh plugin --profile code add codsh-bundle
$ dsh --profile code
05 — 开发

一次迭代只要几秒。

pnpm run dev.dev-home 维护一个仓库本地的 dsh home:首次运行对打包后的工作树做一次真实 profile 安装, 之后每次只把新构建覆盖上去——改动秒级到达运行中的界面。

开发
$ pnpm install
$ pnpm run dev            # build → 同步 → 启动
$ MOCK=markdown pnpm run dev  # 无 key,对着 e2e mock 模型
$ pnpm test              # 单测
$ pnpm run test:e2e      # 打包、安装,驱动真实二进制

e2e 测试的是发布产物:npm pack 的输出装进真实 profile, 由 npm 上的 dsh launcher 启动,配 keyless mock 模型。 那里通过的就是用户装到的——本页那些帧也出自同一套 harness。

codsh 绝不 fork harness。想进上游的改动以普通 PR 提交到 deepseek-harness。 跟随它的发布是全自动的:pnpm run sync:dsh 把所有范围改写到 最新已发布版本,重新核对插件组合,再证明这棵树仍然能构建、能通过测试。