Files
2026Technology-Competition/docs/superpowers/plans/2026-09-12-sidebar-project-tree.md
T

100 lines
6.1 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.
# 侧边栏项目树 + 消息区对齐 + 空态清理 — 实施计划
配套需求:用户 7 条前端优化(侧边栏信息架构重构 + 气泡对齐 + 空态清理)
目标文件:`src/genesis/server/static/{chat.html,chat.css,chat.js,chat_state.js}`
前端无框架、无构建;后端零改动。
## 已确认决策
- D1 气泡对齐到**文本输入框**:左 16px;右留发送按钮宽度(40+10=50px);**删除 assistant 头像点**。
- D2 点击侧边栏项目名 = **选中该项目(设为当前项目)+ 展开/收起**
- D3 抽屉左侧项目列表**保留**(仅删除「+新建项目」项)。
- D4 侧边栏折叠态**隐藏「项目/其他会话」两段**。
- D5 req2 的「提示语及提示词」= 空态主标题 + 建议卡,发送后一并清除。
## 目标侧边栏
```
[G Genesis 概要设计书做成Agent]
[+ 新会话]
项目 + ← 仅"+"hover「追加项目」
▾ 股票系统 ⚙ ← 展开显示其会话;⚙ hover「配置」
· 需求A
· 需求B
▾ 人事系统 ⚙
· 需求C
其他会话
· 需求Dproject=""
```
---
## Task 1chat_state.js 分组纯函数 + node 测试
- 新增 `groupSessionsByProject(sessions)``{ byProject: { "<name>": [s...] }, other: [s...] }``project` 为空者入 `other`)。
- `tests/test_chat_state.js` 增加断言:空项目归 other;两项目分别归组。
- 运行 `node --test tests/test_chat_state.js`
## Task 2chat.html 侧边栏结构 + 移除底部新建项目按钮
- 删除 `<h2>会话历史</h2>``<div id="session-list"></div>`
- 新增 `#sec-projects``side-head`:标题「项目」+ `#side-add-project`「+」)与 `#project-tree`
- 新增 `#sec-others`(标题「其他会话」)与 `#other-session-list`
- 删除 `#tb-newproject` 按钮。
## Task 3chat.css 侧边栏树 + 消息区对齐 + 折叠态
- 新增 `.side-section/.side-head/.side-title/.side-add/.proj-group/.proj-row/.proj-caret/.proj-name/.proj-config/.proj-sessions` 样式;嵌套 `.sess` 缩进。
- 折叠态:`#sidebar.collapsed .side-section { display: none; }`
- 消息区:`#chat { max-width: none; margin: 0; padding: var(--sp-6) var(--sp-4); }``.msg { padding-right: 50px; }``.msg .bubble { max-width: 100%; }`**删除 `.msg.assistant::before`**。
## Task 4chat.js 分组渲染 + 绑定调整 + 空态清理
- `refreshSessions()` 改拉全量并按 `groupSessionsByProject` 分组 → `renderProjectTree()` + `renderOtherSessions()`
-`renderSessItem(s)`(复用现有会话行逻辑)。
- `renderProjectTree()`:项目行点击选中+展开/收起(`collapsedProjects` SetlocalStorage 持久化);`⚙``openProjectDrawer(name)`
- `#side-add-project``openProjectDrawer(null)`(带脏守卫)。
- `renderProjectSwitcher()`:删除 `ps-manage`「项目管理(打开抽屉)」项及绑定。
- `renderDrawerList()`:删除 `di-create`「+新建项目」项。
- `send()`:发消息前 `chatEl.querySelector('.empty-state')?.remove()`
- 删除 `#tb-newproject` 绑定。
## Task 5:验证与提交
- `node --check``node --test``python -m pytest`(≥99%)。
- 手动核对:气泡对齐、空态清理、项目树/⚙/+、底部无新建项目、未选项目时新会话入「其他会话」。
- 更新 `_AI_USAGE_LOG.md` 并提交。
## 风险
- `#sidebar.collapsed``.sess` 旧样式成为死代码(无害)。
- 分组渲染依赖 `GET /api/sessions` 全量返回(已支持 `project` 可选)。
- 若某会话的 project 已从项目列表删除,仍会以其 project 名建组渲染(保证不丢会话)。
---
## 评审结论与计划调整(plan-eng-review
### 采纳的修正
- **F1(正确性,req 5)显式「不选择项目」持久化**
- `chat_state.js``autoBindProject(draftProject, projects, explicitNone = false)` —— `explicitNone` 为真时原样返回 `draftProject`(不移除用户选择);否则维持原自动绑定逻辑。新增 node 断言。
- `chat.js`:读写 `localStorage['genesis_project_explicit_none']``loadProjects()` 传入该标记;选任意项目 → 清除标记;选「不选择项目」→ 设标记。保证「无项目选择 → 新会话进『其他会话』」成立。
- **F2(UX)打开会话所在分组高亮**
- `renderProjectTree()`:组内任一会话 `session_id === sid` 时给 `.proj-group``.has-active`(与 `.current` = 选中项目 区分)。
- **F3(DRY)对齐余量单一来源**
- 新增 CSS 变量:`--send-size: 40px``--composer-gap: 10px``--composer-gutter: calc(var(--send-size) + var(--composer-gap))`
- `#send { width/height: var(--send-size) }``#composer-inner { gap: var(--composer-gap) }``.msg { padding-right: var(--composer-gutter) }`
- **F6(清理)删除折叠态死样式**
- 移除 `#sidebar.collapsed .sess*``#sidebar h2` 相关规则(折叠态整段隐藏、h2 已不存在)。
### 接受现状(标注,不改)
- F4 project 已删的会话以原 project 名成组渲染(不丢会话)。
- F5 DOM 渲染层无自动化测试;靠纯函数 `groupSessionsByProject` 断言 + `node --check` + 手动。
- F7 项目行沿用 `div.onclick`(非键盘可达),与会话行一致。
- F8 `refreshSessions` 每次拉全量;规模增大时再考虑限制。
### 受影响任务更新
- Task 1 追加:`autoBindProject` 第三参数 + `groupSessionsByProject` + node 断言。
- Task 3 追加:`--send-size/--composer-gap/--composer-gutter` 变量;删除折叠死样式。
- Task 4 追加:`explicit_none` 读写与联动;`.has-active` 渲染。
## GSTACK REVIEW REPORT
- STATUS: DONE_WITH_CONCERNS
- REVIEWED: docs/superpowers/plans/2026-09-12-sidebar-project-tree.md
- FINDINGS: F1 正确性(已采纳修复) / F2 UX(已采纳) / F3 DRY(已采纳) / F6 清理(已采纳)F4/F5/F7/F8 接受
- KEY DECISION: 显式「不选择项目」持久化修复(否则 req 5 不成立)
- CONCERN: 渲染层无自动化测试(无 DOM harness);折叠态样式清理后需回归核对
- NEXT: 待用户批准后实施