From 791c993870356bc0681b00acf9e9c6636edcf9fc Mon Sep 17 00:00:00 2001 From: sudacode Date: Thu, 28 May 2026 22:53:22 -0700 Subject: [PATCH] docs: reformat changelog entries as nested bullet lists - Convert flat prose entries in CHANGELOG.md and docs-site/changelog.md to bold headers + sub-bullets - Scope artifact uploads in release/prerelease workflows to `latest*.yml` instead of `*.yml` - Update release-notes and RELEASING docs to match - Adjust workflow tests for new nested bullet format --- .github/workflows/prerelease.yml | 10 +- .github/workflows/release.yml | 10 +- CHANGELOG.md | 171 +++++++++++++++++++++++-------- docs-site/changelog.md | 171 +++++++++++++++++++++++-------- docs/RELEASING.md | 6 +- release/release-notes.md | 164 +++++++++++++++++++++-------- src/prerelease-workflow.test.ts | 9 +- src/release-workflow.test.ts | 9 +- 8 files changed, 403 insertions(+), 147 deletions(-) diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml index 95e149cb..8818ca4e 100644 --- a/.github/workflows/prerelease.yml +++ b/.github/workflows/prerelease.yml @@ -148,7 +148,7 @@ jobs: name: appimage path: | release/*.AppImage - release/*.yml + release/latest*.yml release/*.blockmap if-no-files-found: error @@ -226,7 +226,7 @@ jobs: path: | release/*.dmg release/*.zip - release/*.yml + release/latest*.yml release/*.blockmap if-no-files-found: error @@ -279,7 +279,7 @@ jobs: path: | release/*.exe release/*.zip - release/*.yml + release/latest*.yml release/*.blockmap if-no-files-found: error @@ -353,7 +353,7 @@ jobs: - name: Generate checksums run: | shopt -s nullglob - files=(release/*.AppImage release/*.dmg release/*.exe release/*.zip release/*.tar.gz release/*.yml release/*.blockmap dist/launcher/subminer) + files=(release/*.AppImage release/*.dmg release/*.exe release/*.zip release/*.tar.gz release/latest*.yml release/*.blockmap dist/launcher/subminer) if [ "${#files[@]}" -eq 0 ]; then echo "No release artifacts found for checksum generation." exit 1 @@ -389,7 +389,7 @@ jobs: release/*.exe release/*.zip release/*.tar.gz - release/*.yml + release/latest*.yml release/*.blockmap release/SHA256SUMS.txt dist/launcher/subminer diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f60d05ad..e1778227 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -139,7 +139,7 @@ jobs: name: appimage path: | release/*.AppImage - release/*.yml + release/latest*.yml release/*.blockmap build-macos: @@ -216,7 +216,7 @@ jobs: path: | release/*.dmg release/*.zip - release/*.yml + release/latest*.yml release/*.blockmap build-windows: @@ -268,7 +268,7 @@ jobs: path: | release/*.exe release/*.zip - release/*.yml + release/latest*.yml release/*.blockmap if-no-files-found: error @@ -342,7 +342,7 @@ jobs: - name: Generate checksums run: | shopt -s nullglob - files=(release/*.AppImage release/*.dmg release/*.exe release/*.zip release/*.tar.gz release/*.yml release/*.blockmap dist/launcher/subminer) + files=(release/*.AppImage release/*.dmg release/*.exe release/*.zip release/*.tar.gz release/latest*.yml release/*.blockmap dist/launcher/subminer) if [ "${#files[@]}" -eq 0 ]; then echo "No release artifacts found for checksum generation." exit 1 @@ -396,7 +396,7 @@ jobs: release/*.exe release/*.zip release/*.tar.gz - release/*.yml + release/latest*.yml release/*.blockmap release/SHA256SUMS.txt dist/launcher/subminer diff --git a/CHANGELOG.md b/CHANGELOG.md index f2f50aa1..ab0e125b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,68 +4,151 @@ ### Breaking Changes -- Subsync: The `subsync.defaultMode` config option has been removed; Subsync now always opens the manual subtitle picker regardless of any previously set default mode. +- **Subsync:** + - The `subsync.defaultMode` config option has been removed + - Subsync now always opens the manual subtitle picker regardless of any previously set default mode +- **N+1 Highlighting:** + - N+1 highlighting now has its own dedicated `ankiConnect.nPlusOne.enabled` option, separate from known-word highlighting + - It is no longer enabled automatically when known-word highlighting is on — enable it explicitly to keep N+1 annotations ### Added -- Auto-Updater: Adds tray and `subminer -u` update checks with app update prompts, launcher and Linux rofi theme auto-updates, checksum verification, configurable notifications, and an opt-in prerelease channel via `updates.channel: "prerelease"`. -- Settings Window: New dedicated Settings window via `subminer --settings` or `subminer settings`, organized into Appearance, Behavior, Anki, Input, and Integration sections; click-to-learn keybinding controls including the AniSkip button key; AnkiConnect-backed deck, field, and note-type pickers that auto-fill from the configured Anki deck; cross-category search; and live save for most options including subtitle CSS, stats keys, logging level, Jimaku, Subsync, and Anki mappings. AI and translation settings remain config-file only. -- Inline Character Portraits: Optional AniList character portraits appear inline for name-matched subtitle text; manual AniList overrides scoped per parent media directory so separate season folders maintain separate character dictionary selections. -- Log Export: Sanitized log ZIP export from the tray menu and via `subminer logs -e`, with home-directory usernames redacted from exported contents. -- Launcher CLI: `subminer --version` / `subminer -v` prints the installed app version; `mpv.profile` config and Settings support passes a named mpv profile to managed launches; bundled mpv plugin startup options are now configurable from SubMiner config. -- First-Run Setup: Optional installer for Bun and the `subminer` CLI on Linux, macOS, and Windows, including a Windows `subminer.cmd` PATH shim so `subminer` works without manually adding `SubMiner.exe` to PATH; setup recognizes existing Homebrew or user PATH installs and avoids writing into Homebrew-owned paths; includes an Open SubMiner Settings button; standalone setup app quits after completing, returning terminal control. -- Primary Subtitle Visibility on Yomitan Popup: New `subtitleStyle.primaryVisibleOnYomitanPopup` option keeps hover-mode primary subtitles visible while a Yomitan popup is open. +- **Auto-Updater:** + - Tray and `subminer -u` update checks with app update prompts + - Launcher and Linux rofi theme auto-updates + - Checksum verification and configurable notifications + - Opt-in prerelease channel via `updates.channel: "prerelease"` +- **Settings Window:** + - New dedicated Settings window via `subminer --settings` or `subminer settings`, organized into Appearance, Behavior, Anki, Input, and Integration sections + - Click-to-learn keybinding controls + - AnkiConnect-backed deck, field, and note-type pickers that auto-fill from the configured Anki deck + - Cross-category search + - Live save for most options including subtitle CSS, stats keys, logging level, Jimaku, Subsync, and Anki mappings + - AI and translation settings remain config-file only +- **Inline Character Portraits:** + - Optional AniList character portraits appear inline for name-matched subtitle text + - Manual AniList overrides scoped per parent media directory so separate season folders maintain separate character dictionary selections +- **Character Dictionary Manager:** New `Ctrl/Cmd+D` manager modal to remove, reorder, or override loaded entries. +- **Log Export:** Sanitized log ZIP export from the tray menu and via `subminer logs -e`, with home-directory usernames redacted from exported contents. +- **Launcher CLI:** + - `subminer --version` / `subminer -v` prints the installed app version + - `mpv.profile` config and Settings support passes a named mpv profile to managed launches + - Bundled mpv plugin startup options are now configurable from SubMiner config +- **First-Run Setup:** + - Optional installer for Bun and the `subminer` CLI on Linux, macOS, and Windows + - Windows `subminer.cmd` PATH shim so `subminer` works without manually adding `SubMiner.exe` to PATH + - Setup recognizes existing Homebrew or user PATH installs and avoids writing into Homebrew-owned paths + - Includes an Open SubMiner Settings button + - Standalone setup app quits after completing, returning terminal control +- **Primary Subtitle Visibility on Yomitan Popup:** New `subtitleStyle.primaryVisibleOnYomitanPopup` option keeps hover-mode primary subtitles visible while a Yomitan popup is open. ### Changed -- Subtitle Appearance Config: Primary and secondary subtitle appearance now use color controls plus CSS declaration editors, saved as `subtitleStyle.css`, `subtitleStyle.secondary.css`, and `subtitleSidebar.css`; known-word and N+1 annotation colors moved to `subtitleStyle.knownWordColor` and `subtitleStyle.nPlusOneColor`; subtitle font defaults updated to `Hiragino Sans, M PLUS 1, Source Han Sans JP, Noto Sans CJK JP`. Existing configs migrate automatically; legacy Anki color keys still accepted with deprecation warnings. -- Subtitle Style Defaults: Stronger outline-style text shadow, thicker JLPT underlines, and frequency `topX` default raised to `10000`. -- Character Dictionary: Entries scoped to the current AniList media for name matching and inline portraits; generates Japanese-only name aliases so raw romanized/English aliases no longer surface as separate results; new `Ctrl/Cmd+D` manager modal to remove, reorder, or override loaded entries; in-app AniList selector waits for an explicit search with the box prefilled from the current filename; `subtitleStyle.nameMatchEnabled` is now the sole switch for dictionary sync and builds. -- Electron Runtime: Updated from 39.8.6 to 42.2.0, returning SubMiner to a supported Electron release line. -- N+1 Highlighting Default: `ankiConnect.nPlusOne.enabled` is no longer implicitly enabled when known-word highlighting is on; existing configs that already had N+1 enabled are unchanged, but new configs must set it explicitly. -- Linux Auto-Update Flow: Linux tray "Check for Updates" now installs the new AppImage automatically, matching macOS and Windows; AppImages managed by a system package (e.g. AUR) and non-AppImage launches still use the GitHub-asset flow. -- Jellyfin Setup: Removed the server presets dropdown; setup now shows a single editable server URL field. -- Jellyfin Cast Identity: Device identity now derived from the OS hostname and always reported as SubMiner; previously configurable identity fields are ignored, preventing multiple installs from sharing a remote-session identity. -- Startup Defaults: Jellyfin remote-session startup warmup and character-name subtitle highlighting now default to off. -- Setup Appearance: Removed the bundled mpv runtime plugin readiness card from the setup flow. +- **Subtitle Appearance Config:** + - Primary and secondary subtitle appearance now use color controls plus CSS declaration editors, saved as `subtitleStyle.css`, `subtitleStyle.secondary.css`, and `subtitleSidebar.css` + - Known-word and N+1 annotation colors moved to `subtitleStyle.knownWordColor` and `subtitleStyle.nPlusOneColor` + - Subtitle font defaults updated to `Hiragino Sans, M PLUS 1, Source Han Sans JP, Noto Sans CJK JP` + - Existing configs migrate automatically; legacy Anki color keys still accepted with deprecation warnings +- **Subtitle Style Defaults:** + - Stronger outline-style text shadow + - Thicker JLPT underlines + - Frequency `topX` default raised to `10000` +- **Character Dictionary:** + - Entries scoped to the current AniList media for name matching and inline portraits + - Generates Japanese-only name aliases so raw romanized/English aliases no longer surface as separate results + - In-app AniList selector waits for an explicit search with the box prefilled from the current filename + - `subtitleStyle.nameMatchEnabled` is now the sole switch for dictionary sync and builds +- **Electron Runtime:** Updated from 39.8.6 to 42.2.0, returning SubMiner to a supported Electron release line. +- **Jellyfin Setup:** + - Removed the server presets dropdown + - Setup now shows a single editable server URL field +- **Jellyfin Cast Identity:** + - Device identity now derived from the OS hostname and always reported as SubMiner + - Previously configurable identity fields are ignored, preventing multiple installs from sharing a remote-session identity +- **Startup Defaults:** Jellyfin remote-session startup warmup and character-name subtitle highlighting now default to off. +- **Setup Appearance:** Removed the bundled mpv runtime plugin readiness card from the setup flow. ### Fixed -- AniList Progress: Progress updates fire correctly when playback reaches or skips past the watched threshold using fresh mpv timing events; season-specific results preferred for multi-season files with a clear message when the matched season is not in Planning or Watching; repeated missing-token checks no longer exhaust retry attempts or duplicate dead-letter entries. -- Anki Mining: Sentence-audio padding is opt-in by default; animated AVIF freeze-frame duration aligned to word audio length without double-counting; multi-line sentence alignment fixed for repeated subtitle text; Kiku duplicate-card detection, auto-merge, modal acknowledgment race, and field/tag ordering corrected; YouTube playback cards use mpv's resolved stream URLs; sentence cards refresh the secondary subtitle before saving; known-word cache appends correctly with multiple deck field mappings. -- Jellyfin Discovery: Startup, subtitle track selection, and duplicate ready-signal handling all fixed; paused mpv no longer misreported as playing; startup unpause no longer repeats after a manual pause or `y-t` toggle; delayed Japanese subtitle selection, later-loading foreign track hijacking, and long-lived sidebar ffmpeg extractor leaks fixed; resume corrected when a remote play command sends `StartPositionTicks: 0` despite saved progress; picker library discovery kept working regardless of app log level. -- Jellyfin Remote: Tray checkbox stays in sync on Linux after tray, CLI, or startup changes; stale discovery sessions restarted when the server no longer lists the SubMiner cast target; remote controller visibility and progress sync fixed for seeks, stops, startup path changes, and Linux websocket reconnect windows; Play and Resume now behave correctly (Play from beginning, Resume from saved position); final progress reports reuse SubMiner's last known position when mpv resets on stop; Windows setup login flow fixed with an IPC bridge, immediate feedback, and a timeout with inline error for unreachable servers. -- Jellyfin Subtitles and Overlay: Subtitle overlay shown automatically during Jellyfin playback; `y-t` toggle made reliable and sticky across stream redirects; managed subtitle defaults re-armed on redirect; passive Linux/Hyprland overlay shows no longer steal keyboard focus from mpv; subtitle timing improved with preferred embedded streams over external sidecars, correct Japanese-vs-English cue offset handling, per-stream delay shift restoration, and transient track-list read failure tolerance. -- Overlay (macOS): Overlay hides when mpv loses focus, is minimized, or is no longer the foreground app; stable through transient window geometry disappearances from macOS APIs and when clicking from the overlay back into mpv; stats overlay opened inactive so it appears over fullscreen mpv without switching Spaces; passthrough fixed so mpv controls stay clickable before hovering a subtitle bar; window-tracker polling reduced while mpv is stably focused. -- Overlay (Linux / Hyprland): Placement refreshes after leaving fullscreen; overlay stays above mpv after focus changes from clicks or movement; Settings and Yomitan windows promoted above the subtitle overlay instead of opening behind it; overlay hides when the character dictionary modal opens, including during AniList lookup. -- Overlay Lifecycle: First startup subtitle primed before autoplay resumes so the overlay renders text before playback begins; overlay and subtitle stream kept alive after `y-r` restart with correct Linux bounds reapplication; launcher-owned playback quits SubMiner on end while background/tray sessions stay alive; subtitle sync modal fixed on macOS so it no longer flashes on first attempt or leaves stale state; Windows managed mpv launches from a background instance now correctly receive the start command, retarget the new socket, bind to the player window, and receive startup overlay options. -- Yomitan Sidebar: Playback stays paused for sidebar-opened Yomitan popups when auto-pause is enabled; fixed popups not opening when startup races the Yomitan extension load; sidebar mining cards use audio and images from the clicked sidebar line instead of the current primary subtitle. -- Launcher: Warm launches reuse a running background instance, reapply preferred subtitles, and close launcher-owned tray apps after playback ends; videos stay paused until subtitle priming and tokenization readiness complete; `subminer settings` on macOS exits cleanly when the window is closed; `subminer app` on Linux returns terminal control immediately; Linux first-run installs build with a valid Bun shebang; `subminer app --setup` opens the setup flow when SubMiner is already running in background. -- YouTube Playback: Selected subtitles downloaded to local temp files so the primary bar and sidebar read the same source, with cleanup on reload and quit; false load-failure notifications suppressed; tray icon created on launcher-managed playback that attaches to an already-running process; mpv plugin no longer starts a second SubMiner instance for app-owned YouTube playback. -- Shortcuts: Native mpv menu shortcuts disabled during managed macOS playback so configured SubMiner shortcuts work while mpv has focus; custom session shortcuts including `stats.markWatchedKey` wired through mpv; multi-line copy/mine overlay correctly focused so number keys choose the line count on macOS and Windows. -- Controller Bindings: Controller config and debug shortcuts stay closed while controller support is disabled; binding learn mode starts from the edit pencil; remaps saved per controller profile; binding badges also start learn mode; row reset buttons restore individual bindings to defaults. -- Logging: `logging.level` forwarded to launcher-started and Windows shortcut-started mpv sessions covering mpv log verbosity, plugin logging, and plugin-launched app logging; `logging.rotation` (default 7 days) and per-component `logging.files` toggles added with mpv logs disabled by default; repeated IPC socket warning spam suppressed while waiting for mpv to recreate the socket; Windows mpv IPC, subtitle track, and Yomitan diagnostics added. -- Updater: Linux `subminer -u` performs release updates independently of any running tray app using GitHub release metadata; macOS update dialogs from `subminer -u` reliably appear in the foreground with a manual-install message for builds that cannot apply native updates; macOS and Linux `electron-updater` routes through `/usr/bin/curl` to avoid Electron network crashes; Windows automatic updates keep the native NSIS install path while routing updater HTTP through main-process fetch to avoid delayed exit after launch. -- In-Player Stats: Layering fixed so delete confirmations, overlay modals, and update-check dialogs appear above the stats window; Jellyfin playback stats grouped by item metadata so watched episodes merge with matching local library titles and keep clean display names. -- Tray: Tray stays running when Yomitan settings are closed; settings loading no longer blocks other tray actions; Yomitan extension refreshes serialized at startup; embedded popup preview disabled to prevent renderer hangs during sidebar navigation; Windows "Open SubMiner Setup" action opens the setup window correctly after first-run is complete; session help modal close fixed without mpv running. -- Discord Rich Presence: No longer falls back to Jellyfin stream URLs; Jellyfin playback titles primed before stream loading so presence shows the show/episode title instead of a URL. -- WebSocket Annotations: Annotation spans and token metadata stay on the annotation WebSocket; the regular subtitle WebSocket is plain-text only. -- Subtitle Frequency Highlighting: Frequency annotations kept for determiner-led noun compounds like `その場` while still filtering standalone determiners; fixed for Yomitan single-token compounds with internal particles such as `目の前` while keeping pure grammar/kana helper spans unannotated. -- Subtitle Annotation Prefetching: Cached colored annotations and character images ready sooner for live subtitle changes without delaying raw subtitle display. -- Packaging: macOS compiled mpv window helper correctly built into `dist/scripts` and bundled, preventing fallback to slow Swift source startup; stale Windows helper resource entry removed; one-shot `make clean build install` AppImage flows fixed so install picks up the AppImage built earlier in the same invocation. -- Windows Startup Errors: Fatal startup failures now show a native error dialog and write details to the app log instead of exiting silently. +- **AniList Progress:** + - Progress updates fire correctly when playback reaches or skips past the watched threshold, using fresh mpv timing events + - Season-specific results preferred for multi-season files, with a clear message when the matched season is not in Planning or Watching + - Repeated missing-token checks no longer exhaust retry attempts or duplicate dead-letter entries +- **Anki Mining:** + - Sentence-audio padding is opt-in by default + - Animated AVIF freeze-frame duration aligned to word audio length without double-counting + - Multi-line sentence alignment fixed for repeated subtitle text + - Kiku duplicate-card detection, auto-merge, modal acknowledgment race, and field/tag ordering corrected + - YouTube playback cards use mpv's resolved stream URLs + - Sentence cards refresh the secondary subtitle before saving +- **Jellyfin Discovery:** + - Startup, subtitle track selection, and duplicate ready-signal handling all fixed + - Paused mpv no longer misreported as playing + - Resume corrected when a remote play command sends `StartPositionTicks: 0` despite saved progress +- **Jellyfin Remote:** + - Tray checkbox stays in sync on Linux after tray, CLI, or startup changes + - Remote controller visibility and progress sync fixed for seeks, stops, startup path changes, and Linux websocket reconnect windows + - Play and Resume now behave correctly (Play from beginning, Resume from saved position) + - Final progress reports reuse SubMiner's last known position when mpv resets on stop + - Windows setup login flow fixed with an IPC bridge, immediate feedback, and a timeout with inline error for unreachable servers +- **Overlay (macOS):** + - Overlay hides when mpv loses focus, is minimized, or is no longer the foreground app + - Stays stable through transient window geometry disappearances from macOS APIs and when clicking from the overlay back into mpv + - Stats overlay opened inactive so it appears over fullscreen mpv without switching Spaces + - Passthrough fixed so mpv controls stay clickable before hovering a subtitle bar +- **Yomitan Sidebar:** + - Playback stays paused for sidebar-opened Yomitan popups when auto-pause is enabled + - Popups now open when startup races the Yomitan extension load + - Sidebar mining cards use audio and images from the clicked sidebar line instead of the current primary subtitle +- **Launcher:** + - `subminer app` on Linux returns terminal control immediately + - `subminer app --setup` opens the setup flow when SubMiner is already running in the background +- **YouTube Playback:** + - Selected subtitles downloaded to local temp files so the primary bar and sidebar read the same source, with cleanup on reload and quit + - False load-failure notifications suppressed + - Tray icon created on launcher-managed playback that attaches to an already-running process +- **Shortcuts:** + - Native mpv menu shortcuts disabled during managed macOS playback so configured SubMiner shortcuts work while mpv has focus + - Custom session shortcuts including `stats.markWatchedKey` wired through mpv + - Multi-line copy/mine overlay correctly focused so number keys choose the line count on macOS and Windows +- **Controller Bindings:** + - Controller config and debug shortcuts stay closed while controller support is disabled + - Binding learn mode starts from the edit pencil + - Remaps saved per controller profile + - Binding badges also start learn mode + - Row reset buttons restore individual bindings to defaults +- **Logging:** + - `logging.level` forwarded to launcher-started and Windows shortcut-started mpv sessions, covering mpv log verbosity, plugin logging, and plugin-launched app logging + - `logging.rotation` (default 7 days) and per-component `logging.files` toggles added, with mpv logs disabled by default + - Repeated IPC socket warning spam suppressed while waiting for mpv to recreate the socket + - Windows mpv IPC, subtitle track, and Yomitan diagnostics added +- **In-Player Stats:** + - Layering fixed so delete confirmations, overlay modals, and update-check dialogs appear above the stats window + - Jellyfin playback stats grouped by item metadata so watched episodes merge with matching local library titles and keep clean display names +- **WebSocket Annotations:** + - Annotation spans and token metadata stay on the annotation WebSocket + - The regular subtitle WebSocket is plain-text only +- **Subtitle Annotation Prefetching:** Cached colored annotations and character images ready sooner for live subtitle changes without delaying raw subtitle display. +- **Windows Startup Errors:** Fatal startup failures now show a native error dialog and write details to the app log instead of exiting silently. ### Docs -- Documentation Site: Published stable docs at the site root with current development docs under `/main/`; fixed versioned docs navigation, archived page link handling, and local dev version routing; documented all previously undocumented config options including `subtitleStyle.primaryDefaultMode`, `stats.markWatchedKey`, `immersionTracking.lifetimeSummaries.*`, and all seven `mpv.*` launcher options; added Playback Startup Flow and Runtime Sockets diagrams to the architecture docs with cross-reference pointers in the MPV Plugin and Troubleshooting pages. +- **Documentation Site:** + - Published stable docs at the site root with current development docs under `/main/` + - Fixed versioned docs navigation, archived page link handling, and local dev version routing + - Documented all previously undocumented config options including `subtitleStyle.primaryDefaultMode`, `stats.markWatchedKey`, `immersionTracking.lifetimeSummaries.*`, and all seven `mpv.*` launcher options + - Added Playback Startup Flow and Runtime Sockets diagrams to the architecture docs with cross-reference pointers in the MPV Plugin and Troubleshooting pages
Internal changes ### Internal -- Release Tooling: Release-note polishing treats pending fragments and reviewed prerelease notes as a cumulative final outcome, collapsing prerelease-only fixes into the final user-facing change; prerelease generation reuses existing reviewed notes and merges only new fragment material; `make clean` preserves `release/prerelease-notes.md`. -- Tests: Removed stale Yomitan vendor source-inspection assertions for changes that were not shipped. +- **Release Tooling:** + - Release-note polishing treats pending fragments and reviewed prerelease notes as a cumulative final outcome, collapsing prerelease-only fixes into the final user-facing change + - Prerelease generation reuses existing reviewed notes and merges only new fragment material + - `make clean` preserves `release/prerelease-notes.md` +- **Tests:** Removed stale Yomitan vendor source-inspection assertions for changes that were not shipped.
diff --git a/docs-site/changelog.md b/docs-site/changelog.md index 7e5011d2..c1897771 100644 --- a/docs-site/changelog.md +++ b/docs-site/changelog.md @@ -4,68 +4,151 @@ **Breaking Changes** -- Subsync: The `subsync.defaultMode` config option has been removed; Subsync now always opens the manual subtitle picker regardless of any previously set default mode. +- **Subsync:** + - The `subsync.defaultMode` config option has been removed + - Subsync now always opens the manual subtitle picker regardless of any previously set default mode +- **N+1 Highlighting:** + - N+1 highlighting now has its own dedicated `ankiConnect.nPlusOne.enabled` option, separate from known-word highlighting + - It is no longer enabled automatically when known-word highlighting is on — enable it explicitly to keep N+1 annotations **Added** -- Auto-Updater: Adds tray and `subminer -u` update checks with app update prompts, launcher and Linux rofi theme auto-updates, checksum verification, configurable notifications, and an opt-in prerelease channel via `updates.channel: "prerelease"`. -- Settings Window: New dedicated Settings window via `subminer --settings` or `subminer settings`, organized into Appearance, Behavior, Anki, Input, and Integration sections; click-to-learn keybinding controls including the AniSkip button key; AnkiConnect-backed deck, field, and note-type pickers that auto-fill from the configured Anki deck; cross-category search; and live save for most options including subtitle CSS, stats keys, logging level, Jimaku, Subsync, and Anki mappings. AI and translation settings remain config-file only. -- Inline Character Portraits: Optional AniList character portraits appear inline for name-matched subtitle text; manual AniList overrides scoped per parent media directory so separate season folders maintain separate character dictionary selections. -- Log Export: Sanitized log ZIP export from the tray menu and via `subminer logs -e`, with home-directory usernames redacted from exported contents. -- Launcher CLI: `subminer --version` / `subminer -v` prints the installed app version; `mpv.profile` config and Settings support passes a named mpv profile to managed launches; bundled mpv plugin startup options are now configurable from SubMiner config. -- First-Run Setup: Optional installer for Bun and the `subminer` CLI on Linux, macOS, and Windows, including a Windows `subminer.cmd` PATH shim so `subminer` works without manually adding `SubMiner.exe` to PATH; setup recognizes existing Homebrew or user PATH installs and avoids writing into Homebrew-owned paths; includes an Open SubMiner Settings button; standalone setup app quits after completing, returning terminal control. -- Primary Subtitle Visibility on Yomitan Popup: New `subtitleStyle.primaryVisibleOnYomitanPopup` option keeps hover-mode primary subtitles visible while a Yomitan popup is open. +- **Auto-Updater:** + - Tray and `subminer -u` update checks with app update prompts + - Launcher and Linux rofi theme auto-updates + - Checksum verification and configurable notifications + - Opt-in prerelease channel via `updates.channel: "prerelease"` +- **Settings Window:** + - New dedicated Settings window via `subminer --settings` or `subminer settings`, organized into Appearance, Behavior, Anki, Input, and Integration sections + - Click-to-learn keybinding controls + - AnkiConnect-backed deck, field, and note-type pickers that auto-fill from the configured Anki deck + - Cross-category search + - Live save for most options including subtitle CSS, stats keys, logging level, Jimaku, Subsync, and Anki mappings + - AI and translation settings remain config-file only +- **Inline Character Portraits:** + - Optional AniList character portraits appear inline for name-matched subtitle text + - Manual AniList overrides scoped per parent media directory so separate season folders maintain separate character dictionary selections +- **Character Dictionary Manager:** New `Ctrl/Cmd+D` manager modal to remove, reorder, or override loaded entries. +- **Log Export:** Sanitized log ZIP export from the tray menu and via `subminer logs -e`, with home-directory usernames redacted from exported contents. +- **Launcher CLI:** + - `subminer --version` / `subminer -v` prints the installed app version + - `mpv.profile` config and Settings support passes a named mpv profile to managed launches + - Bundled mpv plugin startup options are now configurable from SubMiner config +- **First-Run Setup:** + - Optional installer for Bun and the `subminer` CLI on Linux, macOS, and Windows + - Windows `subminer.cmd` PATH shim so `subminer` works without manually adding `SubMiner.exe` to PATH + - Setup recognizes existing Homebrew or user PATH installs and avoids writing into Homebrew-owned paths + - Includes an Open SubMiner Settings button + - Standalone setup app quits after completing, returning terminal control +- **Primary Subtitle Visibility on Yomitan Popup:** New `subtitleStyle.primaryVisibleOnYomitanPopup` option keeps hover-mode primary subtitles visible while a Yomitan popup is open. **Changed** -- Subtitle Appearance Config: Primary and secondary subtitle appearance now use color controls plus CSS declaration editors, saved as `subtitleStyle.css`, `subtitleStyle.secondary.css`, and `subtitleSidebar.css`; known-word and N+1 annotation colors moved to `subtitleStyle.knownWordColor` and `subtitleStyle.nPlusOneColor`; subtitle font defaults updated to `Hiragino Sans, M PLUS 1, Source Han Sans JP, Noto Sans CJK JP`. Existing configs migrate automatically; legacy Anki color keys still accepted with deprecation warnings. -- Subtitle Style Defaults: Stronger outline-style text shadow, thicker JLPT underlines, and frequency `topX` default raised to `10000`. -- Character Dictionary: Entries scoped to the current AniList media for name matching and inline portraits; generates Japanese-only name aliases so raw romanized/English aliases no longer surface as separate results; new `Ctrl/Cmd+D` manager modal to remove, reorder, or override loaded entries; in-app AniList selector waits for an explicit search with the box prefilled from the current filename; `subtitleStyle.nameMatchEnabled` is now the sole switch for dictionary sync and builds. -- Electron Runtime: Updated from 39.8.6 to 42.2.0, returning SubMiner to a supported Electron release line. -- N+1 Highlighting Default: `ankiConnect.nPlusOne.enabled` is no longer implicitly enabled when known-word highlighting is on; existing configs that already had N+1 enabled are unchanged, but new configs must set it explicitly. -- Linux Auto-Update Flow: Linux tray "Check for Updates" now installs the new AppImage automatically, matching macOS and Windows; AppImages managed by a system package (e.g. AUR) and non-AppImage launches still use the GitHub-asset flow. -- Jellyfin Setup: Removed the server presets dropdown; setup now shows a single editable server URL field. -- Jellyfin Cast Identity: Device identity now derived from the OS hostname and always reported as SubMiner; previously configurable identity fields are ignored, preventing multiple installs from sharing a remote-session identity. -- Startup Defaults: Jellyfin remote-session startup warmup and character-name subtitle highlighting now default to off. -- Setup Appearance: Removed the bundled mpv runtime plugin readiness card from the setup flow. +- **Subtitle Appearance Config:** + - Primary and secondary subtitle appearance now use color controls plus CSS declaration editors, saved as `subtitleStyle.css`, `subtitleStyle.secondary.css`, and `subtitleSidebar.css` + - Known-word and N+1 annotation colors moved to `subtitleStyle.knownWordColor` and `subtitleStyle.nPlusOneColor` + - Subtitle font defaults updated to `Hiragino Sans, M PLUS 1, Source Han Sans JP, Noto Sans CJK JP` + - Existing configs migrate automatically; legacy Anki color keys still accepted with deprecation warnings +- **Subtitle Style Defaults:** + - Stronger outline-style text shadow + - Thicker JLPT underlines + - Frequency `topX` default raised to `10000` +- **Character Dictionary:** + - Entries scoped to the current AniList media for name matching and inline portraits + - Generates Japanese-only name aliases so raw romanized/English aliases no longer surface as separate results + - In-app AniList selector waits for an explicit search with the box prefilled from the current filename + - `subtitleStyle.nameMatchEnabled` is now the sole switch for dictionary sync and builds +- **Electron Runtime:** Updated from 39.8.6 to 42.2.0, returning SubMiner to a supported Electron release line. +- **Jellyfin Setup:** + - Removed the server presets dropdown + - Setup now shows a single editable server URL field +- **Jellyfin Cast Identity:** + - Device identity now derived from the OS hostname and always reported as SubMiner + - Previously configurable identity fields are ignored, preventing multiple installs from sharing a remote-session identity +- **Startup Defaults:** Jellyfin remote-session startup warmup and character-name subtitle highlighting now default to off. +- **Setup Appearance:** Removed the bundled mpv runtime plugin readiness card from the setup flow. **Fixed** -- AniList Progress: Progress updates fire correctly when playback reaches or skips past the watched threshold using fresh mpv timing events; season-specific results preferred for multi-season files with a clear message when the matched season is not in Planning or Watching; repeated missing-token checks no longer exhaust retry attempts or duplicate dead-letter entries. -- Anki Mining: Sentence-audio padding is opt-in by default; animated AVIF freeze-frame duration aligned to word audio length without double-counting; multi-line sentence alignment fixed for repeated subtitle text; Kiku duplicate-card detection, auto-merge, modal acknowledgment race, and field/tag ordering corrected; YouTube playback cards use mpv's resolved stream URLs; sentence cards refresh the secondary subtitle before saving; known-word cache appends correctly with multiple deck field mappings. -- Jellyfin Discovery: Startup, subtitle track selection, and duplicate ready-signal handling all fixed; paused mpv no longer misreported as playing; startup unpause no longer repeats after a manual pause or `y-t` toggle; delayed Japanese subtitle selection, later-loading foreign track hijacking, and long-lived sidebar ffmpeg extractor leaks fixed; resume corrected when a remote play command sends `StartPositionTicks: 0` despite saved progress; picker library discovery kept working regardless of app log level. -- Jellyfin Remote: Tray checkbox stays in sync on Linux after tray, CLI, or startup changes; stale discovery sessions restarted when the server no longer lists the SubMiner cast target; remote controller visibility and progress sync fixed for seeks, stops, startup path changes, and Linux websocket reconnect windows; Play and Resume now behave correctly (Play from beginning, Resume from saved position); final progress reports reuse SubMiner's last known position when mpv resets on stop; Windows setup login flow fixed with an IPC bridge, immediate feedback, and a timeout with inline error for unreachable servers. -- Jellyfin Subtitles and Overlay: Subtitle overlay shown automatically during Jellyfin playback; `y-t` toggle made reliable and sticky across stream redirects; managed subtitle defaults re-armed on redirect; passive Linux/Hyprland overlay shows no longer steal keyboard focus from mpv; subtitle timing improved with preferred embedded streams over external sidecars, correct Japanese-vs-English cue offset handling, per-stream delay shift restoration, and transient track-list read failure tolerance. -- Overlay (macOS): Overlay hides when mpv loses focus, is minimized, or is no longer the foreground app; stable through transient window geometry disappearances from macOS APIs and when clicking from the overlay back into mpv; stats overlay opened inactive so it appears over fullscreen mpv without switching Spaces; passthrough fixed so mpv controls stay clickable before hovering a subtitle bar; window-tracker polling reduced while mpv is stably focused. -- Overlay (Linux / Hyprland): Placement refreshes after leaving fullscreen; overlay stays above mpv after focus changes from clicks or movement; Settings and Yomitan windows promoted above the subtitle overlay instead of opening behind it; overlay hides when the character dictionary modal opens, including during AniList lookup. -- Overlay Lifecycle: First startup subtitle primed before autoplay resumes so the overlay renders text before playback begins; overlay and subtitle stream kept alive after `y-r` restart with correct Linux bounds reapplication; launcher-owned playback quits SubMiner on end while background/tray sessions stay alive; subtitle sync modal fixed on macOS so it no longer flashes on first attempt or leaves stale state; Windows managed mpv launches from a background instance now correctly receive the start command, retarget the new socket, bind to the player window, and receive startup overlay options. -- Yomitan Sidebar: Playback stays paused for sidebar-opened Yomitan popups when auto-pause is enabled; fixed popups not opening when startup races the Yomitan extension load; sidebar mining cards use audio and images from the clicked sidebar line instead of the current primary subtitle. -- Launcher: Warm launches reuse a running background instance, reapply preferred subtitles, and close launcher-owned tray apps after playback ends; videos stay paused until subtitle priming and tokenization readiness complete; `subminer settings` on macOS exits cleanly when the window is closed; `subminer app` on Linux returns terminal control immediately; Linux first-run installs build with a valid Bun shebang; `subminer app --setup` opens the setup flow when SubMiner is already running in background. -- YouTube Playback: Selected subtitles downloaded to local temp files so the primary bar and sidebar read the same source, with cleanup on reload and quit; false load-failure notifications suppressed; tray icon created on launcher-managed playback that attaches to an already-running process; mpv plugin no longer starts a second SubMiner instance for app-owned YouTube playback. -- Shortcuts: Native mpv menu shortcuts disabled during managed macOS playback so configured SubMiner shortcuts work while mpv has focus; custom session shortcuts including `stats.markWatchedKey` wired through mpv; multi-line copy/mine overlay correctly focused so number keys choose the line count on macOS and Windows. -- Controller Bindings: Controller config and debug shortcuts stay closed while controller support is disabled; binding learn mode starts from the edit pencil; remaps saved per controller profile; binding badges also start learn mode; row reset buttons restore individual bindings to defaults. -- Logging: `logging.level` forwarded to launcher-started and Windows shortcut-started mpv sessions covering mpv log verbosity, plugin logging, and plugin-launched app logging; `logging.rotation` (default 7 days) and per-component `logging.files` toggles added with mpv logs disabled by default; repeated IPC socket warning spam suppressed while waiting for mpv to recreate the socket; Windows mpv IPC, subtitle track, and Yomitan diagnostics added. -- Updater: Linux `subminer -u` performs release updates independently of any running tray app using GitHub release metadata; macOS update dialogs from `subminer -u` reliably appear in the foreground with a manual-install message for builds that cannot apply native updates; macOS and Linux `electron-updater` routes through `/usr/bin/curl` to avoid Electron network crashes; Windows automatic updates keep the native NSIS install path while routing updater HTTP through main-process fetch to avoid delayed exit after launch. -- In-Player Stats: Layering fixed so delete confirmations, overlay modals, and update-check dialogs appear above the stats window; Jellyfin playback stats grouped by item metadata so watched episodes merge with matching local library titles and keep clean display names. -- Tray: Tray stays running when Yomitan settings are closed; settings loading no longer blocks other tray actions; Yomitan extension refreshes serialized at startup; embedded popup preview disabled to prevent renderer hangs during sidebar navigation; Windows "Open SubMiner Setup" action opens the setup window correctly after first-run is complete; session help modal close fixed without mpv running. -- Discord Rich Presence: No longer falls back to Jellyfin stream URLs; Jellyfin playback titles primed before stream loading so presence shows the show/episode title instead of a URL. -- WebSocket Annotations: Annotation spans and token metadata stay on the annotation WebSocket; the regular subtitle WebSocket is plain-text only. -- Subtitle Frequency Highlighting: Frequency annotations kept for determiner-led noun compounds like `その場` while still filtering standalone determiners; fixed for Yomitan single-token compounds with internal particles such as `目の前` while keeping pure grammar/kana helper spans unannotated. -- Subtitle Annotation Prefetching: Cached colored annotations and character images ready sooner for live subtitle changes without delaying raw subtitle display. -- Packaging: macOS compiled mpv window helper correctly built into `dist/scripts` and bundled, preventing fallback to slow Swift source startup; stale Windows helper resource entry removed; one-shot `make clean build install` AppImage flows fixed so install picks up the AppImage built earlier in the same invocation. -- Windows Startup Errors: Fatal startup failures now show a native error dialog and write details to the app log instead of exiting silently. +- **AniList Progress:** + - Progress updates fire correctly when playback reaches or skips past the watched threshold, using fresh mpv timing events + - Season-specific results preferred for multi-season files, with a clear message when the matched season is not in Planning or Watching + - Repeated missing-token checks no longer exhaust retry attempts or duplicate dead-letter entries +- **Anki Mining:** + - Sentence-audio padding is opt-in by default + - Animated AVIF freeze-frame duration aligned to word audio length without double-counting + - Multi-line sentence alignment fixed for repeated subtitle text + - Kiku duplicate-card detection, auto-merge, modal acknowledgment race, and field/tag ordering corrected + - YouTube playback cards use mpv's resolved stream URLs + - Sentence cards refresh the secondary subtitle before saving +- **Jellyfin Discovery:** + - Startup, subtitle track selection, and duplicate ready-signal handling all fixed + - Paused mpv no longer misreported as playing + - Resume corrected when a remote play command sends `StartPositionTicks: 0` despite saved progress +- **Jellyfin Remote:** + - Tray checkbox stays in sync on Linux after tray, CLI, or startup changes + - Remote controller visibility and progress sync fixed for seeks, stops, startup path changes, and Linux websocket reconnect windows + - Play and Resume now behave correctly (Play from beginning, Resume from saved position) + - Final progress reports reuse SubMiner's last known position when mpv resets on stop + - Windows setup login flow fixed with an IPC bridge, immediate feedback, and a timeout with inline error for unreachable servers +- **Overlay (macOS):** + - Overlay hides when mpv loses focus, is minimized, or is no longer the foreground app + - Stays stable through transient window geometry disappearances from macOS APIs and when clicking from the overlay back into mpv + - Stats overlay opened inactive so it appears over fullscreen mpv without switching Spaces + - Passthrough fixed so mpv controls stay clickable before hovering a subtitle bar +- **Yomitan Sidebar:** + - Playback stays paused for sidebar-opened Yomitan popups when auto-pause is enabled + - Popups now open when startup races the Yomitan extension load + - Sidebar mining cards use audio and images from the clicked sidebar line instead of the current primary subtitle +- **Launcher:** + - `subminer app` on Linux returns terminal control immediately + - `subminer app --setup` opens the setup flow when SubMiner is already running in the background +- **YouTube Playback:** + - Selected subtitles downloaded to local temp files so the primary bar and sidebar read the same source, with cleanup on reload and quit + - False load-failure notifications suppressed + - Tray icon created on launcher-managed playback that attaches to an already-running process +- **Shortcuts:** + - Native mpv menu shortcuts disabled during managed macOS playback so configured SubMiner shortcuts work while mpv has focus + - Custom session shortcuts including `stats.markWatchedKey` wired through mpv + - Multi-line copy/mine overlay correctly focused so number keys choose the line count on macOS and Windows +- **Controller Bindings:** + - Controller config and debug shortcuts stay closed while controller support is disabled + - Binding learn mode starts from the edit pencil + - Remaps saved per controller profile + - Binding badges also start learn mode + - Row reset buttons restore individual bindings to defaults +- **Logging:** + - `logging.level` forwarded to launcher-started and Windows shortcut-started mpv sessions, covering mpv log verbosity, plugin logging, and plugin-launched app logging + - `logging.rotation` (default 7 days) and per-component `logging.files` toggles added, with mpv logs disabled by default + - Repeated IPC socket warning spam suppressed while waiting for mpv to recreate the socket + - Windows mpv IPC, subtitle track, and Yomitan diagnostics added +- **In-Player Stats:** + - Layering fixed so delete confirmations, overlay modals, and update-check dialogs appear above the stats window + - Jellyfin playback stats grouped by item metadata so watched episodes merge with matching local library titles and keep clean display names +- **WebSocket Annotations:** + - Annotation spans and token metadata stay on the annotation WebSocket + - The regular subtitle WebSocket is plain-text only +- **Subtitle Annotation Prefetching:** Cached colored annotations and character images ready sooner for live subtitle changes without delaying raw subtitle display. +- **Windows Startup Errors:** Fatal startup failures now show a native error dialog and write details to the app log instead of exiting silently. **Docs** -- Documentation Site: Published stable docs at the site root with current development docs under `/main/`; fixed versioned docs navigation, archived page link handling, and local dev version routing; documented all previously undocumented config options including `subtitleStyle.primaryDefaultMode`, `stats.markWatchedKey`, `immersionTracking.lifetimeSummaries.*`, and all seven `mpv.*` launcher options; added Playback Startup Flow and Runtime Sockets diagrams to the architecture docs with cross-reference pointers in the MPV Plugin and Troubleshooting pages. +- **Documentation Site:** + - Published stable docs at the site root with current development docs under `/main/` + - Fixed versioned docs navigation, archived page link handling, and local dev version routing + - Documented all previously undocumented config options including `subtitleStyle.primaryDefaultMode`, `stats.markWatchedKey`, `immersionTracking.lifetimeSummaries.*`, and all seven `mpv.*` launcher options + - Added Playback Startup Flow and Runtime Sockets diagrams to the architecture docs with cross-reference pointers in the MPV Plugin and Troubleshooting pages
Internal changes **Internal** -- Release Tooling: Release-note polishing treats pending fragments and reviewed prerelease notes as a cumulative final outcome, collapsing prerelease-only fixes into the final user-facing change; prerelease generation reuses existing reviewed notes and merges only new fragment material; `make clean` preserves `release/prerelease-notes.md`. -- Tests: Removed stale Yomitan vendor source-inspection assertions for changes that were not shipped. +- **Release Tooling:** + - Release-note polishing treats pending fragments and reviewed prerelease notes as a cumulative final outcome, collapsing prerelease-only fixes into the final user-facing change + - Prerelease generation reuses existing reviewed notes and merges only new fragment material + - `make clean` preserves `release/prerelease-notes.md` +- **Tests:** Removed stale Yomitan vendor source-inspection assertions for changes that were not shipped.
diff --git a/docs/RELEASING.md b/docs/RELEASING.md index ec6b34e3..95aed8a3 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -33,7 +33,7 @@ `bun run build` When validating auto-update metadata, also run the relevant platform package build and confirm `release/` contains the generated updater metadata - (`*.yml`) and blockmaps (`*.blockmap`). + (`latest*.yml`) and blockmaps (`*.blockmap`). 8. If `docs-site/` changed, also run: `bun run docs:test` `bun run docs:build` @@ -55,7 +55,7 @@ `bun run test:env` `bun run build` When validating packaged updater output, confirm the platform build writes - `*.yml` and `*.blockmap` files under `release/`. + `latest*.yml` and `*.blockmap` files under `release/`. 5. Commit the prerelease prep (package.json version bump + the generated `release/prerelease-notes.md`). CI does not regenerate notes — it uses the committed file — so review it before committing. If you add more @@ -87,7 +87,7 @@ Notes: - Keep Cloudflare Pages Git auto-deploy disabled for `docs.subminer.moe`. Production docs are direct-uploaded by Wrangler from GitHub Actions with `--branch main`. - AUR publish is best-effort: the workflow retries transient SSH clone/push failures, then warns and leaves the GitHub Release green if AUR still fails. Follow up with a manual `git push aur master` from the AUR checkout when needed. - Required GitHub Actions secret: `AUR_SSH_PRIVATE_KEY`. Add the matching public key to your AUR account before relying on the automation. -- Release and prerelease workflows upload updater metadata (`*.yml`) and blockmaps (`*.blockmap`) alongside platform artifacts. Do not remove those files while `electron-updater` is enabled. +- Release and prerelease workflows upload updater metadata (`latest*.yml`) and blockmaps (`*.blockmap`) alongside platform artifacts. Do not remove those files while `electron-updater` is enabled. - macOS tray app updates use the standard `electron-updater`/Squirrel path. Keep `latest-mac.yml`, the macOS `SubMiner--mac.zip`, and ZIP blockmap published; Squirrel uses the ZIP payload even when the DMG remains the user-facing installer. - macOS update metadata and full ZIP downloads are routed through `/usr/bin/curl` before Squirrel installation to avoid Electron main-process network crashes on update checks. - Windows tray app updates use the standard `electron-updater`/NSIS path. Keep `latest.yml`, the Windows NSIS installer, and installer blockmap published; updater HTTP is routed through main-process fetch to avoid Electron main-process network crashes during update checks. diff --git a/release/release-notes.md b/release/release-notes.md index 30b06d2b..d4bd91de 100644 --- a/release/release-notes.md +++ b/release/release-notes.md @@ -1,60 +1,140 @@ ## Highlights ### Breaking Changes -- Subsync: The `subsync.defaultMode` config option has been removed; Subsync now always opens the manual subtitle picker regardless of any previously set default mode. +- **Subsync:** + - The `subsync.defaultMode` config option has been removed + - Subsync now always opens the manual subtitle picker regardless of any previously set default mode +- **N+1 Highlighting:** + - N+1 highlighting now has its own dedicated `ankiConnect.nPlusOne.enabled` option, separate from known-word highlighting + - It is no longer enabled automatically when known-word highlighting is on — enable it explicitly to keep N+1 annotations ### Added -- Auto-Updater: Adds tray and `subminer -u` update checks with app update prompts, launcher and Linux rofi theme auto-updates, checksum verification, configurable notifications, and an opt-in prerelease channel via `updates.channel: "prerelease"`. -- Settings Window: New dedicated Settings window via `subminer --settings` or `subminer settings`, organized into Appearance, Behavior, Anki, Input, and Integration sections; click-to-learn keybinding controls including the AniSkip button key; AnkiConnect-backed deck, field, and note-type pickers that auto-fill from the configured Anki deck; cross-category search; and live save for most options including subtitle CSS, stats keys, logging level, Jimaku, Subsync, and Anki mappings. AI and translation settings remain config-file only. -- Inline Character Portraits: Optional AniList character portraits appear inline for name-matched subtitle text; manual AniList overrides scoped per parent media directory so separate season folders maintain separate character dictionary selections. -- Log Export: Sanitized log ZIP export from the tray menu and via `subminer logs -e`, with home-directory usernames redacted from exported contents. -- Launcher CLI: `subminer --version` / `subminer -v` prints the installed app version; `mpv.profile` config and Settings support passes a named mpv profile to managed launches; bundled mpv plugin startup options are now configurable from SubMiner config. -- First-Run Setup: Optional installer for Bun and the `subminer` CLI on Linux, macOS, and Windows, including a Windows `subminer.cmd` PATH shim so `subminer` works without manually adding `SubMiner.exe` to PATH; setup recognizes existing Homebrew or user PATH installs and avoids writing into Homebrew-owned paths; includes an Open SubMiner Settings button; standalone setup app quits after completing, returning terminal control. -- Primary Subtitle Visibility on Yomitan Popup: New `subtitleStyle.primaryVisibleOnYomitanPopup` option keeps hover-mode primary subtitles visible while a Yomitan popup is open. +- **Auto-Updater:** + - Tray and `subminer -u` update checks with app update prompts + - Launcher and Linux rofi theme auto-updates + - Checksum verification and configurable notifications + - Opt-in prerelease channel via `updates.channel: "prerelease"` +- **Settings Window:** + - New dedicated Settings window via `subminer --settings` or `subminer settings`, organized into Appearance, Behavior, Anki, Input, and Integration sections + - Click-to-learn keybinding controls + - AnkiConnect-backed deck, field, and note-type pickers that auto-fill from the configured Anki deck + - Cross-category search + - Live save for most options including subtitle CSS, stats keys, logging level, Jimaku, Subsync, and Anki mappings + - AI and translation settings remain config-file only +- **Inline Character Portraits:** + - Optional AniList character portraits appear inline for name-matched subtitle text + - Manual AniList overrides scoped per parent media directory so separate season folders maintain separate character dictionary selections +- **Character Dictionary Manager:** New `Ctrl/Cmd+D` manager modal to remove, reorder, or override loaded entries. +- **Log Export:** Sanitized log ZIP export from the tray menu and via `subminer logs -e`, with home-directory usernames redacted from exported contents. +- **Launcher CLI:** + - `subminer --version` / `subminer -v` prints the installed app version + - `mpv.profile` config and Settings support passes a named mpv profile to managed launches + - Bundled mpv plugin startup options are now configurable from SubMiner config +- **First-Run Setup:** + - Optional installer for Bun and the `subminer` CLI on Linux, macOS, and Windows + - Windows `subminer.cmd` PATH shim so `subminer` works without manually adding `SubMiner.exe` to PATH + - Setup recognizes existing Homebrew or user PATH installs and avoids writing into Homebrew-owned paths + - Includes an Open SubMiner Settings button + - Standalone setup app quits after completing, returning terminal control +- **Primary Subtitle Visibility on Yomitan Popup:** New `subtitleStyle.primaryVisibleOnYomitanPopup` option keeps hover-mode primary subtitles visible while a Yomitan popup is open. ### Changed -- Subtitle Appearance Config: Primary and secondary subtitle appearance now use color controls plus CSS declaration editors, saved as `subtitleStyle.css`, `subtitleStyle.secondary.css`, and `subtitleSidebar.css`; known-word and N+1 annotation colors moved to `subtitleStyle.knownWordColor` and `subtitleStyle.nPlusOneColor`; subtitle font defaults updated to `Hiragino Sans, M PLUS 1, Source Han Sans JP, Noto Sans CJK JP`. Existing configs migrate automatically; legacy Anki color keys still accepted with deprecation warnings. -- Subtitle Style Defaults: Stronger outline-style text shadow, thicker JLPT underlines, and frequency `topX` default raised to `10000`. -- Character Dictionary: Entries scoped to the current AniList media for name matching and inline portraits; generates Japanese-only name aliases so raw romanized/English aliases no longer surface as separate results; new `Ctrl/Cmd+D` manager modal to remove, reorder, or override loaded entries; in-app AniList selector waits for an explicit search with the box prefilled from the current filename; `subtitleStyle.nameMatchEnabled` is now the sole switch for dictionary sync and builds. -- Electron Runtime: Updated from 39.8.6 to 42.2.0, returning SubMiner to a supported Electron release line. -- N+1 Highlighting Default: `ankiConnect.nPlusOne.enabled` is no longer implicitly enabled when known-word highlighting is on; existing configs that already had N+1 enabled are unchanged, but new configs must set it explicitly. -- Linux Auto-Update Flow: Linux tray "Check for Updates" now installs the new AppImage automatically, matching macOS and Windows; AppImages managed by a system package (e.g. AUR) and non-AppImage launches still use the GitHub-asset flow. -- Jellyfin Setup: Removed the server presets dropdown; setup now shows a single editable server URL field. -- Jellyfin Cast Identity: Device identity now derived from the OS hostname and always reported as SubMiner; previously configurable identity fields are ignored, preventing multiple installs from sharing a remote-session identity. -- Startup Defaults: Jellyfin remote-session startup warmup and character-name subtitle highlighting now default to off. -- Setup Appearance: Removed the bundled mpv runtime plugin readiness card from the setup flow. +- **Subtitle Appearance Config:** + - Primary and secondary subtitle appearance now use color controls plus CSS declaration editors, saved as `subtitleStyle.css`, `subtitleStyle.secondary.css`, and `subtitleSidebar.css` + - Known-word and N+1 annotation colors moved to `subtitleStyle.knownWordColor` and `subtitleStyle.nPlusOneColor` + - Subtitle font defaults updated to `Hiragino Sans, M PLUS 1, Source Han Sans JP, Noto Sans CJK JP` + - Existing configs migrate automatically; legacy Anki color keys still accepted with deprecation warnings +- **Subtitle Style Defaults:** + - Stronger outline-style text shadow + - Thicker JLPT underlines + - Frequency `topX` default raised to `10000` +- **Character Dictionary:** + - Entries scoped to the current AniList media for name matching and inline portraits + - Generates Japanese-only name aliases so raw romanized/English aliases no longer surface as separate results + - In-app AniList selector waits for an explicit search with the box prefilled from the current filename + - `subtitleStyle.nameMatchEnabled` is now the sole switch for dictionary sync and builds +- **Electron Runtime:** Updated from 39.8.6 to 42.2.0, returning SubMiner to a supported Electron release line. +- **Jellyfin Setup:** + - Removed the server presets dropdown + - Setup now shows a single editable server URL field +- **Jellyfin Cast Identity:** + - Device identity now derived from the OS hostname and always reported as SubMiner + - Previously configurable identity fields are ignored, preventing multiple installs from sharing a remote-session identity +- **Startup Defaults:** Jellyfin remote-session startup warmup and character-name subtitle highlighting now default to off. +- **Setup Appearance:** Removed the bundled mpv runtime plugin readiness card from the setup flow. ### Fixed -- AniList Progress: Progress updates fire correctly when playback reaches or skips past the watched threshold using fresh mpv timing events; season-specific results preferred for multi-season files with a clear message when the matched season is not in Planning or Watching; repeated missing-token checks no longer exhaust retry attempts or duplicate dead-letter entries. -- Anki Mining: Sentence-audio padding is opt-in by default; animated AVIF freeze-frame duration aligned to word audio length without double-counting; multi-line sentence alignment fixed for repeated subtitle text; Kiku duplicate-card detection, auto-merge, modal acknowledgment race, and field/tag ordering corrected; YouTube playback cards use mpv's resolved stream URLs; sentence cards refresh the secondary subtitle before saving; known-word cache appends correctly with multiple deck field mappings. -- Jellyfin Discovery: Startup, subtitle track selection, and duplicate ready-signal handling all fixed; paused mpv no longer misreported as playing; startup unpause no longer repeats after a manual pause or `y-t` toggle; delayed Japanese subtitle selection, later-loading foreign track hijacking, and long-lived sidebar ffmpeg extractor leaks fixed; resume corrected when a remote play command sends `StartPositionTicks: 0` despite saved progress; picker library discovery kept working regardless of app log level. -- Jellyfin Remote: Tray checkbox stays in sync on Linux after tray, CLI, or startup changes; stale discovery sessions restarted when the server no longer lists the SubMiner cast target; remote controller visibility and progress sync fixed for seeks, stops, startup path changes, and Linux websocket reconnect windows; Play and Resume now behave correctly (Play from beginning, Resume from saved position); final progress reports reuse SubMiner's last known position when mpv resets on stop; Windows setup login flow fixed with an IPC bridge, immediate feedback, and a timeout with inline error for unreachable servers. -- Jellyfin Subtitles and Overlay: Subtitle overlay shown automatically during Jellyfin playback; `y-t` toggle made reliable and sticky across stream redirects; managed subtitle defaults re-armed on redirect; passive Linux/Hyprland overlay shows no longer steal keyboard focus from mpv; subtitle timing improved with preferred embedded streams over external sidecars, correct Japanese-vs-English cue offset handling, per-stream delay shift restoration, and transient track-list read failure tolerance. -- Overlay (macOS): Overlay hides when mpv loses focus, is minimized, or is no longer the foreground app; stable through transient window geometry disappearances from macOS APIs and when clicking from the overlay back into mpv; stats overlay opened inactive so it appears over fullscreen mpv without switching Spaces; passthrough fixed so mpv controls stay clickable before hovering a subtitle bar; window-tracker polling reduced while mpv is stably focused. -- Overlay (Linux / Hyprland): Placement refreshes after leaving fullscreen; overlay stays above mpv after focus changes from clicks or movement; Settings and Yomitan windows promoted above the subtitle overlay instead of opening behind it; overlay hides when the character dictionary modal opens, including during AniList lookup. -- Overlay Lifecycle: First startup subtitle primed before autoplay resumes so the overlay renders text before playback begins; overlay and subtitle stream kept alive after `y-r` restart with correct Linux bounds reapplication; launcher-owned playback quits SubMiner on end while background/tray sessions stay alive; subtitle sync modal fixed on macOS so it no longer flashes on first attempt or leaves stale state; Windows managed mpv launches from a background instance now correctly receive the start command, retarget the new socket, bind to the player window, and receive startup overlay options. -- Yomitan Sidebar: Playback stays paused for sidebar-opened Yomitan popups when auto-pause is enabled; fixed popups not opening when startup races the Yomitan extension load; sidebar mining cards use audio and images from the clicked sidebar line instead of the current primary subtitle. -- Launcher: Warm launches reuse a running background instance, reapply preferred subtitles, and close launcher-owned tray apps after playback ends; videos stay paused until subtitle priming and tokenization readiness complete; `subminer settings` on macOS exits cleanly when the window is closed; `subminer app` on Linux returns terminal control immediately; Linux first-run installs build with a valid Bun shebang; `subminer app --setup` opens the setup flow when SubMiner is already running in background. -- YouTube Playback: Selected subtitles downloaded to local temp files so the primary bar and sidebar read the same source, with cleanup on reload and quit; false load-failure notifications suppressed; tray icon created on launcher-managed playback that attaches to an already-running process; mpv plugin no longer starts a second SubMiner instance for app-owned YouTube playback. -- Shortcuts: Native mpv menu shortcuts disabled during managed macOS playback so configured SubMiner shortcuts work while mpv has focus; custom session shortcuts including `stats.markWatchedKey` wired through mpv; multi-line copy/mine overlay correctly focused so number keys choose the line count on macOS and Windows. -- Controller Bindings: Controller config and debug shortcuts stay closed while controller support is disabled; binding learn mode starts from the edit pencil; remaps saved per controller profile; binding badges also start learn mode; row reset buttons restore individual bindings to defaults. -- Logging: `logging.level` forwarded to launcher-started and Windows shortcut-started mpv sessions covering mpv log verbosity, plugin logging, and plugin-launched app logging; `logging.rotation` (default 7 days) and per-component `logging.files` toggles added with mpv logs disabled by default; repeated IPC socket warning spam suppressed while waiting for mpv to recreate the socket; Windows mpv IPC, subtitle track, and Yomitan diagnostics added. -- Updater: Linux `subminer -u` performs release updates independently of any running tray app using GitHub release metadata; macOS update dialogs from `subminer -u` reliably appear in the foreground with a manual-install message for builds that cannot apply native updates; macOS and Linux `electron-updater` routes through `/usr/bin/curl` to avoid Electron network crashes; Windows automatic updates keep the native NSIS install path while routing updater HTTP through main-process fetch to avoid delayed exit after launch. -- In-Player Stats: Layering fixed so delete confirmations, overlay modals, and update-check dialogs appear above the stats window; Jellyfin playback stats grouped by item metadata so watched episodes merge with matching local library titles and keep clean display names. -- Tray: Tray stays running when Yomitan settings are closed; settings loading no longer blocks other tray actions; Yomitan extension refreshes serialized at startup; embedded popup preview disabled to prevent renderer hangs during sidebar navigation; Windows "Open SubMiner Setup" action opens the setup window correctly after first-run is complete; session help modal close fixed without mpv running. -- Discord Rich Presence: No longer falls back to Jellyfin stream URLs; Jellyfin playback titles primed before stream loading so presence shows the show/episode title instead of a URL. -- WebSocket Annotations: Annotation spans and token metadata stay on the annotation WebSocket; the regular subtitle WebSocket is plain-text only. -- Subtitle Frequency Highlighting: Frequency annotations kept for determiner-led noun compounds like `その場` while still filtering standalone determiners; fixed for Yomitan single-token compounds with internal particles such as `目の前` while keeping pure grammar/kana helper spans unannotated. -- Subtitle Annotation Prefetching: Cached colored annotations and character images ready sooner for live subtitle changes without delaying raw subtitle display. -- Packaging: macOS compiled mpv window helper correctly built into `dist/scripts` and bundled, preventing fallback to slow Swift source startup; stale Windows helper resource entry removed; one-shot `make clean build install` AppImage flows fixed so install picks up the AppImage built earlier in the same invocation. -- Windows Startup Errors: Fatal startup failures now show a native error dialog and write details to the app log instead of exiting silently. +- **AniList Progress:** + - Progress updates fire correctly when playback reaches or skips past the watched threshold, using fresh mpv timing events + - Season-specific results preferred for multi-season files, with a clear message when the matched season is not in Planning or Watching + - Repeated missing-token checks no longer exhaust retry attempts or duplicate dead-letter entries +- **Anki Mining:** + - Sentence-audio padding is opt-in by default + - Animated AVIF freeze-frame duration aligned to word audio length without double-counting + - Multi-line sentence alignment fixed for repeated subtitle text + - Kiku duplicate-card detection, auto-merge, modal acknowledgment race, and field/tag ordering corrected + - YouTube playback cards use mpv's resolved stream URLs + - Sentence cards refresh the secondary subtitle before saving +- **Jellyfin Discovery:** + - Startup, subtitle track selection, and duplicate ready-signal handling all fixed + - Paused mpv no longer misreported as playing + - Resume corrected when a remote play command sends `StartPositionTicks: 0` despite saved progress +- **Jellyfin Remote:** + - Tray checkbox stays in sync on Linux after tray, CLI, or startup changes + - Remote controller visibility and progress sync fixed for seeks, stops, startup path changes, and Linux websocket reconnect windows + - Play and Resume now behave correctly (Play from beginning, Resume from saved position) + - Final progress reports reuse SubMiner's last known position when mpv resets on stop + - Windows setup login flow fixed with an IPC bridge, immediate feedback, and a timeout with inline error for unreachable servers +- **Overlay (macOS):** + - Overlay hides when mpv loses focus, is minimized, or is no longer the foreground app + - Stays stable through transient window geometry disappearances from macOS APIs and when clicking from the overlay back into mpv + - Stats overlay opened inactive so it appears over fullscreen mpv without switching Spaces + - Passthrough fixed so mpv controls stay clickable before hovering a subtitle bar +- **Yomitan Sidebar:** + - Playback stays paused for sidebar-opened Yomitan popups when auto-pause is enabled + - Popups now open when startup races the Yomitan extension load + - Sidebar mining cards use audio and images from the clicked sidebar line instead of the current primary subtitle +- **Launcher:** + - `subminer app` on Linux returns terminal control immediately + - `subminer app --setup` opens the setup flow when SubMiner is already running in the background +- **YouTube Playback:** + - Selected subtitles downloaded to local temp files so the primary bar and sidebar read the same source, with cleanup on reload and quit + - False load-failure notifications suppressed + - Tray icon created on launcher-managed playback that attaches to an already-running process +- **Shortcuts:** + - Native mpv menu shortcuts disabled during managed macOS playback so configured SubMiner shortcuts work while mpv has focus + - Custom session shortcuts including `stats.markWatchedKey` wired through mpv + - Multi-line copy/mine overlay correctly focused so number keys choose the line count on macOS and Windows +- **Controller Bindings:** + - Controller config and debug shortcuts stay closed while controller support is disabled + - Binding learn mode starts from the edit pencil + - Remaps saved per controller profile + - Binding badges also start learn mode + - Row reset buttons restore individual bindings to defaults +- **Logging:** + - `logging.level` forwarded to launcher-started and Windows shortcut-started mpv sessions, covering mpv log verbosity, plugin logging, and plugin-launched app logging + - `logging.rotation` (default 7 days) and per-component `logging.files` toggles added, with mpv logs disabled by default + - Repeated IPC socket warning spam suppressed while waiting for mpv to recreate the socket + - Windows mpv IPC, subtitle track, and Yomitan diagnostics added +- **In-Player Stats:** + - Layering fixed so delete confirmations, overlay modals, and update-check dialogs appear above the stats window + - Jellyfin playback stats grouped by item metadata so watched episodes merge with matching local library titles and keep clean display names +- **WebSocket Annotations:** + - Annotation spans and token metadata stay on the annotation WebSocket + - The regular subtitle WebSocket is plain-text only +- **Subtitle Annotation Prefetching:** Cached colored annotations and character images ready sooner for live subtitle changes without delaying raw subtitle display. +- **Windows Startup Errors:** Fatal startup failures now show a native error dialog and write details to the app log instead of exiting silently. ### Docs -- Documentation Site: Published stable docs at the site root with current development docs under `/main/`; fixed versioned docs navigation, archived page link handling, and local dev version routing; documented all previously undocumented config options including `subtitleStyle.primaryDefaultMode`, `stats.markWatchedKey`, `immersionTracking.lifetimeSummaries.*`, and all seven `mpv.*` launcher options; added Playback Startup Flow and Runtime Sockets diagrams to the architecture docs with cross-reference pointers in the MPV Plugin and Troubleshooting pages. +- **Documentation Site:** + - Published stable docs at the site root with current development docs under `/main/` + - Fixed versioned docs navigation, archived page link handling, and local dev version routing + - Documented all previously undocumented config options including `subtitleStyle.primaryDefaultMode`, `stats.markWatchedKey`, `immersionTracking.lifetimeSummaries.*`, and all seven `mpv.*` launcher options + - Added Playback Startup Flow and Runtime Sockets diagrams to the architecture docs with cross-reference pointers in the MPV Plugin and Troubleshooting pages ## Installation diff --git a/src/prerelease-workflow.test.ts b/src/prerelease-workflow.test.ts index 1b1ea5f9..129966a5 100644 --- a/src/prerelease-workflow.test.ts +++ b/src/prerelease-workflow.test.ts @@ -69,14 +69,19 @@ test('prerelease workflow builds and uploads all release platforms', () => { test('prerelease workflow publishes the same release assets as the stable workflow', () => { assert.match( prereleaseWorkflow, - /files=\(release\/\*\.AppImage release\/\*\.dmg release\/\*\.exe release\/\*\.zip release\/\*\.tar\.gz release\/\*\.yml release\/\*\.blockmap dist\/launcher\/subminer\)/, + /files=\(release\/\*\.AppImage release\/\*\.dmg release\/\*\.exe release\/\*\.zip release\/\*\.tar\.gz release\/latest\*\.yml release\/\*\.blockmap dist\/launcher\/subminer\)/, ); assert.match( prereleaseWorkflow, - /artifacts=\([\s\S]*release\/\*\.exe[\s\S]*release\/\*\.yml[\s\S]*release\/\*\.blockmap[\s\S]*release\/SHA256SUMS\.txt[\s\S]*\)/, + /artifacts=\([\s\S]*release\/\*\.exe[\s\S]*release\/latest\*\.yml[\s\S]*release\/\*\.blockmap[\s\S]*release\/SHA256SUMS\.txt[\s\S]*\)/, ); }); +test('prerelease workflow uploads updater metadata without builder debug YAML files', () => { + assert.match(prereleaseWorkflow, /release\/latest\*\.yml/); + assert.doesNotMatch(prereleaseWorkflow, /release\/\*\.yml/); +}); + test('prerelease workflow writes checksum entries using release asset basenames', () => { assert.match(prereleaseWorkflow, /: > release\/SHA256SUMS\.txt/); assert.match(prereleaseWorkflow, /for file in "\$\{files\[@\]\}"; do/); diff --git a/src/release-workflow.test.ts b/src/release-workflow.test.ts index cc678f1b..641ed17c 100644 --- a/src/release-workflow.test.ts +++ b/src/release-workflow.test.ts @@ -105,14 +105,19 @@ test('release workflow generates release notes from committed changelog output', test('release workflow includes the Windows installer in checksums and uploaded assets', () => { assert.match( releaseWorkflow, - /files=\(release\/\*\.AppImage release\/\*\.dmg release\/\*\.exe release\/\*\.zip release\/\*\.tar\.gz release\/\*\.yml release\/\*\.blockmap dist\/launcher\/subminer\)/, + /files=\(release\/\*\.AppImage release\/\*\.dmg release\/\*\.exe release\/\*\.zip release\/\*\.tar\.gz release\/latest\*\.yml release\/\*\.blockmap dist\/launcher\/subminer\)/, ); assert.match( releaseWorkflow, - /artifacts=\([\s\S]*release\/\*\.exe[\s\S]*release\/\*\.yml[\s\S]*release\/\*\.blockmap[\s\S]*release\/SHA256SUMS\.txt[\s\S]*\)/, + /artifacts=\([\s\S]*release\/\*\.exe[\s\S]*release\/latest\*\.yml[\s\S]*release\/\*\.blockmap[\s\S]*release\/SHA256SUMS\.txt[\s\S]*\)/, ); }); +test('release workflow uploads updater metadata without builder debug YAML files', () => { + assert.match(releaseWorkflow, /release\/latest\*\.yml/); + assert.doesNotMatch(releaseWorkflow, /release\/\*\.yml/); +}); + test('release package metadata enables GitHub updater metadata without builder uploads', () => { assert.equal(packageJson.build?.publish?.[0]?.provider, 'github'); assert.equal(packageJson.build?.publish?.[0]?.owner, 'ksyasuda');