mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-20 12:11:28 -07:00
clean up and add new showcase videos
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
---
|
||||
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 -->
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
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 -->
|
||||
@@ -0,0 +1,84 @@
|
||||
---
|
||||
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 -->
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
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 -->
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
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 -->
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
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 -->
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
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 -->
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
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 -->
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
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 -->
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
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 -->
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
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 -->
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
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 -->
|
||||
Reference in New Issue
Block a user