dsh-agent-shell
Đã xác minhdsh-agent-shell · v0.4.0 · MIT · Giao diện web
持久化 tmux 终端面板(DSH Web):多会话管理、复用同一 shell、锁与归属、提示信息与审计复盘。
Cài đặt
dsh plugin add dsh-agent-shell Xác nhận layer đã áp bằng dsh --profile default --dump-config — xem hướng dẫn cài plugin.
Mã nguồn
Thẻ
Tác giả
Readme
dsh-agent-shell
🙋 作者的话
一个人的业余项目,与任何官方无关。 节奏受现实约束(主业/健康/费用),没有 SLA、没有付费支持。所以:① 关键场景自备回退;② 升版前扫一眼 CHANGELOG;③ MIT,风险自负(下面风险清单务必读完)。帮到你了的话,一个 star 就是最实在的支持。
⚠️ 风险,先读清楚再决定装不装
这工具能把你的机器交给 AI。 它不是玩具,也不是"受限执行环境"。
- 由 AI 开发,无人审计——自动化测试 + 真机验证有,人工安全审计没有。
- 授权 = 任意命令——一个对话被授权后,它的 AI 以你自己的用户权限读写一切;本插件没有任何审批防护,不会逐条问你。彻底关审批需显式
requireConsent:false(等于放弃防线)。 - 不负责后果——误删、提示词注入带偏、凭据被读到终端里,后果自负。
- 唯一防线只是启发式护栏——
guardDangerousCommands关键词匹配(rm -rf /、mkfs、dd of=/dev/*等);可被变量/脚本/拼接轻易绕过,也会误报。它是减速带,不是防护。 - 审计 =「可检测篡改」不是「不可篡改」(默认)——哈希链能发现删/改/调序,但同权限的 AI 本就能改审计文件;要内核级防删改跑
./install-deps.sh --audit-lock(chattr +a)。 - ssh/远程只有「录像级」审计——记的是进出隧道的键与屏,不是远端实际执行了什么。
- 闲置回收默认关(0.3.0 起 = 会话永久保留)——只在显式启用
idleClose或单会话idleMinutes后才到点关闭并记审计;只读屏/查询不算活动。 - 整机重启会丢会话——
dsh自身重启存活(systemd scope),但整机/WSL2 虚机关机连 tmux 一起带走。重要工作先落盘。 - 不要放进生产/多用户/有不可替代数据的机器;平台仅 Linux(Windows 用 WSL2,macOS 不支持)。
别在终端里长期输入真凭据——留痕是如实记录的(密码提示会自动脱敏,但其它明文输出不保证)。
一条命令安装
先决条件:Linux(含 WSL2/容器)、Node ≥ 20、运行的 DSH(0.1.5+)。
npx -y dsh-agent-shell install [--profile web] # 当前 0.3.4
依次:登记进 profile → 装依赖 → 检查 tmux → 提示重启 dsh web。配套:--dry-run 预览;doctor 体检;uninstall 反向移除。
它是什么
- 私有 tmux 服务端持有多个持久 shell:关页面、换对话、热重载、重启 DSH 都不丢。
- 7 个模型工具:
shell_open / shell_run / shell_send / shell_read / shell_manage / shell_state / shell_audit;等待并入shell_read(until),护栏预演并入dryrun,寻址用稳定 id(名字只是可改的 label)。 - 面板(右下角胶囊)= 真终端:
sudo提示、vim全屏、REPL、补全、历史全都通。0.3.4 起显示完全复刻真实终端——颜色/背景/加粗/反显/真彩(SGR 渲染)逐段呈现、光标常显(坐标来自 tmux 实测,中文/emoji 单元格换算正确);0.3.3 起的抓屏 SSE 推送(输入当刻回显,断线退回轮询)、🎬 帧回放(replayCapture默认关,逐帧回看"刚才实际发生了什么")。0.3.4 面板内搜索(Ctrl+F 高亮跳转)+ 批量操作(勾选多壳重开/统一尺寸/锁定/关闭)。 - 审计一条链管全部:工具调用/输入键/开关改名/授权/锁定/接管/宏与秘密操作/闲置/设置变更/手动删除(purge)……全部事件在
audit-YYYY-MM-DD.jsonl逐条封链(SHA-256 串接),删一条/改一字节/调顺序 → 断链即报警(事件全表见 SECURITY)。0.3.4 起用户可手动管理日志与审计文件(面板 🪵 日志管理浮层 / CLIpurge-audit/POST /audit-files)——删除动作本身先入链见证(event:purge+ 文件名 + sha256),"销毁过什么"永远可证。
什么时候值得用它
交互式程序(sudo/ssh/vim/gdb/REPL——真 TTY 全通)· 长任务(shell 常驻,路径/历史/环境一直在,不用反复起进程)· 要查账(谁在什么时候让 shell 干了什么:审计链封链 + 🎬 帧回放,断链即报警)。
快速上手
装好重启 → 右下角出现胶囊 >_ N 🔒;点 + 新建 shell(或让 AI shell_open)。面板点锁即直接打字;AI 用 shell_run 发命令、shell_state 看会话。每个对话首次用工具会请你授权一次,之后正常用。
人机双接管(一句话版)
AI 的终端就是普通 tmux 会话(私有 socket -L dsh-agent):你 tmux -L dsh-agent attach -t dsh-xxxx 随时进去接手,想让 AI 彻底放手就说「release」;你在同一 socket 建的壳(务必 -s 带名字),AI shell_manage action=claim 就能接手。秘密(vault)值不过 AI 之手——AI 只能写 {{v:键}} 裸引用喂 stdin 提示;宏({{m:名}})沉淀重复命令、写入全量入链。完整操作与规则见 docs/使用细节.md「人机双接管完全指南」。
安全边界(能挡什么、挡不住什么)
- 确认门一次过后不再问:防手滑与静默启动,不防蓄意 agent——原生 bash 能绕过本插件做它想做的一切,任何"只在插件通道内生效"的防护都只是对这条通道的礼貌。
- 人机互斥:面板解锁 = 人在操作,AI 对该 shell 的修改一律让路(只读不受影响);解锁/上锁记审计。
- 能力降级如实说:无 systemd → 会话不随
dsh重启存活;无/proc→ 嵌套 tmux 忙闲判定退化——每句人话,shell_state/面板 ⓘ//diagnose可查。 - 完整安全模型以 docs/SECURITY.md 为准(随包发布)。
宿主版本现状(dsh,明确说明)
本插件的宿主是 DeepSeek Harness(dsh),两者版本需放在一起看:
- 当前兼容范围:dsh
0.1.5-rc.1至0.2.0-rc.2。本插件 0.3.4 在这两档上均完成全套回归(pure 267 / client 479 / edge / smoke / longrun 全绿)。 - 0.2.0 适配结论(2026-10-02 实测,10-04 复检):宿主升级到 0.2.x 无需重新安装插件——peer(
dsh-tools/cordis/schemastery)由宿主进程注入、不走 npm 安装校验;运行时实测defineTool导出与契约不变、Cordisctx.get/inject/slots注入面未变、schemastery settings 注册兼容。实机 dsh web 日志确认插件startup ready+ 看门狗接管,无加载错误。 - 0.2.0 曾踩的坑(已修):10-04 宿主升 0.2.0 后插件一度不加载(面板胶囊消失、shell_* 工具全无)——根因是 0.2.0 新增的兼容闸(
dsh-app-boot#evaluatePluginCompatibility)装配时检查 peerDependencies 里的@deepseek-ai/dsh-*是否semver.satisfies(运行时),旧声明dsh-tools ^0.1.2-rc.1✗ 不含0.2.0-rc.2→ 静默跳过插件。修法:plugin peer 放宽为^0.1.2-rc.1 || ^0.2.0-rc.2(同时满足 0.1.2/0.1.5/0.2.0)+ profilecompatibility.json补[email protected] → [0.2.0-rc.2]豁免。升级 dsh 后插件消失时先查这个。 - 升级核对动作(任何时候升 dsh 都该做):重跑
scripts/test-edge.mjs+scripts/smoke.mjs(加载+注册+真实 tmux 全链路)+ 面板实机回归(挂载/参数设置/授权浮层/日志管理),以套件绿灯为准。
最近更新
0.4.0(2026-10-07)— 锁模型重构 + 提示信息系统 + 多选功能区 + 详情页重构
① 锁模型(核心重写)
- 摒弃旧的
released单一布尔。锁只有两个来源:输入时自动上锁、用户在面板手动上锁(持久化在 owner 记录里,含原因,只能手动解除、不会因空闲或超时自动失效)。 - AI 侧删除全部锁动词:
shell_manage action=claim/action=release已移除;AI 唯一会遇到的是“被拒绝”,且拒写文案包含锁定时间、你的备注、以及“不要重试 / 不要绕过”的指示。 - 手动锁的覆盖面扩展到改动类动作(
close/resize/rename/respawn)——此前只拦写入,改动类动作能绕过。 - 归属(owner)改为软约定:不可变、无强制力,只提示“谁创建的”;默认为“不主动碰别人的壳”,用户明确要求即可操作。
- 面板侧:手动锁入口、行内 🔒 标记(第二行行首)、上锁/解锁先判断现状(已锁定再上锁、对无锁者解锁 → 拒绝并说明原因)。
② 提示信息系统(新增子系统)
- 浮层:默认右上角,右侧任一菜单打开时自动移到左上角(不被遮挡);最多同屏 6 条、按时间排列;底部倒计时横条;消失时 1 秒渐隐;鼠标悬停暂停(暂停期间也不会被移除);三级配色 提示(灰) / 警告(黄) / 错误(红)。
- 每条含四项:发生时间、等级、简述、详细(详细不论多长只占一行,悬停看全文)。
- 全部调用点重写为
notify(等级, 简述, 详细),填入真实参数(会话清单、cols/rows、锁定原因、服务端错误原文)——不再有靠关键词猜等级的旧通道。 - 落盘复盘:
POST /notice→notices.json(上限 500 条);详情 → 提示信息页签回看历史。
③ 会话选择页与多选功能区
- 取消行内「⋮」菜单与行内重命名编辑;所有操作统一走多选功能区(固定两行):第一行
全选 / 反选 / ✕(✕ = 清空勾选并收起功能区,此时隐藏「新建 shell」);第二行重命名 / 修改尺寸 / 上锁 / 解锁 / 自检 / 关闭 shell。 - 尺寸、上锁、重命名的小表单就地替换第二行(功能区始终两行);已勾选的行有底色 + 左侧强调条;关闭菜单自动清空勾选。
- 操作后就地更新界面(不再等 2.5 秒轮询);重命名不再有“失焦提交”语义(只有 应用 / Enter / Esc)。
④ 详情页重构
- 页签 6 → 5:会话 / 服务端 / 运行状态 / 安全与审批 / 提示信息。删掉「界面与能力」:版本与构建并入服务端,面板自己的 4 条快捷键并入会话;tmux 原生键与 DSH 宿主机键移出界面(属 tmux / DSH 文档)。
- 新增提示信息历史页签;分组小标题加重(字重 + 主题色 + 分隔线)以提升区分度;详情浮层加宽(406 → 470px)。
⑤ 授权与性能
- 授权浮层瘦身:沙箱模式行压成一行;只列真实、非子代理的活跃会话(优先“已授权 / 近期出现”,其余折叠)——不再铺出大量已归档会话。
- 按钮状态模型与其他菜单统一(此前授权自有一套,造成“改完授权后按钮点不动”的观感)。
/actors改 SWR 缓存(TTL 5 分钟)+ 快照窗口 120 + 客户端空闲预取:冷启动 40–50s → 命中约 8ms(即“改完授权要等一会儿才生效”的根因)。- 谱系树层级修正、日志页总体统计(当前日志与留痕的总体信息)。
⑥ 其他修复
- 宏展开后
{{v:}}的漏遮蔽;/actors冷算移出用户交互路径;引用库 / 授权 / 日志的搜索与筛选(含创建者筛选);行菜单跟随鼠标;浮层 80% 不透明度 + 高斯模糊;树的父子层级显示修正。 ⑦ 工具参数体系重构(五块模型 + 任务并行)
参数模型(破坏性变更,不做兼容层)
- 所有有参数的工具统一为五块:
target/action/wait/output/safety;块内字段含义跨工具一致 - 一次调用可含多个
tasks:任务之间并行、任务内多个 shell 并行;同一个 shell 在一次调用里只能被操作一次(重复直接拒绝 —— 取代旧的「同壳跨任务串行」表述) - 新增解析层
lib/args.js(纯函数parseArgs(raw) → IR,27 项离线断言):形状校验、 未知字段一律拒绝、旧扁平参数一律拒绝并给出新写法 - 扩展规则冻结:新能力先加已有块的字段;新维度才新增块且必须所有工具同时支持;参数只增不改不删;
无参数工具(
shell_state)不套五块
并行语义
shell_run/shell_send/shell_manage/shell_audit:任务间并行 + 任务内会话并行 + 会话锁shell_open:任务串行(有意为之) —— 保「现有 + count 超上限时整批拒绝」的预检不被并发绕过; 任务内部并发创建(实测并发 4 优于 8)- 唯一硬约束:同一个 shell 在一次调用里只能出现在一个任务中(重复即拒,在执行任何操作之前失败);跨调用仍由会话锁互斥。审批(规则查表、中央接缝判定一次)与审计
(
appendAudit是同步函数,单线程原子)都不构成并行约束
其它
shell_manage:kind即动作名(不再有单独的 action/op 字段);AI 仍无claim/release- 引用库:
{{v:键}}注入秘密域、{{m:名}}展开宏;shell_manage的vault-list/macro-list可查键与宏;reap只回收闲置 > 10 分钟的壳 shell_open恢复from(从快照复活)—— 它必须出现在 action 载荷里- 五个工具的 AI 面向说明按新模型重写
- 文档:
docs/工具参数手册.md全文重写
研发过程(如实记录):接线过程由三次实机实测暴露并修掉三个运行时 bug ——
执行体留在对象字面量里(属性不是作用域变量)、改名漏掉裸 args、检测正则把 ...args 一起排除。
三条教训已固化为强制检查步骤(改名后正则复核残留、包装字段对照、离线解析预检)。
本次改动量大且触及核心逻辑(锁语义、工具动作、归属模型),以下为自 0.3.4 以来的完整变更清单。
shell_state成为可过滤的总管:无参默认只看本对话创建的 shell,想看全部必须显式传scope:"*";多参数(sessions/label/fg/cwd/state/owner)之间是 AND、同参数内逗号分隔是 OR; 不设显示上限(要少看就自己过滤),总览状态行与引用库摘要行始终显示。发版门禁(长任务测试):每发版前必须跑
docs/长任务测试.md(10 壳并发、任务并行/同壳串行、六种 wait、 vim/top/python 交互、死循环中断、sudo/ssh 密码链路、ssh→wsl单层与五层嵌套、shell_state过滤矩阵、shell_manage全 kind、负向参数规则、取证与收尾)。未跑或未通过不得发布。
⑧ 权限模型:审批 → 模式闸门(语义变更)
- 不再有全局审批:授权默认档直接跟随官方权限模式 —— 完全控制下直接放行、不弹审批; 受限模式按模式推导默认规则,且模式读不到时 fail-open 按完全控制处理。
- 审批判定是规则查表、不是弹窗:
ensureConsent按 actor 查会话规则;无条目则按会话真实沙箱 模式推导;规则 deny 时调用方抛一条可转述的错误,由用户在面板/consent调整。判定发生在 工具调用的中央接缝,与任务数、会话数无关。 - 模式闸门:改动类工具(
shell_open/shell_run/shell_send/shell_manage)只在完全控制 下可用;只查类(shell_state/shell_read/shell_audit)恒可用。 - 修掉模式闸门 6 个实测问题:判错模式(原先读进程环境变量而非会话真实模式,导致完全控制的 会话被误判成受限、连只读工具都被拦)、只读工具豁免写反、错误文案本体损坏等。
- 审批重构(用户拍板):别人的 shell 明细照常可见、删除全局兼容档、恢复"首次使用询问"并接入面板; 安全审计报告 5 项问题的修复与验证。
- 面板侧:授权浮层瘦身(模式压成一行、只列真实非子代理的活跃会话)、按钮状态模型与其它菜单统一、
/actors改 SWR 缓存(TTL 5 分钟)+ 空闲预取(冷启 40–50s → 命中约 8ms)。
界面设计(0.4.0)
面板这一轮的界面约定,都写在下面——想改哪一处,先看这里的规则。
菜单(下拉浮层)
- 统一壳:所有菜单共用同一只壳(标题 / 徽标 / 页签 / 操作按钮),观感一致。
- 宽度:详情 406px · 会话选择 442px · 授权管理 / 引用库 / 日志 541px;都按视口约束,允许比面板宽。
- 上下边界实测对齐:上边界 = 面板内容上边界(实测头部高度),下边界 = 状态栏上方(实测状态栏 + 输入行高度);内容不足按实际高度显示,超出则内部滚动(滚动条可见)。
- 子页签:授权管理(会话授权 / 默认授权)、引用库(秘密域 / 宏命令)、日志(审计文件 / 输出留痕)、详情(会话 / 服务端 / 运行状态 / 安全与审批 / 提示信息)。
列表(所有需要排序/筛选的地方)
固定三部分,自上而下:
- 筛选行:一行平铺不换行——左侧是所有可筛选的键(每个键一个下拉,选中即过滤),右侧是搜索框;筛选键由列定义自动生成。
- 表头:列出全部相关列(键名 / 类型 / 备注 / 时间 / 归属…),末尾是操作列(删除等);点表头切换升 / 降序。
- 显示区:一行一条数据,不换行、不简写,放不下用省略号标记(悬停看完整值);行高固定 30px 且与表头严格一致。
列宽:自适应分配,并可拖动表头右缘手动调整;按表记住(刷新仍在)。筛选值同样持久化。
分区与显示策略
- 默认整块高度给表格;点选一项后,下方才弹出详情 / 配置(授权管理、日志)。
- 引用库:上方是新增 / 更新表单(常驻平铺的卡片,自适应网格),下方是已有键值表格。
- 详情:页签式(会话 / 服务端 / 运行状态 / 安全与审批 / 提示信息)。版本与构建信息在「服务端」,面板自己的快捷键在「会话」——0.4.0 起不再单独设「界面与能力」页(tmux 原生键与宿主机键属 tmux/DSH 文档,不占面板)
视觉层级与窗口对齐
- 页签:未选中也有可见的底与边框(弱),选中是绿色描边 + 实底 + 加粗 —— 一眼看出"我在哪一页"。
- 头部按钮:浮层打开时按钮带绿色包裹(详情 / 日志 / 引用库 / 授权管理都一样;授权管理此前漏了这个标记)。
- 双击右下角的拖拽标记:把面板尺寸对齐到当前 shell 的真实
cols × rows(来自/screen的meta), 目的是不再出现横向滚动条、周围按钮跟着排好;尺寸只增不减,绝不会把已经够用的显示区缩小。
视觉层级与窗口对齐(续)
- 页签:未选中也有可见的底与边框(弱),选中是绿色描边 + 实底 + 加粗。
- 表头吸顶:列表滚动时表头固定在顶部(
position: sticky),不会跟着内容滚走。 - 表格列宽永不溢出:拖动列宽存的是表宽百分比并归一化到 100%(拖宽一列,其余列按比例让位), 旧版存的像素值直接忽略 —— 面板变窄也不会冒出横向滚动条。
- 双击右下角的拖拽标记:把面板对齐到当前 shell 的真实
cols × rows(不再弹提示)。 对齐是幂等的:chrome 差量只测一次并固化,连点多次尺寸不变;宽度再按真实溢出迭代补偿一次, 确保显示区下方不再挂横向滚动条。
日志审计
- 两个子页面(审计文件 / 输出留痕) 都是「上列表、下详情」:默认整块高度给列表,点选一项后下方弹出详情;
详情用
rightFit按内容全量显示(不压缩、不出自己的滚动条),列表吃剩余空间。 - 详情加载分两段:先取"快的那一半"(服务端只读文件头尾各 8KB → 开头 / 结尾 / 字节数立刻可见),
行数与事件统计随后用
?stats=1在后台补齐(结果按size+mtime缓存,同一文件再看秒回; 客户端也缓存,来回点列表不再往返)。不再出现十几秒的「读取详情…」。
快捷键
- 面板内(焦点在面板里才生效,不抢 DSH 与终端的键):
Ctrl+F面板内搜索 ·F2重命名当前 shell ·Esc关浮层(无浮层时照旧送终端)·Ctrl+Shift+↑/↓上一个 / 下一个 shell ·Ctrl+Alt+/开合面板(已注册进官方快捷键系统,可在「设置 → 通用 → 快捷键」里改)。 - 开合面板没有内置降级键:它只走官方系统;官方那条若不生效(被占用 / 偏好未就绪), 详情页会如实说明并给出改键位置,不会再塞一套"第二键位"。
- 详情页只记录面板自己的快捷键(详情 → 会话):切换 shell / 重命名 / 面板内搜索 / 关浮层 共 4 条。终端键位、tmux 原生键、DSH 宿主机键不再列在面板里(属 tmux 与 DSH 文档,0.4.0 移出界面)。 tmux 直通 · DSH 宿主键位(我们避让的) 四组,共 60+ 条。
- 终端键一律不抢:bash / PowerShell(PSReadLine) 的 Ctrl 组合、Alt 组合、
F7,以及 tmux 的Ctrl+B前缀 都原样送进终端;其中Ctrl+W/T/N做了面板级兜底(否则会被浏览器当成关标签页 / 新标签页 / 新窗口)。 - tmux 原生能力直接可用:
Ctrl+B后接"%cz[?等(属 tmux 自身文档;面板 0.4.0 起不再重复列出)。
性能约定
- 打开菜单:空闲预热列表数据 + 缓存优先(有缓存就立即渲染,后台静默刷新)→ 首次打开从秒级降到 ~30ms。
- 面板尺寸测量走 ResizeObserver(不再每秒轮询),只在展开 / 开浮层等时机强制测一次。
主题
全部颜色走 DSH 主题令牌(--dsw-alias-* / --dsw-specific-menu / --dsw-elevation-*),跟随宿主明暗主题,无硬编码 UI 色。
详细文档
| 文档 | 内容 |
|---|---|
| docs/使用细节.md | 人机双接管完全指南、面板/工具用法、配置项、HTTP API、工作原理 |
| docs/工具参数手册.md | 每个工具的每个参数:承诺语义、坑、实测核验结论(56 参数全典) |
| docs/SECURITY.md | 安全模型、审计边界、已知限制(随包发布) |
| CHANGELOG / 更新记录 / 升级注意-0.2到0.3 | 版本变化 / 完整改动根因 / 跨大版本迁移 |
| 设计与实现 / CONTRIBUTING / PUBLISHING / archive/ | 内部结构 / 贡献 / 发布 / 已兑现设计稿归档 |
给 AI 助手的操作卡
写给正在读这份 README 的 AI:用户让你装/验收本插件,或问"这是干什么的",照下面执行。
A. 安装(装前把上方风险清单要点给用户看一眼):npx -y dsh-agent-shell install → npx -y dsh-agent-shell doctor(三行都 ✓)→ 提醒用户重启 dsh web(不是刷新页面)。
B. 验收(按序,全过才算装好):① shell_state 返回 server: running (socket -L …);找不到工具 = 没挂载;② shell_open {name:"verify"} → 对返回 id shell_run {command:"echo ok-$((6*7))"} → 屏上必须出现 ok-42 → shell_manage action=close 收尾;③ shell_audit {days:1,lines:5} 头部 chain: ✓;④ 让用户看右下角悬浮胶囊,没有就刷新页面;⑤ 无 systemd 环境(如 WSL2 旧版)capability 行显示降级属正常。
C. 答疑口径:它给 DSH 加装真实、持久、可审计的终端——AI 用 7 个 shell_* 工具驱动多个后台 tmux 会话(长任务、vim/ssh、跨对话接管),人用右下角面板随时旁观或上手打字,可互相接管/交还;每次输入进哈希链审计,vault 让密码值不过 AI 之手。必须同时讲清:① 这是把真 shell 交给 AI,护栏是减速带不是沙箱;② 不是受限执行环境、不弹审批;③ 默认"可检测篡改",内核级防删改需 --audit-lock。排障细节见 docs/使用细节.md;安全边界以 docs/SECURITY.md 为准。
许可证
MIT(见 LICENSE)。