clean up and add new showcase videos

This commit is contained in:
2026-03-10 02:32:27 -07:00
parent b32c3cf58c
commit ff5ecdaded
20 changed files with 206 additions and 13 deletions

View File

@@ -1,10 +1,11 @@
---
id: TASK-133
title: Improve AniList character dictionary parity with upstream guide
status: To Do
assignee: []
status: In Progress
assignee:
- OpenCode
created_date: '2026-03-08 21:06'
updated_date: '2026-03-08 21:35'
updated_date: '2026-03-10 06:18'
labels:
- dictionary
- anilist
@@ -28,15 +29,11 @@ priority: high
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Plan and implement guide-faithful parity improvements for the AniList character dictionary flow inside SubMiner's current single-media generation path. Scope includes AniList first/last name hints, hint-aware reading generation for kanji/native names, expanded honorific coverage, 160x200 JPEG thumbnail handling, and AniList 429 retry/backoff behavior.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 AniList character queries include first/last name fields and preserve them through runtime data models.
- [ ] #2 Dictionary generation uses hint-aware name splitting and reading generation for kanji and mixed native names, not only kana-only readings.
- [ ] #3 Honorific generation is expanded substantially toward upstream coverage and is covered by regression tests.
@@ -44,10 +41,20 @@ Plan and implement guide-faithful parity improvements for the AniList character
- [ ] #5 AniList requests handle 429 responses with bounded exponential backoff and tests cover retry behavior.
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Add targeted regression tests in `src/main/character-dictionary-runtime.test.ts` for AniList 429 retry behavior and thumbnail conversion/fallback image paths before changing runtime code.
2. Update `fetchAniList` in `src/main/character-dictionary-runtime.ts` to retry 429 responses with bounded exponential backoff or `Retry-After` delays, while preserving existing request pacing hook behavior.
3. Update `downloadCharacterImage` to run downloaded bytes through `convertImageToThumbnail`, returning `.jpg` paths when conversion succeeds and preserving original bytes/extensions on fallback.
4. Run focused character-dictionary tests first, then broader required verification commands if the focused lane passes.
5. Record progress against acceptance criteria #4 and #5 in TASK-133 notes/final checklist once verified.
<!-- SECTION:PLAN:END -->
## Implementation Notes
<!-- SECTION:NOTES:BEGIN -->
Approved design and implementation plan captured on 2026-03-08. Scope stays within current single-media AniList dictionary flow; excludes username-driven CURRENT-list fetching and Yomitan auto-update schema work.
Resumed TASK-133 to finish remaining AC #4 image thumbnail wiring and AC #5 AniList 429 retry handling. Existing code already contains helper constants/functions; next work is wiring plus regression coverage.
<!-- SECTION:NOTES:END -->

View File

@@ -0,0 +1,99 @@
---
id: TASK-151
title: Keep JLPT underline color stable during Yomitan text selection
status: Done
assignee:
- OpenCode
created_date: '2026-03-10 06:42'
updated_date: '2026-03-10 07:54'
labels: []
dependencies: []
references:
- src/renderer/style.css
- src/renderer/subtitle-render.test.ts
documentation:
- ../subminer-docs/development.md
- ../subminer-docs/architecture.md
priority: medium
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Fix the subtitle overlay so JLPT underlines keep their JLPT color when Yomitan lookups trigger hover/selection styling on tokens that are also known, N+1, or frequency-highlighted.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [x] #1 JLPT-tagged subtitle tokens keep their JLPT underline color during hover/selection states used by Yomitan lookup.
- [x] #2 Tokens that combine JLPT with known, N+1, name-match, or frequency styling preserve their primary text color while keeping the JLPT underline color.
- [x] #3 Renderer regression coverage verifies the JLPT underline color remains explicit in the stylesheet for combined styling states.
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Revert the temporary box-shadow JLPT marker experiment and restore native JLPT underline styling in `src/renderer/style.css`.
2. Add explicit JLPT hover/selection color rules with higher specificity so Yomitan lookup highlight states cannot repaint the underline to the token hover color.
3. Update `src/renderer/subtitle-render.test.ts` to verify JLPT hover/selection rules keep the predefined JLPT underline color, then rerun focused and relevant verification commands.
4. Add JLPT-specific `text-decoration-color` overrides directly on child `.c` spans and their hover/selection states, since Yomitan lookup likely paints the decorated child text runs rather than only the parent token span.
<!-- SECTION:PLAN:END -->
## Implementation Notes
<!-- SECTION:NOTES:BEGIN -->
Added a renderer regression test that asserts JLPT underline color stays explicit through hover and selection styling.
Updated `src/renderer/style.css` to route JLPT underline color through `--subtitle-jlpt-underline-color` and re-apply it on word/character hover and selection states.
Verification: `bun test src/renderer/subtitle-render.test.ts`, `bun run typecheck`, `bun run test:fast`, `bun run build`, `bun run changelog:lint`, `bunx prettier --check src/renderer/style.css src/renderer/subtitle-render.test.ts changes/jlpt-underline-yomitan.md`. `bun run format:check:src` still fails because of unrelated existing formatting issues in `src/main-entry-runtime.test.ts` and `src/main-entry-runtime.ts`.
User verified the original CSS variable propagation fix did not resolve the live issue; continuing investigation and reopening the task.
Confirmed Chromium was repainting native `text-decoration` underlines with the selected text color; reproduced it in a temporary browser repro and verified that switching the JLPT marker to an inset box-shadow keeps the JLPT color stable during selection.
Replaced the previous native underline approach with a fragment-safe JLPT marker using `box-shadow` plus `box-decoration-break`, then updated stylesheet regression coverage to match the new implementation.
Verification: `bun test src/renderer/subtitle-render.test.ts`, `bunx prettier --check src/renderer/style.css src/renderer/subtitle-render.test.ts`, `bun run typecheck`, `bun run test:fast`, `bun run build`.
User requested reverting the box-shadow marker experiment. Narrowing the fix to preserve native JLPT underline color during Yomitan hover/selection instead of changing the underline rendering method.
Reverted the box-shadow experiment per user request. Restored native JLPT underline styling and added explicit JLPT hover/selection rules so Yomitan lookup states keep the predefined JLPT underline color with `!important`.
Verification after revert/fix: `bun test src/renderer/subtitle-render.test.ts`, `bunx prettier --check src/renderer/style.css src/renderer/subtitle-render.test.ts`, `bun run typecheck`, `bun run build`.
Issue still reproduces specifically during Shift-held Yomitan lookup. Investigating decoration propagation onto child `.c` spans during lookup-triggered hover/selection states.
Added JLPT-specific `text-decoration-color` overrides directly to child `.c` spans and their hover/selection states, in addition to the token span itself, so lookup-triggered decoration painting on child runs keeps the JLPT color.
Verification: `bun test src/renderer/subtitle-render.test.ts`, `bunx prettier --check src/renderer/style.css src/renderer/subtitle-render.test.ts`, `bun run typecheck`, `bun run build`.
Added a final high-specificity combined-state JLPT override after the annotation hover/selection rules. It targets tokens that are both JLPT-tagged and known/N+1/name-match/frequency-highlighted, forcing `text-decoration-color` back to the JLPT variable after the later annotation state blocks.
Verification: `bun test src/renderer/subtitle-render.test.ts`, `bunx prettier --check src/renderer/style.css src/renderer/subtitle-render.test.ts`, `bun run build`.
Switched the JLPT underline from native `text-decoration` to a separate painted underline layer using `background-image` on JLPT tokens. Also changed hover token highlight rules to use `background-color` so the JLPT underline layer survives Shift+Yomitan hover/lookup interactions.
Verification: `bun test src/renderer/subtitle-render.test.ts`, `bunx prettier --check src/renderer/style.css src/renderer/subtitle-render.test.ts`, `bun run build`.
User reports the latest background-image JLPT underline change introduced grey-looking token highlights. Investigating the interaction between the new underline layer and hover background styling.
The background-image underline layer interacts poorly with hover fills and makes highlighted tokens look grey. Switching the separate JLPT underline layer to an inset box-shadow so hover background color and JLPT underline paint can coexist cleanly.
Adjusted the separate JLPT underline layer from `background-image` to inset `box-shadow`. This keeps the underline decoupled from Yomitan hover color while avoiding the grey-looking underline artifact introduced by the background-image approach.
User reports the separate underline layer still disappears/greys out during lookup. Switching strategy again: use a dedicated `border-bottom` JLPT marker instead of box-shadow/background so the underline stays independent from Yomitan hover paint without blending artifacts.
Replaced the separate JLPT underline layer with `border-bottom` plus a small bottom padding. This keeps the underline visually separate from Yomitan hover paint and avoids the disappearing/grey artifact seen with background-image and box-shadow.
<!-- SECTION:NOTES:END -->
## Final Summary
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
Switched the JLPT underline layer in `src/renderer/style.css` to `border-bottom` plus `padding-bottom`, keeping it independent from Yomitan hover/selection repainting while avoiding the disappearing or grey artifact seen with the background-image and box-shadow approaches.
Updated `src/renderer/subtitle-render.test.ts` to assert the border-bottom-based JLPT underline layer.
Verification: `bun test src/renderer/subtitle-render.test.ts`, `bunx prettier --check src/renderer/style.css src/renderer/subtitle-render.test.ts`, `bun run build`.
<!-- SECTION:FINAL_SUMMARY:END -->

View File

@@ -1,51 +0,0 @@
---
id: TASK-70
title: >-
Overlay runtime refactor: remove invisible mode and bind visible overlay to
mpv subtitles
status: Done
assignee: []
created_date: '2026-02-28 02:38'
updated_date: '2026-02-28 22:36'
labels: []
dependencies: []
references:
- 'commit:a14c9da'
- 'commit:74554a3'
- 'commit:75442a4'
- 'commit:dde51f8'
- 'commit:9e4e588'
- src/main/overlay-runtime.ts
- src/main/runtime/overlay-mpv-sub-visibility.ts
- src/renderer/renderer.ts
- docs/plans/2026-02-26-secondary-subtitles-main-overlay.md
priority: medium
ordinal: 1000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Scope: Branch-only commits main..HEAD on refactor-overlay (a14c9da through 9e4e588) rebuilt overlay behavior around visible overlay mode and removed legacy invisible overlay paths.
Delivered behavior:
- Removed renderer invisible overlay layout/offset helpers and main hover-highlight runtime code paths.
- Added explicit overlay-to-mpv subtitle visibility synchronization so visible overlay state controls primary subtitle visibility consistently.
- Hardened overlay runtime/bootstrap lifecycle around modal fallback open state and bridge send path edge cases.
- Updated plugin/config/docs defaults to reflect visible-overlay-first behavior and subtitle binding controls.
Risk/impact context:
- Large cross-layer refactor touching runtime wiring, renderer event handling, and plugin behavior.
- Regression coverage added/updated for overlay runtime, mpv protocol handling, renderer cleanup, and subtitle rendering paths.
<!-- SECTION:DESCRIPTION:END -->
## Final Summary
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
Completed and validated in branch commit set before merge. Refactor reduces dead overlay modes, centralizes subtitle visibility behavior, and documents new defaults/constraints.
<!-- SECTION:FINAL_SUMMARY:END -->

View File

@@ -1,42 +0,0 @@
---
id: TASK-72
title: 'macOS config validation UX: show full warning details in native dialog'
status: Done
assignee: []
created_date: '2026-02-28 02:38'
updated_date: '2026-02-28 22:36'
labels: []
dependencies: []
references:
- 'commit:cc2f9ef'
- src/main/config-validation.ts
- src/main/runtime/startup-config.ts
- docs/configuration.md
priority: low
ordinal: 3000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Scope: Commit cc2f9ef improves startup config-warning visibility on macOS by ensuring full details are surfaced in the native UI path and reflected in docs.
Delivered behavior:
- Config validation/runtime wiring updated so macOS users can access complete warning details instead of truncated notification-only text.
- Added/updated tests around config validation and startup config warning flows.
- Updated configuration docs to clarify platform-specific warning presentation behavior.
Risk/impact context:
- Low runtime risk; primarily user-facing diagnostics clarity improvement.
<!-- SECTION:DESCRIPTION:END -->
## Final Summary
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
Completed small follow-up fix to reduce config-debug friction on macOS.
<!-- SECTION:FINAL_SUMMARY:END -->

View File

@@ -1,84 +0,0 @@
---
id: TASK-73
title: 'MPV plugin: split into modules and optimize startup/command runtime'
status: Done
assignee: []
created_date: '2026-02-28 20:50'
updated_date: '2026-02-28 22:36'
labels: []
dependencies: []
references:
- plugin/subminer/main.lua
- plugin/subminer/bootstrap.lua
- plugin/subminer/process.lua
- plugin/subminer/aniskip.lua
- plugin/subminer/environment.lua
- plugin/subminer/lifecycle.lua
- plugin/subminer/messages.lua
- plugin/subminer/ui.lua
- plugin/subminer/hover.lua
- plugin/subminer/options.lua
- plugin/subminer/state.lua
- plugin/subminer.conf
- scripts/test-plugin-start-gate.lua
- scripts/test-plugin-process-start-retries.lua
- launcher/commands/playback-command.ts
- launcher/mpv.ts
- launcher/mpv.test.ts
- launcher/smoke.e2e.test.ts
- Makefile
- package.json
- docs/mpv-plugin.md
- docs/installation.md
- docs/architecture.md
- README.md
priority: medium
ordinal: 4000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Scope: Replace monolithic `plugin/subminer.lua` with modular plugin runtime; optimize command execution paths; align install/docs/tests; fix launcher smoke instability.
Delivered behavior:
- Full plugin cutover to `plugin/subminer/main.lua` + module directory (no runtime compatibility shim with old monolith file).
- Process/control command path moved toward async subprocess usage for non-start actions (`stop`, `toggle`, `settings`, restart stop leg), reducing synchronous blocking in mpv script runtime.
- AniSkip path guarded: lookup runs only in SubMiner context (launcher metadata, explicit script-message refresh, or detected running app), instead of every opened file.
- AniSkip lookup pipeline moved to async subprocess calls (no sync `ps`/`curl` on `file-loaded`) with deferred fetch after auto-start and session-level MAL/title/payload caching.
- Startup/runtime loading updated with lazy module initialization via bootstrap proxies.
- Plugin install flow updated to copy `plugin/subminer/` directory and remove legacy `~/.config/mpv/scripts/subminer.lua` file.
- Added plugin gate script wiring to package scripts (`test:plugin:src`) and launcher test flow.
- Smoke tests stabilized across sandbox environments where UNIX socket bind can return `EPERM` while preserving normal-path assertions.
- Playback command cleanup race fixed when mpv exits before exit-listener registration.
Risk/impact context:
- mpv plugin loading path changed from single-file to module directory; packaging/install paths must stay consistent with release assets.
- Async control/AniSkip path changes reduce blocking but can surface timing differences; regression checks added for cold start, file-load gating, and explicit refresh behavior.
<!-- SECTION:DESCRIPTION:END -->
## Final Summary
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
AniSkip gate/async update delivered in plugin runtime:
- `plugin/subminer/lifecycle.lua`: deferred AniSkip fetch and overlay-start trigger.
- `plugin/subminer/aniskip.lua`: async lookup pipeline + context guard + session caches.
- `plugin/subminer/environment.lua`: async app-running detection with short cache.
- `plugin/subminer/messages.lua`: explicit script-message trigger wiring.
Regression coverage updated:
- `scripts/test-plugin-start-gate.lua` now verifies:
- no sync `ps`/`curl` on non-context file load
- no AniSkip network lookup on non-context file load
- script-message refresh forces async AniSkip lookup
Validation run:
- `bun run test:plugin:src` pass.
<!-- SECTION:FINAL_SUMMARY:END -->

View File

@@ -1,76 +0,0 @@
---
id: TASK-74
title: 'Startup warmups: configurable warmup vs defer with low-power mode'
status: Done
assignee: []
created_date: '2026-02-27 21:05'
updated_date: '2026-03-01 04:14'
labels: []
dependencies: []
references:
- src/types.ts
- src/config/definitions/defaults-core.ts
- src/config/definitions/options-core.ts
- src/config/definitions/template-sections.ts
- src/config/resolve/core-domains.ts
- src/main/runtime/startup-warmups.ts
- src/main/runtime/startup-warmups-main-deps.ts
- src/main/runtime/composers/mpv-runtime-composer.ts
- src/core/services/startup.ts
- src/main.ts
- src/config/config.test.ts
- src/main/runtime/startup-warmups.test.ts
- src/main/runtime/startup-warmups-main-deps.test.ts
- src/core/services/app-ready.test.ts
priority: medium
ordinal: 7000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Add startup warmup controls to allow per-integration warmup or deferred first-use loading.
Scope:
- New config section `startupWarmups` with toggles for `mecab`, `yomitanExtension`, `subtitleDictionaries`, and `jellyfinRemoteSession`.
- New `startupWarmups.lowPowerMode` policy: defer everything except Yomitan extension.
- Keep default behavior as full warmup.
- Ensure deferred integrations lazy-load on first real usage path.
- Add test coverage for config parsing/defaults and warmup scheduling behavior.
<!-- SECTION:DESCRIPTION:END -->
## Final Summary
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
Implemented:
- Added `startupWarmups` to config types/defaults/options/template/resolve.
- Warmup scheduler now uses per-integration gating functions.
- Low-power mode now defers MeCab, subtitle dictionaries, and Jellyfin remote session warmups while still warming Yomitan extension.
- Tokenization path guarantees lazy first-use init for deferred dependencies (Yomitan extension, MeCab when missing, subtitle dictionaries).
- Added/updated tests across config and runtime warmup modules.
Validation:
- `bun run test:config:src`
- `bun run test:core:src`
- `tsc --noEmit`
Follow-up updates:
- Startup now triggers warmups earlier in app-ready flow (right after config validation/log-level setup) instead of waiting for initial args/overlay actions. Goal: tokenization warmup is already done or mostly done by first visible-subs toggle.
- Tokenization warmup scheduling consolidated as `subtitle-tokenization` stage; when enabled by toggles, it runs Yomitan extension first, then MeCab/dictionary warmups.
- Added per-stage debug logs for warmup progress and skip reasons:
- `stage start/ready: yomitan-extension`
- `stage start/ready: mecab`
- `stage start/ready: subtitle-dictionaries`
- `stage start/ready: jellyfin-remote-session`
- `stage skipped: jellyfin-remote-session (disabled|auto-connect off)`
- Added regression tests for stage-level logging and earlier startup ordering:
- `src/main/runtime/startup-warmups.test.ts`
- `src/main/runtime/startup-warmups-main-deps.test.ts`
- `src/core/services/app-ready.test.ts`
<!-- SECTION:FINAL_SUMMARY:END -->

View File

@@ -1,41 +0,0 @@
---
id: TASK-75
title: 'Tokenizer: configurable POS exclusions for N+1 and frequency annotations'
status: Done
assignee: []
created_date: '2026-03-01 01:23'
updated_date: '2026-03-01 04:14'
labels: []
dependencies: []
priority: medium
ordinal: 6000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
N+1 and frequency highlighting should ignore non-learning tokens (e.g., particles/auxiliary forms) based on MeCab POS1 tags, while remaining user-configurable.
Problem example: for subtitle phrase containing になれば, the highlighted N+1 target should not be the non-useful inflection/token piece when POS indicates an excluded class.
Implement configurable exclusion defaults with add/remove overrides so users can tune behavior without code changes.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [x] #1 Default exclusion set omits non-useful POS1 classes from both N+1 candidate selection and frequency highlighting.
- [x] #2 Users can add extra POS1 exclusions and remove defaults via config.
- [x] #3 Tokenizer/annotation tests cover default behavior and config add/remove overrides.
<!-- AC:END -->
## Final Summary
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
Implemented configurable annotation POS exclusions with defaults+add/remove for both MeCab POS1 and POS2, wired to N+1 candidate selection and frequency highlighting. Added POS2 default exclusion (非自立), expanded POS1 defaults for function words, added Yomitan->MeCab enrichment to carry pos2/pos3 metadata, updated config docs/examples, and added regression tests including になれば case.
<!-- SECTION:FINAL_SUMMARY:END -->

View File

@@ -1,39 +0,0 @@
---
id: TASK-76
title: 'Tokenizer: remove POS exclusion config surface and keep hardcoded defaults'
status: Done
assignee: []
created_date: '2026-03-01 02:45'
updated_date: '2026-03-01 04:14'
labels: []
dependencies: []
priority: medium
ordinal: 5000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Remove user-facing config keys for annotation POS exclusions. Keep N+1/frequency POS exclusion behavior as built-in defaults with no config required.
Scope: remove config parsing/registry/docs/example for annotationFilters.pos1Exclusions/pos2Exclusions while preserving runtime filtering behavior.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [x] #1 No user-facing config option exists for annotation POS exclusions.
- [x] #2 Runtime N+1/frequency exclusion behavior remains active via built-in defaults.
- [x] #3 Config/docs/example/tests updated accordingly.
<!-- AC:END -->
## Final Summary
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
Removed user-facing subtitleStyle.annotationFilters POS exclusion configuration (schema/resolver/options/docs/example). POS-based N+1/frequency filtering now always uses built-in defaults in runtime. Preserved robust exclusion behavior including merged-token overlap POS handling and N+1-only MeCab enrichment path.
<!-- SECTION:FINAL_SUMMARY:END -->

View File

@@ -1,55 +0,0 @@
---
id: TASK-78
title: 'Launcher + mpv plugin: auto-start visible overlay pause-until-ready and single-start guard'
status: Done
assignee: []
created_date: '2026-02-28 22:45'
updated_date: '2026-02-28 22:45'
labels: []
dependencies: []
priority: medium
ordinal: 9000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Add startup gating behavior for wrapper + mpv plugin flow so playback starts paused when visible overlay auto-start is enabled, then auto-resumes only after subtitle tokenization is ready.
Scope:
- Plugin option `auto_start_pause_until_ready` (default `yes`).
- Launcher reads plugin runtime config and starts mpv paused when `auto_start=yes`, `auto_start_visible_overlay=yes`, and `auto_start_pause_until_ready=yes`.
- Main process signals readiness via mpv script message after tokenized subtitle delivery.
- Prevent duplicate auto-start attempts from showing `SubMiner already running` OSD.
- Keep startup/loading OSD messaging visible and update docs/tests.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [x] #1 Launcher reads `auto_start`, `auto_start_visible_overlay`, and `auto_start_pause_until_ready` from `subminer.conf` and starts mpv with `--pause=yes` when all are enabled.
- [x] #2 Plugin pauses on eligible auto-start and resumes only on readiness signal or timeout fallback.
- [x] #3 Main process emits `script-message subminer-autoplay-ready` after subtitle tokenization is ready.
- [x] #4 Auto-start duplicate triggers are idempotent (no duplicate `--start` behavior and no spurious `Already running` OSD for auto-start path).
- [x] #5 Docs and regression tests cover defaults, startup gating behavior, and duplicate-start suppression.
<!-- AC:END -->
## Final Summary
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
Implemented startup pause gate across launcher/plugin/main runtime:
- Added plugin runtime config parsing in launcher (`auto_start`, `auto_start_visible_overlay`, `auto_start_pause_until_ready`) and mpv start-paused behavior for eligible runs.
- Added plugin auto-play gate state, timeout fallback, and readiness release via `subminer-autoplay-ready` script message.
- Added main-process readiness signaling after tokenization delivery, including unpause fallback command path.
- Split auto-start visibility control into separate control commands and added duplicate auto-start idempotency guard to suppress repeated auto-start `Already running` noise.
- Updated plugin defaults to enabled (`auto_start=yes`, `auto_start_visible_overlay=yes`, `auto_start_pause_until_ready=yes`) and refreshed docs (`README`, usage, launcher, installation, plugin/config docs).
- Added/updated regression coverage (`scripts/test-plugin-start-gate.lua`, launcher smoke/unit tests) validating paused startup, readiness resume, and duplicate-start suppression.
<!-- SECTION:FINAL_SUMMARY:END -->

View File

@@ -1,50 +0,0 @@
---
id: TASK-79
title: 'Jimaku modal: auto-close after successful subtitle load'
status: Done
assignee: []
created_date: '2026-03-01 13:52'
updated_date: '2026-03-01 14:06'
labels: []
dependencies: []
priority: medium
ordinal: 10000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Fix Jimaku modal UX so selecting a subtitle file closes the modal automatically once subtitle download+load succeeds.
Current behavior:
- Subtitle file downloads and loads into mpv.
- Jimaku modal remains open until manual close.
Expected behavior:
- On successful `jimakuDownloadFile` result, close modal immediately.
- Keep error behavior unchanged (stay open + show error).
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [x] #1 Successful subtitle file selection/download in Jimaku closes modal automatically.
- [x] #2 Existing error path keeps modal open and shows error.
- [x] #3 Regression test covers success auto-close behavior.
<!-- AC:END -->
## Final Summary
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
Fixed renderer Jimaku success flow to close modal immediately after successful `jimakuDownloadFile` result. Added regression test (`src/renderer/modals/jimaku.test.ts`) that reproduces keyboard file-selection success path and asserts modal close state + `notifyOverlayModalClosed('jimaku')` emission. Kept failure path unchanged.
Also wired new test into `test:core:src` and `test:core:dist` package scripts.
<!-- SECTION:FINAL_SUMMARY:END -->

View File

@@ -1,50 +0,0 @@
---
id: TASK-80
title: 'Jimaku download: rename subtitle to current video basename'
status: Done
assignee: []
created_date: '2026-03-01 14:17'
updated_date: '2026-03-01 14:19'
labels: []
dependencies: []
priority: medium
ordinal: 11000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
When user selects a Jimaku subtitle, save subtitle with filename derived from currently playing media filename instead of Jimaku release filename.
Example:
- Current media: `anime.mkv`
- Downloaded subtitle extension: `.srt`
- Saved subtitle path: `anime.ja.srt`
Scope:
- Apply in Jimaku download IPC path before writing file.
- Preserve collision-avoidance behavior (suffix with jimaku entry id/counter when target exists).
- Keep mpv load flow unchanged except using renamed path.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [x] #1 Jimaku subtitle destination name uses current media basename plus `.ja` and subtitle extension.
- [x] #2 Existing duplicate filename conflict handling still works.
- [x] #3 Regression tests cover renamed destination path behavior.
<!-- AC:END -->
## Final Summary
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
Jimaku download path generation now derives subtitle filename from currently playing media basename and keeps subtitle extension from Jimaku file (`anime.mkv` + `.srt` => `anime.ja.srt`). Added pure helper `buildJimakuSubtitleFilenameFromMediaPath` and routed IPC download flow through it before existing duplicate-path conflict handling. Added regression tests for local path, missing extension fallback, and remote URL media paths.
<!-- SECTION:FINAL_SUMMARY:END -->

View File

@@ -1,58 +0,0 @@
---
id: TASK-81
title: 'Tokenization performance: disable Yomitan MeCab parser, gate local MeCab init, and add persistent MeCab process'
status: Done
assignee: []
created_date: '2026-03-02 07:44'
updated_date: '2026-03-02 20:44'
labels: []
dependencies: []
priority: high
ordinal: 9001
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Reduce subtitle annotation latency by:
- disabling Yomitan-side MeCab parser requests (`useMecabParser=false`);
- initializing local MeCab only when POS-dependent annotations are enabled (N+1 / JLPT / frequency);
- replacing per-line local MeCab process spawning with a persistent parser process that auto-shuts down after idle time and restarts on demand.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [x] #1 Yomitan parse requests disable MeCab parser path.
- [x] #2 MeCab warmup/init is skipped when all POS-dependent annotation toggles are off.
- [x] #3 Local MeCab tokenizer uses persistent process across subtitle lines.
- [x] #4 Persistent MeCab process auto-shuts down after idle timeout and restarts on next tokenize activity.
- [x] #5 Tests cover parser flag, warmup gating, and persistent MeCab lifecycle behavior.
<!-- AC:END -->
## Final Summary
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
Implemented tokenizer latency optimizations:
- switched Yomitan parse requests to `useMecabParser: false`;
- added annotation-aware MeCab initialization gating in runtime warmup flow;
- added persistent local MeCab process (default idle shutdown: 30s) with queued requests, retry-on-process-end, idle auto-shutdown, and automatic restart on new work;
- added regression tests for Yomitan parse flag, MeCab warmup gating, and persistent/idle lifecycle behavior;
- fixed tokenization warmup gate so first-use warmup completion is sticky (`tokenizationWarmupCompleted`) and sequential `tokenizeSubtitle` calls no longer re-run Yomitan/dictionary warmup path;
- added regression coverage in `src/main/runtime/composers/mpv-runtime-composer.test.ts` for sequential tokenize calls (`warmup` side effects run once);
- post-review critical fix: treat Yomitan default-profile Anki server sync `no-change` as successful check, so `lastSyncedYomitanAnkiServer` is cached and expensive sync checks do not repeat on every subtitle line;
- added regression assertion in `src/core/services/tokenizer/yomitan-parser-runtime.test.ts` for `updated: false` path returning sync success;
- post-review performance fix: refactored POS enrichment to pre-index MeCab tokens by surface plus character-position overlap index, replacing repeated active-candidate filtering/full-scan behavior with direct overlap candidate lookup per token;
- added regression tests in `src/core/services/tokenizer/parser-enrichment-stage.test.ts` for repeated distant-token scan access and repeated active-candidate filter scans; both fail on scan-based behavior and pass with indexed lookup;
- post-review startup fix: moved JLPT/frequency dictionary initialization from synchronous FS APIs to async `fs/promises` path inspection/read and cooperative chunked entry processing to reduce main-thread stall risk during cold start;
- post-review first-line latency fix: decoupled tokenization warmup gating so first `tokenizeSubtitle` only waits on Yomitan extension readiness, while MeCab check + dictionary prewarm continue in parallel background warmups;
- validated with targeted tests and `tsc --noEmit`.
<!-- SECTION:FINAL_SUMMARY:END -->

View File

@@ -1,60 +0,0 @@
---
id: TASK-82
title: 'Subtitle frequency highlighting: fix noisy Yomitan readings and restore known/N+1 color priority'
status: Done
assignee: []
created_date: '2026-03-02 20:10'
updated_date: '2026-03-02 01:44'
labels: []
dependencies: []
priority: high
ordinal: 9002
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Address frequency-highlighting regressions:
- tokens like `断じて` missed rank assignment when Yomitan merged-token reading was truncated/noisy;
- known/N+1 tokens were incorrectly colored by frequency color instead of known/N+1 color.
Expected behavior:
- known/N+1 color always wins;
- if token is frequent and within `topX`, frequency rank label can still appear on hover/metadata.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [x] #1 Frequency lookup succeeds for noisy/truncated merged-token readings via robust fallback behavior.
- [x] #2 Merged-token reading normalization restores missing kana suffixes where safe (`headword === surface` path).
- [x] #3 Known/N+1 tokens keep known/N+1 color classes; frequency color class does not override them.
- [x] #4 Frequency rank hover label remains available for in-range frequent tokens, including known/N+1.
- [x] #5 Regression tests added for tokenizer and renderer behavior.
<!-- AC:END -->
## Final Summary
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
Implemented and validated:
- tokenizer now normalizes selected Yomitan merged-token readings by appending missing trailing kana suffixes when safe (`headword === surface`);
- frequency lookup now does lazy fallback: requests `{term, reading}` first, and only requests `{term, reading: null}` for misses;
- this removes eager `(term, null)` payload inflation on medium-frequency lines and reduces extension RPC payload/load;
- renderer restored known/N+1 color priority over frequency class coloring;
- frequency rank label display remains available for frequent known/N+1 tokens;
- added regression tests covering noisy-reading fallback, lazy fallback-query behavior, and renderer class/label precedence.
Related commits:
- `17a417e` (`fix(subtitle): improve frequency highlight reliability`)
- `79f37f3` (`fix(subtitle): prioritize known and n+1 colors over frequency`)
<!-- SECTION:FINAL_SUMMARY:END -->

View File

@@ -1,53 +0,0 @@
---
id: TASK-83
title: 'Jellyfin subtitle delay: shift to adjacent cue without seek jumps'
status: Done
assignee: []
created_date: '2026-03-02 00:06'
updated_date: '2026-03-02 00:06'
labels: []
dependencies: []
priority: high
ordinal: 9003
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Add keybinding-friendly special commands that shift `sub-delay` to align current subtitle start with next/previous cue start, without `sub-seek` probing (avoid playback jump).
Scope:
- add special commands for next/previous line alignment;
- compute delta from active subtitle cue timeline (external subtitle file/URL, including Jellyfin-delivered URLs);
- apply `add sub-delay <delta>` and show OSD value;
- keep existing proxy OSD behavior for direct `sub-delay` keybinding commands.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [x] #1 New special commands exist for subtitle-delay shift to next/previous cue boundary.
- [x] #2 Shift logic parses active external subtitle source timings (SRT/VTT/ASS) and computes delta from current `sub-start`.
- [x] #3 Runtime applies delay shift without `sub-seek` and shows OSD feedback.
- [x] #4 Direct `sub-delay` proxy commands also show OSD current value.
- [x] #5 Tests added for cue parsing/shift behavior and IPC dispatch wiring.
<!-- AC:END -->
## Final Summary
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
Implemented no-jump subtitle-delay alignment commands:
- added `__sub-delay-next-line` and `__sub-delay-prev-line` special commands;
- added `createShiftSubtitleDelayToAdjacentCueHandler` to parse cue start times from active external subtitle source and apply `add sub-delay` delta from current `sub-start`;
- wired command handling through IPC runtime deps into main runtime;
- retained/extended OSD proxy feedback for `sub-delay` keybindings;
- updated configuration docs and added regression tests for subtitle-delay shift and IPC command routing.
<!-- SECTION:FINAL_SUMMARY:END -->