From 29332b103ef1ee1f88243e49014c9402719090af Mon Sep 17 00:00:00 2001 From: sudacode Date: Mon, 13 Jul 2026 23:40:28 -0700 Subject: [PATCH] Consolidate sync changelog fragments into one entry - Merge the five separate sync change fragments (launcher command, UI window, close/quit fixes, active-session double-count, monthly rollup timezone) into a single changes/sync.md - Fold kana-pos-content-classification.md into annotation-noise-rule-table.md - Drop the now-stale Unreleased sections from CHANGELOG.md and docs-site/changelog.md - Tweak tsukihime-english-subtitles.md wording --- CHANGELOG.md | 6 ------ changes/annotation-noise-rule-table.md | 1 + changes/kana-pos-content-classification.md | 4 ---- changes/launcher-sync-command.md | 4 ---- changes/sync-active-session-frequency-double-count.md | 4 ---- changes/sync-monthly-rollup-timezone.md | 4 ---- changes/sync-ui-window-close-quit.md | 6 ------ changes/sync-ui-window.md | 5 ----- changes/sync.md | 8 ++++++++ changes/tsukihime-english-subtitles.md | 2 +- docs-site/changelog.md | 6 ------ 11 files changed, 10 insertions(+), 40 deletions(-) delete mode 100644 changes/kana-pos-content-classification.md delete mode 100644 changes/launcher-sync-command.md delete mode 100644 changes/sync-active-session-frequency-double-count.md delete mode 100644 changes/sync-monthly-rollup-timezone.md delete mode 100644 changes/sync-ui-window-close-quit.md delete mode 100644 changes/sync-ui-window.md create mode 100644 changes/sync.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f7f2ffc..eaf5e2d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,5 @@ # Changelog -## Unreleased - -### Added -- Stats Sync Without the Launcher: The stats sync engine now runs only inside the app. The sync window and the `subminer sync` command both delegate to `SubMiner --sync-cli` (headless, works over SSH with no display), so neither machine needs bun or the command-line launcher. A remote machine only needs SubMiner itself, found automatically as the app binary or via the launcher proxy. -- Stats Sync With Windows Remotes: Sync now detects the remote shell (POSIX, cmd, or PowerShell) and manages remote temp files through SubMiner itself (`sync --make-temp`/`--remove-temp`) instead of `mktemp`/`rm`, so a Windows machine with the built-in OpenSSH Server works as a sync remote; SubMiner is found in its default Windows install location automatically. - ## v0.18.0 (2026-07-10) ### Added diff --git a/changes/annotation-noise-rule-table.md b/changes/annotation-noise-rule-table.md index 2c35f034..3d748b1d 100644 --- a/changes/annotation-noise-rule-table.md +++ b/changes/annotation-noise-rule-table.md @@ -2,3 +2,4 @@ type: fixed area: overlay - Applied configured primary POS exclusions consistently to merged trailing quote-particle tokens, preserved annotations for supplementary-plane kanji, and stopped treating katakana punctuation as kana-only annotation noise. +- Kept kanji vocabulary tagged `名詞/非自立` eligible for N+1 highlighting, consistent with frequency, JLPT, and vocabulary persistence. diff --git a/changes/kana-pos-content-classification.md b/changes/kana-pos-content-classification.md deleted file mode 100644 index 149304c7..00000000 --- a/changes/kana-pos-content-classification.md +++ /dev/null @@ -1,4 +0,0 @@ -type: fixed -area: overlay - -- Kept kanji vocabulary tagged `名詞/非自立` eligible for N+1 highlighting, consistent with frequency, JLPT, and vocabulary persistence. diff --git a/changes/launcher-sync-command.md b/changes/launcher-sync-command.md deleted file mode 100644 index db351d83..00000000 --- a/changes/launcher-sync-command.md +++ /dev/null @@ -1,4 +0,0 @@ -type: added -area: launcher - -- Added `subminer sync ` to merge immersion stats and watch history between two machines over SSH, with `--push` and `--pull` for one-way insert-only transfers. Each side snapshots its database (`VACUUM INTO`), snapshots are exchanged with `scp`, and each machine merges the other's data as an insert-only union keyed on session UUIDs / video keys / series title keys, so re-syncing is idempotent and nothing is double-counted. Lifetime totals and daily/monthly rollups are updated incrementally (history older than the session retention window is preserved); remote-only historical rollups are copied only when they do not conflict with retained local session history. `subminer sync --snapshot ` and `subminer sync --merge ` expose the underlying steps for manual transfers. The command refuses to run while the stats daemon or a live mpv session is active (`--force` overrides), ignores stale mpv socket files, keeps the guard in place through local/remote merges, supplies standard SubMiner and Bun paths to non-interactive SSH commands, verifies the remote launcher starts, reports remote stderr on failures, and aborts on stats schema version mismatches. diff --git a/changes/sync-active-session-frequency-double-count.md b/changes/sync-active-session-frequency-double-count.md deleted file mode 100644 index 99e227e0..00000000 --- a/changes/sync-active-session-frequency-double-count.md +++ /dev/null @@ -1,4 +0,0 @@ -type: fixed -area: sync - -- Fixed word/kanji frequencies double-counting across syncs when the remote snapshot contained a stale active session (e.g. after a crash): a word new to the local machine adopted the remote's full lifetime frequency, which already included the active session's partial occurrences, and those occurrences were added again when the session finalized and synced. Newly adopted words/kanji now exclude active-session counts, which arrive once the session completes. diff --git a/changes/sync-monthly-rollup-timezone.md b/changes/sync-monthly-rollup-timezone.md deleted file mode 100644 index bc4c7aca..00000000 --- a/changes/sync-monthly-rollup-timezone.md +++ /dev/null @@ -1,4 +0,0 @@ -type: fixed -area: sync - -- Fixed stats sync copying a remote daily rollup that should have been recomputed when the day was the 1st of a month and the machine was on a negative UTC offset (the Americas), which could leave that day's totals wrong after a sync. The rollup day is now read back at local noon instead of UTC midnight, so it always resolves to the correct civil month. diff --git a/changes/sync-ui-window-close-quit.md b/changes/sync-ui-window-close-quit.md deleted file mode 100644 index 12e5ade6..00000000 --- a/changes/sync-ui-window-close-quit.md +++ /dev/null @@ -1,6 +0,0 @@ -type: fixed -area: sync - -- Fixed the app staying alive in the background after closing a standalone Sync window (`subminer sync --ui`) on macOS. The quit re-issued after async will-quit cleanup was dropped by Electron when the cleanup settled within the same tick as the will-quit dispatch; the re-quit now runs on a fresh macrotask, and the standalone Sync window close path uses the same forced-exit fallback as SIGTERM. Windows opened from the tray menu of a running app are unaffected: closing them still leaves the app running. -- Fixed a sync run hanging when the sync child exited without emitting a terminal result: the run waited on `close`, which a descendant holding the inherited stdio pipes can delay indefinitely, stalling the quit-time sync shutdown. Cancelling now settles the run as soon as the child has exited, and an exit with no result settles after a bounded stdout drain window. -- Fixed sync progress and error text being corrupted when a multibyte character (e.g. a Japanese media title) straddled a chunk boundary in the sync child's output. diff --git a/changes/sync-ui-window.md b/changes/sync-ui-window.md deleted file mode 100644 index 5ac2970e..00000000 --- a/changes/sync-ui-window.md +++ /dev/null @@ -1,5 +0,0 @@ -type: added -area: sync - -- Added a sync window (`subminer sync --ui`, or **Sync Stats & History** in the tray menu) for cross-machine immersion sync: saved devices with per-host direction (two-way/push/pull) and remove, one-click sync with live stage-by-stage progress and separate merge summaries for this machine and the remote device, connection testing for first-time setup, cancellable live syncs while the app, stats server, or playback is active, and manual database snapshots (create/merge/reveal/delete, stored in `/tmp/subminer-db-snapshots/` by default). Live sync uses a consistent WAL snapshot and transactional merge, and excludes unfinished sessions until a later sync sees them finalized. Hosts with auto-sync enabled are synced in the background on a configurable interval, including during playback, with results reported as overlay notifications. Hosts synced from the CLI are remembered in `/sync-hosts.json` and show up in the window automatically. `subminer sync --ui` launches silently in the background and returns the shell immediately; closing that standalone Sync window shuts down the app. -- Added `subminer sync --check` to test the SSH connection and remote launcher availability without syncing, using bounded noninteractive probes and settling when the check process exits even if an inherited output pipe remains open, without dropping terminal progress that races process exit. Linux AppImage sync commands clear inherited GUI startup argument transport before launching the bundled engine, then exit directly, so sync window checks and remote snapshots never initialize the GUI or require a display server. Added `subminer sync --json` for machine-readable NDJSON progress output (the protocol the sync window consumes). diff --git a/changes/sync.md b/changes/sync.md new file mode 100644 index 00000000..dab85613 --- /dev/null +++ b/changes/sync.md @@ -0,0 +1,8 @@ +type: added +area: sync + +- Added cross-machine immersion sync for stats and watch history over SSH, available as a window (**Sync Stats & History** in the tray menu, or `subminer sync --ui`) and as a command (`subminer sync `, with `--push` / `--pull` for one-way insert-only transfers). The window keeps saved devices with per-host direction, one-click sync with live stage-by-stage progress and separate merge summaries for each machine, connection testing for first-time setup, cancellable runs while the app/stats server/playback is active, and manual database snapshots (create/merge/reveal/delete, stored in `/tmp/subminer-db-snapshots/` by default). Hosts with auto-sync enabled sync in the background on a configurable interval, including during playback, with results reported as overlay notifications; hosts synced from the CLI are remembered in `/sync-hosts.json` and appear in the window automatically. +- Merges are an insert-only union keyed on session UUIDs / video keys / series title keys, so re-syncing is idempotent and nothing is double-counted: each side snapshots its database (`VACUUM INTO`) from a consistent WAL point, snapshots are exchanged with `scp`, and each machine merges the other's data transactionally. Lifetime totals and daily/monthly rollups are updated incrementally (history older than the session retention window is preserved), unfinished sessions are excluded until a later sync sees them finalized, and remote-only historical rollups are copied only when they do not conflict with retained local session history. Sync aborts on stats schema version mismatches and refuses to run while the stats daemon or a live mpv session is active (`--force` overrides). +- The sync engine runs only inside the app: the sync window and the `subminer sync` command both delegate to `SubMiner --sync-cli` (headless, works over SSH with no display), so neither machine needs bun or the command-line launcher. A remote machine only needs SubMiner itself, found automatically as the app binary or via the launcher proxy. +- Windows remotes are supported: sync detects the remote shell (POSIX, cmd, or PowerShell) and manages remote temp files through SubMiner itself (`sync --make-temp` / `--remove-temp`) instead of `mktemp` / `rm`, so a Windows machine with the built-in OpenSSH Server works as a sync remote, found in its default Windows install location automatically. +- Added supporting flags: `subminer sync --check` tests the SSH connection and remote launcher availability without syncing, `subminer sync --snapshot ` and `--merge ` expose the underlying steps for manual transfers, and `subminer sync --json` emits machine-readable NDJSON progress (the protocol the sync window consumes). diff --git a/changes/tsukihime-english-subtitles.md b/changes/tsukihime-english-subtitles.md index ee20bd7a..03d4a077 100644 --- a/changes/tsukihime-english-subtitles.md +++ b/changes/tsukihime-english-subtitles.md @@ -1,4 +1,4 @@ type: added area: overlay -- Added a TsukiHime integration for downloading primary and secondary subtitles, mirroring the Jimaku flow: `Ctrl+Shift+T` (configurable via `shortcuts.openTsukihime`) opens an in-overlay modal with a Japanese primary tab and a secondary tab that follows `secondarySub.secondarySubLanguages`. It parses the current video filename, searches TsukiHime releases, lists extracted text subtitle tracks filtered by the active tab, then downloads the chosen track, decompresses it (requires the `xz` binary), saves it next to the video with a language suffix (`