docs: add P4.1 auto and wizard writing design spec for v0.5.0
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,482 @@
|
|||||||
|
# 笔临 P4.1 自动写作 + 向导式写作设计规格
|
||||||
|
|
||||||
|
**版本**:1.0
|
||||||
|
**日期**:2026-07-09
|
||||||
|
**范围**:P4.1 — 实装 §6.5.2 自动写作 + §6.5.3 向导式写作(统一写作流引擎)
|
||||||
|
**前置**:P4 交互式写作已交付(v0.4.0,`a8e0ba9`)
|
||||||
|
**参考**:`design/readme.md` v1.1 §6.5.2–§6.5.3、`design/ui_pc.html` AI 面板模式 Tab
|
||||||
|
|
||||||
|
**目标版本**:v0.5.0
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 背景与目标
|
||||||
|
|
||||||
|
### 1.1 阶段定位
|
||||||
|
|
||||||
|
v0.4.0 已交付交互式写作(§6.5.1);「自动写作」「向导」Tab 仍为 `feature.comingSoon` 占位。本阶段在同一 AI 会话体系下实装:
|
||||||
|
|
||||||
|
- **自动写作**:用户设定章节目标与字数范围 → AI 规划场景顺序 → 连续流式生成 → 达标或手动停止 → 成章落盘
|
||||||
|
- **向导式写作**:5 步引导收集参数 → AI 策略预览 → 自动生成 → **handoff 至交互面板**做场景微调
|
||||||
|
|
||||||
|
两模式共享 P4 的场景存储、命名暂停、流式推送与成章逻辑,并通过 **handoff** 与交互写作衔接。
|
||||||
|
|
||||||
|
### 1.2 已确认决策(Brainstorming 2026-07-09)
|
||||||
|
|
||||||
|
| 维度 | 决策 |
|
||||||
|
|------|------|
|
||||||
|
| 范围 | **P4.1**:§6.5.2 + §6.5.3 同时交付;§6.3 / §6.6 / §6.7 仍排除 |
|
||||||
|
| 架构 | **方案 1**:统一写作流引擎,扩展 P4 表与 Service,不重写 |
|
||||||
|
| 向导第 4 步 | **选项 A**:复用 `ContextEditorModal` 确认上下文(含大纲/设定中的伏笔线索),不引入知识库表 |
|
||||||
|
| 向导风格 | 节奏三选一(舒缓/紧张/混合)+ 可选自由文本 `styleNote`;**不做**文风滑杆 |
|
||||||
|
| 向导生成后 | 自动切入 **InteractivePanel**(toast「已进入交互微调」) |
|
||||||
|
| 自动暂停 | 可「继续自动」或「转入交互微调」(handoff,保留 scenes) |
|
||||||
|
| 成章落盘 | 活跃卷新建章节;`origin=auto` 或 `origin=wizard`;合并全部场景 HTML |
|
||||||
|
| AI 快照 | 成章时创建 `type='ai'` 快照(标签「自动写作成章」/「向导写作成章」;**顺带补齐** P4 interactive 成章快照) |
|
||||||
|
| 状态持久化 | **schema v5**:`interactive_flows` 增 `flow_mode` / `mode_config_json`;`interactive_scenes` 不变 |
|
||||||
|
| 启动门槛 | **硬拦截**:复用 P4 `checkInteractiveGate` 逻辑(无正文且无大纲/设定时 Tab 禁用) |
|
||||||
|
| 同会话 flow | 每 `session_id` 仅一个 `status=in_progress` flow;按 `flow_mode` 区分模式 |
|
||||||
|
| AI 后端 | **LM Studio**(延续 P3/P4),`http://127.0.0.1:1234`,`gemma-4-e4b-it` |
|
||||||
|
| 测试原则 | **禁止 Mock**;集成 / E2E 打真实 LM Studio |
|
||||||
|
| 测试超时 | Vitest AI 用例 **240s**;Playwright 全局 **180s**;auto/wizard E2E **300s** |
|
||||||
|
|
||||||
|
### 1.3 验收标准
|
||||||
|
|
||||||
|
用户能完成:
|
||||||
|
|
||||||
|
1. 在有足够上下文的书籍中进入「自动写作」或「向导」Tab(门槛不满足时 Tab 禁用并 tooltip 提示)
|
||||||
|
2. **自动写作**:设定本章目标(大纲选取和/或手写)+ 目标字数范围 → AI 返回场景规划 → 连续流式生成场景(支持命名暂停)→ 字数达范围或点击「结束本章」→ 新建章节 `origin=auto`,编辑器自动打开
|
||||||
|
3. **自动写作干预**:生成中点击「暂停」→ flow 进入 `paused`;可「继续自动」或「转入交互微调」→ 交互面板可见已生成场景并可微调/续写
|
||||||
|
4. **向导写作**:依次完成 5 步(目标 → 节奏/风格 → 视角人物 → 上下文确认 → 策略预览)→ 确认后开始生成 → 生成完成后自动显示交互面板,可微调场景
|
||||||
|
5. 向导成章后章节 `origin=wizard`;自动成章 `origin=auto`
|
||||||
|
6. 关闭应用并重启后,未完成的 auto/wizard flow 恢复到上次步骤
|
||||||
|
7. 切换回「对话」模式时同会话聊天历史仍可见;再次进入 auto/wizard/interactive 时 **恢复已有 flow**(不无条件 reset)
|
||||||
|
8. 所有成章路径均创建 `type='ai'` 快照
|
||||||
|
|
||||||
|
### 1.4 本规格不实现(明确排除)
|
||||||
|
|
||||||
|
| 项 | 归属 |
|
||||||
|
|----|------|
|
||||||
|
| §6.3 文风学习与风格滑杆 | P4.2+ |
|
||||||
|
| §6.6 大纲生成章节骨架 | P4.2+(可独立 spec) |
|
||||||
|
| §6.7 知识自动抽取与审核工作流 | P4.2+ |
|
||||||
|
| §6.4 Skill / MCP | P4+ |
|
||||||
|
| 知识库伏笔追踪 UI | P4.2+ / P5 |
|
||||||
|
| 导入导出、驾驶舱等 | P5+ |
|
||||||
|
| 命名结果自动写入设定库 | 本阶段仅写入正文 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 架构
|
||||||
|
|
||||||
|
### 2.1 进程模型
|
||||||
|
|
||||||
|
```
|
||||||
|
┌──────────────────────────────────────────────────────────────────┐
|
||||||
|
│ 主进程 │
|
||||||
|
│ · schema v5:interactive_flows.flow_mode / mode_config_json │
|
||||||
|
│ · chapters.origin:manual | interactive | auto | wizard │
|
||||||
|
│ · SceneGenerationCore(从 P4 抽取:流式、命名暂停、HTML 规范化) │
|
||||||
|
│ · AutoWritingService(目标→规划→连续生成→暂停/成章/handoff) │
|
||||||
|
│ · WizardWritingService(5 步→策略预览→委托 Auto→handoff) │
|
||||||
|
│ · InteractiveWritingService(P4 不变;handoff 目标) │
|
||||||
|
│ · checkWritingGate(复用 interactive-gate 逻辑,三模式共用) │
|
||||||
|
│ · AiClientService / AiContextBuilder(复用) │
|
||||||
|
│ · IPC:auto:* / wizard:* + interactive:streamChunk(增 flowMode) │
|
||||||
|
└────────────────────────────┬─────────────────────────────────────┘
|
||||||
|
│ contextBridge
|
||||||
|
┌────────────────────────────▼─────────────────────────────────────┐
|
||||||
|
│ 渲染进程 │
|
||||||
|
│ · AiPanel:writingMode=auto|wizard 时挂载 AutoPanel/WizardPanel │
|
||||||
|
│ · handoff 后 writingMode 保持或切 interactive,显示 InteractivePanel│
|
||||||
|
│ · useAutoStore / useWizardStore + useInteractiveStore │
|
||||||
|
│ · ContextEditorModal(向导步骤 4 + 自动可选编辑上下文) │
|
||||||
|
└────────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
**约束**(延续 P0–P4):
|
||||||
|
|
||||||
|
- 渲染进程禁止直接 `fetch` AI API
|
||||||
|
- 流式通过 `webContents.send` 推送,不阻塞 IPC invoke
|
||||||
|
- 写作 flow 绑定 `ai_session_id`;关键轮次可写入 `ai_messages` 作审计(可选,非阻塞)
|
||||||
|
|
||||||
|
### 2.2 Handoff 规则
|
||||||
|
|
||||||
|
从 `auto` 或 `wizard` 转入交互微调时:
|
||||||
|
|
||||||
|
1. `interactive_scenes` 列表 **不变**
|
||||||
|
2. `flow_mode` 更新为 `'interactive'`
|
||||||
|
3. `step` 设为:
|
||||||
|
- 若 `scene_draft_html` 非空 → `'scene_review'`
|
||||||
|
- 否则若已有 scenes → `'plot_suggest'`(进入下一场景循环)
|
||||||
|
- 否则 → `'context_confirm'`
|
||||||
|
4. `mode_config_json` 保留(只读参考),不删除
|
||||||
|
5. 渲染进程 `setWritingMode('interactive')` + toast
|
||||||
|
|
||||||
|
自动模式 **暂停**(非 handoff)时:`step='paused'`,`flow_mode` 仍为 `'auto'`。
|
||||||
|
|
||||||
|
### 2.3 步骤机
|
||||||
|
|
||||||
|
#### 2.3.1 interactive(P4 不变)
|
||||||
|
|
||||||
|
| Step | 名称 |
|
||||||
|
|------|------|
|
||||||
|
| `context_confirm` | 上下文确认 |
|
||||||
|
| `plot_suggest` | 剧情走向 |
|
||||||
|
| `plot_select` | 用户选择 |
|
||||||
|
| `scene_generate` | 场景生成 |
|
||||||
|
| `naming_pause` | 命名暂停 |
|
||||||
|
| `scene_review` | 场景确认/微调 |
|
||||||
|
| `completed` | 成章完成 |
|
||||||
|
|
||||||
|
#### 2.3.2 auto
|
||||||
|
|
||||||
|
| Step | 名称 | AI |
|
||||||
|
|------|------|-----|
|
||||||
|
| `goal_setup` | 目标/字数/大纲 | 无 |
|
||||||
|
| `scene_plan` | 等待用户触发规划 | JSON 场景列表 |
|
||||||
|
| `auto_generate` | 连续生成(含 naming_pause 子状态) | 流式 |
|
||||||
|
| `paused` | 用户暂停 | 无 |
|
||||||
|
| `completed` | 成章完成 | 无 |
|
||||||
|
|
||||||
|
生成循环:按 `scenePlan` 顺序逐场景生成;每场景完成后追加 `interactive_scenes`;累计字数(stripHtml 计)≥ `wordMin` 且 AI 判定目标达成或用户点击「结束本章」时停止。
|
||||||
|
|
||||||
|
#### 2.3.3 wizard
|
||||||
|
|
||||||
|
| Step | 名称 | AI |
|
||||||
|
|------|------|-----|
|
||||||
|
| `wizard_goal` | 步骤 1:本章目标 | 无 |
|
||||||
|
| `wizard_rhythm` | 步骤 2:节奏 + styleNote | 无 |
|
||||||
|
| `wizard_pov` | 步骤 3:视角人物(设定 character) | 无 |
|
||||||
|
| `wizard_context` | 步骤 4:ContextEditorModal | 无 |
|
||||||
|
| `wizard_preview` | 步骤 5:策略预览 | 非流式摘要 |
|
||||||
|
| `wizard_generating` | 委托 Auto 引擎生成 | 流式 |
|
||||||
|
| → handoff | 见 §2.2 | — |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Schema v5
|
||||||
|
|
||||||
|
### 3.1 DDL(每本书 `.sqlite`)
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- schema-v5.sql
|
||||||
|
ALTER TABLE interactive_flows ADD COLUMN flow_mode TEXT NOT NULL DEFAULT 'interactive';
|
||||||
|
ALTER TABLE interactive_flows ADD COLUMN mode_config_json TEXT NOT NULL DEFAULT '{}';
|
||||||
|
|
||||||
|
-- chapters.origin 在应用层扩展为 manual | interactive | auto | wizard
|
||||||
|
-- v4 已有 origin 列,v5 迁移不 ALTER(字符串枚举扩展)
|
||||||
|
```
|
||||||
|
|
||||||
|
`migrate.ts`:`CURRENT_VERSION=5`;v4→v5 应用上述 ALTER。
|
||||||
|
|
||||||
|
### 3.2 mode_config_json
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export type WritingFlowMode = 'interactive' | 'auto' | 'wizard'
|
||||||
|
|
||||||
|
export type AutoRhythm = 'relaxed' | 'tense' | 'mixed'
|
||||||
|
|
||||||
|
export interface ScenePlanItem {
|
||||||
|
label: string
|
||||||
|
summary: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AutoWritingConfig {
|
||||||
|
chapterGoal: string
|
||||||
|
outlineItemIds?: string[]
|
||||||
|
wordMin: number // 默认 2000
|
||||||
|
wordMax: number // 默认 4000
|
||||||
|
scenePlan?: ScenePlanItem[]
|
||||||
|
currentPlanIndex?: number // auto_generate 进度
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WizardWritingConfig extends AutoWritingConfig {
|
||||||
|
rhythm: AutoRhythm
|
||||||
|
styleNote?: string
|
||||||
|
povSettingId?: string
|
||||||
|
strategyPreview?: string // HTML
|
||||||
|
contextBinding?: AiContextBinding // 步骤 4 确认结果
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 共享类型扩展
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export type ChapterOrigin = 'manual' | 'interactive' | 'auto' | 'wizard'
|
||||||
|
|
||||||
|
export type AutoStep =
|
||||||
|
| 'goal_setup'
|
||||||
|
| 'scene_plan'
|
||||||
|
| 'auto_generate'
|
||||||
|
| 'paused'
|
||||||
|
| 'completed'
|
||||||
|
|
||||||
|
export type WizardStep =
|
||||||
|
| 'wizard_goal'
|
||||||
|
| 'wizard_rhythm'
|
||||||
|
| 'wizard_pov'
|
||||||
|
| 'wizard_context'
|
||||||
|
| 'wizard_preview'
|
||||||
|
| 'wizard_generating'
|
||||||
|
|
||||||
|
// InteractiveFlow 扩展:
|
||||||
|
// flowMode: WritingFlowMode
|
||||||
|
// modeConfig: AutoWritingConfig | WizardWritingConfig | Record<string, never>
|
||||||
|
// step: InteractiveStep | AutoStep | WizardStep
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 服务层
|
||||||
|
|
||||||
|
### 4.1 SceneGenerationCore
|
||||||
|
|
||||||
|
从 `InteractiveWritingService` 抽取(或内部组合):
|
||||||
|
|
||||||
|
- `generateSceneStream(flowId, planItem, config, onChunk, signal)`
|
||||||
|
- `resolveNaming(flowId, chosenName, ...)`
|
||||||
|
- `normalizeSceneHtml(raw: string): string`
|
||||||
|
- 命名暂停检测:复用 `tryParseNamingFromBuffer`
|
||||||
|
|
||||||
|
### 4.2 AutoWritingService
|
||||||
|
|
||||||
|
| 方法 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `start(sessionId)` | 创建 `flow_mode=auto`, `step=goal_setup` |
|
||||||
|
| `getFlow(sessionId)` | 按 session 查 in_progress |
|
||||||
|
| `setGoal(flowId, config: Partial<AutoWritingConfig>)` | 写入 mode_config,`step=scene_plan` |
|
||||||
|
| `planScenes(flowId)` | AI JSON → `scenePlan`,`step=auto_generate` |
|
||||||
|
| `generateNext(flowId, onChunk, signal)` | 生成当前 plan 项;处理 naming;追加 scene;更新 index |
|
||||||
|
| `pause(flowId)` | `step=paused`,abort 进行中的生成 |
|
||||||
|
| `resume(flowId)` | `step=auto_generate`,继续下一项 |
|
||||||
|
| `handoffToInteractive(flowId)` | §2.2 |
|
||||||
|
| `finishChapter(flowId, volumeId, title?)` | 合并 scenes → 新建章 `origin=auto` + AI 快照 |
|
||||||
|
| `shouldStop(flowId)` | 字数 ≥ wordMin 且(最后一项 plan 完成 或 AI 返回 stop 标记) |
|
||||||
|
|
||||||
|
### 4.3 WizardWritingService
|
||||||
|
|
||||||
|
| 方法 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `start(sessionId)` | `flow_mode=wizard`, `step=wizard_goal` |
|
||||||
|
| `setGoal` / `setRhythm` / `setPov` | 逐步写入 mode_config,推进 step |
|
||||||
|
| `confirmContext(flowId, binding)` | 步骤 4;`step=wizard_preview` |
|
||||||
|
| `buildPreview(flowId)` | AI 生成 strategyPreview HTML |
|
||||||
|
| `startGenerate(flowId, onChunk, signal)` | `step=wizard_generating`;构建 AutoWritingConfig 并调用 AutoWritingService 全量生成 |
|
||||||
|
| `handoffToInteractive(flowId)` | 生成完成后自动调用 §2.2 |
|
||||||
|
|
||||||
|
### 4.4 成章与快照(三模式统一)
|
||||||
|
|
||||||
|
`finishChapter` 路径均:
|
||||||
|
|
||||||
|
1. 合并 `interactive_scenes.content_html`
|
||||||
|
2. `chapters.create(..., origin)`
|
||||||
|
3. `snapshots.create(chapterId, merged, type='ai', label=...)`
|
||||||
|
4. `flow.status=completed`, `step=completed`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. IPC
|
||||||
|
|
||||||
|
### 5.1 通道(`ipc-channels.ts` 追加)
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// auto
|
||||||
|
AUTO_CHECK_GATE: 'auto:checkGate' // 实际复用 gate service
|
||||||
|
AUTO_GET_FLOW: 'auto:getFlow'
|
||||||
|
AUTO_START: 'auto:start'
|
||||||
|
AUTO_SET_GOAL: 'auto:setGoal'
|
||||||
|
AUTO_PLAN_SCENES: 'auto:planScenes'
|
||||||
|
AUTO_GENERATE: 'auto:generate' // 生成下一场景或批量至 pause/stop
|
||||||
|
AUTO_PAUSE: 'auto:pause'
|
||||||
|
AUTO_RESUME: 'auto:resume'
|
||||||
|
AUTO_HANDOFF_INTERACTIVE: 'auto:handoffInteractive'
|
||||||
|
AUTO_FINISH_CHAPTER: 'auto:finishChapter'
|
||||||
|
AUTO_GET_SCENE_DRAFT: 'auto:getSceneDraft'
|
||||||
|
AUTO_ABORT: 'auto:abort'
|
||||||
|
|
||||||
|
// wizard
|
||||||
|
WIZARD_GET_FLOW: 'wizard:getFlow'
|
||||||
|
WIZARD_START: 'wizard:start'
|
||||||
|
WIZARD_SET_GOAL: 'wizard:setGoal'
|
||||||
|
WIZARD_SET_RHYTHM: 'wizard:setRhythm'
|
||||||
|
WIZARD_SET_POV: 'wizard:setPov'
|
||||||
|
WIZARD_CONFIRM_CONTEXT: 'wizard:confirmContext'
|
||||||
|
WIZARD_BUILD_PREVIEW: 'wizard:buildPreview'
|
||||||
|
WIZARD_START_GENERATE: 'wizard:startGenerate'
|
||||||
|
WIZARD_HANDOFF_INTERACTIVE: 'wizard:handoffInteractive'
|
||||||
|
WIZARD_ABORT: 'wizard:abort'
|
||||||
|
```
|
||||||
|
|
||||||
|
流式事件 `interactive:streamChunk` payload 扩展:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
{ flowId, flowMode: WritingFlowMode, phase: 'scene' | 'naming' | 'refine', delta: string, done: boolean }
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 Preload / electron-api.d.ts
|
||||||
|
|
||||||
|
暴露 `window.electronAPI.auto.*` 与 `window.electronAPI.wizard.*` 命名空间。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Prompt 设计
|
||||||
|
|
||||||
|
### 6.1 场景规划(auto planScenes)
|
||||||
|
|
||||||
|
输入:章节目标、大纲条目摘要、已有上下文摘要、wordMin/wordMax。
|
||||||
|
输出 JSON:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scenes": [
|
||||||
|
{ "label": "场景1", "summary": "…≥80字…" },
|
||||||
|
{ "label": "场景2", "summary": "…" }
|
||||||
|
],
|
||||||
|
"estimatedWords": 3200
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
约束:3–6 个场景;总预估字数在 [wordMin, wordMax] 内。
|
||||||
|
|
||||||
|
### 6.2 自动场景生成
|
||||||
|
|
||||||
|
输入:当前 plan item、累计 scenes 摘要、AutoWritingConfig。
|
||||||
|
输出:HTML 段落(600–1500 字/场景);命名暂停格式同 P4。
|
||||||
|
|
||||||
|
### 6.3 向导策略预览(wizard buildPreview)
|
||||||
|
|
||||||
|
输入:WizardWritingConfig 全量 + AiContextBuilder 摘要。
|
||||||
|
输出 HTML 一段,模板语义:
|
||||||
|
|
||||||
|
> 我将以 **[视角人物]** 视角,用 **[节奏]** 节奏,写一段达成 **[目标]** 的剧情。风格说明:…。重点上下文:…。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 渲染进程 UI
|
||||||
|
|
||||||
|
### 7.1 AiPanel
|
||||||
|
|
||||||
|
- 移除 `auto` / `wizard` 的 `comingSoon`
|
||||||
|
- `handleModeClick('auto'|'wizard')`:checkGate → loadFlow → 无 flow 则 start(**不**无条件 reset 已有 flow)
|
||||||
|
- `writingMode === 'auto'` → `<AutoPanel />`
|
||||||
|
- `writingMode === 'wizard'` → `<WizardPanel />`;handoff 后 `writingMode='interactive'` → `<InteractivePanel />`
|
||||||
|
|
||||||
|
### 7.2 AutoPanel
|
||||||
|
|
||||||
|
| data-testid | 元素 |
|
||||||
|
|-------------|------|
|
||||||
|
| `auto-panel` | 根容器 |
|
||||||
|
| `auto-goal-input` | 本章目标 |
|
||||||
|
| `auto-outline-picker` | 大纲多选 |
|
||||||
|
| `auto-word-min` / `auto-word-max` | 字数范围 |
|
||||||
|
| `auto-plan-scenes` | 触发规划 |
|
||||||
|
| `auto-start-generate` | 开始/继续生成 |
|
||||||
|
| `auto-scene-preview` | 流式预览 |
|
||||||
|
| `auto-pause` | 暂停 |
|
||||||
|
| `auto-handoff-interactive` | 转入交互 |
|
||||||
|
| `auto-finish-chapter` | 结束本章 |
|
||||||
|
|
||||||
|
步骤条:`目标 → 规划 → 生成 → 完成`
|
||||||
|
|
||||||
|
### 7.3 WizardPanel
|
||||||
|
|
||||||
|
| data-testid | 元素 |
|
||||||
|
|-------------|------|
|
||||||
|
| `wizard-panel` | 根容器 |
|
||||||
|
| `wizard-step-indicator` | 1–5 步指示 |
|
||||||
|
| `wizard-goal-input` | 步骤 1 |
|
||||||
|
| `wizard-rhythm-*` | 步骤 2 节奏选项 |
|
||||||
|
| `wizard-style-note` | 步骤 2 风格说明 |
|
||||||
|
| `wizard-pov-select` | 步骤 3 |
|
||||||
|
| `wizard-context-edit` | 步骤 4 打开 ContextEditorModal |
|
||||||
|
| `wizard-preview` | 步骤 5 策略摘要 |
|
||||||
|
| `wizard-start-generate` | 开始生成 |
|
||||||
|
|
||||||
|
生成完成后隐藏 WizardPanel,显示 InteractivePanel(同 session)。
|
||||||
|
|
||||||
|
### 7.4 i18n 键(zh-CN / en)
|
||||||
|
|
||||||
|
`auto.gateBlocked`、`auto.gateTooltip`、`auto.step.*`、`auto.pause`、`auto.resume`、`auto.handoffInteractive`、`auto.finishChapter`、`auto.chapterCreated`
|
||||||
|
`wizard.step.*`、`wizard.rhythm.*`、`wizard.previewTitle`、`wizard.startGenerate`、`wizard.handoffToast`
|
||||||
|
及步骤条、placeholder、错误 toast 文案。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 错误处理
|
||||||
|
|
||||||
|
| 场景 | 行为 |
|
||||||
|
|------|------|
|
||||||
|
| planScenes JSON 解析失败 | 重试一次(追加「仅返回 JSON」);仍失败 → toast + 保持 `scene_plan` |
|
||||||
|
| 生成中用户 pause | AbortController abort;`step=paused`;已生成 scenes 保留 |
|
||||||
|
| 无活跃卷 finishChapter | IPC 错误码;toast「请先创建分卷」 |
|
||||||
|
| 离线 / 非 lmstudio 且无网络 | 同 P3/P4:disabled + offline banner |
|
||||||
|
| wizard 某步必填缺失 | 下一步按钮 disabled |
|
||||||
|
| handoff 时无 scenes 且无 draft | 仍 handoff 到 `context_confirm`,toast 提示可手动续写 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 测试
|
||||||
|
|
||||||
|
### 9.1 单元 / 集成(Vitest,真实 LM Studio)
|
||||||
|
|
||||||
|
| ID | 场景 | 超时 |
|
||||||
|
|----|------|------|
|
||||||
|
| UT-MIG-05 | v4 DB 迁移到 v5,flow_mode 列存在 | — |
|
||||||
|
| IT-AUTO-01 | planScenes 返回 ≥2 个 scene | 240s |
|
||||||
|
| IT-AUTO-02 | generateNext 写入非空 scene | 240s |
|
||||||
|
| IT-AUTO-03 | pause 后 step=paused;resume 继续 | 240s |
|
||||||
|
| IT-AUTO-04 | handoff 后 flow_mode=interactive | — |
|
||||||
|
| IT-WIZ-01 | buildPreview 非空 HTML | 240s |
|
||||||
|
| IT-WIZ-02 | startGenerate 完成后 scenes.length ≥ 1 | 300s |
|
||||||
|
| IT-FIN-01 | auto finishChapter → origin=auto + ai 快照 | — |
|
||||||
|
| IT-FIN-02 | interactive finishChapter → ai 快照(P4 补齐) | — |
|
||||||
|
|
||||||
|
### 9.2 E2E(Playwright,300s)
|
||||||
|
|
||||||
|
| ID | 场景 |
|
||||||
|
|----|------|
|
||||||
|
| E2E-AUTO-01 | 自动:设目标 → 规划 → 生成 → 成章 → 编辑器非空 |
|
||||||
|
| E2E-AUTO-02 | 自动:暂停 → 转交互 → accept scene 可见 |
|
||||||
|
| E2E-WIZ-01 | 向导 5 步 → 生成 → InteractivePanel 可见 |
|
||||||
|
| E2E-AUTO-03 | 空书 auto tab disabled(门槛,无 AI) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. 文件清单(实现参考)
|
||||||
|
|
||||||
|
| 文件 | 职责 |
|
||||||
|
|------|------|
|
||||||
|
| `src/main/db/schema-v5.sql` | v5 DDL |
|
||||||
|
| `src/main/db/migrate.ts` | v4→v5 |
|
||||||
|
| `src/main/db/repositories/interactive.repo.ts` | flow_mode / mode_config CRUD |
|
||||||
|
| `src/main/services/scene-generation-core.service.ts` | 共享生成逻辑 |
|
||||||
|
| `src/main/services/auto-writing.service.ts` | 自动写作步骤机 |
|
||||||
|
| `src/main/services/wizard-writing.service.ts` | 向导步骤机 |
|
||||||
|
| `src/main/services/auto-prompt-builder.service.ts` | plan / scene / preview prompt |
|
||||||
|
| `src/main/ipc/handlers/auto.handler.ts` | auto IPC |
|
||||||
|
| `src/main/ipc/handlers/wizard.handler.ts` | wizard IPC |
|
||||||
|
| `src/renderer/components/ai/AutoPanel.tsx` | 自动 UI |
|
||||||
|
| `src/renderer/components/ai/WizardPanel.tsx` | 向导 UI |
|
||||||
|
| `src/renderer/stores/useAutoStore.ts` | auto 状态 |
|
||||||
|
| `src/renderer/stores/useWizardStore.ts` | wizard 状态 |
|
||||||
|
| `tests/main/migrate-v5.test.ts` | 迁移 |
|
||||||
|
| `tests/main/auto-*.test.ts` | 集成 |
|
||||||
|
| `tests/main/wizard-*.test.ts` | 集成 |
|
||||||
|
| `e2e/auto-writing.spec.ts` | E2E |
|
||||||
|
| `e2e/wizard-writing.spec.ts` | E2E |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. Spec 自检
|
||||||
|
|
||||||
|
| 检查项 | 结果 |
|
||||||
|
|--------|------|
|
||||||
|
| Placeholder 扫描 | 无 TBD/TODO;排除项已列 §1.4 |
|
||||||
|
| 内部一致性 | handoff / 步骤机 / IPC / UI testid 对齐 |
|
||||||
|
| 范围 | 单阶段可交付 v0.5.0;§6.7 已通过 ContextEditor 降级 |
|
||||||
|
| 歧义 | 成章 origin 三分;同 session 单 in_progress flow;恢复 flow 不 reset |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*本规格为笔临 P4.1 子项目。知识抽取、大纲骨架等各自在后续 spec 中增量修订。*
|
||||||
Reference in New Issue
Block a user