diff --git a/docs/superpowers/plans/2026-09-12-doubao-layout.md b/docs/superpowers/plans/2026-09-12-doubao-layout.md new file mode 100644 index 0000000..5615d1f --- /dev/null +++ b/docs/superpowers/plans/2026-09-12-doubao-layout.md @@ -0,0 +1,62 @@ +# Genesis「豆包式」布局重构 — 实施计划 + +配套设计:`docs/superpowers/specs/2026-09-12-doubao-layout-design.md` +目标文件:`src/genesis/server/static/{chat.html,chat.css,chat.js,chat_state.js}`、`src/genesis/server/{app.py,service.py}` + +## 全局约束 +- 保留现有深色主题与 `chat.css` 设计令牌;不新增依赖;不引入构建步骤。 +- 现有测试须继续通过(`tests/test_chat_state.js`、`tests/test_chat_ws.js`、`tests/test_frontend_audit_fixes.py`、`python -m pytest` 覆盖率 ≥99%)。 +- 前端无自动化 DOM 测试:前端任务以 `node --check` + 手动验收为准;纯状态函数须补 node 断言。 + +--- + +### Task 1:后端会话重命名(TDD) +- 测试(RED):`tests/test_server_api.py` 新增 + - 建会话 → `PATCH /api/sessions/{sid}` body `{name: "股票系统需求"}` → 200 且返回 name;`GET` 复核。 + - 空名 → 400 `INVALID_NAME`。 + - 不存在 → 404 `SESSION_NOT_FOUND`。 +- 实现(GREEN):`service.rename_session`;`app.py` `PATCH /api/sessions/{sid}` + 请求模型(name 非空校验)。 +- 提交。 + +### Task 2:chat_state.js 纯函数 + node 测试 +- 新增 `emptyHeadline()`、`quickPrompts()`;`buildWelcome` 方向词「上方」→「下方」。 +- `tests/test_chat_state.js` 增加断言:`emptyHeadline()` 含「有什么可以帮到你的」;`quickPrompts()` 含「影响调查」且长度为 4。 +- 运行 `node --test tests/test_chat_state.js`。 + +### Task 3:chat.html 结构重构 +- header:仅 `#session-title`(移除 h1 / proj-switcher 顶栏位 / rag-bar 顶栏位 / sid-badge)。 +- `#chat` 内新增 `#empty-state`(图标 + 主标题 + 副提示 + `#suggests` 建议卡)。 +- `#composer` 下新增 `#composer-toolbar`:`▤ 项目`(打开 `ps-menu`)、`+ 新建项目`、`📎 上传资料`(触发展开上传控件)、`◎ 影响调查`(RAG 开关+stats+触发)。 +- 上传类型下拉移除 `existing_system` 选项。 +- 抽屉目录字段移出 `
`,改文案。 +- 历史项模板(JS 渲染)加 `⋯` 与重命名菜单(DOM 由 JS 生成)。 + +### Task 4:chat.css 样式 +- `#empty-state`(居中、图标、主标题、副提示)、建议卡 `.suggests`/`.suggest-card`。 +- `#composer-toolbar` 图标+文字按钮 `.tb-btn`、`.tb-menu`(项目列表向上弹出)。 +- `.sess .kebab` 与 `.rename-menu`(hover 显示)。 +- `.ps-menu` 改 `bottom: calc(100% + 6px); top: auto;` 向上。 +- 响应式:底部工具栏换行。 + +### Task 5:chat.js 行为 +- `badge` → `#session-title`;各更新点(newSession/loadSession/send/上传后)写会话名。 +- `renderEmptyOrWelcome()` 改写为空态渲染;建议卡点击 `insertPrompt(text)`(写入 `#input` + focus,不发送)。 +- `insertPrompt` 新增。 +- 底部按钮绑定:`#tb-project`→`toggleProjectSwitcher`;`#tb-newproject`→`openProjectDrawer(null)`;`#tb-upload`→触发展开上传控件;`#impact-btn` 逻辑复用。 +- 历史项 `⋯` → 重命名菜单 → 行内编辑(Enter 保存/Esc 取消)→ `PATCH /api/sessions/{sid}` → 刷新列表与顶栏。 +- 文案:「顶栏项目」→「当前项目」;RAG 空态提示语更新。 + +### Task 6:验证与提交 +- `node --check`(抽取 chat.js)。 +- `node --test tests/test_chat_state.js tests/test_chat_ws.js`。 +- `python -m pytest`(≥99%)。 +- 手动验收(设计 §8)。 +- 提交 + 更新 `_AI_USAGE_LOG.md`。 + +## Self-Review 覆盖 +- 设计 §4 组件映射 → Task 3/5。 +- 设计 §5 后端 rename → Task 1。 +- 设计 §6 文案 → Task 2/5。 +- 设计 §7 状态函数 → Task 2。 +- 设计 §8 验收 → Task 6。 +- 非目标(RAG 取材/chips/浅色)本轮不做。 diff --git a/docs/superpowers/specs/2026-09-12-doubao-layout-design.md b/docs/superpowers/specs/2026-09-12-doubao-layout-design.md new file mode 100644 index 0000000..f801b3f --- /dev/null +++ b/docs/superpowers/specs/2026-09-12-doubao-layout-design.md @@ -0,0 +1,96 @@ +# Genesis 前端「豆包式」布局重构 — 设计文档 + +日期:2026-09-12 +范围:`src/genesis/server/static/`(chat.html / chat.css / chat.js / chat_state.js)+ 后端会话重命名端点 +主题:参考豆包工作台布局,**保留现有深色指挥中心主题**,仅调整布局与交互。 + +## 1. 背景与目标 + +现有布局为「顶栏标题 + 顶栏项目下拉 + RAG 条 + 上传条 + 输入框」。本次参考豆包工作台重构为: + +1. **项目创建/配置下移到聊天框下部**,图标+文字形式(`▤ 项目` / `+ 新建项目`)。 +2. **页面顶部显示会话名**(只读)。 +3. **新建会话空态显示「有什么可以帮到你的?」** + 建议卡。 +4. **上传资料与「影响调查(RAG)」开关一并收进底部工具栏**。 +5. **会话重命名入口**:左侧历史项 hover 显示的「⋯」→ 菜单「重命名」(图标+文字)。 + +## 2. 已确认决策 + +- D1 保留现有深色主题与设计令牌,仅改布局。 +- D2 上传/RAG 收进底部工具栏;**新建项目改为用户设置项目目录**;**移除「既有系统 zip」上传选项**。 +- D3 空态建议卡点击 → 提示词**填入输入框**(用户可编辑后自行发送);**暂不做输入框上方 chips**。 +- D4 会话重命名入口仅 `⋯` 菜单;顶栏会话名只读,暂不设其他入口。 +- D5 **RAG 取材改造(从项目目录建索引)留作下一轮独立子项目**,本轮不动后端 RAG。 + +## 3. 目标布局 + +``` +┌─ 顶栏 ────────────────────────────────────────┐ +│ 会话名(只读;rec.name / 未创建会话) │ +├───────────────────────────────────────────────┤ +│ (新会话空态) │ +│ [G] 有什么可以帮到你的? │ +│ (副提示:buildWelcome 文案) │ +│ [生成概要设计书] [影响调查] [用中文生成] [状态] │ ← 建议卡(点击填入输入框) +│ (有消息 → 聊天气泡) │ +├───────────────────────────────────────────────┤ +│ ┌─────────────────────────────────────────┐ │ +│ │ 输入框 [发送] │ │ +│ └─────────────────────────────────────────┘ │ +│ [▤ 项目▾] [+ 新建项目] [📎 上传资料] [◎ 影响调查] │ ← 底部工具栏(图标+文字) +└───────────────────────────────────────────────┘ +``` +侧边栏(品牌 / 新会话 / 会话历史)与右侧项目抽屉保留;抽屉新增/编辑项目的目录字段提升为常规字段。 + +## 4. 组件映射 + +| 现状 | 改为 | +|---|---| +| 顶栏 `

` | `#session-title` 会话名(只读) | +| 顶栏项目下拉 `ps-current`/`ps-menu` | 底部「▤ 项目」按钮 + 向上弹出 `ps-menu` | +| 顶栏 `#rag-bar` | 底部「◎ 影响调查」(RAG 开关+统计+触发) | +| `#upload-bar` | 底部「📎 上传资料」按钮(点击展开现有上传控件) | +| 空态 assistant 气泡(buildWelcome) | `#empty-state`:图标 + 「有什么可以帮到你的?」 + buildWelcome 副提示 + 建议卡 | +| 历史项「× 删除」 | 增加 hover 显示的「⋯」→ 菜单「重命名」 | + +## 5. 后端:会话重命名 + +- 新增端点 `PATCH /api/sessions/{sid}`,请求体 `{ "name": "<非空>" }`。 +- `service.rename_session(sid, name)` → `store.update_session(sid, name=name)`(`update_session` 已支持任意 to_dict 字段)。 +- 校验:`name` 去空白后为空 → 400 `INVALID_NAME`;会话不存在 → 404 `SESSION_NOT_FOUND`。 +- 返回 `{ "session_id", "name" }`。 +- 这是本轮**唯一**的后端改动。 + +## 6. 文案调整 + +- `buildWelcome` 方向词「请先在上方📎上传」→「请先在**下方**📎上传」(仍满足现有 node 断言:含 `要件定义`、`项目「A」`;无项目时含 `请新建项目|选择项目`)。 +- 项目不匹配提示条「当前**顶栏**项目」→「当前**项目**」。 +- RAG 空态提示「请上传既有系统 zip」→「请在项目配置中设置既有系统代码库目录」。 + +## 7. 状态函数(chat_state.js) + +新增纯函数(UMD 导出,Node 可测): +- `emptyHeadline()` → `'有什么可以帮到你的?'` +- `quickPrompts()` → `['生成概要设计书', '影响调查', '用中文生成', '现在什么状态?']` + +`buildWelcome` / `autoBindProject` / `computeDrawerSnapshot` / `isDrawerDirty` / `shouldHideUploadSelect` / `resolveUploadType` 语义与签名不变。 + +## 8. 验收标准 + +1. 顶栏仅显示会话名;`loadSession`/首条消息建会话/上传后均正确更新。 +2. 空态显示「有什么可以帮到你的?」+ 建议卡;点卡片把提示词填入输入框(不自动发送)。 +3. 底部工具栏四项(项目/新建项目/上传资料/影响调查)图标+文字,功能正常;项目菜单向上弹出。 +4. 上传类型下拉不再含「既有系统 zip」;项目抽屉目录字段为常规字段。 +5. 历史项 hover 显示「⋯」→「重命名」→ 行内编辑保存后列表与顶栏同步;`PATCH` 生效。 +6. 深色主题视觉一致;响应式(≤860px)无溢出破坏。 + +## 9. 非目标(Out of Scope) + +- RAG 从项目目录建索引(下一轮)。 +- 输入框上方快捷 chips(后续按需添加)。 +- 主题浅色化。 + +## 10. 风险 + +- 移除 zip 上传后,本轮 RAG 无来源,「◎ 影响调查」将显示 0 片段并禁用(符合 D5)。 +- 新增重命名端点需补 pytest;前端 DOM 重构须保持 `tests/test_frontend_audit_fixes.py`(仅测后端)与 `tests/test_chat_state.js` 通过。