feat: ship v0.3.0 with P2.1 editor polish and P3 AI collaboration

Add chapter reorder, search replace, inspiration capture, and AI chat with context editing, settings, offline handling, and naming checks. Fix dev black screen by keeping process.env reads in the main process only.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-06 16:33:56 +08:00
parent 0b5aa146bd
commit 8ce35a1e8e
59 changed files with 3808 additions and 100 deletions
+81
View File
@@ -60,6 +60,8 @@ export interface GlobalSettings {
snapshotMaxAuto: number
snapshotMaxPersist: number
searchHistory: string[]
aiConfig: AiConfig
namingIgnoreWords: string[]
}
export interface BookMeta {
@@ -192,3 +194,82 @@ export interface UpdateChapterParams {
status?: ChapterStatus
cursorOffset?: number
}
export type AiBackend = 'lmstudio' | 'openai' | 'anthropic'
export type AiMessageRole = 'user' | 'assistant' | 'system'
export type AiWritingMode = 'chat' | 'interactive' | 'auto' | 'wizard'
export interface AiConfig {
backend: AiBackend
baseUrl: string
model: string
apiKey?: string
timeoutMs: number
maxTokens: number
}
export const DEFAULT_AI_CONFIG: AiConfig = {
backend: 'lmstudio',
baseUrl: 'http://127.0.0.1:1234',
model: 'gemma-4-e4b-it',
timeoutMs: 60_000,
maxTokens: 2048
}
export interface AiContextBinding {
chapterIds: string[]
outlineIds: string[]
settingIds: string[]
inspirationIds: string[]
}
export interface AiSession {
id: string
title: string
model: string
archived: boolean
context: AiContextBinding
createdAt: string
updatedAt: string
}
export interface AiMessage {
id: string
sessionId: string
role: AiMessageRole
content: string
createdAt: string
}
export interface NamingConflict {
termA: string
termB: string
confidence: number
reason: string
suggestedCanonical?: string
}
export interface AiStreamChunkEvent {
messageId: string
delta: string
done: boolean
}
export interface AiNetworkStatusEvent {
online: boolean
}
export type ContextPreviewKind = 'chapter' | 'outline' | 'setting' | 'inspiration'
export interface ContextPreviewItem {
kind: ContextPreviewKind
id: string
title: string
excerpt: string
charCount: number
}
export interface AiContextBuildResult {
systemPrompt: string
preview: ContextPreviewItem[]
}