mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-27 18:22:41 -08:00
chore: switch texthooker-ui workflow to pnpm and add backlog tasks
This commit is contained in:
14
Makefile
14
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
|
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:
|
||||||
|
|||||||
@@ -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
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -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 -->
|
||||||
|
|
||||||
@@ -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 -->
|
||||||
|
|
||||||
@@ -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 -->
|
||||||
|
|
||||||
@@ -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 -->
|
||||||
|
|
||||||
@@ -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 -->
|
||||||
|
|
||||||
@@ -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 -->
|
||||||
|
|
||||||
@@ -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 -->
|
||||||
|
|
||||||
@@ -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 -->
|
||||||
|
|
||||||
@@ -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 -->
|
||||||
|
|
||||||
@@ -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 -->
|
||||||
|
|
||||||
@@ -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 -->
|
||||||
|
|
||||||
@@ -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 -->
|
||||||
|
|
||||||
@@ -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 -->
|
||||||
|
|
||||||
@@ -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 -->
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user