01 · 需求分析
本篇只回答一个问题:使用者为什么会需要它。
每条需求都从「用户会怎么说」写起——他遇到什么处境、他想要什么结果、他怎样才算满意。
不写我们是怎么实现的:实现机制与故障根因在 02-系统架构 与 06-故障排查,
本篇末尾只留一份索引供开发/排障查阅。
验收标准一律写成用户能亲手点到、亲眼看到的东西,不写测试用例名、不写提交号。
一、谁在用
| 使用者 |
他在干什么 |
他对右侧栏的期待 |
| 在 DSH Desktop 里做项目的开发者(主要) |
一边跟模型对话干活,一边开着文件、终端、预览 |
这是他一天里看得最多的那块地方:别挡道、别自相矛盾、点开就有用 |
| 同时放出去好几个子代理的「指挥者」 |
主会话里派活,子代理并行跑 |
不用翻聊天记录就知道谁在跑、谁停了 |
| 接手这套环境的同事 / 运维 |
装插件、升级、出事定位 |
装得上、看得出在跑、能退回去、文档照着做就行 |
一句话场景:他打开 DSH,右列就是他的工作台;他希望在一个地方同时管住「文件、终端、预览」以及这场会话的全局态势。
二、使用者的需求
U1 「我看不见谁在替我干活」
|
|
| 他会怎么说 |
「我刚派了四个子代理,现在聊天记录刷得飞快——还剩几个在跑?哪个已经停了?」 |
| 为什么难受 |
在聊天流里回溯是唯一的办法:往上翻,翻到就丢了上下文。原生会话树只回答"有哪些会话",不回答"这场会话里现在有谁、在干什么"。用户被迫在两个地方来回找同一条信息。 |
| 他想要 |
点一下就有一张这场会话的队伍表:主代理在最上,它的直系子代理一人一行,谁在跑、谁停了,写在脸上。 |
| 怎样算满意 |
① 不离开右列就能看到;② 人数与状态一眼可辨(运行中 / 已结束、一次性 / 可续);③ 没有子代理时明确告诉他"没有",而不是留一片空白让他怀疑是不是坏了;④ 不用等刷新,开面板就是最新的。 |
| 状态 |
✅ 已满足(apes:agents) |
U2 「我不知道这活儿是在哪儿干的」
|
|
| 他会怎么说 |
「同时开着三个项目,会话标题长得都差不多——我现在这个是哪个目录下的?等下写文件会不会写错地方?」 |
| 为什么难受 |
工作区是他唯一能确认"我在哪儿"的锚点,但它只存在于终端提示符里。切回一个会话时,他得先开个终端敲 pwd 才能安心。 |
| 他想要 |
面板直接告诉他这场会话锚在哪个工作区;更好的是还告诉他这属于哪个「应用」。 |
| 怎样算满意 |
① 打开就能看到工作区路径(不用他自己去敲命令);② 拿不到应用层信息时如实写"宿主现在没有应用信息",而不是留空让他猜哪里出了问题。 |
| 状态 |
◑ 部分满足:工作区 ✅(apes:apps)/应用层信息受宿主限制(见 §四) |
U3 「这个会话现在是什么状态、值不值得等」
|
|
| 他会怎么说 |
「它还在跑吗?还是刚才就停了?我刚回来,这个会话是哪一次来着?」 |
| 为什么难受 |
会话的"身份"和"当前状态"散落在界面细节里,要靠猜;离开一会儿回来,就要重新建立"我在看什么"的心智模型。 |
| 他想要 |
一张会话画像:这次会话是什么、现在在跑还是空闲、工作区在哪儿。 |
| 怎样算满意 |
① 运行 / 空闲有明确文字,不用看动画猜;② 标题或工作区缺失时给出替代信息或明确提示。 |
| 状态 |
✅ 已满足(apes:profile:标题 / 运行态 / cwd) |
U4 「我点开一个 HTML,结果只有一行 forbidden」
|
|
| 他会怎么说 |
「模型给我生成了一份报表 / 图表 / 原型页面,我点开——就一行 forbidden。文件是坏了吗?」 |
| 为什么难受 |
HTML 是最直观的交付物,也是他最想直接验收的东西。看到的却是一行技术错误:他既不知道文件是好是坏,也不知道该找谁。信心成本很高——一旦怀疑"预览不可信",他下次就直接绕开功能,回到最原始的"下载下来用浏览器打开"。 |
| 他想要 |
点开就能看到内容。而且不希望为了让他看见,就把安全边界拆掉。 |
| 怎样算满意 |
① 自包含 HTML(内联样式/脚本)完整显示;② 多文件 HTML 至少正文可读,需要外链资源时由他本人点「临时解锁」这个显式动作来放宽;③ 真取不到文档时,显示真实原因,不是白屏。 |
| 状态 |
✅ 已满足(默认沙箱态可读;多文件需显式解锁,见 03-功能说明 §3.1) |
U5 「我的界面自己乱套了」
a. 右边有两套侧边栏,我不知道该点哪个
|
|
| 他会怎么说 |
「窗口右边出现了两个侧边栏、两个开合按钮——哪个是真的?」 |
| 为什么难受 |
两个入口、两套内容,用户无法判断该用哪个;他会同时试两个,再怀疑是不是装重了。不可信的工具会先被弃用,然后才被排障。 |
| 他想要 |
右列只有一套——DSH 自己那套;插件的东西住在里面,而不是另起一套。 |
| 怎样算满意 |
右列只有一个展开/收起入口;插件每个面板都能从原生入口进入;不会出现"关掉一个还剩一个"。 |
| 状态 |
✅ 已满足 |
b. 弹窗被插件面板切掉一角
|
|
| 他会怎么说 |
「我打开插件市场,弹窗左下角被切了一块,按钮点不到。」 |
| 为什么难受 |
他遇到的不是"功能缺失",而是功能互相打架:明明能用的东西被自己的插件挡住。这类问题最伤使用意愿,因为用户会归咎于"这个插件不可靠"。 |
| 他想要 |
弹窗是更上层的东西,应该完整盖住插件面板;同时插件面板仍要盖在对话正文之上。 |
| 怎样算满意 |
弹窗完整可见、按钮可点;面板不回退到被对话正文压住。 |
| 状态 |
✅ 已满足 |
U6 「我不敢升级——也不知道该装哪一版」
|
|
| 他会怎么说 |
「升了一版,插件就像没装一样,没报错也没日志。我这台该装哪版?出事怎么退回去?」 |
| 为什么难受 |
宿主对版本不匹配是静默禁用——没有错误提示,用户只会得出"这东西坏了/不可信"的结论,而真正的原因是版本配错。加上换机器、多环境,选线成本全压在用户的记忆里。 |
| 他想要 |
① 一份"哪个宿主配哪个版本"的对照,照着选就能装上;② 每步升级都留可回滚的锚点;③ 万一装错,文档能告诉他"现象就是像没装"以及怎么换回来。 |
| 怎样算满意 |
① 按 04-部署指南 的对照表选线即装得上;② 升级前后有分支/tag,一条命令回退;③ 能在 06-故障排查 里按症状自查。 |
| 状态 |
✅ 已满足(两条版本线 + 锚点;新宿主线待实机验证,见 05-运维手册) |
三、我们不做的事(先说清,省得期待错位)
| 不做 |
对使用者意味着 |
| 不重造「文件 / 终端 / 浏览器」 |
这些上游与宿主已经有了,再造一遍只会让你的界面更乱 |
| 不做团队 / 房间 / 多智能体协作面板 |
那是宿主另一类能力的职责,不该塞进右列 |
| 不为「看得见」放宽沙箱 |
想加载沙箱外资源,必须由你本人点一次显式解锁;插件不会替你默默降级 |
| 不承诺"装上看不见变化"就是坏的 |
宿主对版本不匹配是静默禁用,先按 06-故障排查 自查宿主版本 |
四、已知的「暂时满足不了」(如实交代)
| 使用者想要的 |
现状 |
为什么 |
何时会好 |
| 应用级信息(这场会话属于哪个「应用」、有哪些入口) |
apes:apps 只显示工作区 cwd |
宿主当前没有向插件提供应用清单的通道 |
宿主提供 feed 后即可接上 |
| 一次摊开完整子代理树(含子代理的子代理) |
只显示直系子代理 |
宿主投影只给一层 catalog |
同上 |
| 沙箱态下多文件 HTML 的相对资源 |
需点「临时解锁」 |
不透明源沙箱里子请求拿不到宿主信任头——这是安全边界的必然结果 |
刻意保留,不计划改变 |
五、验收总表(你可以自己动手验)
| 你做什么 |
你应该看到 |
| 展开右列 |
只有一套侧边栏、一个开合入口 |
| 点「智能体」 |
主代理 + 直系子代理,带运行态;没有子代理时明确提示"没有" |
| 点「应用」 |
当前工作区路径;宿主无应用 feed 时写明原因 |
| 点「画像」 |
会话标题 / 运行或空闲 / 工作区 |
| 打开一个自包含 HTML |
内容完整显示在面板里,不是 forbidden |
| 打开一个多文件 HTML |
正文可读;需要外链资源时由你点「临时解锁」 |
| 打开插件市场 |
弹窗完整盖在面板之上,按钮可点 |
| 打开某个 HTML 后 ⌘Q 重启 DSH |
面板仍在、开合入口仍只有一个 |
六、优先级与当前状态
| 需求 |
优先级 |
状态 |
| U1 看得见队伍(谁在替我干活) |
P0 |
✅ apes:agents |
| U4 HTML 看得见、且不降级安全 |
P0 |
✅ 默认沙箱可读;多文件需显式解锁 |
| U5 界面别乱(单一侧边栏 + 层叠正确) |
P0 |
✅ |
| U6 敢升级、能回滚 |
P1 |
✅ 两条版本线 + 锚点;新宿主线待实机验证 |
| U2 知道在哪儿干活 |
P1 |
◑ 工作区 ✅/应用层等宿主 |
| U3 会话画像 |
P2 |
✅ apes:profile |
附录 A · 根因档案(实现视角,开发与排障看,其他读者可跳过)
| 需求 |
机制 / 证据 |
详细页 |
| U1 / U2 / U3 信息层三 tab |
按 DSH 标准 TabDescriptor 注册(order 60/65/70、single);数据来自 ctx.sessions.list 的 byId 与宿主会话投影;随基线同步进两条版本线 |
02 · 03 |
| U4 HTML 预览 |
桌面壳对所有路由做前置围栏,只信任带 Electron 注入头的请求;沙箱 iframe 源为 null 因而发不出合规请求。解法:主框架 fetch 取文档 → 注入 <base href> → srcDoc 交付,沙箱令牌一字未改 |
06 · 03 §3.1 |
| U5-a 两套侧边栏 |
fork 基线 v0.18.0 自绘右列与开关(toggleCluster),而 DSH 自带原生右列;升级到上游 v0.19.1(原生注册路径)后仅剩一套 |
02 |
| U5-b 弹窗被切 |
桌面壳给 #root 加 isolation: isolate 形成层叠上下文,宿主 overlay(z-index: 1000)被封在其中;插件面板宿主当时挂在 document.body(上下文之外)且带 z-index: 25。解法:把面板宿主挂进 #root,无标记时回退 document.body |
02 · 06 |
| U6 静默禁用 |
宿主启动预检 semver.satisfies(host, peerRange, { includePrerelease: true }),caret 跨 minor 为 false → 整行跳过,无日志。对策:两条独立版本线 + 分支/tag 锚点 |
05 · 04 |