From f299f2a19e2d42dd4fcc22b05f86cc754a743aaa Mon Sep 17 00:00:00 2001 From: kyasuda Date: Wed, 18 Feb 2026 18:05:42 -0800 Subject: [PATCH] chore: switch texthooker-ui workflow to pnpm and add backlog tasks --- Makefile | 14 +++-- README.md | 2 +- ...ion-validation-and-deprecation-handling.md | 46 ++++++++++++++ ...ath-resolution-across-main-and-launcher.md | 45 ++++++++++++++ ....ts-into-domain-runtime-modules-round-2.md | 50 ++++++++++++++++ ...ng-strict-with-clear-user-facing-errors.md | 44 ++++++++++++++ ...auncher-mpv-socket-readiness-primitives.md | 45 ++++++++++++++ ...-config-discovery-and-command-branching.md | 48 +++++++++++++++ ...v-osd-log-writes-to-buffered-async-path.md | 44 ++++++++++++++ ...ion-orchestrator-into-workflow-services.md | 55 +++++++++++++++++ ...ection-enrichment-and-annotation-stages.md | 54 +++++++++++++++++ ...ig-definitions-and-validation-by-domain.md | 56 +++++++++++++++++ ...-state-transitions-and-reducers-in-main.md | 55 +++++++++++++++++ ...t-typing-and-runtime-payload-validation.md | 54 +++++++++++++++++ ...to-command-modules-and-process-adapters.md | 57 ++++++++++++++++++ ...or-launcher-mpv-ipc-and-overlay-runtime.md | 60 +++++++++++++++++++ docs/development.md | 2 +- docs/installation.md | 2 +- scripts/patch-texthooker.sh | 2 +- 19 files changed, 726 insertions(+), 9 deletions(-) create mode 100644 backlog/tasks/task-69 - Harden-legacy-config-migration-validation-and-deprecation-handling.md create mode 100644 backlog/tasks/task-70 - Unify-config-path-resolution-across-main-and-launcher.md create mode 100644 backlog/tasks/task-71 - Split-main.ts-into-domain-runtime-modules-round-2.md create mode 100644 backlog/tasks/task-72 - Make-startup-config-loading-strict-with-clear-user-facing-errors.md create mode 100644 backlog/tasks/task-73 - Consolidate-launcher-mpv-socket-readiness-primitives.md create mode 100644 backlog/tasks/task-74 - Add-launcher-regression-tests-for-config-discovery-and-command-branching.md create mode 100644 backlog/tasks/task-75 - Move-mpv-osd-log-writes-to-buffered-async-path.md create mode 100644 backlog/tasks/task-76 - Decompose-anki-integration-orchestrator-into-workflow-services.md create mode 100644 backlog/tasks/task-77 - Split-tokenizer-pipeline-into-parser-selection-enrichment-and-annotation-stages.md create mode 100644 backlog/tasks/task-78 - Modularize-config-definitions-and-validation-by-domain.md create mode 100644 backlog/tasks/task-79 - Introduce-explicit-runtime-state-transitions-and-reducers-in-main.md create mode 100644 backlog/tasks/task-80 - Strengthen-ipc-contract-typing-and-runtime-payload-validation.md create mode 100644 backlog/tasks/task-81 - Refactor-launcher-into-command-modules-and-process-adapters.md create mode 100644 backlog/tasks/task-82 - Add-end-to-end-smoke-suite-for-launcher-mpv-ipc-and-overlay-runtime.md diff --git a/Makefile b/Makefile index fb446fb..20c3d58 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: help deps build build-launcher install build-linux build-macos build-macos-unsigned clean install-linux install-macos install-plugin uninstall uninstall-linux uninstall-macos print-dirs pretty ensure-bun generate-config generate-example-config docs-dev docs docs-preview dev-start dev-start-macos dev-toggle dev-stop +.PHONY: help deps build build-launcher install build-linux build-macos build-macos-unsigned clean install-linux install-macos install-plugin uninstall uninstall-linux uninstall-macos print-dirs pretty ensure-bun ensure-pnpm generate-config generate-example-config docs-dev docs docs-preview dev-start dev-start-macos dev-toggle dev-stop APP_NAME := subminer THEME_FILE := subminer.rasi @@ -91,12 +91,16 @@ print-dirs: deps: @$(MAKE) --no-print-directory ensure-bun + @$(MAKE) --no-print-directory ensure-pnpm @bun install - @cd vendor/texthooker-ui && bun install + @cd vendor/texthooker-ui && pnpm install --frozen-lockfile ensure-bun: @command -v bun >/dev/null 2>&1 || { printf '%s\n' "[ERROR] bun not found"; exit 1; } +ensure-pnpm: + @command -v pnpm >/dev/null 2>&1 || { printf '%s\n' "[ERROR] pnpm not found"; exit 1; } + pretty: ensure-bun @bun run format @@ -118,17 +122,17 @@ install: build-linux: deps @printf '%s\n' "[INFO] Building Linux package (AppImage)" - @cd vendor/texthooker-ui && bun run build + @cd vendor/texthooker-ui && pnpm run build @bun run build:appimage build-macos: deps @printf '%s\n' "[INFO] Building macOS package (DMG + ZIP)" - @cd vendor/texthooker-ui && bun run build + @cd vendor/texthooker-ui && pnpm run build @bun run build:mac build-macos-unsigned: deps @printf '%s\n' "[INFO] Building macOS package (DMG + ZIP, unsigned)" - @cd vendor/texthooker-ui && bun run build + @cd vendor/texthooker-ui && pnpm run build @bun run build:mac:unsigned build-launcher: diff --git a/README.md b/README.md index b961fd1..d6a1e74 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ The `subminer` wrapper uses a [Bun](https://bun.sh) shebang, so `bun` must be on git clone --recurse-submodules https://github.com/ksyasuda/SubMiner.git cd SubMiner bun install -cd vendor/texthooker-ui && bun install && cd ../.. +cd vendor/texthooker-ui && pnpm install --frozen-lockfile && cd ../.. make build make install ``` diff --git a/backlog/tasks/task-69 - Harden-legacy-config-migration-validation-and-deprecation-handling.md b/backlog/tasks/task-69 - Harden-legacy-config-migration-validation-and-deprecation-handling.md new file mode 100644 index 0000000..5dd6411 --- /dev/null +++ b/backlog/tasks/task-69 - Harden-legacy-config-migration-validation-and-deprecation-handling.md @@ -0,0 +1,46 @@ +--- +id: TASK-69 +title: Harden legacy config migration validation and deprecation handling +status: To Do +assignee: [] +created_date: '2026-02-18 11:35' +updated_date: '2026-02-18 11:35' +labels: + - config + - validation + - safety +dependencies: [] +priority: high +--- + +## Description + + +`src/config/service.ts` still applies many legacy `ankiConnect` keys via unchecked casts (`as string|number|boolean`) in the `mapLegacy` block. Invalid legacy values can enter resolved runtime config without warnings and break downstream behavior. + + +## Action Steps + + +1. Inventory every legacy key currently handled in `mapLegacy`. +2. Replace unchecked assignment with typed validators (`asString`, `asNumber`, `asBoolean`, enum guards). +3. Emit deprecation warnings for accepted legacy keys and validation warnings for invalid values. +4. Preserve backward compatibility for valid legacy configs. +5. Add regression tests for invalid legacy value types and accepted legacy values. +6. Update configuration docs with migration/deprecation notes. + + +## Acceptance Criteria + +- [ ] #1 No legacy key path writes directly to resolved config without type validation +- [ ] #2 Invalid legacy values produce warnings and safe fallback behavior +- [ ] #3 Valid legacy configs still map to equivalent resolved config +- [ ] #4 Config test suite includes legacy-invalid regression coverage + + +## Definition of Done + +- [ ] #1 `bun run test:config:dist` passes +- [ ] #2 Any doc changes for migration/deprecation are committed + + diff --git a/backlog/tasks/task-70 - Unify-config-path-resolution-across-main-and-launcher.md b/backlog/tasks/task-70 - Unify-config-path-resolution-across-main-and-launcher.md new file mode 100644 index 0000000..7976845 --- /dev/null +++ b/backlog/tasks/task-70 - Unify-config-path-resolution-across-main-and-launcher.md @@ -0,0 +1,45 @@ +--- +id: TASK-70 +title: Unify config path resolution across main and launcher +status: To Do +assignee: [] +created_date: '2026-02-18 11:35' +updated_date: '2026-02-18 11:35' +labels: + - config + - launcher + - consistency +dependencies: [] +priority: high +--- + +## Description + + +Config discovery logic is duplicated and inconsistent between app main process and launcher. Main resolves `XDG_CONFIG_HOME` + case variants (`SubMiner`/`subminer`), while launcher loaders still hardcode `~/.config/SubMiner` in places. + + +## Action Steps + + +1. Extract shared config path discovery utility (candidate roots, case variants, `.jsonc`/`.json` preference). +2. Replace ad-hoc resolution in `src/main.ts`, `launcher/main.ts`, and `launcher/config.ts`. +3. Normalize fallback behavior when config file is absent. +4. Keep existing user-visible behavior for `subminer config path|show`. +5. Add tests for XDG and case-variant path resolution. +6. Update docs if path precedence changes. + + +## Acceptance Criteria + +- [ ] #1 Single canonical path-resolution logic used by app and launcher +- [ ] #2 `XDG_CONFIG_HOME` and `SubMiner|subminer` precedence covered by tests +- [ ] #3 No behavior drift for existing config-path CLI commands + + +## Definition of Done + +- [ ] #1 Launcher and config tests pass +- [ ] #2 Code no longer duplicates config path candidate logic + + diff --git a/backlog/tasks/task-71 - Split-main.ts-into-domain-runtime-modules-round-2.md b/backlog/tasks/task-71 - Split-main.ts-into-domain-runtime-modules-round-2.md new file mode 100644 index 0000000..16f9a41 --- /dev/null +++ b/backlog/tasks/task-71 - Split-main.ts-into-domain-runtime-modules-round-2.md @@ -0,0 +1,50 @@ +--- +id: TASK-71 +title: Split main.ts into domain runtime modules round 2 +status: To Do +assignee: [] +created_date: '2026-02-18 11:35' +updated_date: '2026-02-18 11:35' +labels: + - architecture + - refactor + - maintainability +dependencies: [] +priority: high +--- + +## Description + + +`src/main.ts` remains >3k LOC and still mixes composition, runtime state mutation, domain workflows (Jellyfin, AniList), tray/UI setup, and IPC wiring. This creates high cognitive load and broad change blast radius. + + +## Action Steps + + +1. Extract cohesive runtime modules: + - AniList runtime orchestration + - Jellyfin runtime orchestration + - tray runtime + - MPV event binding/runtime hooks +2. Keep `main.ts` as composition root only (state wiring + module registration). +3. Define narrow service/deps interfaces per module to reduce closure capture. +4. Add/adjust unit tests for extracted modules. +5. Preserve existing CLI/IPC behavior exactly. +6. Update architecture docs with new ownership boundaries. + + +## Acceptance Criteria + +- [ ] #1 `src/main.ts` responsibilities reduced to composition/wiring concerns +- [ ] #2 Extracted runtime modules have focused interfaces and isolated tests +- [ ] #3 No CLI/IPC regressions in existing test suite +- [ ] #4 Docs reflect new module boundaries + + +## Definition of Done + +- [ ] #1 `bun run test:fast` passes +- [ ] #2 Architecture docs updated + + diff --git a/backlog/tasks/task-72 - Make-startup-config-loading-strict-with-clear-user-facing-errors.md b/backlog/tasks/task-72 - Make-startup-config-loading-strict-with-clear-user-facing-errors.md new file mode 100644 index 0000000..09dfec2 --- /dev/null +++ b/backlog/tasks/task-72 - Make-startup-config-loading-strict-with-clear-user-facing-errors.md @@ -0,0 +1,44 @@ +--- +id: TASK-72 +title: Make startup config loading strict with clear user-facing errors +status: To Do +assignee: [] +created_date: '2026-02-18 11:35' +updated_date: '2026-02-18 11:35' +labels: + - config + - ux + - reliability +dependencies: [] +priority: medium +--- + +## Description + + +Startup config loading currently falls back to default config when strict parse fails, while hot-reload path reports strict errors. This mismatch can hide broken config at startup and cause surprising runtime behavior. + + +## Action Steps + + +1. Align startup loading semantics with strict reload behavior. +2. Surface parse/validation errors to user via clear logs/OSD/notification where appropriate. +3. Define fallback policy explicitly (fail fast vs safe mode) and apply consistently. +4. Add regression tests for malformed JSON/JSONC at startup. +5. Document startup error behavior in troubleshooting/config docs. + + +## Acceptance Criteria + +- [ ] #1 Startup and hot-reload use consistent strictness semantics +- [ ] #2 Malformed config surfaces explicit actionable error +- [ ] #3 Tests cover malformed startup config path + + +## Definition of Done + +- [ ] #1 Config and startup tests pass +- [ ] #2 Docs updated for new startup error behavior + + diff --git a/backlog/tasks/task-73 - Consolidate-launcher-mpv-socket-readiness-primitives.md b/backlog/tasks/task-73 - Consolidate-launcher-mpv-socket-readiness-primitives.md new file mode 100644 index 0000000..021282f --- /dev/null +++ b/backlog/tasks/task-73 - Consolidate-launcher-mpv-socket-readiness-primitives.md @@ -0,0 +1,45 @@ +--- +id: TASK-73 +title: Consolidate launcher mpv socket readiness primitives +status: To Do +assignee: [] +created_date: '2026-02-18 11:35' +updated_date: '2026-02-18 11:35' +labels: + - launcher + - mpv + - refactor +dependencies: [] +priority: medium +--- + +## Description + + +Launcher contains multiple overlapping MPV readiness/polling helpers (`waitForSocket`, `waitForPathExists`, `waitForUnixSocketReady`) with mixed timeout/poll semantics. Consolidation needed for clarity and lower maintenance. + + +## Action Steps + + +1. Define one canonical socket readiness contract (existence + connectability + timeout). +2. Replace duplicate polling helpers with a single implementation. +3. Update all callsites (`mpv status`, idle launch flow, subtitle loading dependencies). +4. Keep user-visible behavior and exit codes stable. +5. Add focused tests for timeout and success/failure edge cases. + + +## Acceptance Criteria + +- [ ] #1 Single canonical MPV socket readiness helper remains +- [ ] #2 All launcher callsites use unified helper +- [ ] #3 Behavior/exit code compatibility maintained for CLI flows +- [ ] #4 Test coverage added for readiness timeout behavior + + +## Definition of Done + +- [ ] #1 Launcher tests pass +- [ ] #2 No dead helper functions remain + + diff --git a/backlog/tasks/task-74 - Add-launcher-regression-tests-for-config-discovery-and-command-branching.md b/backlog/tasks/task-74 - Add-launcher-regression-tests-for-config-discovery-and-command-branching.md new file mode 100644 index 0000000..55c2aeb --- /dev/null +++ b/backlog/tasks/task-74 - Add-launcher-regression-tests-for-config-discovery-and-command-branching.md @@ -0,0 +1,48 @@ +--- +id: TASK-74 +title: Add launcher regression tests for config discovery and command branching +status: To Do +assignee: [] +created_date: '2026-02-18 11:35' +updated_date: '2026-02-18 11:35' +labels: + - launcher + - tests + - regression +dependencies: + - TASK-70 +priority: medium +--- + +## Description + + +Launcher currently has no direct test coverage for config discovery behavior and key command branching paths. This leaves wrapper flows vulnerable to regressions when refactoring config or process-control logic. + + +## Action Steps + + +1. Add launcher-focused test harness (unit/integration-lite) under existing project test runner. +2. Cover config discovery matrix: + - `XDG_CONFIG_HOME` overrides + - `SubMiner` vs `subminer` + - `.jsonc` vs `.json` preference +3. Cover CLI branch behavior (`doctor`, `config path/show`, `mpv status/socket`, jellyfin command routing). +4. Mock fs/process/spawn boundaries to keep tests deterministic. +5. Wire tests into existing `test:core:dist` or dedicated launcher test command. + + +## Acceptance Criteria + +- [ ] #1 Launcher config discovery paths are regression-tested +- [ ] #2 Core launcher command branches are regression-tested +- [ ] #3 Tests run in CI/local test gate without external process dependencies + + +## Definition of Done + +- [ ] #1 Launcher tests included in standard test workflow +- [ ] #2 Documented how to run launcher tests locally + + diff --git a/backlog/tasks/task-75 - Move-mpv-osd-log-writes-to-buffered-async-path.md b/backlog/tasks/task-75 - Move-mpv-osd-log-writes-to-buffered-async-path.md new file mode 100644 index 0000000..a3208df --- /dev/null +++ b/backlog/tasks/task-75 - Move-mpv-osd-log-writes-to-buffered-async-path.md @@ -0,0 +1,44 @@ +--- +id: TASK-75 +title: Move mpv OSD log writes to buffered async path +status: To Do +assignee: [] +created_date: '2026-02-18 11:35' +updated_date: '2026-02-18 11:35' +labels: + - logging + - performance + - main-process +dependencies: [] +priority: low +--- + +## Description + + +`appendToMpvLog` in `src/main.ts` uses synchronous fs operations on OSD writes. Frequent OSD activity can block the event loop and adds avoidable latency in main process runtime paths. + + +## Action Steps + + +1. Replace sync file writes with buffered async logger flow. +2. Ensure log directory creation and write failures remain best-effort (non-fatal). +3. Add flush behavior for shutdown to avoid dropping trailing log lines. +4. Keep log format/path unchanged unless explicitly intended. +5. Add tests for non-blocking behavior and graceful error handling. + + +## Acceptance Criteria + +- [ ] #1 OSD log path no longer uses synchronous fs calls +- [ ] #2 Logging remains best-effort and does not break runtime behavior on fs failure +- [ ] #3 Shutdown flush behavior verified by tests + + +## Definition of Done + +- [ ] #1 Core tests pass with new logging path +- [ ] #2 No user-visible regression in MPV OSD/log output behavior + + diff --git a/backlog/tasks/task-76 - Decompose-anki-integration-orchestrator-into-workflow-services.md b/backlog/tasks/task-76 - Decompose-anki-integration-orchestrator-into-workflow-services.md new file mode 100644 index 0000000..6dae2a2 --- /dev/null +++ b/backlog/tasks/task-76 - Decompose-anki-integration-orchestrator-into-workflow-services.md @@ -0,0 +1,55 @@ +--- +id: TASK-76 +title: Decompose anki-integration orchestrator into workflow services +status: To Do +assignee: [] +created_date: '2026-02-18 11:43' +updated_date: '2026-02-18 11:43' +labels: + - anki + - refactor + - maintainability +dependencies: + - TASK-57 +priority: high +--- + +## Description + + +`src/anki-integration.ts` remains a large orchestration hotspot after earlier splits. This task executes decomposition work (beyond evaluation) by extracting cohesive workflows and narrowing the central orchestrator to composition + policy decisions. + + +## Suggestions + + +- Prefer workflow modules over helper sprawl: `card-update-workflow`, `media-attachment-workflow`, `known-word-sync-workflow`, `field-mapping-workflow`. +- Keep side-effect adapters explicit (AnkiConnect API, fs/media, notification). +- Introduce a small façade API from `anki-integration.ts` to preserve callsite stability. + + +## Action Steps + + +1. Convert `TASK-57` findings into concrete extraction map with target module ownership. +2. Extract top two highest-churn workflows first (card creation/update and media attachment). +3. Move pure mapping/normalization logic to isolated pure modules with unit tests. +4. Keep backward-compatible public API for existing callsites. +5. Add regression tests for key mining flows (new card, update existing, audio-card mark, failure handling). +6. Update `docs/anki-integration.md` with new module boundaries. + + +## Acceptance Criteria + +- [ ] #1 `src/anki-integration.ts` reduced to orchestration/composition role +- [ ] #2 Extracted workflow modules have focused tests +- [ ] #3 Existing mining behavior remains unchanged in regression tests +- [ ] #4 Documentation updated with ownership boundaries + + +## Definition of Done + +- [ ] #1 `bun run test:core:dist` passes with Anki-related suites green +- [ ] #2 No callsite API breakage outside planned changes + + diff --git a/backlog/tasks/task-77 - Split-tokenizer-pipeline-into-parser-selection-enrichment-and-annotation-stages.md b/backlog/tasks/task-77 - Split-tokenizer-pipeline-into-parser-selection-enrichment-and-annotation-stages.md new file mode 100644 index 0000000..42f04d1 --- /dev/null +++ b/backlog/tasks/task-77 - Split-tokenizer-pipeline-into-parser-selection-enrichment-and-annotation-stages.md @@ -0,0 +1,54 @@ +--- +id: TASK-77 +title: Split tokenizer pipeline into parser selection enrichment and annotation stages +status: To Do +assignee: [] +created_date: '2026-02-18 11:43' +updated_date: '2026-02-18 11:43' +labels: + - tokenizer + - subtitles + - refactor +dependencies: [] +priority: high +--- + +## Description + + +`src/core/services/tokenizer.ts` mixes parser-window lifecycle, candidate scoring, MeCab enrichment, and post-annotation (known/JLPT/frequency/N+1). This task decomposes the tokenizer into explicit pipeline stages with stable contracts. + + +## Suggestions + + +- Use a stage pipeline contract (`TokenizationInput -> StageOutput`) to isolate concerns. +- Isolate Yomitan parser-window lifecycle into a dedicated runtime adapter module. +- Keep heuristics/test fixtures in one place to make scoring behavior reviewable. + + +## Action Steps + + +1. Define stage interfaces: source parsing, candidate selection, POS enrichment, semantic annotation. +2. Extract parser runtime adapter (`ensure parser window`, `execute parse`) from annotation logic. +3. Extract candidate scoring/selection into pure module with fixture-based tests. +4. Extract annotation passes (known-word, frequency, JLPT, N+1) into composable functions. +5. Add regression tests with fixed subtitle inputs to lock behavior. +6. Update tokenizer architecture notes in docs. + + +## Acceptance Criteria + +- [ ] #1 Tokenizer code is split into explicit stages with narrow interfaces +- [ ] #2 Candidate selection logic is pure + directly testable +- [ ] #3 Parser lifecycle concerns are separated from annotation passes +- [ ] #4 Existing tokenization behavior preserved in regression tests + + +## Definition of Done + +- [ ] #1 Tokenizer-related test suites pass +- [ ] #2 New stage-level tests exist for scoring and annotation + + diff --git a/backlog/tasks/task-78 - Modularize-config-definitions-and-validation-by-domain.md b/backlog/tasks/task-78 - Modularize-config-definitions-and-validation-by-domain.md new file mode 100644 index 0000000..050cbcd --- /dev/null +++ b/backlog/tasks/task-78 - Modularize-config-definitions-and-validation-by-domain.md @@ -0,0 +1,56 @@ +--- +id: TASK-78 +title: Modularize config definitions and validation by domain +status: To Do +assignee: [] +created_date: '2026-02-18 11:43' +updated_date: '2026-02-18 11:43' +labels: + - config + - refactor + - maintainability +dependencies: + - TASK-69 + - TASK-72 +priority: high +--- + +## Description + + +Config defaults and resolution are still concentrated in large files (`src/config/definitions.ts`, `src/config/service.ts`). This task splits config schema/defaults/validation into domain modules while preserving a single composed public config API. + + +## Suggestions + + +- Organize by domain (`anki`, `subtitle`, `jellyfin`, `anilist`, `launcher`, `runtime`). +- Keep one composition root that merges domain validators and defaults. +- Prefer small reusable validator helpers over per-field inline logic. + + +## Action Steps + + +1. Define domain module boundaries for defaults + validation rules. +2. Extract domain validators with shared primitives and warning builder. +3. Compose resolved config in a central aggregator module. +4. Keep `ConfigService` external API stable. +5. Expand tests for domain-level validation and composed config output. +6. Update config docs to reflect module ownership and extension workflow. + + +## Acceptance Criteria + +- [ ] #1 Config definitions/validation are split by domain with clear ownership +- [ ] #2 `ConfigService` API remains backward-compatible +- [ ] #3 Validation behavior remains stable under existing tests +- [ ] #4 New domain-level tests prevent regression in future config additions + + +## Definition of Done + +- [ ] #1 Config and core tests pass +- [ ] #2 Documentation updated for config extension workflow + + diff --git a/backlog/tasks/task-79 - Introduce-explicit-runtime-state-transitions-and-reducers-in-main.md b/backlog/tasks/task-79 - Introduce-explicit-runtime-state-transitions-and-reducers-in-main.md new file mode 100644 index 0000000..a234c4f --- /dev/null +++ b/backlog/tasks/task-79 - Introduce-explicit-runtime-state-transitions-and-reducers-in-main.md @@ -0,0 +1,55 @@ +--- +id: TASK-79 +title: Introduce explicit runtime state transitions and reducers in main +status: To Do +assignee: [] +created_date: '2026-02-18 11:43' +updated_date: '2026-02-18 11:43' +labels: + - main-process + - state-management + - architecture +dependencies: + - TASK-71 +priority: medium +--- + +## Description + + +Main runtime state is currently mutable from many callsites. This task introduces explicit state-transition functions (reducer-like actions) for critical state domains to improve traceability and reduce accidental cross-feature coupling. + + +## Suggestions + + +- Start with high-risk domains: overlay visibility, MPV connection/session, AniList/Jellyfin runtime status. +- Use action-style transition helpers (`setMediaPath`, `setOverlayVisibility`, `setAnilistState`) instead of direct field mutation. +- Keep transition helpers side-effect free; invoke effects in orchestration layer. + + +## Action Steps + + +1. Inventory direct mutation hotspots in `src/main.ts` and runtime modules. +2. Define state transition API in `src/main/state.ts` for priority domains. +3. Migrate callsites incrementally to transition helpers. +4. Add unit tests for transition behavior and invariant enforcement. +5. Add lightweight debug tracing for transition events in debug mode. +6. Document state ownership and mutation rules in architecture docs. + + +## Acceptance Criteria + +- [ ] #1 Critical runtime state domains mutate through explicit transition helpers +- [ ] #2 State invariants are test-covered +- [ ] #3 Direct ad-hoc mutation in migrated domains is removed +- [ ] #4 Ownership/mutation rules documented + + +## Definition of Done + +- [ ] #1 Core tests pass after migration +- [ ] #2 No behavior regressions in startup/IPC/overlay flows + + diff --git a/backlog/tasks/task-80 - Strengthen-ipc-contract-typing-and-runtime-payload-validation.md b/backlog/tasks/task-80 - Strengthen-ipc-contract-typing-and-runtime-payload-validation.md new file mode 100644 index 0000000..2f37953 --- /dev/null +++ b/backlog/tasks/task-80 - Strengthen-ipc-contract-typing-and-runtime-payload-validation.md @@ -0,0 +1,54 @@ +--- +id: TASK-80 +title: Strengthen IPC contract typing and runtime payload validation +status: To Do +assignee: [] +created_date: '2026-02-18 11:43' +updated_date: '2026-02-18 11:43' +labels: + - ipc + - type-safety + - reliability +dependencies: [] +priority: medium +--- + +## Description + + +IPC handlers still rely on many `unknown` payload casts in main process paths. This task formalizes typed IPC contracts and validates runtime payloads before dispatch to reduce runtime-only failures. + + +## Suggestions + + +- Define canonical channel map (`channel -> request/response/error types`). +- Add boundary validators for untrusted renderer payloads. +- Keep channel registration centralized to avoid drift. + + +## Action Steps + + +1. Inventory IPC channels and payload shapes in `src/main/ipc-runtime.ts` and registration callsites. +2. Introduce shared IPC type map and typed registration helpers. +3. Add runtime guards/validators at IPC entry points. +4. Remove unsafe casts where typed contracts are introduced. +5. Add negative tests for malformed payloads and expected error responses. +6. Document IPC contract extension process. + + +## Acceptance Criteria + +- [ ] #1 IPC channels are defined in a typed central contract +- [ ] #2 Runtime payload validation exists for externally supplied IPC data +- [ ] #3 Unsafe cast usage in IPC boundary code is materially reduced +- [ ] #4 Malformed payloads are handled gracefully and test-covered + + +## Definition of Done + +- [ ] #1 IPC-related tests pass +- [ ] #2 IPC contract docs updated + + diff --git a/backlog/tasks/task-81 - Refactor-launcher-into-command-modules-and-process-adapters.md b/backlog/tasks/task-81 - Refactor-launcher-into-command-modules-and-process-adapters.md new file mode 100644 index 0000000..17a1d11 --- /dev/null +++ b/backlog/tasks/task-81 - Refactor-launcher-into-command-modules-and-process-adapters.md @@ -0,0 +1,57 @@ +--- +id: TASK-81 +title: Refactor launcher into command modules and process adapters +status: To Do +assignee: [] +created_date: '2026-02-18 11:43' +updated_date: '2026-02-18 11:43' +labels: + - launcher + - cli + - architecture +dependencies: + - TASK-70 + - TASK-73 + - TASK-74 +priority: medium +--- + +## Description + + +Launcher code is still large and process-control heavy (`launcher/main.ts`, `launcher/mpv.ts`, `launcher/config.ts`). This task refactors launcher flows into command modules plus explicit process adapters to reduce branching complexity and improve testability. + + +## Suggestions + + +- Split by command domain (`doctor`, `config`, `mpv`, `jellyfin`, `play`). +- Isolate shell/process invocations behind adapter interfaces. +- Keep argv parsing independent from command execution side effects. + + +## Action Steps + + +1. Define launcher command dispatcher and command handler interfaces. +2. Extract command handlers from `launcher/main.ts`. +3. Move spawn/fs/net operations into process + platform adapter modules. +4. Keep CLI UX and exit-code behavior stable. +5. Add unit tests per command module with mocked adapters. +6. Update launcher docs for module structure and extension guidance. + + +## Acceptance Criteria + +- [ ] #1 Launcher commands are implemented as focused modules +- [ ] #2 Process side effects are isolated behind adapter interfaces +- [ ] #3 Existing CLI behavior and exit codes remain compatible +- [ ] #4 Launcher testability improves via mocked adapter tests + + +## Definition of Done + +- [ ] #1 Launcher tests and core test gate pass +- [ ] #2 No regression in wrapper command behavior + + diff --git a/backlog/tasks/task-82 - Add-end-to-end-smoke-suite-for-launcher-mpv-ipc-and-overlay-runtime.md b/backlog/tasks/task-82 - Add-end-to-end-smoke-suite-for-launcher-mpv-ipc-and-overlay-runtime.md new file mode 100644 index 0000000..51d2fc3 --- /dev/null +++ b/backlog/tasks/task-82 - Add-end-to-end-smoke-suite-for-launcher-mpv-ipc-and-overlay-runtime.md @@ -0,0 +1,60 @@ +--- +id: TASK-82 +title: Add end-to-end smoke suite for launcher mpv ipc and overlay runtime +status: To Do +assignee: [] +created_date: '2026-02-18 11:43' +updated_date: '2026-02-18 11:43' +labels: + - testing + - e2e + - launcher + - mpv +dependencies: + - TASK-74 +priority: high +--- + +## Description + + +Current coverage is strong at unit/service level but thin on end-to-end behavior across launcher, mpv socket lifecycle, IPC wiring, and overlay runtime initialization. This task introduces an observable e2e smoke suite to reduce refactor risk. + + +## Suggestions + + +- Start with deterministic smoke flows, not full UI automation. +- Use minimal fixtures and fakeable mpv socket harness where possible. +- Treat this as release gate signal, with clear pass/fail logs. + + +## Action Steps + + +1. Define smoke scenarios: + - launcher command branch sanity + - mpv socket ready/not-ready handling + - IPC channel registration + key command dispatch + - overlay runtime bootstrap lifecycle +2. Build test harness that can run headless in CI/local environments. +3. Add stable fixtures/mocks for mpv and external tool boundaries. +4. Produce concise logs/artifacts for failures. +5. Integrate smoke suite into pre-release validation flow. +6. Document smoke test usage and troubleshooting. + + +## Acceptance Criteria + +- [ ] #1 E2E smoke suite exists and runs in automated workflow +- [ ] #2 Core launcher/mpv/ipc/overlay startup scenarios are covered +- [ ] #3 Failures produce actionable logs/artifacts +- [ ] #4 Smoke suite documented in development/release docs + + +## Definition of Done + +- [ ] #1 Smoke suite passes on baseline branch +- [ ] #2 Release checklist references smoke suite + + diff --git a/docs/development.md b/docs/development.md index f472093..d0490bf 100644 --- a/docs/development.md +++ b/docs/development.md @@ -13,7 +13,7 @@ cd SubMiner make deps # or manually: bun install -cd vendor/texthooker-ui && bun install +cd vendor/texthooker-ui && pnpm install --frozen-lockfile ``` ## Building diff --git a/docs/installation.md b/docs/installation.md index 41d0581..64bd365 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -83,7 +83,7 @@ brew install mpv mecab mecab-ipadic git clone https://github.com/ksyasuda/SubMiner.git cd SubMiner bun install -cd vendor/texthooker-ui && bun install && bun run build && cd ../.. +cd vendor/texthooker-ui && pnpm install --frozen-lockfile && pnpm run build && cd ../.. bun run build:mac ``` diff --git a/scripts/patch-texthooker.sh b/scripts/patch-texthooker.sh index d5ba26f..329056f 100755 --- a/scripts/patch-texthooker.sh +++ b/scripts/patch-texthooker.sh @@ -233,4 +233,4 @@ echo " 2. socket.ts: Skip emitting empty sentences" echo " 3. app.css: Apply SubMiner default styling (without !important)" echo " 4. stores.ts: Update default settings for title/whitespace/animation/reconnect" echo "" -echo "To rebuild: cd vendor/texthooker-ui && bun run build" +echo "To rebuild: cd vendor/texthooker-ui && pnpm run build"