## 方案：Chat 交互 UI

### 架构

单个自包含 HTML 文件 `static/index.html`，零外部依赖（marked.js 从 CDN 按需加载用于 Markdown 渲染），通过 Fetch + ReadableStream 实现 POST SSE 流式消费。

### 文件变更

| 文件 | 操作 |
|------|------|
| `static/index.html` | **新建** — 完整聊天 UI（~600 行） |
| `main.py` | **新增** `@app.get("/")` 根路由，重定向到 `/static/index.html` |

### 页面布局（Zcode/Codex 风格三栏）

```
┌──────────────┬──────────────────────────┬─────────────────────┐
│  会话列表     │      消息区（主）          │   详情面板            │
│  (Session)   │  ┌─────────────────┐    │  (Detail)           │
│              │  │ 用户消息         │    │                     │
│  + 新会话    │  │ 助手回复(流式)   │    │  - 任务进度          │
│              │  │   ▶ 思考过程     │    │  - 工具调用记录       │
│  session-1   │  │   工具调用...     │    │  - 会话信息          │
│  session-2   │  └─────────────────┘    │                     │
│              │                         │                     │
│              │  ┌─────────────────┐    │                     │
│              │  │ 📎 上传文件      │    │                     │
│              │  │ 输入框 + 发送    │    │                     │
│              │  └─────────────────┘    │                     │
└──────────────┴──────────────────────────┴─────────────────────┘
```

### 核心功能

| 功能 | 实现 |
|------|------|
| **流式 SSE 消费** | Fetch + `response.body.getReader()` 逐行解析 `data:` 前缀 |
| **思考过程折叠** | `thinking_token` / `thinking` 事件渲染为可折叠 `<details>` 块 |
| **工具调用展示** | `tool_call` / `tool_result` / `executing` 渲染为工具图标 + 状态行 |
| **任务进度** | `updated_todo_list` / `agent_todos` 渲染为 checkbox 列表 |
| **Markdown 渲染** | 使用 marked.js（CDN），表格/代码块/列表完整支持 |
| **文件上传** | `<input type="file">` + FormData 提交 |
| **会话管理** | `GET /api/sessions` 列表、`DELETE /api/sessions/{id}` 删除、新建自动 |
| **深色主题** | CSS 变量驱动，类 VS Code 暗色配色 |

### SSE 事件 → UI 映射

| SSE type | UI 行为 |
|----------|---------|
| `thinking` | 状态栏显示"正在分析..." |
| `thinking_token` | 追加到折叠思考块 |
| `executing` | 状态栏显示工具中文名 + 图标 |
| `token` | 追加到助手消息（流式打字效果） |
| `tool_call` | 插入工具调用卡片 |
| `tool_result` | 更新工具卡片为完成状态 |
| `updated_todo_list` | 渲染右侧任务进度面板 |
| `done` | 停止流式，保存到历史 |
| `error` | 显示错误 Toast |
| `progress` | 状态栏（review 管线） |
| `agent_start/done` | 子智能体进度条（review 管线） |

### 技术要点

- **POST SSE**：EventSource 不支持 POST，用 `fetch()` + `ReadableStream` + 手动分割 `\n\n`
- **中止请求**：AbortController，切换会话时取消进行中的流
- **自动滚动**：新 token 到达时智能滚动（用户手动上滚则不自动滚）
- **会话持久化**：session_id 存 localStorage，刷新页面恢复