用户纠正:editor/git/subagent/sidechat/terminal/browser 也是 apes-sidebar 打包进来的,对外是一个完整需求整体,对比的另一端只能是 DSH 官方原生。 - 用官方包自带 README 取证:原生右列 = 容器(sidebar-right) + 唯一页「文件」 (sidebar-files, 只读) + 唯一查看器(documentpreview, kind=text, 纯文本兜底) - 新增官方原生做不到的九件事表,作为 user 处境的 before - 洞察 0 改为「官方假设你只是看,而真实使用是在这儿干活」(只读→可写) - 新增洞察 6:官方只有一个入口→罗盘不出现;入口一多罗盘才登场(单一工具→工作台) - 附录补官方证据引文;上游/fork 的区别降为对内维护说明
15 KiB
01 · 需求分析:官方原生右列 vs 装了 apes-sidebar
本篇只回答一个问题:一个在 DSH 里干活的人,从"官方原生"换到"装了这个包",他的需求和处境发生了什么变化? 对比的两端只有两个:官方原生的右侧栏,和装了 apes-sidebar 之后的右侧栏(那个包是一个整体,九个 tab 一起算)。 机制与根因只在附录 A留索引,细节见 02-系统架构、06-故障排查。
一、先钉住"谁在用、他在哪儿干活"
在 DSH 里,右侧栏是使用者一天里盯得最久的一块地方。它不是"偶尔打开的设置页",而是"工作台 + 仪表盘"。
一个典型使用者(在 DSH 里做项目的人):
- 中间是对话主线——他和模型一起干活;
- 右边是这块地方——看文件、看改动、看子代理、顺手追问、跑命令、看预览;
- 他往往同时开着好几个会话、好几个项目。
这决定了本页所有需求的共同特征:这些信息"看一眼就够,但要频繁看"。 频繁看的东西必须常驻在视野里——不能要求他"跳出去看一眼,再跳回来"。
二、官方原生的右列:一个「只读的文件浏览器 + 预览器」
本机宿主(dsh@0.1.5-rc.2)里,官方真正放进右列的东西只有三件:
| 官方包 | 它给用户什么 | 官方原话 |
|---|---|---|
dsh-client-ui-sidebar-right |
容器:每会话一块可停靠面板、两种形态(贴靠 / 全屏)、展开按钮在会话 header 角落、最多左右两格、拖拽与浮窗、tab 菜单、内置撤销历史 | "为每个会话持有一个停靠面……拥有导航控制器(ctx.sidebarRight)、tab 类型注册表" |
dsh-client-ui-sidebar-files |
唯一的页:「文件」——把会话工作区根目录画成一棵只读的树 | "把会话的工作区根目录画成一棵树,逐层经线上列出,并把文件打开到 Sidebar 里" |
dsh-client-ui-sidebar-documentpreview |
唯一的查看器(kind = text):预览 Markdown / 代码 / 图片 / PDF / HTML,认不出的扩展名走纯文本兜底 |
"在右侧 Sidebar 预览可读文件,无需另开 tab 即可切换已注册的渲染器" |
一个容易被忽略、但对"用户体验"影响很大的细节:
引导页(罗盘)只在注册了两个以上入口时才出现——官方随包只有一个入口(Files), 所以官方用户的右列默认直接就是那棵文件树,罗盘从不露面。 (原文:"恰好一个入口时直接打开对应页面(随包组合中为 Files)"。)
一句话概括官方原生的取向:它假设你只是想「看」。 它给你树和预览,都是只读的;它不假设你要在这块地方「干活」。
于是,官方原生用户在右列里做不到这些事(每一条都是他能直接感知的缺失):
| 他想做的事 | 官方原生右列 | 他只能怎么办 |
|---|---|---|
| 改一个文件 | ❌ 只有预览,没有可写的编辑器 | 跳出去,用外部编辑器打开 |
| 知道刚才改了哪些东西 | ❌ 没有变更清单、没有 diff | 切终端敲 git status / git diff,或另开 diff 工具 |
| 看某个子代理干了什么 | ❌ 右列里没有这个入口 | 翻会话树、翻聊天记录去认人 |
| 追问一句又不想弄脏主线 | ❌ 没有旁路对话 | 硬着头皮在主对话里问,或另开一个窗口 |
| 跑一条命令 | ❌ 没有终端 | 切到系统终端,还得先 cd 到对的目录 |
| 看页面 / HTML 出来什么样 | ❌ 没有内嵌浏览器 | 切浏览器标签,或手动打开产物文件 |
| 知道谁在替我干活、跑到哪了 | ❌ 完全没有 | 只能往上翻记录,翻到一半又忘了上下文 |
| 知道这摊活是在哪儿干的 | ❌ 界面不写 | 靠脑子记,或敲 pwd 确认 |
| 知道这个会话现在什么状态 | ❌ 界面不写 | 靠界面上的小细节猜 |
三、装了 apes-sidebar 之后:同一块地方,从「看」变成「干 + 心里有数」
apes-sidebar 把这九件事一次性放进右列。它们是一个整体需求:把右列从"文件浏览器"变成"工作台 + 仪表盘"。
| tab | 他真正想要的是什么 | 官方原生时他被迫怎么做 | 装了之后 | 需求被改变成 |
|---|---|---|---|---|
| 文件(编辑器) | 看和改代码,而不丢掉当前上下文 | ⌘Tab 跳到外部编辑器;回来要重新找位置 | 右列里直接看、直接改 | 「看文件不该让我离开现场」 |
| 文件变动(git) | 刚才到底改了哪些东西 | 切终端敲命令,或另开 diff 工具 | 变更清单 + 单文件 diff,就在旁边 | 「改了什么必须当场看得见」——这是信任的前提 |
| 子代理 | 进某个子代理,看它到底干了什么 | 翻会话树、翻记录去认人 | 右列里直接进入该子代理 | 「子代理是可进入的,不是只能干等的」 |
| 侧边对话 | 追问一句,但不想污染主线 | 硬着头皮在主对话里问,或另开窗口 | 旁路开一个小对话,两边互不干扰 | 「提问不该有副作用」——性质变了 |
| 终端 | 跑一条命令 | 切到系统终端,常常还得先 cd |
右列里跑,工作目录天然就是对的 | 「命令的上下文应该跟着会话走」 |
| 浏览器 / 预览 | 看这个页面出来是什么样 | 切浏览器标签,或手动打开产物 | 右列内嵌,当场看 | 「产出物要能当场验收」 |
| 智能体 | 谁在替我干活、跑到哪了、哪个停了 | 基本没办法——只能翻记录猜 | 主代理在最上,直系子代理一人一行,带运行/结束状态 | 「派了活之后,我要的是扫一眼,不是盯着守」(见 §四·洞察 4) |
| 应用 | 这摊活到底是在哪儿干的 | 基本没办法——靠脑子记或敲 pwd |
打开就看到当前会话锚定的工作区 | 「界面应该告诉我我在哪,而不是要我自己记住」 |
| 画像 | 这个会话现在是什么状态 | 靠界面小细节猜(在跑?停了?哪一次?) | 标题 / 运行或空闲 / 工作区,写清楚 | 「离席回来,不用重建心智模型」 |
连顺序都在讲同一件事:10…50 是操作面(看/改/查/问/跑/验),60…70 是态势面(谁在干、在哪儿干、什么状态)。
先让"活能在这儿干完",再让"我心里有数"——这是这个包对用户的两级承诺。
四、深度分析:需求到底发生了什么变化
洞察 0 · 官方原生假设"你只是看",而真实使用是"在这儿干活"
这是整个需求空间的起点。官方原生不是做得不好,而是取向不同:只读预览是"查看器"的思路, 而使用者把它当"工位"用——他会在这里改一个文件、跑一条命令、瞄一眼改动。 当一块地方被当成工位,只读就会立刻变成绕路。 这就是这个包存在的全部理由。
洞察 1 · 从「只读」到「可写」:补的不是功能,是主权的归还
官方只给预览,意味着每一个"改一下"都要离开这块地方。装上之后,改、查改动、跑、验四件事都在原地完成。 用户省下的不是几次点击,而是每次离开都要付出的"上下文重建"成本——回来要重新找到刚才的位置、重新想起来自己在干嘛。 需求因此从「我要能看」变成「我要在这儿把活干完」。
洞察 2 · 「留在原地」会变成默认预期(棘轮效应)
一旦右列里能改文件、能跑命令、能看预览,他对"跳出去一下"的容忍度会永久下降。 他会开始说「为什么这个还要我切窗口?」——而这句话在他用官方原生时是说不出口的(因为原生本来就没有可切的东西)。 这类需求只前进、不后退,所以值得一次做对:它一旦被填好,就变成基础设施。
洞察 3 · 消除副作用之后,他会开始"问"(侧边对话)
侧边对话的价值不在"多一个对话框",而在把提问的代价从"可能污染主线"降到"零"。 需求的性质变了:以前他的问题是「要不要问?」(一个决策),现在变成「顺手问一下」(一个动作)。 当一件事的代价趋近于零,用户的行为频率会跳一个数量级——这是需求分析里最值得警惕、也最值得利用的一条规律。
洞察 4 · 看得见 → 敢放手(智能体 tab 的核心价值)
这是整个包里最值钱的一条。官方原生在这一点上是彻底空白:
- 官方没有子代理视图,也没有任何"队伍"概念 → 他派了活之后只能等,或者不停往上翻记录确认;
- 这个包的「子代理」让他能进入某一个;「智能体」让他不必进去就看得到全局——主代理 + 直系子代理,谁在跑、谁停了。
用户真正的痛点不是"我进不去子代理",而是**"我不敢派太多活"**: 因为看不见,他只能用"盯着"来对冲风险,而盯着就失去了并行的意义。
看得见 → 敢放手 → 真的并行 → 才配得上"多智能体"。 需求从「我要能看见」升级为「我要能放心」。
洞察 5 · 心智模型从脑子里搬到界面上(应用 / 画像)
多项目、多会话的人切换时要重建一次"我这是在哪儿"——标题差不多的会话最容易看错, 而看错的代价是写错文件。官方原生在右列里一个字都不写这件事。 「应用」「画像」做的就是把这份"我记得"外化成"界面写着"。 需求的性质:从「我要记性好」变成「界面不该让我记」。
洞察 6 · "引导页"第一次有了意义:从单一工具到工作台
官方原生只有一个入口(Files),所以它默认直接开文件树,罗盘界面根本不会出现。 入口一多,罗盘才登场——用户第一次能"一屏看见这块地方能干什么"。 这是用户层面的分水岭:官方是"一个工具",装了之后是"一个工作台的目录页"。 (对照 §二那个细节:入口数决定了这块地方的形态。)
洞察 7 · 价值随"并行度"放大;而成本几乎为零
- 单会话、单项目的用户:「应用」「画像」几乎用不上,「智能体」也只有一个主代理;
- 一旦同时开几个会话、派几个子代理、换几个项目:这三个 tab 的边际价值陡增。
所以这套东西不是人人需要,但接到的人离不开。 同时它不新增数据源、不新增进程、不引入新的失败面——只是把宿主已经投影出来的信息换个视角呈现 (逐条列在 03-功能说明)。对使用者意味着:低风险地换到确定性,这是它最该守住的边界。
五、由以上分析推出的需求(U1–U6)
| # | 需求(用户口吻) | 怎么算他满意了 | 现状 |
|---|---|---|---|
| U1 | 「我要在这儿把活干完,别老让我跳出去」 | 改文件、查改动、跑命令、看预览、顺手追问,都在右列完成 | ✅ 操作面六个 tab |
| U2 | 「我要看得见谁在替我干活」 | 右列点一下就有队伍表;人数/状态一眼可辨;没有子代理时明确说"没有",不是空白 | ✅ 智能体 tab |
| U3 | 「我要知道我是在哪儿干的活、这会话什么状态」 | 打开就看到工作区与运行/空闲,不用敲 pwd;拿不到应用信息时如实说明 |
◑ 工作区/状态 ✅ · 应用层等宿主 |
| U4 | 「我点开 HTML 就该看得见」 | 自包含 HTML 完整显示,而不是一行 forbidden;但不许为此拆掉沙箱 |
✅(多文件需我本人点「临时解锁」) |
| U5 | 「我的界面不许自己乱套」 | 右列只有一套侧边栏、一个开合入口;弹窗完整盖在面板之上、按钮点得到 | ✅ |
| U6 | 「我敢升级,也退得回去」 | 有"宿主版本 ↔ 插件版本"对照表;每步升级都有分支/tag 可回滚 | ✅ 两条版本线;新宿主线待实机验证 |
六、我们不做的事(省得期待错位)
- 不重造官方已有的东西。 官方给了容器与文件树,我们在它里面长东西,不另起一套侧边栏。
- 不为"看得见"放宽安全边界。 需要放宽必须由用户本人显式点「临时解锁」。
- 不做团队/房间/多智能体协作编排。 那是宿主的另一类职责。
- 不承诺"装上立刻见效"。 单会话用户可能几乎感觉不到差异(见洞察 7)。
七、已知的「暂时满足不了」(诚实交代)
| 他想要的 | 现状 | 为什么(一句话) | 何时会有 |
|---|---|---|---|
| 知道这摊活属于哪个应用、有哪些入口 | 「应用」只显示工作区 | 宿主目前没有向插件提供应用清单的通道 | 宿主提供 feed 后即可接上 |
| 一次摊开完整子代理树(子代理的子代理) | 只显示直系 | 宿主投影只给一层 | 同上 |
| 沙箱状态下多文件 HTML 的相对资源 | 需点「临时解锁」 | 不透明源沙箱下子请求拿不到宿主信任头(安全边界的必然结果) | 不打算改——这是刻意保留的边界 |
这三条说明同一件事:需求跑在宿主能力前面。写出来不是免责,是让读的人知道 "不能用"和"还没做"是两回事。
附录 A · 证据与实现索引
开发与排障看这里;其余读者可跳过。
"官方原生到底有什么"的证据(本机宿主 dsh@0.1.5-rc.2,官方包自带文档):
- 容器:
@deepseek-ai/dsh-client-ui-sidebar-right/README.zh.md—— 停靠面、两种形态、扩展席位、引导页。 - 唯一的页:
@deepseek-ai/dsh-client-ui-sidebar-files/README.zh.md—— "文件树 tab 类型……把文件打开到 Sidebar 里"。 - 唯一的查看器:
@deepseek-ai/dsh-client-ui-sidebar-documentpreview/README.zh.md—— "Sidebar tab 的 kind 为text",未知扩展名纯文本兜底。 - "官方只有一个入口 ⇒ 罗盘不出现":同上 sidebar-right 文档「引导页」一节。
本包一侧的对应实现(editor/git/subagent/sidechat/terminal/browser 为随包操作面;
agents/apps/profile 是本 fork 自增的态势面——对内维护用,对外它是一个包):
| 需求 | 机制(去哪看) | 关键证据 |
|---|---|---|
| U5-a 右列只有一套侧边栏 | 每个 tab 注册成原生 tab 类型(kind = descriptor.id)渲染进官方右列;自绘面板已移除 |
02-系统架构、05-运维手册 |
| U5-b 弹窗不被面板切 | 宿主容器上的层叠上下文(isolation)导致;挂载点改挂 #root 而不再挂 document.body |
06-故障排查 |
| U4 HTML 预览 | 主框架 fetch → srcDoc,sandbox 属性未动;失败回退路由 URL |
06-故障排查 |
与官方 text 预览的关系 |
本包的编辑器类型以更高优先级接管 dsh-resource://file/**,卸载即恢复官方预览 |
docs/external-plugin-guide.md §「内置类型接管」 |
| U6 版本线 | 宿主版本不匹配时宿主静默禁用整行(不报错、无日志);^ 跨 minor 判 false |
04-部署指南、06-故障排查 |