feat: ship v0.5.0 with auto and wizard writing modes

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-06 20:57:31 +08:00
parent 86b66a311a
commit 6a949b54ba
38 changed files with 2581 additions and 184 deletions
@@ -1,6 +1,6 @@
# 笔临 P4.1 自动写作 + 向导式写作 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.
> **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 (`- [x]`) syntax for tracking.
**Goal:** 交付 v0.5.0:实装自动写作(§6.5.2)与向导式写作(§6.5.3),统一写作流引擎扩展 P4;补齐三模式成章 AI 快照。
@@ -65,7 +65,7 @@
- Modify: `src/shared/ipc-channels.ts`
- Create: `tests/main/migrate-v5.test.ts`
- [ ] **Step 1: 写迁移失败测试**
- [x] **Step 1: 写迁移失败测试**
`tests/main/migrate-v5.test.ts`
@@ -114,7 +114,7 @@ describe('migrate v5', () => {
})
```
- [ ] **Step 2: 运行确认 FAIL**
- [x] **Step 2: 运行确认 FAIL**
```bash
npm run test -- tests/main/migrate-v5.test.ts
@@ -122,14 +122,14 @@ npm run test -- tests/main/migrate-v5.test.ts
Expected: FAILversion 仍为 4 或列不存在)
- [ ] **Step 3: 创建 `schema-v5.sql`**
- [x] **Step 3: 创建 `schema-v5.sql`**
```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 '{}';
```
- [ ] **Step 4: 更新 `migrate.ts`**
- [x] **Step 4: 更新 `migrate.ts`**
```typescript
import schemaV5 from './schema-v5.sql?raw'
@@ -148,7 +148,7 @@ if (current < 5) {
}
```
- [ ] **Step 5: `types.ts` 追加类型**
- [x] **Step 5: `types.ts` 追加类型**
```typescript
export type WritingFlowMode = 'interactive' | 'auto' | 'wizard'
@@ -219,7 +219,7 @@ export interface InteractiveStreamChunkEvent {
}
```
- [ ] **Step 6: `ipc-channels.ts` 追加**
- [x] **Step 6: `ipc-channels.ts` 追加**
```typescript
AUTO_CHECK_GATE: 'auto:checkGate',
@@ -247,13 +247,13 @@ WIZARD_HANDOFF_INTERACTIVE: 'wizard:handoffInteractive',
WIZARD_ABORT: 'wizard:abort',
```
- [ ] **Step 7: 运行测试 PASS**
- [x] **Step 7: 运行测试 PASS**
```bash
npm run test -- tests/main/migrate-v5.test.ts
```
- [ ] **Step 8: Commit**
- [x] **Step 8: Commit**
```bash
git add src/main/db/schema-v5.sql src/main/db/migrate.ts src/shared/types.ts src/shared/ipc-channels.ts tests/main/migrate-v5.test.ts
@@ -267,7 +267,7 @@ git commit -m "feat: add schema v5 and auto/wizard shared types"
**Files:**
- Modify: `src/main/db/repositories/interactive.repo.ts`
- [ ] **Step 1: 扩展 `create` 支持 flow_mode**
- [x] **Step 1: 扩展 `create` 支持 flow_mode**
```typescript
create(sessionId: string, flowMode: WritingFlowMode = 'interactive', initialStep?: WritingStep): InteractiveFlow {
@@ -288,7 +288,7 @@ resetInProgress(sessionId: string, flowMode: WritingFlowMode = 'interactive'): I
}
```
- [ ] **Step 2: 泛化 `updateStep`**
- [x] **Step 2: 泛化 `updateStep`**
```typescript
updateStep(
@@ -308,7 +308,7 @@ updateStep(
在 patch 中若 `modeConfigJson` / `flowMode` 有值则追加 SET。
- [ ] **Step 3: mode_config 读写**
- [x] **Step 3: mode_config 读写**
```typescript
getModeConfig<T extends AutoWritingConfig | WizardWritingConfig>(flowId: string): T {
@@ -329,7 +329,7 @@ setModeConfig(flowId: string, config: AutoWritingConfig | WizardWritingConfig):
}
```
- [ ] **Step 4: 更新 `mapFlow`**
- [x] **Step 4: 更新 `mapFlow`**
```typescript
private mapFlow(row: Record<string, unknown>): InteractiveFlow {
@@ -352,7 +352,7 @@ private mapFlow(row: Record<string, unknown>): InteractiveFlow {
}
```
- [ ] **Step 5: 运行现有 migrate + gate 测试**
- [x] **Step 5: 运行现有 migrate + gate 测试**
```bash
npm run test -- tests/main/migrate-v4.test.ts tests/main/interactive-gate.test.ts
@@ -360,7 +360,7 @@ npm run test -- tests/main/migrate-v4.test.ts tests/main/interactive-gate.test.t
Expected: PASS
- [ ] **Step 6: Commit**
- [x] **Step 6: Commit**
```bash
git add src/main/db/repositories/interactive.repo.ts
@@ -376,7 +376,7 @@ git commit -m "feat: extend InteractiveRepository for flow_mode and mode_config"
- Create: `src/main/services/auto-prompt-builder.service.ts`
- Create: `tests/main/auto-parse.test.ts`
- [ ] **Step 1: 写解析单元测试(无 AI)**
- [x] **Step 1: 写解析单元测试(无 AI)**
`tests/main/auto-parse.test.ts`
@@ -404,7 +404,7 @@ describe('parseScenePlanJson', () => {
})
```
- [ ] **Step 2: 实现 `auto-parse.service.ts`**
- [x] **Step 2: 实现 `auto-parse.service.ts`**
```typescript
import type { ScenePlanItem } from '../../shared/types'
@@ -440,7 +440,7 @@ export function parseScenePlanJson(response: string): ScenePlanResult {
}
```
- [ ] **Step 3: 实现 `auto-prompt-builder.service.ts`**
- [x] **Step 3: 实现 `auto-prompt-builder.service.ts`**
导出三个函数(参考 P4 `interactive-prompt-builder.service.ts` 风格):
@@ -469,7 +469,7 @@ export function buildWizardPreviewMessages(
system prompt 约束:plan 返回 JSON `{ scenes, estimatedWords }`scene 返回 HTMLpreview 返回一段中文 HTML `<p>…</p>`
- [ ] **Step 4: 运行 PASS + Commit**
- [x] **Step 4: 运行 PASS + Commit**
```bash
npm run test -- tests/main/auto-parse.test.ts
@@ -488,7 +488,7 @@ git commit -m "feat: add auto scene plan parse and prompt builder"
- Modify: `src/main/services/interactive-writing.service.ts`
- Create: `tests/main/chapter-finish-snapshot.test.ts`
- [ ] **Step 1: 写快照失败测试**
- [x] **Step 1: 写快照失败测试**
`tests/main/chapter-finish-snapshot.test.ts`
@@ -535,7 +535,7 @@ describe('ChapterFinishService', () => {
})
```
- [ ] **Step 2: 实现 `chapter-finish.service.ts`**
- [x] **Step 2: 实现 `chapter-finish.service.ts`**
```typescript
export class ChapterFinishService {
@@ -564,7 +564,7 @@ export class ChapterFinishService {
}
```
- [ ] **Step 3: 实现 `writing-flow-handoff.service.ts`**
- [x] **Step 3: 实现 `writing-flow-handoff.service.ts`**
```typescript
export function handoffToInteractive(repo: InteractiveRepository, flowId: string): InteractiveFlow {
@@ -577,7 +577,7 @@ export function handoffToInteractive(repo: InteractiveRepository, flowId: string
}
```
- [ ] **Step 4: 实现 `scene-generation-core.service.ts`**
- [x] **Step 4: 实现 `scene-generation-core.service.ts`**
`InteractiveWritingService.generateScene` / `resolveNaming` 抽取:
@@ -604,17 +604,17 @@ export class SceneGenerationCore {
}
```
- [ ] **Step 5: 重构 `interactive-writing.service.ts`**
- [x] **Step 5: 重构 `interactive-writing.service.ts`**
`finishChapter` 改为调用 `ChapterFinishService.finishFromFlow(..., 'interactive', '交互写作成章')`
- [ ] **Step 6: 运行测试 PASS**
- [x] **Step 6: 运行测试 PASS**
```bash
npm run test -- tests/main/chapter-finish-snapshot.test.ts tests/main/interactive-finish.test.ts
```
- [ ] **Step 7: Commit**
- [x] **Step 7: Commit**
```bash
git add src/main/services/scene-generation-core.service.ts src/main/services/writing-flow-handoff.service.ts src/main/services/chapter-finish.service.ts src/main/services/interactive-writing.service.ts tests/main/chapter-finish-snapshot.test.ts
@@ -631,7 +631,7 @@ git commit -m "feat: add chapter finish with ai snapshot and scene generation co
- Create: `tests/main/auto-generate.test.ts`
- Create: `tests/main/auto-handoff.test.ts`
- [ ] **Step 1: IT-AUTO-01 集成测试**
- [x] **Step 1: IT-AUTO-01 集成测试**
`tests/main/auto-plan.test.ts`240s,真实 LM Studio):
@@ -642,7 +642,7 @@ it('IT-AUTO-01: planScenes returns >=2 scenes', async () => {
}, 240_000)
```
- [ ] **Step 2: 实现 `AutoWritingService`**
- [x] **Step 2: 实现 `AutoWritingService`**
核心方法按 spec §4.2
@@ -692,12 +692,12 @@ export class AutoWritingService {
}
```
- [ ] **Step 3: IT-AUTO-02/03/04 测试**
- [x] **Step 3: IT-AUTO-02/03/04 测试**
`auto-generate.test.ts`generateNext 写入 scenepause/resume step 断言。
`auto-handoff.test.ts`handoff 后 `flowMode==='interactive'`(无 AI)。
- [ ] **Step 4: 运行 PASS + Commit**
- [x] **Step 4: 运行 PASS + Commit**
```bash
npm run test -- tests/main/auto-plan.test.ts tests/main/auto-generate.test.ts tests/main/auto-handoff.test.ts
@@ -713,7 +713,7 @@ git commit -m "feat: add AutoWritingService with plan and generate"
- Create: `tests/main/wizard-preview.test.ts`
- Create: `tests/main/wizard-generate.test.ts`
- [ ] **Step 1: IT-WIZ-01 集成测试**
- [x] **Step 1: IT-WIZ-01 集成测试**
`wizard-preview.test.ts`240s):
@@ -724,7 +724,7 @@ it('IT-WIZ-01: buildPreview returns non-empty HTML', async () => {
}, 240_000)
```
- [ ] **Step 2: 实现 `WizardWritingService`**
- [x] **Step 2: 实现 `WizardWritingService`**
```typescript
export class WizardWritingService {
@@ -760,11 +760,11 @@ export class WizardWritingService {
}
```
- [ ] **Step 3: IT-WIZ-02 集成测试**300s
- [x] **Step 3: IT-WIZ-02 集成测试**300s
生成完成后 `flow.flowMode === 'interactive'``scenes.length >= 1`
- [ ] **Step 4: 运行 PASS + Commit**
- [x] **Step 4: 运行 PASS + Commit**
```bash
npm run test -- tests/main/wizard-preview.test.ts tests/main/wizard-generate.test.ts
@@ -782,7 +782,7 @@ git commit -m "feat: add WizardWritingService with preview and generate handoff"
- Modify: `src/preload/index.ts`
- Modify: `src/shared/electron-api.d.ts`
- [ ] **Step 1: 实现 `registerAutoHandlers`**
- [x] **Step 1: 实现 `registerAutoHandlers`**
参照 `interactive.handler.ts`
@@ -791,12 +791,12 @@ git commit -m "feat: add WizardWritingService with preview and generate handoff"
- `AUTO_CHECK_GATE`:调用 `checkInteractiveGate`
- `AUTO_HANDOFF_INTERACTIVE`:返回 enrich 后 flow
- [ ] **Step 2: 实现 `registerWizardHandlers`**
- [x] **Step 2: 实现 `registerWizardHandlers`**
- `WIZARD_START_GENERATE`:流式 + 完成后 flow 已 handoff
- 其余为同步 invoke
- [ ] **Step 3: `register.ts` 注册**
- [x] **Step 3: `register.ts` 注册**
```typescript
import { registerAutoHandlers } from './handlers/auto.handler'
@@ -806,7 +806,7 @@ registerAutoHandlers(books, settings, aiClient)
registerWizardHandlers(books, settings, aiClient)
```
- [ ] **Step 4: preload 暴露命名空间**
- [x] **Step 4: preload 暴露命名空间**
```typescript
auto: {
@@ -819,7 +819,7 @@ wizard: { /* 对称 */ },
onInteractiveStreamChunk: (callback) => { /* 已有,payload 含 flowMode */ }
```
- [ ] **Step 5: Commit**
- [x] **Step 5: Commit**
```bash
git add src/main/ipc/handlers/auto.handler.ts src/main/ipc/handlers/wizard.handler.ts src/main/ipc/register.ts src/preload/index.ts src/shared/electron-api.d.ts
@@ -838,7 +838,7 @@ git commit -m "feat: add auto and wizard IPC handlers and preload API"
- Modify: `src/renderer/components/ai/AiPanel.tsx`
- Modify: `src/renderer/styles/layout.css`
- [ ] **Step 1: `useAutoStore`**
- [x] **Step 1: `useAutoStore`**
参照 `useInteractiveStore.ts`
@@ -863,22 +863,22 @@ interface AutoState {
}
```
- [ ] **Step 2: `useWizardStore`**
- [x] **Step 2: `useWizardStore`**
```typescript
// wizardGoal / setRhythm / setPov / confirmContext / buildPreview / startGenerate
// startGenerate 完成后:useAiStore.setWritingMode('interactive') + showToast
```
- [ ] **Step 3: `AutoPanel.tsx`**
- [x] **Step 3: `AutoPanel.tsx`**
按 spec §7.2 实现全部 `data-testid`;步骤条;`goal_setup` / `scene_plan` / `auto_generate` / `paused` 分支 UI。
- [ ] **Step 4: `WizardPanel.tsx`**
- [x] **Step 4: `WizardPanel.tsx`**
5 步 wizard UI;步骤 4 按钮 `onClick={() => setContextOpen(true)}` 打开 `ContextEditorModal`;步骤 5 展示 `strategyPreview` HTML。
- [ ] **Step 5: 修改 `AiPanel.tsx`**
- [x] **Step 5: 修改 `AiPanel.tsx`**
移除 auto/wizard 的 `comingSoon``handleModeClick` 仿 interactive
@@ -904,11 +904,11 @@ if (mode === 'auto' || mode === 'wizard') {
Tab disabled`mode.id === 'auto' && !useAutoStore.gateEligible`wizard 同理)。
- [ ] **Step 6: CSS**
- [x] **Step 6: CSS**
`.auto-panel``.wizard-panel``.wizard-step-indicator``.auto-step-bar`(复用 `.interactive-step-bar` 模式)。
- [ ] **Step 7: Commit**
- [x] **Step 7: Commit**
```bash
git add src/renderer/stores/useAutoStore.ts src/renderer/stores/useWizardStore.ts src/renderer/components/ai/AutoPanel.tsx src/renderer/components/ai/WizardPanel.tsx src/renderer/components/ai/AiPanel.tsx src/renderer/styles/layout.css
@@ -923,7 +923,7 @@ git commit -m "feat: add AutoPanel and WizardPanel UI"
- Modify: `public/locales/zh-CN/translation.json`
- Modify: `public/locales/en/translation.json`
- [ ] **Step 1: 追加文案键**
- [x] **Step 1: 追加文案键**
zh-CN 示例:
@@ -952,7 +952,7 @@ zh-CN 示例:
}
```
- [ ] **Step 2: Commit**
- [x] **Step 2: Commit**
```bash
git add public/locales/zh-CN/translation.json public/locales/en/translation.json
@@ -967,7 +967,7 @@ git commit -m "feat: add auto and wizard i18n strings"
- Create: `e2e/auto-writing.spec.ts`
- Create: `e2e/wizard-writing.spec.ts`
- [ ] **Step 1: E2E-AUTO-03(门槛,无 AI**
- [x] **Step 1: E2E-AUTO-03(门槛,无 AI**
```typescript
test('E2E-AUTO-03: auto tab disabled on empty book', async () => {
@@ -975,7 +975,7 @@ test('E2E-AUTO-03: auto tab disabled on empty book', async () => {
})
```
- [ ] **Step 2: E2E-AUTO-01(完整流程,300s**
- [x] **Step 2: E2E-AUTO-01(完整流程,300s**
```typescript
test('E2E-AUTO-01: auto flow creates chapter', async () => {
@@ -984,7 +984,7 @@ test('E2E-AUTO-01: auto flow creates chapter', async () => {
})
```
- [ ] **Step 3: E2E-AUTO-02(暂停转交互,300s**
- [x] **Step 3: E2E-AUTO-02(暂停转交互,300s**
```typescript
test('E2E-AUTO-02: pause and handoff to interactive', async () => {
@@ -992,7 +992,7 @@ test('E2E-AUTO-02: pause and handoff to interactive', async () => {
})
```
- [ ] **Step 4: E2E-WIZ-01(向导 300s**
- [x] **Step 4: E2E-WIZ-01(向导 300s**
```typescript
test('E2E-WIZ-01: wizard flow reaches interactive panel', async () => {
@@ -1002,13 +1002,13 @@ test('E2E-WIZ-01: wizard flow reaches interactive panel', async () => {
})
```
- [ ] **Step 5: 运行 E2E**
- [x] **Step 5: 运行 E2E**
```bash
npm run test:e2e -- e2e/auto-writing.spec.ts e2e/wizard-writing.spec.ts
```
- [ ] **Step 6: Commit**
- [x] **Step 6: Commit**
```bash
git add e2e/auto-writing.spec.ts e2e/wizard-writing.spec.ts
@@ -1025,16 +1025,16 @@ git commit -m "test: add auto and wizard writing E2E specs"
- Modify: `src/renderer/components/settings/SettingsPage.tsx`
- Modify: `docs/superpowers/plans/2026-07-09-bilin-p41-auto-wizard.md`(勾选完成项)
- [ ] **Step 1: 版本号 → `0.5.0`**
- [x] **Step 1: 版本号 → `0.5.0`**
- [ ] **Step 2: README 功能概览追加 P4.1**
- [x] **Step 2: README 功能概览追加 P4.1**
```markdown
- 自动写作:章节目标、场景规划、连续生成、暂停转交互(P4.1)
- 向导式写作:5 步引导、策略预览、生成后交互微调(P4.1)
```
- [ ] **Step 3: 全量测试**
- [x] **Step 3: 全量测试**
```bash
npm run test
@@ -1044,7 +1044,7 @@ npm run test:e2e
Expected: 单元全部 PASSauto/wizard E2E PASSLM Studio 运行中)
- [ ] **Step 4: Commit**
- [x] **Step 4: Commit**
```bash
git commit -m "chore: release v0.5.0 with auto and wizard writing modes"