This commit is contained in:
voocel
2026-03-07 21:25:55 +08:00
commit 27bd85ef90
60 changed files with 5658 additions and 0 deletions

32
domain/chapter.go Normal file
View File

@@ -0,0 +1,32 @@
package domain
import (
"fmt"
"strings"
"unicode/utf8"
)
// MergeScenes 将多个场景草稿按顺序合并为完整章节正文。
// 返回合并后的正文和总字数(按 rune 计)。
func MergeScenes(scenes []SceneDraft) (string, int) {
var b strings.Builder
for i, s := range scenes {
if i > 0 {
b.WriteString("\n\n")
}
b.WriteString(s.Content)
}
content := b.String()
return content, utf8.RuneCountInString(content)
}
// ReviewInterval 全局审阅间隔(每 N 章触发一次)。
const ReviewInterval = 5
// ShouldReview 根据已完成章节数判断是否需要全局审阅。
func ShouldReview(completedCount int) (bool, string) {
if completedCount > 0 && completedCount%ReviewInterval == 0 {
return true, fmt.Sprintf("已完成 %d 章,触发全局审阅", completedCount)
}
return false, ""
}

51
domain/review.go Normal file
View File

@@ -0,0 +1,51 @@
package domain
// TimelineEvent 时间线事件。
type TimelineEvent struct {
Chapter int `json:"chapter"`
Time string `json:"time"`
Event string `json:"event"`
Characters []string `json:"characters,omitempty"`
}
// ForeshadowEntry 伏笔条目。
type ForeshadowEntry struct {
ID string `json:"id"`
Description string `json:"description"`
PlantedAt int `json:"planted_at"`
Status string `json:"status"` // planted / advanced / resolved
ResolvedAt int `json:"resolved_at,omitempty"`
}
// ForeshadowUpdate 伏笔增量操作。
type ForeshadowUpdate struct {
ID string `json:"id"`
Action string `json:"action"` // plant / advance / resolve
Description string `json:"description,omitempty"`
}
// RelationshipEntry 人物关系条目。
type RelationshipEntry struct {
CharacterA string `json:"character_a"`
CharacterB string `json:"character_b"`
Relation string `json:"relation"`
Chapter int `json:"chapter"`
}
// ConsistencyIssue 一致性问题。
type ConsistencyIssue struct {
Type string `json:"type"` // timeline / foreshadow / relationship / character
Severity string `json:"severity"` // error / warning
Description string `json:"description"`
Suggestion string `json:"suggestion,omitempty"`
}
// ReviewEntry Editor 的审阅条目。
type ReviewEntry struct {
Chapter int `json:"chapter"`
Scope string `json:"scope"` // chapter / global
Issues []ConsistencyIssue `json:"issues"`
Verdict string `json:"verdict"` // accept / polish / rewrite
Summary string `json:"summary"`
AffectedChapters []int `json:"affected_chapters,omitempty"` // 需要重写/打磨的章节号
}

73
domain/runtime.go Normal file
View File

@@ -0,0 +1,73 @@
package domain
// Phase 表示小说创作阶段。
type Phase string
const (
PhaseInit Phase = "init"
PhasePremise Phase = "premise"
PhaseOutline Phase = "outline"
PhaseWriting Phase = "writing"
PhaseComplete Phase = "complete"
)
// FlowState 当前活动流程类型,用于 checkpoint 恢复。
type FlowState string
const (
FlowWriting FlowState = "writing"
FlowReviewing FlowState = "reviewing"
FlowRewriting FlowState = "rewriting"
FlowPolishing FlowState = "polishing"
FlowSteering FlowState = "steering"
)
// Progress 进度追踪,持久化到 meta/progress.json。
type Progress struct {
NovelName string `json:"novel_name"`
Phase Phase `json:"phase"`
CurrentChapter int `json:"current_chapter"`
TotalChapters int `json:"total_chapters"`
CompletedChapters []int `json:"completed_chapters"`
TotalWordCount int `json:"total_word_count"`
ChapterWordCounts map[int]int `json:"chapter_word_counts,omitempty"` // 每章字数,支持重写时修正总字数
InProgressChapter int `json:"in_progress_chapter,omitempty"` // 正在写作的章节(场景级恢复)
CompletedScenes []int `json:"completed_scenes,omitempty"` // 当前章节已完成的场景编号
Flow FlowState `json:"flow,omitempty"` // 当前流程
PendingRewrites []int `json:"pending_rewrites,omitempty"` // 待重写章节队列
RewriteReason string `json:"rewrite_reason,omitempty"` // 重写原因
}
// IsResumable 判断是否可以从断点恢复。
func (p *Progress) IsResumable() bool {
return p.Phase == PhaseWriting && p.CurrentChapter > 0
}
// NextChapter 返回下一个要写的章节号。
func (p *Progress) NextChapter() int {
if len(p.CompletedChapters) == 0 {
return 1
}
max := 0
for _, ch := range p.CompletedChapters {
if ch > max {
max = ch
}
}
return max + 1
}
// RunMeta 运行元信息,持久化到 meta/run.json。
type RunMeta struct {
StartedAt string `json:"started_at"`
Style string `json:"style"`
Model string `json:"model"`
SteerHistory []SteerEntry `json:"steer_history,omitempty"`
PendingSteer string `json:"pending_steer,omitempty"` // 未完成的 Steer 指令,中断恢复时重新注入
}
// SteerEntry 用户干预记录。
type SteerEntry struct {
Input string `json:"input"`
Timestamp string `json:"timestamp"`
}

32
domain/story.go Normal file
View File

@@ -0,0 +1,32 @@
package domain
// Novel 小说元信息。
type Novel struct {
Name string `json:"name"`
TotalChapters int `json:"total_chapters"`
}
// OutlineEntry 大纲条目,对应一章。
type OutlineEntry struct {
Chapter int `json:"chapter"`
Title string `json:"title"`
CoreEvent string `json:"core_event"`
Hook string `json:"hook"`
Scenes []string `json:"scenes"`
}
// Character 角色档案。
type Character struct {
Name string `json:"name"`
Role string `json:"role"`
Description string `json:"description"`
Arc string `json:"arc"`
Traits []string `json:"traits"`
}
// WorldRule 世界观规则条目。
type WorldRule struct {
Category string `json:"category"` // magic / technology / geography / society / other
Rule string `json:"rule"` // 规则描述
Boundary string `json:"boundary"` // 不可违反的边界
}

48
domain/writing.go Normal file
View File

@@ -0,0 +1,48 @@
package domain
// ChapterPlan 章节规划,写入 drafts/{ch}.plan.json。
type ChapterPlan struct {
Chapter int `json:"chapter"`
Title string `json:"title"`
Goal string `json:"goal"`
Conflict string `json:"conflict"`
Scenes []ScenePlan `json:"scenes"`
Hook string `json:"hook"`
EmotionArc string `json:"emotion_arc,omitempty"`
}
// ScenePlan 场景规划。
type ScenePlan struct {
Index int `json:"index"`
Summary string `json:"summary"`
POV string `json:"pov,omitempty"`
Location string `json:"location,omitempty"`
}
// SceneDraft 场景草稿。
type SceneDraft struct {
Chapter int `json:"chapter"`
Scene int `json:"scene"`
Content string `json:"content"`
WordCount int `json:"word_count"`
}
// ChapterSummary 章节摘要,供后续章节的上下文窗口使用。
type ChapterSummary struct {
Chapter int `json:"chapter"`
Summary string `json:"summary"`
Characters []string `json:"characters"`
KeyEvents []string `json:"key_events"`
}
// CommitResult 是 commit_chapter 工具的结构化返回值。
// 宿主程序和 Coordinator 读取此信号做控制决策。
type CommitResult struct {
Chapter int `json:"chapter"`
Committed bool `json:"committed"`
WordCount int `json:"word_count"`
SceneCount int `json:"scene_count"`
NextChapter int `json:"next_chapter"`
ReviewRequired bool `json:"review_required"`
ReviewReason string `json:"review_reason,omitempty"`
}