{"_id":"@aruvelut_6/dsh-cli","_rev":"2-8487bc59b9890d76029e708fcacc0cd1","name":"@aruvelut_6/dsh-cli","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@aruvelut_6/dsh-cli","version":"0.1.0","license":"MIT","_id":"@aruvelut_6/dsh-cli@0.1.0","maintainers":[{"name":"aruvelut_6","email":"2562160171@qq.com"}],"bin":{"dshcli":"bin/dshcli.js"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"90e27d9e645dbdcc79dee849911148e1a43b1262","tarball":"https://registry.npmjs.org/@aruvelut_6/dsh-cli/-/dsh-cli-0.1.0.tgz","fileCount":9,"integrity":"sha512-X2mODeZgDvgQbJ5fDJf4ZcppqYO7AHKSB4BsfewcveEbv6EHDxg/NFDQMP8cAUCuqCfWbDgmNw16EFlH/FjPWw==","signatures":[{"sig":"MEYCIQCcwqx9+6Mumlxt6FIXNhRqdAOdLdqxTgM5ad+n4qYw7wIhAKPK0ucLy9NIdSsWv012wPYbnzP8JHUWmrWZslhAQzoG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":88275},"main":"index.js","type":"module","engines":{"node":">=20.12"},"exports":{".":"./index.js","./startup":"./startup.js","./package.json":"./package.json","./cordis.patch.yml":"./cordis.patch.yml"},"gitHead":"6369a9a0bb5148846c94d1b3f5b140a3848ccb53","_npmUser":{"name":"aruvelut_6","email":"2562160171@qq.com"},"_npmVersion":"10.9.8","description":"Interactive terminal CLI for DeepSeek Harness — a Claude Code-like REPL","directories":{},"_nodeVersion":"22.23.2","dependencies":{"ink":"^5.2.1","react":"^18.3.1","commander":"^15.0.0","@deepseek-ai/dsh":"^0.1.0-rc.7","@deepseek-ai/dsh-llm":"^0.1.0-rc.7","@deepseek-ai/dsh-agent":"^0.1.0-rc.7","@deepseek-ai/dsh-cmdline":"^0.1.0-rc.7","@deepseek-ai/dsh-session":"^0.1.0-rc.7","@deepseek-ai/schemastery":"^3.18.1","@deepseek-ai/dsh-app-boot":"^0.1.0-rc.7","@deepseek-ai/dsh-home-paths":"^0.1.0-rc.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/dsh-cli_0.1.0_1787123018280_0.2849296250400548","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@aruvelut_6/dsh-cli","publishConfig":{"access":"public"},"version":"0.1.1","description":"Interactive terminal CLI for DeepSeek Harness — a Claude Code-like REPL","type":"module","engines":{"node":">=20.12"},"bin":{"dshcli":"bin/dshcli.js"},"main":"index.js","exports":{".":"./index.js","./startup":"./startup.js","./cordis.patch.yml":"./cordis.patch.yml","./package.json":"./package.json"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"license":"MIT","dependencies":{"@deepseek-ai/dsh":"^0.1.0-rc.7","@deepseek-ai/dsh-agent":"^0.1.0-rc.7","@deepseek-ai/dsh-app-boot":"^0.1.0-rc.7","@deepseek-ai/dsh-cmdline":"^0.1.0-rc.7","@deepseek-ai/dsh-home-paths":"^0.1.0-rc.7","@deepseek-ai/dsh-llm":"^0.1.0-rc.7","@deepseek-ai/dsh-session":"^0.1.0-rc.7","@deepseek-ai/schemastery":"^3.18.1","commander":"^15.0.0","ink":"^5.2.1","react":"^18.3.1"},"_id":"@aruvelut_6/dsh-cli@0.1.1","gitHead":"f62af4f031b96be9cbf836cd89fe72f389fa63df","_nodeVersion":"22.23.2","_npmVersion":"10.9.8","dist":{"integrity":"sha512-wNziRbLytl31ZO56AWQ+4I3K4yMVqWqiuPp8g8VbInAHElJcReWeDYRz4ZlkScvFcLgF4UWHpFoD9qPBxXWn7Q==","shasum":"38b72caf66ed6c08c8108db666203134034c09c5","tarball":"https://registry.npmjs.org/@aruvelut_6/dsh-cli/-/dsh-cli-0.1.1.tgz","fileCount":9,"unpackedSize":93525,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDhNfAD5RA61fviVwMeiORiozVWphsu0dXDxNHW8mIwxAiEA+Jkafk6Uq6rN4fH1fKM/qmP5AqgcC31zQMB2Uj4bKBs="}]},"_npmUser":{"name":"aruvelut_6","email":"2562160171@qq.com"},"directories":{},"maintainers":[{"name":"aruvelut_6","email":"2562160171@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dsh-cli_0.1.1_1787127324820_0.16991976342480686"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-19T07:03:37.848Z","modified":"2026-08-19T08:15:25.133Z","0.1.0":"2026-08-19T07:03:38.433Z","0.1.1":"2026-08-19T08:15:24.968Z"},"license":"MIT","description":"Interactive terminal CLI for DeepSeek Harness — a Claude Code-like REPL","maintainers":[{"name":"aruvelut_6","email":"2562160171@qq.com"}],"readme":"# dshcli\n\n[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 的交互式终端 CLI —— 一个 Claude Code 风格的 REPL。\n\n它启动 Harness 自带的 agent/session/tools 核心（与 `dsh web` / `dsh --profile headless` 同一套机制），但用全屏 Ink（React）TUI 驱动，支持流式输出、多轮上下文和会话续接。\n\n## 安装\n\n从 npm 全局安装（推荐）：\n\n```sh\nnpm install -g @aruvelut_6/dsh-cli    # 需要 Node ≥ 20.12\n```\n\n装完直接敲 `dshcli` 进入交互界面（命令名保持 `dshcli`，npm 包名是\n`@aruvelut_6/dsh-cli`——`dshcli`、`dsh-cli` 这两个非作用域名分别被占用和\n被 npm 的反抢注策略拦截）。\n\n开发者本地构建：\n\n```sh\ncd dshcli\nnpm install --registry https://registry.npmjs.org/   # 如果 node_modules 尚未安装\nnpm link                                              # 把 dshcli 放到 PATH 上\n```\n\n> 本项目自带 `.npmrc`，把源固定为公共 npm（`https://registry.npmjs.org/`），\n> 保证 `@deepseek-ai/*` 依赖取到最新版本。如果你的全局 npm 配置指向了其他镜像，\n> 请保留该文件（项目级 `.npmrc` 优先于全局配置）。\n\n`dshcli` 复用 `$DSH_HOME`（默认 `~/.dsh`）存放凭据、设置和会话——已装过\nDeepSeek Harness 的用户直接共享现有的 API key 和模型配置。\n\n### 首次运行：API Key 引导\n\n不需要预先安装 DeepSeek Harness：harness 全套是 npm 依赖，`npm install -g`\n自动装齐。首次运行如果检测不到 DeepSeek API Key（来源顺序：环境变量\n`DEEPSEEK_API_KEY` > `$DSH_HOME/.credentials.yaml` > 项目 `.env` > 用户\n`.env`），终端里会交互式引导输入（Enter 跳过，跳过则打印手动配置方法）：\n\n- key 通过 harness 凭据通道写入 `~/.dsh/.credentials.yaml`（原子写入、权限\n  600、保留文件里其他条目，写入后当前进程立即生效）\n- 申请地址：https://platform.deepseek.com/api_keys\n- 也可以绕过引导：`DEEPSEEK_API_KEY=sk-... dshcli` 只对本次运行生效，或手动\n  创建 `~/.dsh/.credentials.yaml` 写入 `DEEPSEEK_API_KEY: sk-...` 再\n  `chmod 600`\n\n非 TTY（管道）场景不打断流程，只在 stderr 打印配置提示。\n\n## 用法\n\n```sh\ndshcli                          # 新建交互会话\ndshcli \"run the tests\"          # 先执行一个初始任务，然后保持交互\ndshcli --resume <session-id>    # 按 id 续接已持久化的会话\ndshcli --continue               # 续接最近一次会话\ndshcli -m deepseek-chat         # 指定模型\ndshcli --help                   # 查看本应用的命令行参数\n```\n\n### 会话内命令\n\n| 命令 | 作用 |\n|---|---|\n| `/help` | 显示命令列表 |\n| `/sessions` | 列出已持久化的会话（id · 时间） |\n| `/model [name]` | 切换模型（真正的热切换，下一条消息立即生效） |\n| `/model`（裸命令） | 打开交互式模型选择器（读取 harness 的 llm 目录，↑↓ 选择） |\n| `/compact` | 压缩上下文（走 harness 的 compaction seam，超出阈值时生成摘要） |\n| `/clear` | 物理清屏，开始全新对话记录 |\n| `/exit`、`/quit` | 保存并退出 |\n| `Tab` | 斜杠命令补全：`/` 开头时循环补全，否则弹出命令调色板 |\n| `Esc` | 中断当前回合 / 关闭对话框（Claude Code 同款） |\n| Ctrl-C | 中断当前回合（空闲时则退出） |\n| Ctrl-D | 输入为空时退出 |\n| ↑/↓ | 输入历史（调色板/选择器中为移动选择） |\n| 其他内容 | 作为消息发给 agent |\n\n## 界面布局\n\n```\n╭──────────────────────────────────────╮\n│ 🐋 Welcome to dshcli!                │  ← 圆角蓝色边框欢迎横幅（Claude Code 同款）\n│   /help for help                     │\n│   cwd: /path/to/dshcli               │\n│   model: deepseek-v4-pro             │\n╰──────────────────────────────────────╯\n\n> Reply with exactly one word: OK        ← 对话滚动区（<Static>），用户行蓝色\nOK\n  ⚙ bash ls                              ← 工具调用一行摘要\n  ✓\n  🐋 Thinking… (3s · esc to interrupt)   ← 流式期间：动词循环思考指示器\n╭──────────────────────────────╮\n│> /model  show or switch the model│     ← Tab 调色板 / /model 选择器（圆角边框浮层）\n│  ↑↓ select · esc cancel          │\n╰──────────────────────────────╯\n>                                         ← 输入行（自研单行编辑器，CJK 感知）\n 🐋 dshcli · deepseek-v4-pro · ↑73 ↓2 …  ← 反白状态栏\n```\n\n整体视觉以 DeepSeek 蓝（`#4D6BFE`）+ 🐋 鲸鱼品牌标识重设计，参考 Claude Code 的\nUI 规范：圆角欢迎横幅、动词循环思考指示器（`esc to interrupt`）、`Tab` 命令调色板、\n低上下文警告（`Context low (…) · Run /compact to compact & continue`）。\n\n每一条完成的输出行都会先用 `string-width` 按终端宽度预换行（CJK 安全），再立即\n锁定进 `<Static>`，和 Claude Code 把完成行锁进滚动区的方式一致。动态区保持很小\n（流式行 + 思考指示器 + 待回答问题 + 浮层），光标移动全部交给 Ink，退出时终端状态\n必然恢复。当 stdin/stdout 不是 TTY 时（管道用法），同一套 runner 回退到普通的\nreadline REPL。\n\n## 工作原理\n\n`dshcli` 既是一个 npm 包，也是一个 Harness **bundle**（类似 `dsh-headless`）。\n首次运行会在 `$DSH_HOME/profiles/dshcli` 初始化 profile，并通过\n`@deepseek-ai/dsh-app-boot` 在进程内启动它，在 `dsh-base` 之上挂载两个插件：\n\n- `dshcli/startup` — 解析命令行参数并发布 flags。\n- `dshcli`（runner，`index.js`）— 创建或续接 agent，然后交给 `tui.js`（TTY 上的\n  Ink UI）或行内 REPL（管道场景）。\n\n事件泵消费 `assistant/chunk` 事件做流式输出，工具调用渲染成一行摘要\n（`⚙ bash echo hi`），`str_replace_editor` 的编辑以红/绿 diff 高亮，应答 agent 的\n`ask_user_question` 提问，应答 tools 流水线的 `approval/request` 审批瀑布流。\n`/model` 直接改 harness 的每步模型选择（`installModelSelection`），无需重建 agent，\n下一条消息立即生效；裸 `/model` 的选择器读取 `ctx.llm.listProviders()` /\n`listModels()` 的模型目录。`/compact` 走 `ctx.compaction.compactNow()`（由\n`dsh-compaction-basic` 引擎实现），成功后重同步事件泵。\n\nTUI 的几个\"踩坑\"细节（下面的测试套件都会覆盖）：\n\n- Ink 只会把**单独**的 `\\r` 识别为 `key.return`；连发按键或粘贴会以单个多字符\n  chunk 到达，其中的 `\\r` 会被当成字面字符插入导致画面乱码。输入分发器按\n  readline 语义拆分 chunk、逐行提交。\n- Ink 的 `<Static>` 按 `items` 引用做 diff（`useMemo`），历史数组必须每次渲染传\n  一份新拷贝，否则追加的行永远画不出来。\n- `/clear` 必须自己物理清屏并重置 Ink 累积的静态输出——Ink 只会擦除最后一帧。\n\n## 测试 —— PTY 闭环\n\n`scripts/pty-driver.py` 在真实伪终端里启动这个二进制，喂入脚本化输入，再用迷你\nVT100 解释器渲染屏幕——每个布局断言都对照真实渲染画面验证，无需人工介入。截图\n输出在 `scripts/out/`。\n\n```sh\npython3 scripts/pty-driver.py <case> [rows cols]   # 例如 all、basic、cjk\n```\n\n| 用例 | 验证内容 | API 调用次数 |\n|---|---|---|\n| `basic` | 启动横幅、`/help`、`/sessions`、`/model` 热切换、`/clear` 物理清屏、`/exit` → 0 | 0 |\n| `turn` | 完整模型回合、状态栏 token 统计 | 1 |\n| `tool` | bash 工具调用渲染（`⚙` → `✓`） | 1 |\n| `interrupt` | 流式中 Esc 与 Ctrl-C 各中断一次、输入恢复 | 2 |\n| `cjk` | 中文提问/回复、所有可见行不超终端宽度（含双宽字符） | 1 |\n| `palette` | Tab 调色板、输入过滤、Enter 把命令插回输入行 | 0 |\n| `picker` | 裸 `/model` 选择器浮层、Esc 关闭 | 0 |\n| `compact` | 一轮对话后 `/compact` 走 harness compaction seam 出结果 | 1 |\n| `firstrun` | 空 DSH_HOME 首启：key 引导出现、0600 落盘、进入 TUI 退出 | 0 |\n\n## 功能状态\n\n已完成：流式多轮 REPL、全屏 Ink TUI（滚动区 + 状态栏）、会话续接\n（`--resume` / `--continue`）、动词循环思考指示器、工具调用摘要、红/绿 diff 高亮、\n斜杠命令、用户提问应答、审批应答、CJK 安全换行、蓝色系 + 鲸鱼品牌 UI、\n`Tab` 命令调色板、`Esc` 中断、交互式 `/model` 选择器、`/compact` 上下文压缩、\nPTY 测试闭环（9 个用例，含 4 个零 API 调用用例）。\n\n尚未完成：独立的 subagent 面板。Harness 底层能力已具备，剩余的是终端渲染工作。\n","readmeFilename":"README.md"}