6.1 KiB
id, title, status, assignee, created_date, updated_date, labels, dependencies, references, priority, ordinal
| id | title | status | assignee | created_date | updated_date | labels | dependencies | references | priority | ordinal | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| TASK-39 | Add hot-reload for non-destructive config changes | Done |
|
2026-02-14 02:04 | 2026-02-18 09:29 |
|
|
low | 59000 |
Description
Watch the config file for changes and apply non-destructive updates (colors, font sizes, subtitle modes, overlay opacity, keybindings) without requiring an app restart.
Motivation
Currently all config is loaded at startup. Users tweaking visual settings (font size, colors, subtitle positioning) must restart the app after every change, which breaks their video session. Hot-reload for safe config values would dramatically improve the tuning experience.
Scope
- Watch the config file using
fs.watchor similar - On change, re-parse and re-validate the config
- Categorize config fields as hot-reloadable vs restart-required
- Apply hot-reloadable changes immediately (push to renderer via IPC if needed)
- For restart-required changes, show a notification that a restart is needed
- Debounce file-change events (editors save multiple times rapidly)
Hot-reloadable candidates
- Font family, size, weight, color
- Subtitle background opacity/color
- Secondary subtitle display mode
- Overlay opacity and positioning offsets
- Keybinding mappings
- AI translation provider settings
Restart-required (NOT hot-reloadable)
- Anki field mappings (affects card creation pipeline)
- MeCab path / tokenizer settings
- MPV socket path
- Window tracker selection
Acceptance Criteria
- #1 Config file changes are detected automatically via file watcher.
- #2 Hot-reloadable fields are applied immediately without restart.
- #3 Restart-required fields trigger a user-visible notification.
- #4 File change events are debounced to handle editor save patterns.
- #5 Invalid config changes are rejected with an error notification, keeping the previous valid config.
- #6 Renderer receives updated styles/settings via IPC without full page reload.
Implementation Plan
Implementation plan documented in docs/plans/2026-02-18-task-39-hot-reload-config.md.
Execution breakdown:
- Add strict config reload API in
ConfigServiceso invalid JSON/JSONC updates are rejected without mutating current runtime config. - Add testable hot-reload coordinator service with debounced file-change handling and diff classification (hot-reload vs restart-required fields).
- Wire coordinator into main process watcher lifecycle; apply hot changes (style/keybindings/shortcuts/secondary mode/anki AI), emit restart-needed notification for non-hot changes, and emit invalid-config notification.
- Add renderer/preload live update IPC hooks for style/keybinding refresh without page reload.
- Run build + targeted tests (
test:fast) and validate criteria with notes.
Implementation Notes
Implemented strict config reload path in ConfigService (reloadConfigStrict) to reject invalid JSON/JSONC while preserving the last valid in-memory config.
Added createConfigHotReloadRuntime with debounced watcher-driven reloads, hot-vs-restart diff classification, and invalid-config callback handling.
Wired runtime into main process startup/teardown with fs.watch-based config path monitoring (file or config dir fallback), hot update application, restart-needed notifications, and invalid-config notifications.
Added renderer IPC hot-update channel (config:hot-reload) through preload/types, updating keybindings map, subtitle style, and secondary subtitle mode without page reload.
Updated core/config tests and test runner list to cover strict reload behavior and new hot-reload runtime service.
Updated user-facing docs to describe hot-reload behavior and restart-required notifications in README.md, docs/configuration.md, and docs/usage.md.
Regenerated config.example.jsonc and docs-served docs/public/config.example.jsonc from updated template metadata so hot-reload notes appear inline in config sections.
Final Summary
Implemented TASK-39 by introducing a debounced config hot-reload pipeline that watches config changes, safely reloads with strict JSON/JSONC validation, and applies non-destructive runtime updates without requiring a full app restart.
What changed
- Added
reloadConfigStrict()toConfigServiceso malformed config edits are rejected and the previous valid runtime config remains active. - Added new core runtime service
createConfigHotReloadRuntimeto:- debounce rapid save bursts,
- classify changed fields into hot-reloadable vs restart-required,
- route invalid reload errors to user-visible notifications.
- Wired hot-reload runtime into
main.tsapp lifecycle:- starts after initial config load,
- stops on app quit,
- applies hot updates for subtitle styling, keybindings, shortcuts, secondary subtitle mode defaults, and Anki AI config patching.
- Added renderer live-update IPC channel (
config:hot-reload) viapreload.ts+types.ts, and applied updates in renderer without page reload. - Added/updated tests:
- strict reload behavior in
src/config/config.test.ts, - hot-reload diff/debounce/invalid handling in
src/core/services/config-hot-reload.test.ts, - included new test file in
test:core:distscript.
- strict reload behavior in
Validation
bun run build && node --test dist/config/config.test.jsbun run build && node --test dist/core/services/config-hot-reload.test.jsbun run test:fast
All above commands passed.
Added follow-up documentation coverage for the shipped feature: README feature/quickstart note, configuration hot-reload behavior section, usage guide live-reload section, and regenerated config templates with per-section hot-reload notes.