mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-27 18:22:41 -08:00
refactor(main): modularize runtime and harden anilist setup flow
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
project_name: 'SubMiner'
|
||||
default_status: 'To Do'
|
||||
statuses: ['To Do', 'In Progress', 'Done']
|
||||
project_name: "SubMiner"
|
||||
default_status: "To Do"
|
||||
statuses: ["To Do", "In Progress", "Done"]
|
||||
labels: []
|
||||
milestones: []
|
||||
date_format: yyyy-mm-dd
|
||||
max_column_width: 20
|
||||
default_editor: 'nvim'
|
||||
default_editor: "nvim"
|
||||
auto_open_browser: false
|
||||
default_port: 6420
|
||||
remote_operations: true
|
||||
@@ -13,4 +13,4 @@ auto_commit: false
|
||||
bypass_git_hooks: false
|
||||
check_active_branches: true
|
||||
active_branch_days: 30
|
||||
task_prefix: 'task'
|
||||
task_prefix: "task"
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
id: TASK-29.3
|
||||
title: Fix AniList OAuth callback token handling in setup window
|
||||
status: Done
|
||||
assignee: []
|
||||
created_date: '2026-02-19 16:56'
|
||||
labels:
|
||||
- anilist
|
||||
- oauth
|
||||
- bug
|
||||
dependencies: []
|
||||
parent_task_id: TASK-29
|
||||
priority: high
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
AniList login flow shows unsupported_grant_type after auth because setup window does not consume callback URL token and persist it.
|
||||
|
||||
Need robust callback handling for both query and hash access_token forms and graceful close/success UX.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [x] #1 AniList setup flow persists access token from callback URL query/hash
|
||||
- [x] #2 Setup window closes and state updates to resolved when token captured
|
||||
- [x] #3 No unsafe navigation regressions in AniList setup window
|
||||
<!-- AC:END -->
|
||||
|
||||
## Definition of Done
|
||||
<!-- DOD:BEGIN -->
|
||||
- [x] #1 Build passes
|
||||
- [x] #2 Targeted AniList runtime tests pass
|
||||
<!-- DOD:END -->
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
<!-- SECTION:IMPLEMENTATION_NOTES:BEGIN -->
|
||||
- Added robust AniList callback token parsing for query/hash and `subminer://anilist-setup?...` deep links.
|
||||
- Added app-level protocol handling (`open-url` + second-instance argv deep link parsing) so browser callback buttons resolve even when setup window is not navigating.
|
||||
- Added/updated targeted AniList setup runtime tests and verified build + runtime test pass.
|
||||
<!-- SECTION:IMPLEMENTATION_NOTES:END -->
|
||||
@@ -4,19 +4,19 @@ title: Add error boundary and recovery in renderer overlay
|
||||
status: Done
|
||||
assignee: []
|
||||
created_date: '2026-02-14 01:01'
|
||||
updated_date: '2026-02-19 21:50'
|
||||
updated_date: '2026-02-19 23:18'
|
||||
labels:
|
||||
- renderer
|
||||
- reliability
|
||||
- error-handling
|
||||
dependencies: []
|
||||
priority: medium
|
||||
ordinal: 60000
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
|
||||
Add a top-level error boundary in the renderer orchestrator that catches unhandled errors in modals and rendering logic, displays a user-friendly error message, and recovers without crashing the overlay.
|
||||
|
||||
## Motivation
|
||||
@@ -39,9 +39,7 @@ If a renderer modal throws (e.g., jimaku API timeout, DOM manipulation error, ma
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
<!-- AC:BEGIN -->
|
||||
|
||||
- [x] #1 Unhandled errors in modal flows are caught and do not crash the overlay.
|
||||
- [x] #2 After an error, the overlay returns to a functional state (subtitles render, shortcuts work).
|
||||
- [x] #3 A brief toast/notification informs the user that an error occurred.
|
||||
@@ -52,6 +50,7 @@ If a renderer modal throws (e.g., jimaku API timeout, DOM manipulation error, ma
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
<!-- SECTION:NOTES:BEGIN -->
|
||||
- Added renderer recovery module with guarded callback boundaries and global `window.onerror` / `window.unhandledrejection` handlers.
|
||||
- Recovery now uses modal close/cancel APIs (including Kiku cancel) to preserve cleanup semantics and avoid hanging pending callbacks.
|
||||
- Added overlay recovery toast UI and contextual recovery logging payloads.
|
||||
@@ -61,3 +60,4 @@ If a renderer modal throws (e.g., jimaku API timeout, DOM manipulation error, ma
|
||||
|
||||
- `bun run build`
|
||||
- `bun run test:core:dist`
|
||||
<!-- SECTION:NOTES:END -->
|
||||
|
||||
@@ -5,13 +5,14 @@ status: Done
|
||||
assignee:
|
||||
- codex-main
|
||||
created_date: '2026-02-14 02:02'
|
||||
updated_date: '2026-02-19 08:21'
|
||||
updated_date: '2026-02-19 23:18'
|
||||
labels:
|
||||
- config
|
||||
- developer-experience
|
||||
- error-handling
|
||||
dependencies: []
|
||||
priority: medium
|
||||
ordinal: 66000
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
---
|
||||
id: TASK-65
|
||||
title: Add overlay drag-drop playlist loading and clipboard append shortcut
|
||||
status: Done
|
||||
assignee: []
|
||||
created_date: '2026-02-18 13:10'
|
||||
updated_date: '2026-02-18 13:10'
|
||||
labels: []
|
||||
dependencies: []
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
Implement direct playlist control from the overlay:
|
||||
|
||||
- Drag/drop video files onto overlay:
|
||||
- default drop: replace current playback with dropped set (first `replace`, remainder `append`)
|
||||
- `Shift` + drop: append all dropped files
|
||||
- `Ctrl/Cmd+A`: read clipboard text, if it resolves to a supported local video file path, append it to mpv playlist.
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
- [x] Add TDD coverage for drop path parsing, command mode generation, and clipboard path parsing (`src/core/services/overlay-drop.test.ts`).
|
||||
- [x] Implement drop/clipboard parser + mpv command-builder utility (`src/core/services/overlay-drop.ts`).
|
||||
- [x] Wire renderer drag/drop handling and mpv command dispatch (`src/renderer/renderer.ts`).
|
||||
- [x] Add IPC API for clipboard append flow (`src/types.ts`, `src/preload.ts`, `src/core/services/ipc.ts`, `src/main/dependencies.ts`).
|
||||
- [x] Implement main-process clipboard validation + append behavior (`src/main.ts`).
|
||||
- [x] Add fixed keyboard shortcut hook (`Ctrl/Cmd+A`) in renderer keyboard handler (`src/renderer/handlers/keyboard.ts`, `src/renderer/renderer.ts`).
|
||||
- [x] Update docs for new interaction model (`docs/usage.md`, `docs/configuration.md`).
|
||||
|
||||
## Verification
|
||||
|
||||
- `bun run build`
|
||||
- `node --test dist/core/services/overlay-drop.test.js dist/core/services/ipc.test.js`
|
||||
@@ -4,7 +4,7 @@ title: Run Electron app as background tray service with IPC startup
|
||||
status: Done
|
||||
assignee: []
|
||||
created_date: '2026-02-18 08:48'
|
||||
updated_date: '2026-02-19 21:50'
|
||||
updated_date: '2026-02-19 23:18'
|
||||
labels:
|
||||
- electron
|
||||
- tray
|
||||
@@ -12,6 +12,7 @@ labels:
|
||||
- desktop-entry
|
||||
dependencies: []
|
||||
priority: high
|
||||
ordinal: 61000
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
@@ -4,7 +4,7 @@ title: Make wrapper stop auto-sending --start by default
|
||||
status: Done
|
||||
assignee: []
|
||||
created_date: '2026-02-18 09:47'
|
||||
updated_date: '2026-02-18 10:02'
|
||||
updated_date: '2026-02-19 23:18'
|
||||
labels:
|
||||
- launcher
|
||||
- wrapper
|
||||
@@ -12,6 +12,7 @@ labels:
|
||||
- background-mode
|
||||
dependencies: []
|
||||
priority: high
|
||||
ordinal: 68000
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
@@ -4,12 +4,13 @@ title: Allow trailing commas in JSONC config parsing
|
||||
status: Done
|
||||
assignee: []
|
||||
created_date: '2026-02-18 10:13'
|
||||
updated_date: '2026-02-18 10:13'
|
||||
updated_date: '2026-02-19 23:18'
|
||||
labels:
|
||||
- config
|
||||
- jsonc
|
||||
dependencies: []
|
||||
priority: medium
|
||||
ordinal: 67000
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
@@ -5,13 +5,14 @@ status: Done
|
||||
assignee:
|
||||
- codex-main
|
||||
created_date: '2026-02-18 11:35'
|
||||
updated_date: '2026-02-19 08:27'
|
||||
updated_date: '2026-02-19 23:18'
|
||||
labels:
|
||||
- config
|
||||
- validation
|
||||
- safety
|
||||
dependencies: []
|
||||
priority: high
|
||||
ordinal: 65000
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
@@ -5,13 +5,14 @@ status: Done
|
||||
assignee:
|
||||
- codex-main
|
||||
created_date: '2026-02-18 11:35'
|
||||
updated_date: '2026-02-19 09:05'
|
||||
updated_date: '2026-02-19 23:18'
|
||||
labels:
|
||||
- config
|
||||
- launcher
|
||||
- consistency
|
||||
dependencies: []
|
||||
priority: high
|
||||
ordinal: 63000
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
@@ -5,13 +5,14 @@ status: Done
|
||||
assignee:
|
||||
- codex-main
|
||||
created_date: '2026-02-19 08:38'
|
||||
updated_date: '2026-02-19 08:40'
|
||||
updated_date: '2026-02-19 23:18'
|
||||
labels:
|
||||
- config
|
||||
- anki
|
||||
- cleanup
|
||||
dependencies: []
|
||||
priority: medium
|
||||
ordinal: 64000
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
id: TASK-85
|
||||
title: Refactor large files for maintainability and readability
|
||||
status: In Progress
|
||||
assignee: []
|
||||
created_date: '2026-02-19 09:46'
|
||||
updated_date: '2026-02-19 10:01'
|
||||
labels:
|
||||
- architecture
|
||||
- refactor
|
||||
- maintainability
|
||||
dependencies: []
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Several core files are oversized and high-coupling (`src/main.ts`, `src/anki-integration.ts`, `src/config/service.ts`, `src/core/services/immersion-tracker-service.ts`). This task tracks phased, behavior-preserving decomposition plus guardrails and generated-launcher workflow cleanup.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Suggestions
|
||||
|
||||
<!-- SECTION:SUGGESTIONS:BEGIN -->
|
||||
- Use seam tests before each extraction.
|
||||
- Keep `src/main.ts` + `src/anki-integration.ts` as thin composition/coordinator layers.
|
||||
- Formalize `subminer` as generated artifact only.
|
||||
<!-- SECTION:SUGGESTIONS:END -->
|
||||
|
||||
## Action Steps
|
||||
|
||||
<!-- SECTION:PLAN:BEGIN -->
|
||||
1. Add file-budget guardrails and baseline report.
|
||||
2. Split `src/main.ts` into runtime domain modules.
|
||||
3. Split `src/anki-integration.ts` into focused collaborators.
|
||||
4. Split `src/config/service.ts` by load/migrate/validate/warn phases.
|
||||
5. Split immersion tracker service by state, persistence, sync responsibilities.
|
||||
6. Clarify generated launcher artifact workflow and docs.
|
||||
7. Run full build/test gate and publish maintainability report.
|
||||
<!-- SECTION:PLAN:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 `src/main.ts` reduced to orchestration-focused module with extracted runtime domains
|
||||
- [ ] #2 `src/anki-integration.ts` reduced to facade with helper collaborators
|
||||
- [ ] #3 Config and immersion tracker services decomposed without behavior regressions
|
||||
- [ ] #4 `subminer` generated artifact ownership/workflow documented and enforced
|
||||
- [ ] #5 Full build + config/core tests pass after refactor
|
||||
<!-- AC:END -->
|
||||
|
||||
## Definition of Done
|
||||
<!-- DOD:BEGIN -->
|
||||
- [ ] #1 Plan at `docs/plans/2026-02-19-repo-maintainability-refactor-plan.md` executed or decomposed into child tasks
|
||||
- [ ] #2 Regression coverage added for extracted seams
|
||||
- [ ] #3 Docs updated for architecture and contributor workflow changes
|
||||
<!-- DOD:END -->
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
id: TASK-86
|
||||
title: Include config validation issue details in user notifications
|
||||
status: Done
|
||||
assignee: []
|
||||
created_date: '2026-02-19 17:24'
|
||||
updated_date: '2026-02-19 23:18'
|
||||
labels: []
|
||||
dependencies: []
|
||||
priority: medium
|
||||
ordinal: 62000
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
When config validation finds non-fatal issues, users should see concise per-issue details in notification body (not only issue count) so they can fix config quickly without checking logs.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [x] #1 Startup notification body includes per-issue details (path + message) for config validation warnings.
|
||||
- [x] #2 Hot-reload validation warning notifications include per-issue details in notification body.
|
||||
- [x] #3 Notification text remains concise and does not exceed practical desktop notification limits.
|
||||
- [x] #4 Automated tests cover notification body formatting with detailed issues.
|
||||
<!-- AC:END -->
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
<!-- SECTION:NOTES:BEGIN -->
|
||||
Added `buildConfigWarningNotificationBody` to format concise multi-line warning details (path+message, line limit + overflow count). Startup warnings now use this formatter for desktop notification body. Config hot-reload runtime now emits non-fatal validation warnings via `onValidationWarnings(configPath, warnings)` and main process surfaces them through desktop notifications. Added tests for formatter output, startup notification body content, and hot-reload warning callback behavior.
|
||||
<!-- SECTION:NOTES:END -->
|
||||
|
||||
## Final Summary
|
||||
|
||||
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
|
||||
Config validation notifications now include concrete issue details in the notification body instead of only a count. Startup and hot-reload warning paths both surface per-issue `path: message` lines with concise truncation safeguards. Added regression tests covering formatter output and both notification paths.
|
||||
<!-- SECTION:FINAL_SUMMARY:END -->
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: TASK-87
|
||||
title: Fix plugin --start flow so tokenization/frequency/N+1 initialize correctly
|
||||
status: Done
|
||||
assignee: []
|
||||
created_date: '2026-02-19 19:05'
|
||||
updated_date: '2026-02-19 23:18'
|
||||
labels: []
|
||||
dependencies: []
|
||||
priority: medium
|
||||
ordinal: 69000
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Plugin startup flow (`--texthooker` then `--start`) can miss tokenization initialization, which makes frequency highlighting and N+1 appear broken even when dictionaries/config are correct. Ensure `--start` initializes overlay runtime when needed, including second-instance handoff mode.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [x] #1 `--start` initializes overlay runtime when runtime is not yet initialized.
|
||||
- [x] #2 `second-instance --start` is ignored only when overlay runtime is already initialized.
|
||||
- [x] #3 Regression tests cover both `--start` behaviors and pass.
|
||||
<!-- AC:END -->
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
<!-- SECTION:NOTES:BEGIN -->
|
||||
Root cause: subtitle tokenization path in `src/main.ts` only runs when overlay windows exist; command runtime did not initialize overlay runtime for `--start`, especially visible in plugin handoff (`--texthooker` -> `--start`). Updated `src/core/services/cli-command.ts` to initialize overlay runtime for `--start`, and narrowed second-instance ignore behavior to already-initialized runtime only. Added regression tests in `src/core/services/cli-command.test.ts`.
|
||||
<!-- SECTION:NOTES:END -->
|
||||
|
||||
## Final Summary
|
||||
|
||||
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
|
||||
Fixed plugin/start regression by ensuring `--start` initializes overlay runtime when needed and no longer gets dropped in second-instance handoff before runtime init. Added/updated CLI command tests; targeted suite passes.
|
||||
<!-- SECTION:FINAL_SUMMARY:END -->
|
||||
Reference in New Issue
Block a user