mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-04-09 16:19:25 -07:00
Compare commits
19 Commits
v0.9.3
...
81daf79492
| Author | SHA1 | Date | |
|---|---|---|---|
|
81daf79492
|
|||
|
5763650036
|
|||
|
5ea064a446
|
|||
|
4c6e4b9f0b
|
|||
|
a9ad268393
|
|||
|
87f7b87b5a
|
|||
|
36e5a07b92
|
|||
|
45d183d02d
|
|||
|
a42fe599cb
|
|||
|
76b5ab68ba
|
|||
|
0c3ec7a567
|
|||
|
01c171629a
|
|||
|
09b112f25f
|
|||
|
3df5d4d6a2
|
|||
|
bbdd98cbff
|
|||
|
b049cf388d
|
|||
|
de111dbf8d
|
|||
|
ea86f4e504
|
|||
|
bb54898747
|
74
CHANGELOG.md
74
CHANGELOG.md
@@ -1,74 +1,20 @@
|
||||
# Changelog
|
||||
|
||||
## v0.9.3 (2026-03-25)
|
||||
|
||||
### Changed
|
||||
- Launcher: Moved YouTube primary subtitle language defaults to `youtube.primarySubLanguages`.
|
||||
- Launcher: Removed the placeholder YouTube subtitle retime step and now uses downloaded primary subtitle tracks directly, so there is no fake path rewrite before playback/sidebar loading.
|
||||
- YouTube: Removed the `src/core/services/youtube/retime` helper and its tests after retiring the internal retime strategy.
|
||||
- Docs: Clarified optional `alass` / `ffsubsync` subtitle-sync requirements and setup steps, including fallback behavior when sync tools are absent.
|
||||
- Launcher: Removed the old `youtubeSubgen.primarySubLanguages` config path from the generated config and docs.
|
||||
|
||||
## v0.9.2 (2026-03-25)
|
||||
|
||||
### Fixed
|
||||
- Overlay: Fixed overlay pointer tracking so Windows click-through toggles immediately when the cursor enters or leaves subtitle regions, without waiting for a later hover resync.
|
||||
- Overlay: Fixed Windows overlay window tracking on scaled displays by converting native tracked window bounds to Electron DIP coordinates before applying overlay bounds.
|
||||
- Launcher: Fixed Windows direct `--youtube-play` startup so MPV boots reliably, stays paused until the app-owned subtitle flow is ready, and reuses an already-running SubMiner instance when available.
|
||||
- Launcher: Fixed standalone Windows `--youtube-play` sessions so closing MPV fully exits SubMiner instead of leaving hidden overlay windows or a background process behind.
|
||||
- Overlay: Fixed `subminer <youtube-url>` on Linux so the YouTube playback flow waits for Yomitan to load before creating the overlay window, avoiding the broken lookup popup state that previously required a manual overlay refresh.
|
||||
|
||||
## v0.9.1 (2026-03-24)
|
||||
|
||||
### Changed
|
||||
- Release: Reduced packaged release size by excluding duplicate `extraResources` payload and pruning docs, tests, sourcemaps, and other source-only files from Electron bundles.
|
||||
|
||||
### Fixed
|
||||
- Overlay: Restored controller navigation and lookup/mining controls while the subtitle sidebar is open, while keeping true modal dialogs blocking controller actions.
|
||||
- Tokenizer: Fixed subtitle annotation clearing so explanatory contrast endings like `んですけど` are excluded consistently across the shared tokenizer filter and annotation stage.
|
||||
|
||||
## v0.9.0 (2026-03-23)
|
||||
|
||||
### Added
|
||||
- Docs: Added a new WebSocket / Texthooker API and integration guide covering WebSocket payloads, custom client patterns, mpv plugin automation, and webhook-style relay examples. Linked from configuration and mining workflow docs for easier discovery.
|
||||
|
||||
### Changed
|
||||
- Launcher: Added an app-owned YouTube subtitle flow that pauses mpv, uses absPlayer-style YouTube timedtext parsing/conversion to download subtitle tracks, and injects them as external files before playback resumes.
|
||||
- Launcher: Changed YouTube subtitle startup to auto-load the best-available primary and secondary subtitle tracks at launch instead of forcing the picker modal first. Secondary subtitle failures no longer block playback resume.
|
||||
- Launcher: Added `Ctrl+Alt+C` as the default keybinding to manually open the YouTube subtitle picker during active YouTube playback.
|
||||
- Launcher: Added yt-dlp metadata probing so YouTube playback and immersion tracking record canonical video title and channel metadata.
|
||||
- Launcher: Stopped forcing `--ytdl-raw-options=` before user-provided mpv options so existing YouTube cookie integrations in user `--args` are no longer clobbered.
|
||||
- Launcher: Disabled mpv native YouTube subtitle auto-loading for the app-owned flow so injected external subtitle files remain authoritative.
|
||||
- Launcher: Added OSD status messages for YouTube playback startup, subtitle acquisition, and subtitle loading so the flow stays visible before and during the picker.
|
||||
- Subtitle Sidebar: Added startup-auto-open controls and resume positioning improvements so the sidebar jumps directly to the first resolved active cue.
|
||||
- Subtitle Sidebar: Improved subtitle prefetch and embedded overlay passthrough sync so sidebar and overlay subtitle states stay consistent across media transitions.
|
||||
- Subtitle Sidebar: Updated scroll handling, embedded layout styling, and active-cue visual behavior.
|
||||
- Stats: Stats Library tab now displays YouTube video title, channel name, and channel thumbnail for YouTube media entries, with retry logic to fill in metadata that arrives after initial load.
|
||||
|
||||
### Fixed
|
||||
- Launcher: Fixed Anki media mining for mpv YouTube streams by unwrapping the stream URL so audio and screenshot capture work correctly for YouTube playback sessions.
|
||||
- Immersion: Fixed YouTube media path handling in the immersion runtime and tracking so YouTube sessions record correct media references, AniList guessing skips YouTube URLs, and post-watch state transitions do not fire for YouTube media.
|
||||
- Launcher: Fixed startup-launched YouTube playback so primary subtitle overlay updates continue after auto-load completes.
|
||||
- Launcher: Fixed auto-loaded YouTube primary subtitles so parsed cues appear in the subtitle sidebar without needing a manual picker retry.
|
||||
- Launcher: Fixed the YouTube picker to guard against duplicate subtitle submissions and tightened YouTube URL detection so follow-up runtime flows only treat real YouTube hosts as YouTube playback.
|
||||
- Launcher: Fixed primary subtitle failure notifications being shown while app-owned YouTube subtitle probing and downloads are still in flight.
|
||||
- Launcher: Preserved existing authoritative YouTube subtitle tracks when available; downloaded tracks are used only to fill missing sides, and native mpv secondary subtitle rendering is hidden so the overlay remains the sole secondary display.
|
||||
|
||||
## v0.8.0 (2026-03-22)
|
||||
|
||||
### Added
|
||||
- Overlay: Added the subtitle sidebar feature with a new `subtitleSidebar` configuration surface and rendered sidebar modal with cue list rendering, click-to-seek, active-cue highlighting, and embedded layout support.
|
||||
- IPC: Added sidebar snapshot plumbing between renderer and main process for overlay/sidebar synchronization.
|
||||
|
||||
### Changed
|
||||
- Config: Added hot-reloadable sidebar options for enablement, layout, visibility, typography, opacity, sizing, and interaction behavior (`autoOpen`, `pauseOnHover`, `autoScroll`, toggle key).
|
||||
- Docs: Added full `subtitleSidebar` documentation coverage, including sample config, option table, and toggle shortcut notes.
|
||||
- Runtime: Improved subtitle prefetch/rendering flow so sidebar and overlay subtitle states stay in sync across media transitions.
|
||||
- Docs: Refreshed the vendored Texthooker docs/index.html bundle to match the latest local build artifacts.
|
||||
|
||||
### Fixed
|
||||
- Overlay: Kept sidebar cue tracking stable across playback transitions and timing edge cases.
|
||||
- Overlay: Improved sidebar resume/start behavior to jump directly to the first resolved active cue.
|
||||
- Overlay: Stopped stale subtitle refreshes from regressing active-cue and text state.
|
||||
- Anki: Known-word cache refreshes now reconcile Anki changes incrementally instead of wiping and rebuilding on startup, mined cards can append their word into the cache immediately through a new default-enabled config flag, and explicit refreshes now run through `subminer doctor --refresh-known-words`.
|
||||
- Subtitle: Restored known-word coloring and JLPT underlines for subtitle tokens like `大体` when the subtitle token is kanji but the known-word cache only matches the kana reading.
|
||||
- Stats: Episode progress in the anime page now uses the last ended playback position instead of cumulative active watch time, avoiding distorted percentages after rewatches or repeated sessions.
|
||||
- Stats: Anime episode progress now keeps the latest known playback position through active-session checkpoints and stale-session recovery, so recently watched episodes no longer lose their progress percentage.
|
||||
- Stats: Anime episode progress now falls back to the latest retained subtitle/event timing when a session is missing a persisted playback-position checkpoint, so older watch sessions no longer get stuck at `0%` progress.
|
||||
- Overlay: Kept subtitle sidebar cue tracking stable across transitions by avoiding cue-line regression on subtitle timing edge cases and stale text updates.
|
||||
- Overlay: Improved sidebar config by documenting and exposing layout mode and typography options (`layout`, `fontFamily`, `fontSize`) in the generated documentation flow.
|
||||
- Overlay: Added `subtitleSidebar.autoOpen` (default `false`) to open the subtitle sidebar once during overlay startup when the sidebar feature is enabled.
|
||||
- Overlay: Made subtitle sidebar resume/start positioning jump directly to the first resolved active cue instead of smooth-scrolling through the full list, while keeping smooth auto-follow for later cue changes.
|
||||
|
||||
## v0.7.0 (2026-03-19)
|
||||
|
||||
|
||||
236
README.md
236
README.md
@@ -1,168 +1,60 @@
|
||||
<div align="center">
|
||||
|
||||
<img src="assets/SubMiner.png" width="160" alt="SubMiner logo">
|
||||
<img src="assets/SubMiner.png" width="140" alt="SubMiner logo">
|
||||
|
||||
# SubMiner
|
||||
|
||||
## Turn mpv into a sentence-mining workstation.
|
||||
**Sentence-mine from mpv — look up words, one-key Anki export, immersion tracking.**
|
||||
|
||||
Look up words with Yomitan, export to Anki in one key, track your immersion — all without leaving mpv.
|
||||
|
||||
[](https://www.gnu.org/licenses/gpl-3.0)
|
||||
[](https://github.com/ksyasuda/SubMiner)
|
||||
[](https://docs.subminer.moe)
|
||||
[](https://aur.archlinux.org/packages/subminer-bin)
|
||||
|
||||
[](./assets/minecard.mp4)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0)
|
||||
[](https://github.com/ksyasuda/SubMiner)
|
||||
[](https://docs.subminer.moe)
|
||||
[](https://aur.archlinux.org/packages/subminer-bin)
|
||||
|
||||
</div>
|
||||
|
||||
## How It Works
|
||||
|
||||
SubMiner runs as an invisible Electron overlay on top of mpv. Subtitles render as an interactive layer. Move your cursor over any word and trigger a [Yomitan](https://github.com/yomidevs/yomitan) lookup. Press one key to snapshot the sentence, audio, and screenshot into Anki via AnkiConnect.
|
||||
|
||||
## Features
|
||||
|
||||
### Dictionary Lookups
|
||||
|
||||
Yomitan runs inside the overlay. Trigger a lookup on any word for full dictionary popups — definitions, pitch accent, frequency data — without ever leaving mpv.
|
||||
|
||||
<div align="center">
|
||||
<img src="docs-site/public/screenshots/yomitan-lookup.png" width="800" alt="Yomitan dictionary popup over annotated subtitles in mpv">
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
### Instant Anki Mining
|
||||
|
||||
Create an Anki card with the sentence, audio clip, screenshot, and machine translation from the exact playback moment with one key press, click, or controller input.
|
||||
|
||||
<div align="center">
|
||||
<img src="docs-site/public/screenshots/one-key-mining.png" width="800" alt="Anki card created from SubMiner with sentence, audio, and screenshot">
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
### Reading Annotations
|
||||
|
||||
Real-time subtitle annotations with frequency highlighting, JLPT tags, N+1 targeting, and a character name dictionary. Known words fade back; new words stand out. Grammar-only tokens render as plain text so you focus on what matters.
|
||||
|
||||
<div align="center">
|
||||
<img src="docs-site/public/screenshots/annotations.png" width="800" alt="Annotated subtitles with frequency coloring, JLPT underlines, and N+1 targets">
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
### Immersion Dashboard
|
||||
|
||||
Local stats dashboard — watch time, anime library, vocabulary growth, mining throughput, session history, and trends. All stored locally, no third-party tracking.
|
||||
|
||||
<div align="center">
|
||||
<img src="docs-site/public/screenshots/stats-overview.png" width="800" alt="Stats dashboard showing watch time, cards mined, streaks, and tracking data">
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
### Integrations
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><b>YouTube</b></td>
|
||||
<td>Auto-loaded yt-dlp subtitle tracks at startup with a manual overlay picker on demand (<code>Ctrl+Alt+C</code>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>AniList</b></td>
|
||||
<td>Automatic episode tracking and progress sync</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Jellyfin</b></td>
|
||||
<td>Browse and launch media from your Jellyfin server</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Jimaku</b></td>
|
||||
<td>Search and download Japanese subtitles</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>alass / ffsubsync</b></td>
|
||||
<td>Automatic subtitle retiming — requires <code>alass</code> or <code>ffsubsync</code> on your <code>PATH</code> (optional; subtitle syncing is disabled without them)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>WebSocket</b></td>
|
||||
<td>Annotated subtitle feed for external clients (texthooker pages, custom tools)</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div align="center">
|
||||
<img src="docs-site/public/screenshots/texthooker.png" width="800" alt="Texthooker page receiving annotated subtitle lines via WebSocket">
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
---
|
||||
|
||||
## Requirements
|
||||
SubMiner is an Electron overlay for [mpv](https://mpv.io) that turns video into a sentence-mining workstation. Look up any word with [Yomitan](https://github.com/yomidevs/yomitan), mine it to Anki with one key, and track your immersion over time.
|
||||
|
||||
| | Required | Optional |
|
||||
| -------------- | --------------------------------------- | -------------------------------------- |
|
||||
| **Player** | [`mpv`](https://mpv.io) with IPC socket | — |
|
||||
| **Processing** | `ffmpeg`, `mecab` + `mecab-ipadic` | `guessit` (AniSkip), `alass` / `ffsubsync` (subtitle sync) |
|
||||
| **Media** | — | `yt-dlp`, `chafa`, `ffmpegthumbnailer` |
|
||||
| **Selection** | — | `fzf` / `rofi` |
|
||||
<div align="center">
|
||||
|
||||
> [!NOTE]
|
||||
> [`bun`](https://bun.sh) is required if building from source or using the CLI wrapper: `subminer`. Pre-built releases (AppImage, DMG, installer) do not require it.
|
||||
[](./assets/minecard.mp4)
|
||||
|
||||
**Platform-specific:**
|
||||
</div>
|
||||
|
||||
| Linux | macOS | Windows |
|
||||
| ----------------------------------- | ------------------------ | ------------- |
|
||||
| `hyprctl` or `xdotool` + `xwininfo` | Accessibility permission | No extra deps |
|
||||
## Features
|
||||
|
||||
<details>
|
||||
<summary><b>Arch Linux</b></summary>
|
||||
**Dictionary lookups** — Yomitan runs inside the overlay. Hover or navigate to any word for full dictionary popups without leaving mpv.
|
||||
|
||||
```bash
|
||||
paru -S --needed mpv ffmpeg mecab-git mecab-ipadic
|
||||
# Optional
|
||||
paru -S --needed yt-dlp fzf rofi chafa ffmpegthumbnailer xdotool xorg-xwininfo
|
||||
# Optional: subtitle sync (install at least one for subtitle syncing to work)
|
||||
paru -S --needed alass python-ffsubsync
|
||||
# X11 / XWAYLAND
|
||||
paru -S --needed xdotool xorg-xwininfo
|
||||
```
|
||||
**One-key Anki mining** — Press one key to create a card with the sentence, audio clip, screenshot, and machine translation from the exact playback moment.
|
||||
|
||||
</details>
|
||||
<div align="center">
|
||||
<img src="docs-site/public/screenshots/yomitan-lookup.png" width="800" alt="Yomitan popup with dictionary entry and mine button over annotated subtitles in mpv">
|
||||
</div>
|
||||
|
||||
<details>
|
||||
<summary><b>macOS</b></summary>
|
||||
**Reading annotations** — Real-time subtitle annotations with N+1 targeting, frequency highlighting, JLPT tags, and a character name dictionary. Grammar-only tokens render as plain text.
|
||||
|
||||
```bash
|
||||
brew install mpv ffmpeg mecab mecab-ipadic
|
||||
# Optional
|
||||
brew install yt-dlp fzf rofi chafa ffmpegthumbnailer
|
||||
# Optional: subtitle sync (install at least one for subtitle syncing to work)
|
||||
brew install alass
|
||||
pip install ffsubsync
|
||||
```
|
||||
<div align="center">
|
||||
<img src="docs-site/public/screenshots/annotations.png" width="800" alt="Annotated subtitles with frequency highlighting, JLPT underlines, known words, and N+1 targets">
|
||||
</div>
|
||||
|
||||
Grant Accessibility permission to SubMiner in **System Settings > Privacy & Security > Accessibility**.
|
||||
**Immersion dashboard** — Local stats dashboard with watch time, anime progress, vocabulary growth, mining throughput, and session history.
|
||||
|
||||
</details>
|
||||
<div align="center">
|
||||
<img src="docs-site/public/screenshots/stats-overview.png" width="800" alt="Stats dashboard with watch time, cards mined, streaks, and tracking snapshot">
|
||||
</div>
|
||||
|
||||
<details>
|
||||
<summary><b>Windows</b></summary>
|
||||
**Integrations** — AniList episode tracking, Jellyfin remote playback, Jimaku subtitle downloads, alass/ffsubsync, and an annotated websocket feed for external clients.
|
||||
|
||||
Install [`mpv`](https://mpv.io/installation/) and [`ffmpeg`](https://ffmpeg.org/download.html) and ensure both are on your `PATH`.
|
||||
|
||||
For MeCab, install [MeCab for Windows](https://taku910.github.io/mecab/#download) with the UTF-8 dictionary.
|
||||
|
||||
</details>
|
||||
<div align="center">
|
||||
<img src="docs-site/public/screenshots/texthooker.png" width="800" alt="Texthooker page with annotated subtitle lines and frequency highlighting">
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Install
|
||||
### Install
|
||||
|
||||
<details>
|
||||
<summary><b>Arch Linux (AUR)</b></summary>
|
||||
@@ -196,63 +88,53 @@ wget https://github.com/ksyasuda/SubMiner/releases/latest/download/subminer -O ~
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>macOS</b></summary>
|
||||
<summary><b>macOS / Windows / From source</b></summary>
|
||||
|
||||
Download the latest DMG or ZIP from [GitHub Releases](https://github.com/ksyasuda/SubMiner/releases/latest) and drag `SubMiner.app` into `/Applications`.
|
||||
**macOS** — Download the latest DMG/ZIP from [GitHub Releases](https://github.com/ksyasuda/SubMiner/releases/latest) and drag `SubMiner.app` into `/Applications`.
|
||||
|
||||
**Windows** — Download the latest installer or portable `.zip` from [GitHub Releases](https://github.com/ksyasuda/SubMiner/releases/latest). Keep `mpv` on `PATH`.
|
||||
|
||||
**From source** — See [docs.subminer.moe/installation#from-source](https://docs.subminer.moe/installation#from-source).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Windows</b></summary>
|
||||
### First Launch
|
||||
|
||||
Download the latest installer or portable `.zip` from [GitHub Releases](https://github.com/ksyasuda/SubMiner/releases/latest). Make sure `mpv` is on your `PATH`.
|
||||
Run `SubMiner.AppImage` (Linux), `SubMiner.app` (macOS), or `SubMiner.exe` (Windows). On first launch, SubMiner starts in the tray, creates a default config, and opens a setup popup where you can install the mpv plugin and configure Yomitan dictionaries.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>From source</b></summary>
|
||||
|
||||
See the [build-from-source guide](https://docs.subminer.moe/installation#from-source).
|
||||
|
||||
</details>
|
||||
|
||||
### 2. First Launch
|
||||
|
||||
Run the app. On first launch SubMiner starts in the system tray, creates a default config, and opens a setup popup to install the mpv plugin and configure Yomitan dictionaries.
|
||||
|
||||
### 3. Mine
|
||||
### Mine
|
||||
|
||||
```bash
|
||||
subminer video.mkv # play video with overlay
|
||||
subminer --start video.mkv # explicit overlay start
|
||||
subminer stats # open immersion dashboard
|
||||
subminer stats -b # stats daemon in background
|
||||
subminer stats -s # stop background stats daemon
|
||||
subminer video.mkv # auto-starts overlay + resumes playback
|
||||
subminer --start video.mkv # explicit overlay start (if plugin auto_start=no)
|
||||
subminer stats # open the immersion dashboard
|
||||
subminer stats -b # keep the stats daemon running in background
|
||||
subminer stats -s # stop the dedicated stats daemon
|
||||
subminer stats cleanup # repair/prune stored stats vocabulary rows
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Requirements
|
||||
|
||||
| Required | Optional |
|
||||
| ------------------------------------------------------ | ----------------------------- |
|
||||
| [`mpv`](https://mpv.io) with IPC socket | `yt-dlp` |
|
||||
| `ffmpeg` | `guessit` (AniSkip detection) |
|
||||
| `mecab` + `mecab-ipadic` | `fzf` / `rofi` |
|
||||
| [`bun`](https://bun.sh) (source builds, Linux wrapper) | `chafa`, `ffmpegthumbnailer` |
|
||||
| Linux: `hyprctl` or `xdotool` + `xwininfo` | |
|
||||
| macOS: Accessibility permission | |
|
||||
|
||||
Windows uses native window tracking and does not need the Linux compositor tools.
|
||||
|
||||
## Documentation
|
||||
|
||||
Full guides on configuration, Anki setup, Jellyfin, immersion tracking, and more: **[docs.subminer.moe](https://docs.subminer.moe)**
|
||||
|
||||
---
|
||||
Full guides on configuration, Anki, Jellyfin, immersion tracking, and more at **[docs.subminer.moe](https://docs.subminer.moe)**.
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
SubMiner builds on the work of these open-source projects:
|
||||
|
||||
| Project | Role |
|
||||
| ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
|
||||
| [Anacreon-Script](https://github.com/friedrich-de/Anacreon-Script) | Inspiration for the mining workflow |
|
||||
| [asbplayer](https://github.com/killergerbah/asbplayer) | Inspiration for subtitle sidebar and logic for YouTube subtitle parsing |
|
||||
| [Bee's Character Dictionary](https://github.com/bee-san/Japanese_Character_Name_Dictionary) | Character name recognition in subtitles |
|
||||
| [GameSentenceMiner](https://github.com/bpwhelan/GameSentenceMiner) | Inspiration for Electron overlay with Yomitan integration |
|
||||
| [jellyfin-mpv-shim](https://github.com/jellyfin/jellyfin-mpv-shim) | Jellyfin integration |
|
||||
| [Jimaku.cc](https://jimaku.cc) | Japanese subtitle search and downloads |
|
||||
| [Renji's Texthooker Page](https://github.com/Renji-XD/texthooker-ui) | Base for the WebSocket texthooker integration |
|
||||
| [Yomitan](https://github.com/yomidevs/yomitan) | Dictionary engine powering all lookups and the morphological parser |
|
||||
| [yomitan-jlpt-vocab](https://github.com/stephenmk/yomitan-jlpt-vocab) | JLPT level tags for vocabulary |
|
||||
Built on [GameSentenceMiner](https://github.com/bpwhelan/GameSentenceMiner), [Renji's Texthooker Page](https://github.com/Renji-XD/texthooker-ui), [Anacreon-Script](https://github.com/friedrich-de/Anacreon-Script), and [Bee's Character Dictionary](https://github.com/bee-san/Japanese_Character_Name_Dictionary). Subtitles from [Jimaku.cc](https://jimaku.cc). Lookups via [Yomitan](https://github.com/yomidevs/yomitan). JLPT tags from [yomitan-jlpt-vocab](https://github.com/stephenmk/yomitan-jlpt-vocab).
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
---
|
||||
id: TASK-143
|
||||
title: Keep character dictionary auto-sync non-blocking during startup
|
||||
status: Done
|
||||
status: In Progress
|
||||
assignee:
|
||||
- codex
|
||||
created_date: '2026-03-09 01:45'
|
||||
updated_date: '2026-03-23 03:22'
|
||||
updated_date: '2026-03-20 09:22'
|
||||
labels:
|
||||
- dictionary
|
||||
- startup
|
||||
@@ -18,7 +18,7 @@ references:
|
||||
- >-
|
||||
/home/sudacode/projects/japanese/SubMiner/src/main/runtime/current-media-tokenization-gate.ts
|
||||
priority: high
|
||||
ordinal: 144500
|
||||
ordinal: 38500
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
@@ -5,7 +5,7 @@ status: Done
|
||||
assignee:
|
||||
- '@codex'
|
||||
created_date: '2026-03-19 17:46'
|
||||
updated_date: '2026-03-23 03:22'
|
||||
updated_date: '2026-03-19 17:54'
|
||||
labels:
|
||||
- stats
|
||||
- immersion-tracking
|
||||
@@ -19,7 +19,6 @@ references:
|
||||
- src/core/services/stats-server.ts
|
||||
parent_task_id: TASK-177
|
||||
priority: medium
|
||||
ordinal: 132500
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
@@ -5,7 +5,7 @@ status: Done
|
||||
assignee:
|
||||
- '@codex'
|
||||
created_date: '2026-03-19 19:38'
|
||||
updated_date: '2026-03-23 03:22'
|
||||
updated_date: '2026-03-19 19:40'
|
||||
labels:
|
||||
- stats
|
||||
- immersion-tracking
|
||||
@@ -17,7 +17,6 @@ references:
|
||||
- stats/src/lib/dashboard-data.ts
|
||||
parent_task_id: TASK-177
|
||||
priority: medium
|
||||
ordinal: 130500
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
@@ -5,7 +5,7 @@ status: Done
|
||||
assignee:
|
||||
- '@codex'
|
||||
created_date: '2026-03-19 20:15'
|
||||
updated_date: '2026-03-23 03:22'
|
||||
updated_date: '2026-03-19 20:17'
|
||||
labels:
|
||||
- launcher
|
||||
- stats
|
||||
@@ -19,7 +19,6 @@ references:
|
||||
- src/main/runtime/stats-cli-command.test.ts
|
||||
parent_task_id: TASK-177
|
||||
priority: medium
|
||||
ordinal: 129500
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
@@ -5,7 +5,7 @@ status: Done
|
||||
assignee:
|
||||
- codex
|
||||
created_date: '2026-03-19 20:31'
|
||||
updated_date: '2026-03-23 03:22'
|
||||
updated_date: '2026-03-19 20:52'
|
||||
labels:
|
||||
- bug
|
||||
- stats
|
||||
@@ -17,7 +17,6 @@ references:
|
||||
- >-
|
||||
/Users/sudacode/projects/japanese/SubMiner/stats/src/lib/session-detail.test.tsx
|
||||
parent_task_id: TASK-182
|
||||
ordinal: 128500
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
@@ -5,7 +5,7 @@ status: Done
|
||||
assignee:
|
||||
- codex
|
||||
created_date: '2026-03-18 00:29'
|
||||
updated_date: '2026-03-23 03:22'
|
||||
updated_date: '2026-03-18 00:55'
|
||||
labels:
|
||||
- stats
|
||||
- performance
|
||||
@@ -22,7 +22,6 @@ references:
|
||||
- stats/src/types/stats.ts
|
||||
- stats/src/lib/dashboard-data.ts
|
||||
priority: medium
|
||||
ordinal: 138500
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
@@ -5,7 +5,7 @@ status: Done
|
||||
assignee:
|
||||
- codex
|
||||
created_date: '2026-03-17 23:15'
|
||||
updated_date: '2026-03-23 03:22'
|
||||
updated_date: '2026-03-17 23:18'
|
||||
labels:
|
||||
- pr-review
|
||||
- stats
|
||||
@@ -16,7 +16,6 @@ references:
|
||||
- src/core/services/immersion-tracker-service.ts
|
||||
- src/core/services/immersion-tracker-service.test.ts
|
||||
priority: medium
|
||||
ordinal: 139500
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
id: TASK-192
|
||||
title: 'Assess remaining PR #19 review batch'
|
||||
status: Done
|
||||
assignee:
|
||||
- codex
|
||||
created_date: '2026-03-17 23:24'
|
||||
updated_date: '2026-03-17 23:42'
|
||||
labels:
|
||||
- pr-review
|
||||
- stats
|
||||
- docs
|
||||
milestone: m-1
|
||||
dependencies: []
|
||||
references:
|
||||
- docs/superpowers/plans/2026-03-12-immersion-stats-page.md
|
||||
- src/core/services/immersion-tracker/__tests__/query.test.ts
|
||||
- src/core/services/ipc.ts
|
||||
- src/core/services/stats-server.ts
|
||||
- src/main.ts
|
||||
- src/renderer/handlers/keyboard.ts
|
||||
- stats/src
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Validate the remaining PR #19 automated review findings against the current branch, implement only the technically correct fixes, and document which comments are stale, already addressed, or not warranted.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [x] #1 Each remaining review comment is classified as actionable, already fixed, stale, or not warranted
|
||||
- [x] #2 Confirmed bugs or correctness issues are fixed with focused regression coverage where it fits
|
||||
- [x] #3 Final notes record which comments were intentionally not applied and why
|
||||
<!-- AC:END -->
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
<!-- SECTION:PLAN:BEGIN -->
|
||||
1. Inspect the referenced files in batches and compare each comment against current branch behavior.
|
||||
2. Separate correctness/security regressions from stylistic nitpicks and already-fixed items.
|
||||
3. Add tests first for confirmed behavior bugs where practical, apply the smallest safe fixes, and rerun targeted verification.
|
||||
<!-- SECTION:PLAN:END -->
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
<!-- SECTION:NOTES:BEGIN -->
|
||||
Swept the pasted PR #19 review batch against the current branch.
|
||||
|
||||
Classification:
|
||||
- Already fixed on current branch: `src/core/services/immersion-tracker/__tests__/query.test.ts` cleanup rethrow, `src/core/services/ipc.ts` limit validation, `src/core/services/stats-server.ts` max-limit parsing and CORS removal, `src/main.ts` quit-path TDZ issue, `src/renderer/handlers/keyboard.ts` stats-toggle shortcut ordering/config usage, `stats/src/components/vocabulary/WordList.tsx`, `stats/src/hooks/useSessions.ts`, `stats/src/hooks/useTrends.ts` stale-error reset, `src/core/services/__tests__/stats-server.test.ts` kanji endpoint/readability notes, `src/core/services/stats-window.ts`, `stats/src/App.tsx`, `stats/src/components/layout/TabBar.tsx`, `stats/src/components/overview/QuickStats.tsx`, `stats/src/components/overview/WatchTimeChart.tsx`, `stats/src/components/sessions/SessionDetail.tsx`, `stats/src/components/sessions/SessionRow.tsx`, `stats/src/components/trends/DateRangeSelector.tsx`, `stats/src/components/vocabulary/KanjiBreakdown.tsx`, `stats/src/components/vocabulary/VocabularyTab.tsx`, `stats/src/hooks/useVocabulary.ts`, `stats/src/lib/api-client.ts`, `stats/src/types/stats.ts`.
|
||||
- Stale / obsolete against current architecture: `docs/superpowers/plans/2026-03-12-immersion-stats-page.md` path does not exist on this branch; `stats/src/components/trends/TrendsTab.tsx` / monthly-range comments describe older client-side aggregation code that is no longer present because trends now come from `getTrendsDashboard`.
|
||||
- Not warranted as written: `stats/src/lib/formatters.ts` no longer emits negative `Xd ago`; current code short-circuits future timestamps to `just now`, so the reported bug condition is gone even though the suggested wording differs.
|
||||
- Actionable and fixed now: `src/core/services/ipc.ts` no-tracker `statsGetOverview` fallback omitted required hint fields (`totalLookupCount`, `totalLookupHits`, `newWordsToday`, `newWordsThisWeek`). Added the missing fields in the fallback object and updated IPC tests to assert the full shape.
|
||||
|
||||
Verification:
|
||||
- `bun test src/core/services/ipc.test.ts`
|
||||
- `bun test src/core/services/ipc.test.ts --test-name-pattern "empty stats overview shape without a tracker|validates and clamps stats request limits"`
|
||||
- `bash .agents/skills/subminer-change-verification/scripts/classify_subminer_diff.sh src/core/services/ipc.ts src/core/services/ipc.test.ts`
|
||||
|
||||
Repo verifier note:
|
||||
- `bash .agents/skills/subminer-change-verification/scripts/verify_subminer_change.sh --lane core src/core/services/ipc.ts src/core/services/ipc.test.ts`
|
||||
- That verifier run captured a temporary `bun run typecheck` failure in `src/anki-integration.test.ts` and `src/core/services/__tests__/stats-server.test.ts`, but a fresh rerun after the follow-up validation no longer reproduces those diagnostics.
|
||||
- Fresh verification: `bun run typecheck` passes locally.
|
||||
- artifact dir from the earlier failed verifier snapshot: `.tmp/skill-verification/subminer-verify-20260317-234027-i6QJ3n`
|
||||
<!-- SECTION:NOTES:END -->
|
||||
|
||||
## Final Summary
|
||||
|
||||
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
|
||||
The larger pasted PR #19 review batch was not mostly new work on the current branch. After verifying each item against the live code, almost all were already fixed or stale. One additional item was still actionable: the no-tracker fallback returned by `statsGetOverview` in `src/core/services/ipc.ts` omitted required hint fields, which made the fallback shape inconsistent with the normal overview payload. That fallback is now fixed and covered by IPC tests.
|
||||
|
||||
Count-wise: the earlier open CodeRabbit service comments contributed 2 actionable fixes, and this larger pasted batch contributed 1 additional actionable fix on top of those.
|
||||
<!-- SECTION:FINAL_SUMMARY:END -->
|
||||
@@ -5,7 +5,7 @@ status: Done
|
||||
assignee:
|
||||
- codex
|
||||
created_date: '2026-03-20 00:12'
|
||||
updated_date: '2026-03-23 03:22'
|
||||
updated_date: '2026-03-20 00:14'
|
||||
labels:
|
||||
- stats
|
||||
- immersion-tracker
|
||||
@@ -17,7 +17,6 @@ references:
|
||||
- src/core/services/immersion-tracker/query.ts
|
||||
- src/core/services/immersion-tracker-service.test.ts
|
||||
priority: medium
|
||||
ordinal: 127500
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
---
|
||||
id: TASK-194
|
||||
title: App-owned YouTube subtitle picker flow
|
||||
status: Done
|
||||
assignee: []
|
||||
created_date: '2026-03-18 07:52'
|
||||
updated_date: '2026-03-23 03:22'
|
||||
labels: []
|
||||
dependencies: []
|
||||
references:
|
||||
- /home/sudacode/projects/japanese/SubMiner/launcher/youtube/orchestrator.ts
|
||||
- /home/sudacode/projects/japanese/SubMiner/launcher/youtube/manual-subs.ts
|
||||
- /home/sudacode/projects/japanese/SubMiner/src/core/services/tokenizer.ts
|
||||
documentation:
|
||||
- /home/sudacode/projects/japanese/SubMiner/youtube.md
|
||||
priority: medium
|
||||
ordinal: 137500
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Replace the YouTube subtitle-generation-first flow with an app-owned picker flow that boots mpv paused, opens an overlay track picker, downloads selected subtitles into external subtitle files, and preserves generation as an explicit mode. Keep the existing SubMiner tokenization and annotation pipeline as the downstream consumer of downloaded subtitle files.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [x] #1 Launcher and app expose YouTube subtitle acquisition modes `download` and `generate`, with `download` as the default.
|
||||
- [x] #2 YouTube playback boots mpv paused and presents an overlay selection UI for primary and secondary subtitle choices.
|
||||
- [x] #3 Selected YouTube subtitle tracks are downloaded to external subtitle files and loaded into mpv before playback resumes.
|
||||
- [x] #4 `generate` mode preserves the existing subtitle generation path as an explicit opt-in behavior.
|
||||
- [x] #5 Downloaded YouTube subtitle files integrate with the existing SubMiner subtitle/tokenization/annotation pipeline without regressing current overlay behavior.
|
||||
- [x] #6 Tests cover mode selection, subtitle-track enumeration/selection flow, and the paused bootstrap plus app handoff path.
|
||||
- [x] #7 User-facing config and launcher docs are updated to describe the new modes and default behavior.
|
||||
<!-- AC:END -->
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
id: TASK-194
|
||||
title: Redesign YouTube subtitle acquisition around download-first track selection
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-03-18 07:52'
|
||||
labels: []
|
||||
dependencies: []
|
||||
references:
|
||||
- /home/sudacode/projects/japanese/SubMiner/launcher/youtube/orchestrator.ts
|
||||
- /home/sudacode/projects/japanese/SubMiner/launcher/youtube/manual-subs.ts
|
||||
- /home/sudacode/projects/japanese/SubMiner/src/core/services/tokenizer.ts
|
||||
documentation:
|
||||
- /home/sudacode/projects/japanese/SubMiner/youtube.md
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Replace the current YouTube subtitle-generation-first flow with a download-first flow that enumerates available YouTube subtitle tracks, prompts for primary and secondary track selection before playback, downloads selected tracks into external subtitle files for mpv, and preserves generation as an explicit mode and as fallback behavior in auto mode. Keep the existing SubMiner tokenization and annotation pipeline as the downstream consumer of downloaded subtitle files.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Launcher and config expose YouTube subtitle acquisition modes `download`, `generate`, and `auto`, with `download` as the default for launcher YouTube playback.
|
||||
- [ ] #2 YouTube playback enumerates available subtitle tracks before mpv launch and presents a selection UI that supports primary and secondary subtitle choices.
|
||||
- [ ] #3 Selected YouTube subtitle tracks are downloaded to external subtitle files and loaded into mpv before playback starts when download mode succeeds.
|
||||
- [ ] #4 `auto` mode attempts download-first for the selected tracks and falls back to generation only when required tracks cannot be downloaded or download fails.
|
||||
- [ ] #5 `generate` mode preserves the existing whisper/AI generation path as an explicit opt-in behavior.
|
||||
- [ ] #6 Downloaded YouTube subtitle files integrate with the existing SubMiner subtitle/tokenization/annotation pipeline without regressing current overlay behavior.
|
||||
- [ ] #7 Tests cover mode selection, subtitle-track enumeration/selection flow, download-first success path, and fallback behavior for auto mode.
|
||||
- [ ] #8 User-facing config and launcher docs are updated to describe the new modes and default behavior.
|
||||
<!-- AC:END -->
|
||||
@@ -4,16 +4,13 @@ title: Fix subtitle prefetch cache-key mismatch and active-cue window
|
||||
status: Done
|
||||
assignee: []
|
||||
created_date: '2026-03-18 16:05'
|
||||
updated_date: '2026-03-23 03:22'
|
||||
labels: []
|
||||
dependencies: []
|
||||
references:
|
||||
- >-
|
||||
/home/sudacode/projects/japanese/SubMiner/src/core/services/subtitle-processing-controller.ts
|
||||
- >-
|
||||
/home/sudacode/projects/japanese/SubMiner/src/core/services/subtitle-prefetch.ts
|
||||
- /home/sudacode/projects/japanese/SubMiner/src/core/services/subtitle-processing-controller.ts
|
||||
- /home/sudacode/projects/japanese/SubMiner/src/core/services/subtitle-prefetch.ts
|
||||
documentation: []
|
||||
priority: high
|
||||
ordinal: 136500
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
@@ -4,19 +4,15 @@ title: Eliminate per-line plain subtitle flash on prefetch cache hit
|
||||
status: Done
|
||||
assignee: []
|
||||
created_date: '2026-03-18 16:28'
|
||||
updated_date: '2026-03-23 03:22'
|
||||
labels: []
|
||||
dependencies:
|
||||
- TASK-196
|
||||
references:
|
||||
- >-
|
||||
/home/sudacode/projects/japanese/SubMiner/src/core/services/subtitle-processing-controller.ts
|
||||
- >-
|
||||
/home/sudacode/projects/japanese/SubMiner/src/main/runtime/mpv-main-event-actions.ts
|
||||
- >-
|
||||
/home/sudacode/projects/japanese/SubMiner/src/main/runtime/mpv-main-event-main-deps.ts
|
||||
- /home/sudacode/projects/japanese/SubMiner/src/core/services/subtitle-processing-controller.ts
|
||||
- /home/sudacode/projects/japanese/SubMiner/src/main/runtime/mpv-main-event-actions.ts
|
||||
- /home/sudacode/projects/japanese/SubMiner/src/main/runtime/mpv-main-event-main-deps.ts
|
||||
documentation: []
|
||||
priority: high
|
||||
ordinal: 135500
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
@@ -4,7 +4,6 @@ title: Forward launcher log level into mpv plugin script opts
|
||||
status: Done
|
||||
assignee: []
|
||||
created_date: '2026-03-18 21:16'
|
||||
updated_date: '2026-03-23 03:22'
|
||||
labels: []
|
||||
dependencies:
|
||||
- TASK-198
|
||||
@@ -13,8 +12,8 @@ references:
|
||||
- /home/sudacode/projects/japanese/SubMiner/launcher/mpv.ts
|
||||
- /home/sudacode/projects/japanese/SubMiner/launcher/main.test.ts
|
||||
- /home/sudacode/projects/japanese/SubMiner/launcher/aniskip-metadata.test.ts
|
||||
documentation: []
|
||||
priority: medium
|
||||
ordinal: 134500
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user