Files
apes-sidebar/docs/wiki/01-需求分析.md
T
figmar 2224991047
CI / ci (push) Canceled after 0s
CI / ci-windows (push) Canceled after 0s
CI / plugin-mount (push) Canceled after 0s
docs(wiki): 需求分析改为使用者视角重写
原稿按「现象/根因(含证据)/需求/验收标准」组织,实质是在讲我们怎么修的;
现在从「用户为什么会需要」写起:谁在用 → 他会怎么说 → 为什么难受 → 他想要什么
→ 怎样算满意(全部是用户能亲手点到、亲眼看到的行为)。

- 五条实现导向的需求 → U1~U6 用户问题(U5 拆成两套侧边栏 / 弹窗被切)
- 新增:不做什么(省得期待错位)、已知的暂时满足不了(应用层 feed、完整子代理树、
  沙箱态相对资源),如实交代边界
- 新增:验收总表(动作 → 应看到)与优先级/状态表
- 实现机制与提交号全部移入附录 A「根因档案」索引,指向 02/03/05/06
2026-10-04 01:55:35 +08:00

143 lines
12 KiB
Markdown
Raw Blame History

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