# AI 输出逐字显示与等待态优化设计

## 目标

AI 接口耗时较长时，用户不能在空白页面等待；收到流式输出后，文本不能一大段一大段跳出，而要在当前页面风格下逐字平滑显示。优化范围包括 `mini-program`、`life-script` 和 `web` 中所有现有 AI 流式输出入口。

## 范围

- 小程序：剧本生成、实现路径生成、人生事件 AI 帮写。
- life-script：剧本生成、实现路径生成、人生轨迹 AI 反馈。
- web：聊天 WebSocket AI 流式消息。
- 不改变后端接口协议，不降低后端流式传输速度。

## 方案

各端新增轻量 typewriter 控制器。后端仍按当前速度返回 SSE/WebSocket delta，前端把 delta 放入缓冲区，再用固定节奏输出到可见文本。这样既不拖慢真实请求，也能避免一次性展示大段文字。

### 输出状态

- `waiting`：请求已发出但尚未收到首个 delta，显示动态 loading 和中文提示。
- `streaming`：已收到输出，逐字显示文本，页面保持可滚动。
- `draining`：后端已结束但缓冲区还有文字，继续输出剩余文字。
- `done`：缓冲区清空，进入完成态。
- `error`：停止逐字输出，保留已显示内容，展示中文错误。

### 小程序

小程序新增 `useTypewriterStream` composable，返回可见文本、等待状态、输出状态和控制方法。剧本生成页保留当前紫色宇宙风格，生成态增加星轨 loading、阶段文案和逐字正文。路径生成与 AI 帮写复用同一个 composable。

### life-script

life-script 新增 React hook `useTypewriterStream`，把 `onDelta` 的完整输出转为逐字可见输出。剧本、路径、生命事件反馈页面接入该 hook，并保留玻璃拟态视觉风格。

### web

web 聊天 store 在 `AI_STREAM_DELTA` 到达时不再直接追加到 `message.content`，而是写入该消息的 pending buffer。定时器每次取若干字符刷到可见消息，`AI_STREAM_DONE` 只标记后端已完成，等缓冲区清空后再置为 `sent`。

## 验证

- `mini-program npm run build:mp-weixin`
- `life-script npm run build`
- `web npm run build`
- `git diff --check`

重点人工验证：

- AI 首 token 前有动态等待态。
- 后端一次返回大段文本时，页面仍逐字显示。
- 后端完成后不会截断缓冲区剩余文本。
- 出错时保留已显示文本并展示错误。
