docs: 补充 AI 打字机输出、小程序灵感卡片、脚本主页布局等设计文档和计划

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-24 18:39:26 +08:00
parent 886f04046b
commit 6e5a379bef
12 changed files with 722 additions and 0 deletions
@@ -0,0 +1,60 @@
# AI Typewriter Output Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Make all existing AI stream outputs in mini-program, life-script, and web show a themed loading state first, then reveal generated text smoothly one character at a time.
**Architecture:** Keep backend stream protocol unchanged. Add a small typewriter buffer utility per frontend stack and wire pages/stores to display the typewriter-visible text while retaining the full stream output for saving and final state.
**Tech Stack:** Vue 3/uni-app, React, Pinia, WebSocket/SSE streaming.
---
### Task 1: Mini Program Typewriter
**Files:**
- Create: `mini-program/src/composables/useTypewriterStream.js`
- Modify: `mini-program/src/pages/main/ScriptView.vue`
- Modify: `mini-program/src/pages/main/PathView.vue`
- Modify: `mini-program/src/pages/life-event/form.vue`
- [x] Add a composable with `visibleText`, `isWaiting`, `isStreaming`, `push`, `finish`, `fail`, `reset`, `dispose`.
- [x] In `ScriptView.vue`, push each full stream output to the composable and render `visibleText`.
- [x] Improve the generating panel with themed loading copy and a typing cursor.
- [x] In `PathView.vue` and `life-event/form.vue`, use typewriter visible text for AI output.
### Task 2: Life Script Typewriter
**Files:**
- Create: `life-script/src/hooks/useTypewriterStream.js`
- Modify: `life-script/src/views/ScriptView.jsx`
- Modify: `life-script/src/views/PathView.jsx`
- Modify: `life-script/src/views/TimelineView.jsx`
- [x] Add a React hook with the same buffer behavior.
- [x] Replace direct `setStreamContent(output)` / `setStreamFeedback(output)` calls with `push(output)`.
- [x] Render hook `visibleText` during AI generation.
- [x] Add a subtle glass loading state before the first visible character.
### Task 3: Web Chat Typewriter
**Files:**
- Modify: `web/src/stores/chat.ts`
- [x] Add per-message pending buffers and timer maps inside the chat store.
- [x] On `AI_STREAM_DELTA`, append delta to the buffer and start a timer for the target message.
- [x] On `AI_STREAM_DONE`, mark the message as done only after the pending buffer is empty.
- [x] On error or disconnect, stop timers for affected messages.
### Task 4: Verification
**Commands:**
- `cd mini-program && npm run build:mp-weixin`
- `cd life-script && npm run build`
- `cd web && npm run build`
- `git diff --check`
- [x] Mini-program build passes.
- [x] life-script build passes.
- [x] web build passes.
- [x] Diff check reports no new whitespace errors.
@@ -0,0 +1,40 @@
# Mini Program Inspiration Compact Cards Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Make inspiration cards on the mini-program script generation page compact, single-line, and ellipsis-truncated while preserving full prompt selection behavior.
**Architecture:** Reuse the existing `recommendations` data and `useRecommendation(item.text)` click path. Change only the presentation in `ScriptView.vue`: remove visible tag text and tighten the card CSS.
**Tech Stack:** Vue 3 single-file component, uni-app mini-program build.
---
### Task 1: Compact Inspiration Card Template
**Files:**
- Modify: `mini-program/src/pages/main/ScriptView.vue`
- [x] Remove the visible `<text class="recommend-tag">...</text>` from each `recommend-card`.
- [x] Keep `@click="useRecommendation(item.text)"` unchanged so the full prompt still fills `wishText`.
- [x] Keep the `v-for`, `:key`, `recommend-card`, and `recommend-text` bindings unchanged.
### Task 2: Single-Line Ellipsis Styling
**Files:**
- Modify: `mini-program/src/pages/main/ScriptView.vue`
- [x] Change `.recommend-card` from a tall vertical card to a compact row with `min-height: 68rpx`.
- [x] Use centered row alignment and smaller padding.
- [x] Add `min-width: 0` so text truncation works inside the grid.
- [x] Change `.recommend-text` to one-line ellipsis with `white-space: nowrap`, `overflow: hidden`, and `text-overflow: ellipsis`.
- [x] Remove or neutralize unused `.recommend-tag` styling.
### Task 3: Validate
**Commands:**
- `cd mini-program && npm run build:mp-weixin`
- `git diff --check`
- [x] Mini-program build passes.
- [x] Diff check reports no new whitespace errors.
@@ -0,0 +1,60 @@
# Mini Program Script Generation Feedback Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Add animated progress, long-wait guidance, and graceful failure recovery to the mini-program `心愿实现中` screen.
**Architecture:** Keep all AI stream calls unchanged and add a small local feedback state in `ScriptView.vue`. The screen uses timer thresholds to distinguish normal waiting, slow waiting, very slow waiting, streaming output, and failure.
**Tech Stack:** Vue 3 single-file component, uni-app mini-program build, existing `useTypewriterStream` composable.
---
### Task 1: Add Generation Feedback State
**Files:**
- Modify: `mini-program/src/pages/main/ScriptView.vue`
- [x] Add `generationStatus`, `generationError`, `generationHintIndex`, and `lastSubmitSource` refs.
- [x] Add local timers for rotating hints, 8-second slow state, and 20-second very-slow state.
- [x] Add `startGenerationFeedback`, `clearGenerationFeedbackTimers`, `markGenerationStreaming`, and `markGenerationFailed` helpers.
- [x] Clear timers on success, failure, returning home, and component unmount.
### Task 2: Update Generation Flow
**Files:**
- Modify: `mini-program/src/pages/main/ScriptView.vue`
- [x] Call `startGenerationFeedback()` when `submitWish` enters `viewState = 'generating'`.
- [x] Call `markGenerationStreaming()` in the stream `onDelta` callback before pushing typewriter text.
- [x] On failure, keep `viewState = 'generating'` and show a failure state instead of immediately returning home with only a toast.
- [x] Add `retryGeneration()` and `returnToEdit()` actions for the failure state.
### Task 3: Update Generation Screen UI
**Files:**
- Modify: `mini-program/src/pages/main/ScriptView.vue`
- [x] Replace static `心愿实现中……` copy with computed `generationTitle`.
- [x] Add thinking dots when no stream output has arrived.
- [x] Add a secondary hint line under the main loading copy.
- [x] Add failure actions `再试一次` and `返回修改` when `generationStatus === 'failed'`.
### Task 4: Add Themed Animations
**Files:**
- Modify: `mini-program/src/pages/main/ScriptView.vue`
- [x] Animate `.loading-orbit` with a gentle breathing pulse.
- [x] Animate `.loading-orbit::after` as the small orbiting light.
- [x] Add animated thinking dots inside the system bubble.
- [x] Style the failure copy and actions in the current purple/gold theme.
### Task 5: Validate
**Commands:**
- `cd mini-program && npm run build:mp-weixin`
- `git diff --check`
- [x] Mini-program build passes.
- [x] Diff check reports no new whitespace errors.
@@ -0,0 +1,49 @@
# Mini Program Script Home Cosmic Background Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Center the script generation headline and add subtle cosmic background motion without interfering with the page content.
**Architecture:** Add a decorative background layer inside `ScriptView.vue` and keep all interactive content above it. Use CSS-only planets, star speckles, and meteors so no assets or runtime logic are needed.
**Tech Stack:** Vue 3 single-file component, uni-app mini-program build, scoped CSS animations.
---
### Task 1: Add Background Layer
**Files:**
- Modify: `mini-program/src/pages/main/ScriptView.vue`
- [x] Add a non-interactive `cosmic-background` view as the first child of `.script-view`.
- [x] Add child views for two planets, two star fields, and three meteors.
- [x] Ensure the decorative layer has no event handlers.
### Task 2: Fix Layering and Headline Alignment
**Files:**
- Modify: `mini-program/src/pages/main/ScriptView.vue`
- [x] Set `.script-view` to `position: relative` and `overflow: hidden`.
- [x] Set `.wish-home`, `.generation-view`, and `.result-view` to `position: relative; z-index: 1`.
- [x] Center `.hero-copy` with `justify-content: center` and `text-align: center`.
- [x] Increase the spacing under `.hero-copy` so the inspiration section breathes.
### Task 3: Add Cosmic Styling
**Files:**
- Modify: `mini-program/src/pages/main/ScriptView.vue`
- [x] Style `.cosmic-background` with absolute positioning, low opacity, and `pointer-events: none`.
- [x] Style planet elements with radial gradients and slow drift animations.
- [x] Style meteor elements with diagonal motion and staggered animation delays.
- [x] Style star fields with low-contrast radial gradients.
### Task 4: Validate
**Commands:**
- `cd mini-program && npm run build:mp-weixin`
- `git diff --check`
- [x] Mini-program build passes.
- [x] Diff check reports no new whitespace errors.
@@ -0,0 +1,41 @@
# Mini Program Script Home Layout Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Make the mini-program script generation home screen keep its headline on one line and place the microphone lower for easier voice input.
**Architecture:** Reorder existing template blocks in `ScriptView.vue` without changing data flow or event handlers. Adjust the existing hero CSS so the headline is a single non-wrapping row while preserving the current visual theme.
**Tech Stack:** Vue 3 single-file component, uni-app mini-program build.
---
### Task 1: Reorder Home Screen Blocks
**Files:**
- Modify: `mini-program/src/pages/main/ScriptView.vue`
- [x] Move the `inspiration-section` block so it appears immediately after `hero-copy`.
- [x] Keep `wish-input-wrap` after `inspiration-section`.
- [x] Keep `profile-boost` after `wish-input-wrap`.
- [x] Move `orb-wrap` and `voice-copy` after `profile-boost`.
- [x] Verify no event bindings change: `useRecommendation`, `shuffleInspirations`, `submitWish`, `startVoicePress`, `endVoicePress`, `cancelVoicePress`, and `openSocialInsights` remain attached to the same elements.
### Task 2: Make Headline Single Line
**Files:**
- Modify: `mini-program/src/pages/main/ScriptView.vue`
- [x] Update the two headline text nodes into a single row under `.hero-copy`.
- [x] Change `.hero-copy` to a horizontal flex container with `white-space: nowrap`.
- [x] Reduce `.hero-title` font size enough for common mini-program viewport widths.
- [x] Preserve `.hero-highlight` styling.
### Task 3: Validate
**Commands:**
- `cd mini-program && npm run build:mp-weixin`
- `git diff --check`
- [x] Mini-program build passes.
- [x] Diff check reports no new whitespace errors.
@@ -0,0 +1,50 @@
# 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 前有动态等待态。
- 后端一次返回大段文本时,页面仍逐字显示。
- 后端完成后不会截断缓冲区剩余文本。
- 出错时保留已显示文本并展示错误。
@@ -0,0 +1,40 @@
# Mini Program Inspiration Compact Cards Design
## Goal
Optimize the mini-program script generation page so inspiration cards use less vertical space while still filling the full selected prompt into the send input.
## Approved Approach
Use option A: keep the existing two-column inspiration grid, but make each card a compact single-line candidate.
## Behavior
- Each inspiration card displays only `item.text`.
- Displayed text is constrained to one line.
- Overflowing text is hidden with an ellipsis.
- The category/tag chip is not shown in the compact card.
- Clicking a card still calls `useRecommendation(item.text)` and writes the full text into the send input.
- The existing `换一换` action and recommendation source logic remain unchanged.
## Implementation Notes
Only `mini-program/src/pages/main/ScriptView.vue` needs to change.
Update the card template to remove the visible tag node. Update CSS so:
- `.recommend-card` is a compact row, about `68rpx` high.
- `.recommend-text` uses `white-space: nowrap`, `overflow: hidden`, and `text-overflow: ellipsis`.
- Grid remains two columns.
- Visual theme remains consistent with the current purple glass style.
## Validation
Run:
```bash
cd mini-program
npm run build:mp-weixin
```
Expected result: build succeeds with no new errors.
@@ -0,0 +1,45 @@
# Mini Program Script Generation Feedback Design
## Goal
Improve the mini-program `心愿实现中` screen so users can clearly tell that generation is running, understand long waits, and recover gently if the AI stream fails or produces no output.
## Approved Approach
Use option A: add a scene-friendly loading state with phased guidance and a graceful failure panel.
## Behavior
When script generation starts:
1. The page stays on the current `心愿实现中` screen.
2. The existing chat bubble and orbit motif remain.
3. The orbit gets breathing/rotating animation and small star-dot motion.
4. A rotating hint line appears while no stream text has arrived.
5. If no stream text arrives after about 8 seconds, show a gentle slow-wait message.
6. If no stream text arrives after about 20 seconds, show a warmer network-slow message, while still waiting for the stream.
7. Once stream text arrives, switch to the existing typewriter text output.
8. If the call fails or returns empty output, keep the user on the generation screen and show a soft failure state with `再试一次` and `返回修改`.
## Implementation Notes
Only `mini-program/src/pages/main/ScriptView.vue` needs to change.
Add a small local generation feedback state:
- `generationStatus`: `idle | waiting | slow | verySlow | streaming | failed`
- `generationError`: user-facing failure copy
- timers for rotating hints and long-wait thresholds
Do not change backend API calls or stream protocol. `streamAiScene` remains the source of stream output. Existing `useTypewriterStream` continues to render text progressively after the first output arrives.
## Validation
Run:
```bash
cd mini-program
npm run build:mp-weixin
```
Expected result: build succeeds with no new errors.
@@ -0,0 +1,42 @@
# Mini Program Script Home Cosmic Background Design
## Goal
Polish the mini-program script generation home page so the headline is centered with comfortable spacing, and the page background gains subtle cosmic motion that matches the current purple/gold style.
## Approved Approach
Use option A: a restrained cosmic background.
## Behavior
- Center the headline `今天有什么心愿想实现`.
- Keep the headline on one line.
- Add a slightly larger gap between the headline and the inspiration section.
- Add background-only cosmic elements:
- a distant planet near the upper-right edge,
- a faint smaller planet near the lower-left edge,
- a few animated meteors moving diagonally,
- subtle star speckles.
- Background elements must stay behind page content and must not affect tapping inputs, inspiration cards, buttons, or the microphone.
## Implementation Notes
Only `mini-program/src/pages/main/ScriptView.vue` needs to change.
Add a `cosmic-background` layer as the first child of `.script-view`. Set it to `position: absolute`, `inset: 0`, `pointer-events: none`, and a lower `z-index`.
Set `.script-view` to `position: relative` and `overflow: hidden`. Set `.wish-home`, `.generation-view`, and `.result-view` to `position: relative; z-index: 1;`.
Use CSS-only animation for meteors and slow planet drift. Keep opacity low so content remains readable.
## Validation
Run:
```bash
cd mini-program
npm run build:mp-weixin
```
Expected result: build succeeds with no new errors.
@@ -0,0 +1,39 @@
# Mini Program Script Home Layout Design
## Goal
Optimize the mini-program script generation home screen so the headline stays on one line and voice input is easier to reach.
## Approved Layout
Use the approved A layout:
1. Keep the headline text `今天有什么 心愿 想实现` on a single line.
2. Move the full `灵感一下` section above the input and voice area.
3. Move the wish text input, social insight binding card, and press-to-talk microphone below the inspiration section.
4. Keep the existing visual theme, colors, copy, analytics behavior, voice events, and generation flow unchanged.
## Implementation Notes
Only `mini-program/src/pages/main/ScriptView.vue` needs to change.
The template should reorder existing blocks instead of recreating them:
- Header and headline remain at the top.
- Inspiration section follows the headline.
- Wish input follows inspiration.
- Social insight card follows the input.
- Microphone orb and voice copy sit at the bottom of the home content.
CSS should make the headline a single flex row with no wrapping. The text must remain readable on normal mini-program widths, so the headline font size should be reduced from the current two-line hero scale to a single-line scale with `white-space: nowrap`.
## Validation
Run:
```bash
cd mini-program
npm run build:mp-weixin
```
Expected result: build succeeds with no new errors.