chore: switch texthooker-ui workflow to pnpm and add backlog tasks

This commit is contained in:
kyasuda
2026-02-18 18:05:42 -08:00
parent ebaed49f76
commit f299f2a19e
19 changed files with 726 additions and 9 deletions

View File

@@ -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 APP_NAME := subminer
THEME_FILE := subminer.rasi THEME_FILE := subminer.rasi
@@ -91,12 +91,16 @@ print-dirs:
deps: deps:
@$(MAKE) --no-print-directory ensure-bun @$(MAKE) --no-print-directory ensure-bun
@$(MAKE) --no-print-directory ensure-pnpm
@bun install @bun install
@cd vendor/texthooker-ui && bun install @cd vendor/texthooker-ui && pnpm install --frozen-lockfile
ensure-bun: ensure-bun:
@command -v bun >/dev/null 2>&1 || { printf '%s\n' "[ERROR] bun not found"; exit 1; } @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 pretty: ensure-bun
@bun run format @bun run format
@@ -118,17 +122,17 @@ install:
build-linux: deps build-linux: deps
@printf '%s\n' "[INFO] Building Linux package (AppImage)" @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 @bun run build:appimage
build-macos: deps build-macos: deps
@printf '%s\n' "[INFO] Building macOS package (DMG + ZIP)" @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 @bun run build:mac
build-macos-unsigned: deps build-macos-unsigned: deps
@printf '%s\n' "[INFO] Building macOS package (DMG + ZIP, unsigned)" @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 @bun run build:mac:unsigned
build-launcher: build-launcher:

View File

@@ -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 git clone --recurse-submodules https://github.com/ksyasuda/SubMiner.git
cd SubMiner cd SubMiner
bun install bun install
cd vendor/texthooker-ui && bun install && cd ../.. cd vendor/texthooker-ui && pnpm install --frozen-lockfile && cd ../..
make build make build
make install make install
``` ```

View File

@@ -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
<!-- SECTION:DESCRIPTION:BEGIN -->
`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.
<!-- SECTION:DESCRIPTION:END -->
## Action Steps
<!-- SECTION:PLAN:BEGIN -->
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.
<!-- SECTION:PLAN:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #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
<!-- AC:END -->
## Definition of Done
<!-- DOD:BEGIN -->
- [ ] #1 `bun run test:config:dist` passes
- [ ] #2 Any doc changes for migration/deprecation are committed
<!-- DOD:END -->

View File

@@ -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
<!-- SECTION:DESCRIPTION:BEGIN -->
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.
<!-- SECTION:DESCRIPTION:END -->
## Action Steps
<!-- SECTION:PLAN:BEGIN -->
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.
<!-- SECTION:PLAN:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #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
<!-- AC:END -->
## Definition of Done
<!-- DOD:BEGIN -->
- [ ] #1 Launcher and config tests pass
- [ ] #2 Code no longer duplicates config path candidate logic
<!-- DOD:END -->

View File

@@ -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
<!-- SECTION:DESCRIPTION:BEGIN -->
`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.
<!-- SECTION:DESCRIPTION:END -->
## Action Steps
<!-- SECTION:PLAN:BEGIN -->
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.
<!-- SECTION:PLAN:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #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
<!-- AC:END -->
## Definition of Done
<!-- DOD:BEGIN -->
- [ ] #1 `bun run test:fast` passes
- [ ] #2 Architecture docs updated
<!-- DOD:END -->

View File

@@ -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
<!-- SECTION:DESCRIPTION:BEGIN -->
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.
<!-- SECTION:DESCRIPTION:END -->
## Action Steps
<!-- SECTION:PLAN:BEGIN -->
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.
<!-- SECTION:PLAN:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 Startup and hot-reload use consistent strictness semantics
- [ ] #2 Malformed config surfaces explicit actionable error
- [ ] #3 Tests cover malformed startup config path
<!-- AC:END -->
## Definition of Done
<!-- DOD:BEGIN -->
- [ ] #1 Config and startup tests pass
- [ ] #2 Docs updated for new startup error behavior
<!-- DOD:END -->

View File

@@ -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
<!-- SECTION:DESCRIPTION:BEGIN -->
Launcher contains multiple overlapping MPV readiness/polling helpers (`waitForSocket`, `waitForPathExists`, `waitForUnixSocketReady`) with mixed timeout/poll semantics. Consolidation needed for clarity and lower maintenance.
<!-- SECTION:DESCRIPTION:END -->
## Action Steps
<!-- SECTION:PLAN:BEGIN -->
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.
<!-- SECTION:PLAN:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #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
<!-- AC:END -->
## Definition of Done
<!-- DOD:BEGIN -->
- [ ] #1 Launcher tests pass
- [ ] #2 No dead helper functions remain
<!-- DOD:END -->

View File

@@ -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
<!-- SECTION:DESCRIPTION:BEGIN -->
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.
<!-- SECTION:DESCRIPTION:END -->
## Action Steps
<!-- SECTION:PLAN:BEGIN -->
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.
<!-- SECTION:PLAN:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #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
<!-- AC:END -->
## Definition of Done
<!-- DOD:BEGIN -->
- [ ] #1 Launcher tests included in standard test workflow
- [ ] #2 Documented how to run launcher tests locally
<!-- DOD:END -->

View File

@@ -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
<!-- SECTION:DESCRIPTION:BEGIN -->
`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.
<!-- SECTION:DESCRIPTION:END -->
## Action Steps
<!-- SECTION:PLAN:BEGIN -->
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.
<!-- SECTION:PLAN:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #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
<!-- AC:END -->
## Definition of Done
<!-- DOD:BEGIN -->
- [ ] #1 Core tests pass with new logging path
- [ ] #2 No user-visible regression in MPV OSD/log output behavior
<!-- DOD:END -->

View File

@@ -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
<!-- SECTION:DESCRIPTION:BEGIN -->
`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.
<!-- SECTION:DESCRIPTION:END -->
## Suggestions
<!-- SECTION:SUGGESTIONS:BEGIN -->
- 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.
<!-- SECTION:SUGGESTIONS:END -->
## Action Steps
<!-- SECTION:PLAN:BEGIN -->
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.
<!-- SECTION:PLAN:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #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
<!-- AC:END -->
## Definition of Done
<!-- DOD:BEGIN -->
- [ ] #1 `bun run test:core:dist` passes with Anki-related suites green
- [ ] #2 No callsite API breakage outside planned changes
<!-- DOD:END -->

View File

@@ -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
<!-- SECTION:DESCRIPTION:BEGIN -->
`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.
<!-- SECTION:DESCRIPTION:END -->
## Suggestions
<!-- SECTION:SUGGESTIONS:BEGIN -->
- 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.
<!-- SECTION:SUGGESTIONS:END -->
## Action Steps
<!-- SECTION:PLAN:BEGIN -->
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.
<!-- SECTION:PLAN:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #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
<!-- AC:END -->
## Definition of Done
<!-- DOD:BEGIN -->
- [ ] #1 Tokenizer-related test suites pass
- [ ] #2 New stage-level tests exist for scoring and annotation
<!-- DOD:END -->

View File

@@ -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
<!-- SECTION:DESCRIPTION:BEGIN -->
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.
<!-- SECTION:DESCRIPTION:END -->
## Suggestions
<!-- SECTION:SUGGESTIONS:BEGIN -->
- 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.
<!-- SECTION:SUGGESTIONS:END -->
## Action Steps
<!-- SECTION:PLAN:BEGIN -->
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.
<!-- SECTION:PLAN:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #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
<!-- AC:END -->
## Definition of Done
<!-- DOD:BEGIN -->
- [ ] #1 Config and core tests pass
- [ ] #2 Documentation updated for config extension workflow
<!-- DOD:END -->

View File

@@ -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
<!-- SECTION:DESCRIPTION:BEGIN -->
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.
<!-- SECTION:DESCRIPTION:END -->
## Suggestions
<!-- SECTION:SUGGESTIONS:BEGIN -->
- 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.
<!-- SECTION:SUGGESTIONS:END -->
## Action Steps
<!-- SECTION:PLAN:BEGIN -->
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.
<!-- SECTION:PLAN:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #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
<!-- AC:END -->
## Definition of Done
<!-- DOD:BEGIN -->
- [ ] #1 Core tests pass after migration
- [ ] #2 No behavior regressions in startup/IPC/overlay flows
<!-- DOD:END -->

View File

@@ -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
<!-- SECTION:DESCRIPTION:BEGIN -->
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.
<!-- SECTION:DESCRIPTION:END -->
## Suggestions
<!-- SECTION:SUGGESTIONS:BEGIN -->
- Define canonical channel map (`channel -> request/response/error types`).
- Add boundary validators for untrusted renderer payloads.
- Keep channel registration centralized to avoid drift.
<!-- SECTION:SUGGESTIONS:END -->
## Action Steps
<!-- SECTION:PLAN:BEGIN -->
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.
<!-- SECTION:PLAN:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #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
<!-- AC:END -->
## Definition of Done
<!-- DOD:BEGIN -->
- [ ] #1 IPC-related tests pass
- [ ] #2 IPC contract docs updated
<!-- DOD:END -->

View File

@@ -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
<!-- SECTION:DESCRIPTION:BEGIN -->
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.
<!-- SECTION:DESCRIPTION:END -->
## Suggestions
<!-- SECTION:SUGGESTIONS:BEGIN -->
- 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.
<!-- SECTION:SUGGESTIONS:END -->
## Action Steps
<!-- SECTION:PLAN:BEGIN -->
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.
<!-- SECTION:PLAN:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #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
<!-- AC:END -->
## Definition of Done
<!-- DOD:BEGIN -->
- [ ] #1 Launcher tests and core test gate pass
- [ ] #2 No regression in wrapper command behavior
<!-- DOD:END -->

View File

@@ -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
<!-- SECTION:DESCRIPTION:BEGIN -->
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.
<!-- SECTION:DESCRIPTION:END -->
## Suggestions
<!-- SECTION:SUGGESTIONS:BEGIN -->
- 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.
<!-- SECTION:SUGGESTIONS:END -->
## Action Steps
<!-- SECTION:PLAN:BEGIN -->
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.
<!-- SECTION:PLAN:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #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
<!-- AC:END -->
## Definition of Done
<!-- DOD:BEGIN -->
- [ ] #1 Smoke suite passes on baseline branch
- [ ] #2 Release checklist references smoke suite
<!-- DOD:END -->

View File

@@ -13,7 +13,7 @@ cd SubMiner
make deps make deps
# or manually: # or manually:
bun install bun install
cd vendor/texthooker-ui && bun install cd vendor/texthooker-ui && pnpm install --frozen-lockfile
``` ```
## Building ## Building

View File

@@ -83,7 +83,7 @@ brew install mpv mecab mecab-ipadic
git clone https://github.com/ksyasuda/SubMiner.git git clone https://github.com/ksyasuda/SubMiner.git
cd SubMiner cd SubMiner
bun install 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 bun run build:mac
``` ```

View File

@@ -233,4 +233,4 @@ echo " 2. socket.ts: Skip emitting empty sentences"
echo " 3. app.css: Apply SubMiner default styling (without !important)" echo " 3. app.css: Apply SubMiner default styling (without !important)"
echo " 4. stores.ts: Update default settings for title/whitespace/animation/reconnect" echo " 4. stores.ts: Update default settings for title/whitespace/animation/reconnect"
echo "" echo ""
echo "To rebuild: cd vendor/texthooker-ui && bun run build" echo "To rebuild: cd vendor/texthooker-ui && pnpm run build"