feat: ship v1.0.0 with character graph and writing analytics

Add P7 Cytoscape relationship graph with setting CRUD, P9 cockpit analytics driven by writing_sessions, chapter POV selection, and full test coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-08 10:48:31 +08:00
parent 2c9b034a29
commit 4adafa1936
44 changed files with 2062 additions and 602 deletions
+14 -2
View File
@@ -2,9 +2,15 @@ import { ipcMain } from 'electron'
import { IPC } from '../../../shared/ipc-channels'
import type { BookMeta, CreateBookParams } from '../../../shared/types'
import { BookRegistryService } from '../../services/book-registry'
import type { WritingSessionService } from '../../services/writing-session.service'
import { wrap } from '../result'
export function registerBookHandlers(registry: BookRegistryService): void {
let previousBookId: string | null = null
export function registerBookHandlers(
registry: BookRegistryService,
writingSessions?: WritingSessionService
): void {
ipcMain.handle(IPC.BOOK_LIST, () => wrap(() => registry.list()))
ipcMain.handle(IPC.BOOK_CREATE, (_event, params: CreateBookParams) =>
@@ -18,7 +24,13 @@ export function registerBookHandlers(registry: BookRegistryService): void {
)
ipcMain.handle(IPC.BOOK_OPEN, (_event, { bookId }: { bookId: string }) =>
wrap(() => registry.open(bookId))
wrap(() => {
if (writingSessions && previousBookId && previousBookId !== bookId) {
writingSessions.endActive(previousBookId)
}
previousBookId = bookId
return registry.open(bookId)
})
)
ipcMain.handle(