feat: deliver P2 v0.2.0 with unified editor, search, and snapshots
Implement schema v2 migration, outline/setting/inspiration CRUD, unified TipTap editing, reference panel with mentions, FTS global search, chapter version history, writing landmarks, word frequency analysis, light theme contrast fixes, and full unit/E2E test coverage. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Vendored
+125
-1
@@ -1,13 +1,24 @@
|
||||
import type {
|
||||
ActionId,
|
||||
Bookmark,
|
||||
BookMeta,
|
||||
BookOpenResult,
|
||||
Chapter,
|
||||
CreateBookParams,
|
||||
GlobalSettings,
|
||||
InspirationEntry,
|
||||
IpcResult,
|
||||
LandmarkType,
|
||||
OutlineItem,
|
||||
OutlineStatus,
|
||||
SearchResult,
|
||||
SettingEntry,
|
||||
SettingType,
|
||||
Snapshot,
|
||||
SnapshotType,
|
||||
UpdateChapterParams,
|
||||
Volume
|
||||
Volume,
|
||||
WordFreqResult
|
||||
} from './types'
|
||||
|
||||
export interface ElectronAPI {
|
||||
@@ -45,6 +56,119 @@ export interface ElectronAPI {
|
||||
update: (params: UpdateChapterParams) => Promise<IpcResult<Chapter>>
|
||||
delete: (bookId: string, chapterId: string) => Promise<IpcResult<void>>
|
||||
}
|
||||
outline: {
|
||||
list: (bookId: string) => Promise<IpcResult<OutlineItem[]>>
|
||||
create: (
|
||||
bookId: string,
|
||||
title: string,
|
||||
parentId?: string | null,
|
||||
sortOrder?: number
|
||||
) => Promise<IpcResult<OutlineItem>>
|
||||
update: (
|
||||
bookId: string,
|
||||
id: string,
|
||||
patch: Partial<{
|
||||
title: string
|
||||
description: string
|
||||
status: OutlineStatus
|
||||
expectedWordCount: number | null
|
||||
chapterId: string | null
|
||||
sortOrder: number
|
||||
}>
|
||||
) => Promise<IpcResult<OutlineItem>>
|
||||
delete: (bookId: string, id: string) => Promise<IpcResult<void>>
|
||||
move: (
|
||||
bookId: string,
|
||||
id: string,
|
||||
parentId: string | null,
|
||||
sortOrder: number
|
||||
) => Promise<IpcResult<OutlineItem>>
|
||||
}
|
||||
setting: {
|
||||
list: (bookId: string, type?: SettingType) => Promise<IpcResult<SettingEntry[]>>
|
||||
create: (bookId: string, type: SettingType, name: string) => Promise<IpcResult<SettingEntry>>
|
||||
update: (
|
||||
bookId: string,
|
||||
id: string,
|
||||
patch: Partial<{ name: string; description: string; type: SettingType; properties: Record<string, unknown> }>
|
||||
) => Promise<IpcResult<SettingEntry>>
|
||||
delete: (bookId: string, id: string) => Promise<IpcResult<void>>
|
||||
syncRefs: (bookId: string, id: string, chapterIds: string[]) => Promise<IpcResult<SettingEntry>>
|
||||
}
|
||||
inspiration: {
|
||||
list: (bookId: string) => Promise<IpcResult<InspirationEntry[]>>
|
||||
create: (
|
||||
bookId: string,
|
||||
title?: string,
|
||||
content?: string,
|
||||
tags?: string[]
|
||||
) => Promise<IpcResult<InspirationEntry>>
|
||||
update: (
|
||||
bookId: string,
|
||||
id: string,
|
||||
patch: Partial<{ title: string; content: string; tags: string[] }>
|
||||
) => Promise<IpcResult<InspirationEntry>>
|
||||
delete: (bookId: string, id: string) => Promise<IpcResult<void>>
|
||||
convert: (
|
||||
bookId: string,
|
||||
id: string,
|
||||
targetKind: 'outline' | 'setting',
|
||||
settingType?: SettingType
|
||||
) => Promise<IpcResult<OutlineItem | SettingEntry>>
|
||||
}
|
||||
snapshot: {
|
||||
list: (bookId: string, chapterId: string) => Promise<IpcResult<Snapshot[]>>
|
||||
create: (
|
||||
bookId: string,
|
||||
chapterId: string,
|
||||
type: SnapshotType,
|
||||
name?: string,
|
||||
content?: string
|
||||
) => Promise<IpcResult<Snapshot>>
|
||||
restore: (bookId: string, chapterId: string, snapshotId: string) => Promise<IpcResult<Chapter>>
|
||||
delete: (bookId: string, snapshotId: string) => Promise<IpcResult<void>>
|
||||
startAutoSave: (bookId: string, chapterId: string) => Promise<IpcResult<void>>
|
||||
stopAutoSave: (bookId: string, chapterId: string) => Promise<IpcResult<void>>
|
||||
}
|
||||
bookmark: {
|
||||
list: (bookId: string, chapterId?: string, resolved?: boolean) => Promise<IpcResult<Bookmark[]>>
|
||||
create: (
|
||||
bookId: string,
|
||||
chapterId: string,
|
||||
position: number,
|
||||
label: string,
|
||||
landmarkType?: LandmarkType
|
||||
) => Promise<IpcResult<Bookmark>>
|
||||
update: (
|
||||
bookId: string,
|
||||
id: string,
|
||||
patch: Partial<{ label: string; position: number; landmarkType: LandmarkType }>
|
||||
) => Promise<IpcResult<Bookmark>>
|
||||
resolve: (bookId: string, id: string, resolved: boolean) => Promise<IpcResult<Bookmark>>
|
||||
delete: (bookId: string, id: string) => Promise<IpcResult<void>>
|
||||
}
|
||||
search: {
|
||||
query: (
|
||||
bookId: string,
|
||||
query: string,
|
||||
options?: { regex?: boolean; caseSensitive?: boolean; matchWholeWord?: boolean }
|
||||
) => Promise<IpcResult<SearchResult[]>>
|
||||
replace: (
|
||||
bookId: string,
|
||||
query: string,
|
||||
replacement: string,
|
||||
dryRun: boolean,
|
||||
options?: { regex?: boolean; caseSensitive?: boolean }
|
||||
) => Promise<IpcResult<{ count: number; previews: SearchResult[] }>>
|
||||
getHistory: () => Promise<IpcResult<string[]>>
|
||||
saveHistory: (query: string) => Promise<IpcResult<string[]>>
|
||||
}
|
||||
wordfreq: {
|
||||
analyze: (
|
||||
bookId: string,
|
||||
scope: { kind: 'book' | 'volume' | 'chapter'; chapterId?: string; volumeId?: string }
|
||||
) => Promise<IpcResult<WordFreqResult>>
|
||||
}
|
||||
shortcut: {
|
||||
getAll: () => Promise<IpcResult<Record<ActionId, string>>>
|
||||
register: (action: ActionId, accelerator: string) => Promise<IpcResult<void>>
|
||||
|
||||
Reference in New Issue
Block a user