feat(stats): add stats server, API endpoints, config, and Anki integration

- Hono HTTP server with 20+ REST endpoints for stats data
- Stats overlay BrowserWindow with toggle keybinding
- IPC channel definitions and preload bridge
- Stats config section (toggleKey, serverPort, autoStartServer, autoOpenBrowser)
- Config resolver for stats section
- AnkiConnect proxy endpoints (guiBrowse, notesInfo)
- Note ID passthrough in card mining callback chain
- Stats CLI command with autoOpenBrowser respect
This commit is contained in:
2026-03-14 22:14:09 -07:00
parent f005f542a3
commit a7c294a90c
36 changed files with 2312 additions and 4 deletions

View File

@@ -28,6 +28,7 @@ export const IPC_CHANNELS = {
kikuFieldGroupingRespond: 'kiku:field-grouping-respond',
reportOverlayContentBounds: 'overlay-content-bounds:report',
overlayModalOpened: 'overlay:modal-opened',
toggleStatsOverlay: 'stats:toggle-overlay',
},
request: {
getVisibleOverlayVisibility: 'get-visible-overlay-visibility',
@@ -40,6 +41,7 @@ export const IPC_CHANNELS = {
getMecabStatus: 'get-mecab-status',
getKeybindings: 'get-keybindings',
getConfigShortcuts: 'get-config-shortcuts',
getStatsToggleKey: 'get-stats-toggle-key',
getControllerConfig: 'get-controller-config',
getSecondarySubMode: 'get-secondary-sub-mode',
getCurrentSecondarySub: 'get-current-secondary-sub',
@@ -60,6 +62,19 @@ export const IPC_CHANNELS = {
jimakuListFiles: 'jimaku:list-files',
jimakuDownloadFile: 'jimaku:download-file',
kikuBuildMergePreview: 'kiku:build-merge-preview',
statsGetOverview: 'stats:get-overview',
statsGetDailyRollups: 'stats:get-daily-rollups',
statsGetMonthlyRollups: 'stats:get-monthly-rollups',
statsGetSessions: 'stats:get-sessions',
statsGetSessionTimeline: 'stats:get-session-timeline',
statsGetSessionEvents: 'stats:get-session-events',
statsGetVocabulary: 'stats:get-vocabulary',
statsGetKanji: 'stats:get-kanji',
statsGetMediaLibrary: 'stats:get-media-library',
statsGetMediaDetail: 'stats:get-media-detail',
statsGetMediaSessions: 'stats:get-media-sessions',
statsGetMediaDailyRollups: 'stats:get-media-daily-rollups',
statsGetMediaCover: 'stats:get-media-cover',
},
event: {
subtitleSet: 'subtitle:set',