mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-27 18:22:41 -08:00
refactor(config): slim resolver facade and expand regression lanes
Collapse src/config/resolve.ts into an orchestrated pipeline over domain modules, wire launcher regression coverage into test scripts, and sync backlog/subagent tracking artifacts for completed TASK-74/TASK-96/TASK-98 follow-up planning.
This commit is contained in:
@@ -0,0 +1,50 @@
|
|||||||
|
---
|
||||||
|
id: TASK-100
|
||||||
|
title: Run post-refactor dead code prune and cleanup
|
||||||
|
status: To Do
|
||||||
|
assignee: []
|
||||||
|
created_date: '2026-02-21 07:15'
|
||||||
|
updated_date: '2026-02-21 07:15'
|
||||||
|
labels:
|
||||||
|
- cleanup
|
||||||
|
- maintainability
|
||||||
|
- refactor
|
||||||
|
dependencies:
|
||||||
|
- TASK-96
|
||||||
|
- TASK-97
|
||||||
|
priority: medium
|
||||||
|
---
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||||
|
Major refactors likely left unused exports/helpers and stale compatibility code. Perform a deliberate dead-code sweep with regression safety.
|
||||||
|
<!-- SECTION:DESCRIPTION:END -->
|
||||||
|
|
||||||
|
## Action Steps
|
||||||
|
|
||||||
|
<!-- SECTION:PLAN:BEGIN -->
|
||||||
|
1. Run unused-export scans (`ts-prune` or equivalent) and collect candidate list.
|
||||||
|
2. Manually verify each candidate to avoid false positives from dynamic loading/IPC wiring.
|
||||||
|
3. Remove or inline confirmed dead code; simplify import surfaces/barrels accordingly.
|
||||||
|
4. Delete stale helper paths retained only for pre-composer wiring.
|
||||||
|
5. Add or update regression tests where removal could alter behavior.
|
||||||
|
6. Run verification gate: `bun run build`, `bun run test:config:dist`, `bun run test:core:dist`.
|
||||||
|
7. Publish cleanup report: removed files/exports, kept exceptions, and rationale.
|
||||||
|
<!-- SECTION:PLAN:END -->
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
<!-- AC:BEGIN -->
|
||||||
|
- [ ] #1 Confirmed dead code removed without behavior regressions.
|
||||||
|
- [ ] #2 Remaining flagged candidates either resolved or documented with justification.
|
||||||
|
- [ ] #3 Build and core/config suites pass after cleanup.
|
||||||
|
- [ ] #4 Import graph complexity reduced (fewer exports/entrypoints where applicable).
|
||||||
|
<!-- AC:END -->
|
||||||
|
|
||||||
|
## Definition of Done
|
||||||
|
<!-- DOD:BEGIN -->
|
||||||
|
- [ ] #1 Dead-code report attached in task notes.
|
||||||
|
- [ ] #2 Regression test updates included for risky removals.
|
||||||
|
- [ ] #3 Verification gate commands complete successfully.
|
||||||
|
<!-- DOD:END -->
|
||||||
|
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
---
|
||||||
|
id: TASK-101
|
||||||
|
title: Consolidate architecture docs and archive task noise
|
||||||
|
status: To Do
|
||||||
|
assignee: []
|
||||||
|
created_date: '2026-02-21 07:15'
|
||||||
|
updated_date: '2026-02-21 07:15'
|
||||||
|
labels:
|
||||||
|
- documentation
|
||||||
|
- maintainability
|
||||||
|
dependencies:
|
||||||
|
- TASK-96
|
||||||
|
- TASK-97
|
||||||
|
- TASK-98
|
||||||
|
- TASK-99
|
||||||
|
- TASK-100
|
||||||
|
priority: low
|
||||||
|
---
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||||
|
Architecture guidance is fragmented across long-lived docs and task notes. Consolidate canonical runtime architecture docs and move stale/noisy task-level detail to archive.
|
||||||
|
<!-- SECTION:DESCRIPTION:END -->
|
||||||
|
|
||||||
|
## Action Steps
|
||||||
|
|
||||||
|
<!-- SECTION:PLAN:BEGIN -->
|
||||||
|
1. Audit architecture and development docs for duplicated runtime composition guidance.
|
||||||
|
2. Select one canonical architecture section for runtime composition and dependency boundaries.
|
||||||
|
3. Refactor duplicate sections to brief pointers to the canonical section.
|
||||||
|
4. Move stale task-evidence prose from persistent docs to backlog/archive where appropriate.
|
||||||
|
5. Add a compact architecture diagram and update links in contributor docs.
|
||||||
|
6. Validate docs build and link integrity.
|
||||||
|
7. Record what moved and why in task notes for traceability.
|
||||||
|
<!-- SECTION:PLAN:END -->
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
<!-- AC:BEGIN -->
|
||||||
|
- [ ] #1 Runtime composition guidance exists in one canonical location.
|
||||||
|
- [ ] #2 Duplicated/stale architecture notes removed from long-lived docs.
|
||||||
|
- [ ] #3 Task evidence retained in backlog/archive, not lost.
|
||||||
|
- [ ] #4 Docs build and links pass after consolidation.
|
||||||
|
<!-- AC:END -->
|
||||||
|
|
||||||
|
## Definition of Done
|
||||||
|
<!-- DOD:BEGIN -->
|
||||||
|
- [ ] #1 Change log of moved/removed doc sections included in task notes.
|
||||||
|
- [ ] #2 `bun run docs:build` passes.
|
||||||
|
- [ ] #3 Contributor-facing entry points link to canonical architecture section.
|
||||||
|
<!-- DOD:END -->
|
||||||
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
id: TASK-74
|
id: TASK-74
|
||||||
title: Add launcher regression tests for config discovery and command branching
|
title: Add launcher regression tests for config discovery and command branching
|
||||||
status: To Do
|
status: Done
|
||||||
assignee: []
|
assignee: []
|
||||||
created_date: '2026-02-18 11:35'
|
created_date: '2026-02-18 11:35'
|
||||||
updated_date: '2026-02-18 11:35'
|
updated_date: '2026-02-21 20:21'
|
||||||
labels:
|
labels:
|
||||||
- launcher
|
- launcher
|
||||||
- tests
|
- tests
|
||||||
@@ -35,14 +35,13 @@ Launcher currently has no direct test coverage for config discovery behavior and
|
|||||||
|
|
||||||
## Acceptance Criteria
|
## Acceptance Criteria
|
||||||
<!-- AC:BEGIN -->
|
<!-- AC:BEGIN -->
|
||||||
- [ ] #1 Launcher config discovery paths are regression-tested
|
- [x] #1 Launcher config discovery paths are regression-tested
|
||||||
- [ ] #2 Core launcher command branches are regression-tested
|
- [x] #2 Core launcher command branches are regression-tested
|
||||||
- [ ] #3 Tests run in CI/local test gate without external process dependencies
|
- [x] #3 Tests run in CI/local test gate without external process dependencies
|
||||||
<!-- AC:END -->
|
<!-- AC:END -->
|
||||||
|
|
||||||
## Definition of Done
|
## Definition of Done
|
||||||
<!-- DOD:BEGIN -->
|
<!-- DOD:BEGIN -->
|
||||||
- [ ] #1 Launcher tests included in standard test workflow
|
- [x] #1 Launcher tests included in standard test workflow
|
||||||
- [ ] #2 Documented how to run launcher tests locally
|
- [x] #2 Documented how to run launcher tests locally
|
||||||
<!-- DOD:END -->
|
<!-- DOD:END -->
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
---
|
||||||
|
id: TASK-96
|
||||||
|
title: Split config resolve into domain modules
|
||||||
|
status: Done
|
||||||
|
assignee:
|
||||||
|
- '@codex-task96-config-resolve'
|
||||||
|
created_date: '2026-02-21 07:15'
|
||||||
|
updated_date: '2026-02-21 20:10'
|
||||||
|
labels:
|
||||||
|
- architecture
|
||||||
|
- refactor
|
||||||
|
- maintainability
|
||||||
|
dependencies:
|
||||||
|
- TASK-85
|
||||||
|
priority: high
|
||||||
|
---
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||||
|
`src/config/resolve.ts` remains oversized and mixes unrelated concerns. Split into domain-focused modules while preserving behavior and public API.
|
||||||
|
<!-- SECTION:DESCRIPTION:END -->
|
||||||
|
|
||||||
|
## Action Steps
|
||||||
|
|
||||||
|
<!-- SECTION:PLAN:BEGIN -->
|
||||||
|
1. Capture baseline: LOC, exported symbols, and current test coverage touching config resolution.
|
||||||
|
2. Create domain modules under `src/config/resolve/`:
|
||||||
|
- `env-paths.ts`
|
||||||
|
- `subtitle-style.ts`
|
||||||
|
- `integrations.ts`
|
||||||
|
- `validation-errors.ts`
|
||||||
|
3. Keep `src/config/resolve.ts` as thin orchestrator/barrel that composes domain resolvers.
|
||||||
|
4. Add seam tests per new module; keep existing config suite green.
|
||||||
|
5. Verify no call-site changes required outside config service layer.
|
||||||
|
6. Run verification gate: `bun run build`, `bun run test:config:dist`, `bun run check:file-budgets`.
|
||||||
|
7. Record before/after LOC and ownership map in task notes.
|
||||||
|
<!-- SECTION:PLAN:END -->
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
<!-- AC:BEGIN -->
|
||||||
|
- [x] #1 `src/config/resolve.ts` reduced to orchestration/barrel role.
|
||||||
|
- [x] #2 New domain modules exist with clear single-responsibility boundaries.
|
||||||
|
- [x] #3 Existing config behavior preserved with passing tests.
|
||||||
|
- [x] #4 New seam tests cover domain-specific resolution logic.
|
||||||
|
- [x] #5 File-budget report shows measurable reduction in hotspot file size.
|
||||||
|
<!-- AC:END -->
|
||||||
|
|
||||||
|
## Implementation Plan
|
||||||
|
|
||||||
|
<!-- SECTION:PLAN:BEGIN -->
|
||||||
|
Execution plan (2026-02-21 codex refresh):
|
||||||
|
1. Capture baseline metrics (`wc -l src/config/resolve.ts`, `bun run check:file-budgets`) and keep evidence in notes.
|
||||||
|
2. Ensure seam test coverage exists for extracted domain modules (`src/config/resolve/anki-connect.test.ts`, `src/config/resolve/subtitle-style.test.ts`, `src/config/resolve/jellyfin.test.ts`) and wire config test scripts so these tests run in src + dist lanes.
|
||||||
|
3. Reduce `src/config/resolve.ts` to orchestration facade by composing extracted modules in stable order:
|
||||||
|
- `createResolveContext`
|
||||||
|
- `applyTopLevelConfig`
|
||||||
|
- `applyCoreDomainConfig`
|
||||||
|
- `applySubtitleDomainConfig`
|
||||||
|
- `applyIntegrationConfig`
|
||||||
|
- `applyImmersionTrackingConfig`
|
||||||
|
- `applyAnkiConnectResolution`
|
||||||
|
4. Verify no behavior drift with required gates: `bun run build`, `bun run test:config:dist`, `bun run check:file-budgets`.
|
||||||
|
5. Record before/after LOC + budget results and finalize acceptance criteria / DoD in task metadata (no commit).
|
||||||
|
<!-- SECTION:PLAN:END -->
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
|
||||||
|
<!-- SECTION:NOTES:BEGIN -->
|
||||||
|
[baseline] `wc -l src/config/resolve.ts` => 1414 LOC.
|
||||||
|
|
||||||
|
[baseline] `bun run check:file-budgets` reports `src/config/resolve.ts: 1415 LOC` and 17 files over 500 LOC.
|
||||||
|
|
||||||
|
[implementation] Reduced `src/config/resolve.ts` to orchestration facade that now composes extracted domain modules in stable order: top-level -> core -> subtitle -> integrations -> immersion-tracking -> anki-connect.
|
||||||
|
|
||||||
|
[implementation] Wired config seam tests into official config lanes by updating `package.json` scripts `test:config:src` and `test:config:dist` to include `src/config/resolve/{anki-connect,subtitle-style,jellyfin}.test.ts` (and compiled dist equivalents).
|
||||||
|
|
||||||
|
[verification] `bun run build && bun run test:config:dist && bun run check:file-budgets` passed. Config dist lane now runs 48 tests including seam tests; all passing.
|
||||||
|
|
||||||
|
[metrics] LOC before/after: `wc -l src/config/resolve.ts` baseline 1414 -> final 33.
|
||||||
|
|
||||||
|
[metrics] Budget before/after: baseline report showed 18 files over 500 LOC including `src/config/resolve.ts: 1415 LOC`; final report shows 17 files over 500 LOC and `src/config/resolve.ts` no longer over budget.
|
||||||
|
<!-- SECTION:NOTES:END -->
|
||||||
|
|
||||||
|
## Final Summary
|
||||||
|
|
||||||
|
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
|
||||||
|
Refactored config resolution into domain-focused modules and reduced `src/config/resolve.ts` to a thin orchestration facade while preserving behavior. Added/wired resolver seam tests into src+dist config test lanes and verified with required gates (`build`, `test:config:dist`, `check:file-budgets`) plus before/after LOC and budget evidence.
|
||||||
|
<!-- SECTION:FINAL_SUMMARY:END -->
|
||||||
|
|
||||||
|
## Definition of Done
|
||||||
|
<!-- DOD:BEGIN -->
|
||||||
|
- [x] #1 Baseline and final LOC metrics recorded in Implementation Notes.
|
||||||
|
- [x] #2 `bun run build` and `bun run test:config:dist` pass.
|
||||||
|
- [x] #3 `bun run check:file-budgets` completed and attached in notes.
|
||||||
|
<!-- DOD:END -->
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
---
|
||||||
|
id: TASK-98
|
||||||
|
title: Shift core tests to source level and trim dist coupling
|
||||||
|
status: In Progress
|
||||||
|
assignee:
|
||||||
|
- opencode
|
||||||
|
created_date: '2026-02-21 07:15'
|
||||||
|
updated_date: '2026-02-21 09:56'
|
||||||
|
labels:
|
||||||
|
- testing
|
||||||
|
- maintainability
|
||||||
|
- developer-experience
|
||||||
|
dependencies:
|
||||||
|
- TASK-95
|
||||||
|
priority: medium
|
||||||
|
---
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||||
|
Core test flow is heavily coupled to `dist/` artifacts, increasing cycle time and reducing test clarity. Move the majority of tests to source-level execution while retaining minimal dist smoke coverage.
|
||||||
|
<!-- SECTION:DESCRIPTION:END -->
|
||||||
|
|
||||||
|
## Action Steps
|
||||||
|
|
||||||
|
<!-- SECTION:PLAN:BEGIN -->
|
||||||
|
1. Catalog current test commands and classify tests: source-level candidates vs required dist smoke tests.
|
||||||
|
2. Introduce/standardize source-level test runners for core suites.
|
||||||
|
3. Migrate high-volume `dist/core/services/*` tests to source-level equivalents.
|
||||||
|
4. Keep a small dist smoke suite for packaging/runtime sanity only.
|
||||||
|
5. Update `package.json` scripts and CI workflow steps to use new split.
|
||||||
|
6. Capture timing comparison (before/after) for local and CI runs.
|
||||||
|
7. Run verification gate for both lanes: source-level tests + dist smoke tests.
|
||||||
|
<!-- SECTION:PLAN:END -->
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
<!-- AC:BEGIN -->
|
||||||
|
- [x] #1 Majority of core regression tests run from source-level entrypoints.
|
||||||
|
- [x] #2 Dist suite reduced to explicit smoke scope with documented purpose.
|
||||||
|
- [x] #3 CI still validates packaged/runtime assumptions via smoke lane.
|
||||||
|
- [x] #4 Total default test cycle time improves measurably.
|
||||||
|
<!-- AC:END -->
|
||||||
|
|
||||||
|
## Implementation Plan
|
||||||
|
|
||||||
|
<!-- SECTION:PLAN:BEGIN -->
|
||||||
|
1) Baseline current dist-coupled matrix and capture `time bun run test:fast` before timing.
|
||||||
|
2) Update `package.json` scripts so default regression lanes (`test:config`, `test:core`, `test:fast`) run source-level tests (`bun test src/...`) instead of `dist` artifacts.
|
||||||
|
3) Introduce explicit `test:smoke:dist` command for minimal compiled/runtime smoke checks; keep launcher smoke behavior intact.
|
||||||
|
4) Update `.github/workflows/ci.yml` and `.github/workflows/release.yml` to run source lane as primary + dist smoke lane as secondary.
|
||||||
|
5) Document command matrix in `docs/development.md`, rerun timing commands, capture before/after delta in task notes, then finalize AC/DoD.
|
||||||
|
|
||||||
|
Detailed execution plan: `docs/plans/2026-02-21-task-98-source-tests-dist-smoke-split.md`
|
||||||
|
<!-- SECTION:PLAN:END -->
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
|
||||||
|
<!-- SECTION:NOTES:BEGIN -->
|
||||||
|
Execution updates (2026-02-21):
|
||||||
|
- Default regression lane moved to source entrypoints in `package.json`:
|
||||||
|
- `test:config` -> `test:config:src` (`bun test src/config/config.test.ts src/config/path-resolution.test.ts`)
|
||||||
|
- `test:core` -> `test:core:src` (`bun test` over curated core list)
|
||||||
|
- `test:fast` -> source config + source core
|
||||||
|
- Dist coupling trimmed to explicit smoke lane:
|
||||||
|
- `test:smoke:dist` -> `test:config:smoke:dist` + `test:core:smoke:dist`
|
||||||
|
- Smoke scope validates compiled/runtime assumptions across config, IPC/electron interop (`overlay-manager`, `anilist-token-store`), startup, renderer, main URL guard, and x11 tracker.
|
||||||
|
- CI/release wiring updated:
|
||||||
|
- `.github/workflows/ci.yml`: `test:fast` (source) before build; `test:smoke:dist` after build.
|
||||||
|
- `.github/workflows/release.yml` quality-gate: source tests, build, dist smoke.
|
||||||
|
- Docs updated in `docs/development.md` with source-vs-dist command matrix and smoke rationale.
|
||||||
|
- Timing evidence (repro commands):
|
||||||
|
- Before: `time bun run test:fast` (dist-coupled) => `1.438 total`
|
||||||
|
- After: `time bun run test:fast` (source lane) => `1.017 total`
|
||||||
|
- Delta: ~`0.421s` faster (~29.3% reduction).
|
||||||
|
- Dist smoke timing: `time bun run test:smoke:dist` => `0.206 total`.
|
||||||
|
- Verification:
|
||||||
|
- PASS: `bun run test:config:src && bun run test:core:src`
|
||||||
|
- PASS: `bun run test:smoke:dist`
|
||||||
|
- BLOCKED (pre-existing unrelated workspace errors): `bun run build` currently fails in `src/main.ts` and `src/main/runtime/composers/mpv-runtime-composer.test.ts` from in-flight TASK-96/97 changes present in working tree; not introduced by TASK-98 edits.
|
||||||
|
<!-- SECTION:NOTES:END -->
|
||||||
|
|
||||||
|
## Definition of Done
|
||||||
|
<!-- DOD:BEGIN -->
|
||||||
|
- [x] #1 Test command matrix documented in task notes.
|
||||||
|
- [ ] #2 CI config updated and passing with new source/dist split.
|
||||||
|
- [x] #3 Performance delta captured with reproducible timing commands.
|
||||||
|
<!-- DOD:END -->
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
---
|
||||||
|
id: TASK-99
|
||||||
|
title: Expand maintainability guardrails and runtime cycle checks
|
||||||
|
status: To Do
|
||||||
|
assignee: []
|
||||||
|
created_date: '2026-02-21 07:15'
|
||||||
|
updated_date: '2026-02-21 07:15'
|
||||||
|
labels:
|
||||||
|
- quality
|
||||||
|
- architecture
|
||||||
|
- ci
|
||||||
|
dependencies:
|
||||||
|
- TASK-96
|
||||||
|
- TASK-97
|
||||||
|
priority: medium
|
||||||
|
---
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||||
|
Current guardrails cover `main.ts` fan-in and broad file budgets. Add targeted checks for newly extracted hotspots and runtime import-cycle detection.
|
||||||
|
<!-- SECTION:DESCRIPTION:END -->
|
||||||
|
|
||||||
|
## Action Steps
|
||||||
|
|
||||||
|
<!-- SECTION:PLAN:BEGIN -->
|
||||||
|
1. Rebaseline file-size budgets for known hotspots (including post-TASK-96 files).
|
||||||
|
2. Extend `check:file-budgets` config to enforce thresholds on new modules and key test files.
|
||||||
|
3. Add runtime dependency cycle detection for `src/main/runtime/**` (script + CI hook).
|
||||||
|
4. Wire new checks into local gate commands and CI workflow.
|
||||||
|
5. Add failure guidance output so contributors can remediate quickly.
|
||||||
|
6. Run gates on current branch and capture pass/fail evidence in task notes.
|
||||||
|
<!-- SECTION:PLAN:END -->
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
<!-- AC:BEGIN -->
|
||||||
|
- [ ] #1 Budget thresholds include new hotspot modules and prevent silent growth.
|
||||||
|
- [ ] #2 Runtime cycle check detects at least one injected fixture cycle in tests.
|
||||||
|
- [ ] #3 CI runs both checks and fails fast on violations.
|
||||||
|
- [ ] #4 Contributor guidance exists for fixing guardrail failures.
|
||||||
|
<!-- AC:END -->
|
||||||
|
|
||||||
|
## Definition of Done
|
||||||
|
<!-- DOD:BEGIN -->
|
||||||
|
- [ ] #1 Guardrail scripts and CI wiring merged with passing checks.
|
||||||
|
- [ ] #2 Documentation updated with local commands and expected outputs.
|
||||||
|
- [ ] #3 Baseline numbers recorded to justify thresholds.
|
||||||
|
<!-- DOD:END -->
|
||||||
|
|
||||||
@@ -95,3 +95,11 @@ Use `subminer <subcommand> -h` for command-specific help.
|
|||||||
- Default log level is `info`
|
- Default log level is `info`
|
||||||
- `--background` mode defaults to `warn` unless `--log-level` is explicitly set
|
- `--background` mode defaults to `warn` unless `--log-level` is explicitly set
|
||||||
- `--dev` / `--debug` control app behavior, not logging verbosity — use `--log-level` for that
|
- `--dev` / `--debug` control app behavior, not logging verbosity — use `--log-level` for that
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
Run launcher regression tests (config discovery + command branching):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun run test:launcher
|
||||||
|
```
|
||||||
|
|||||||
@@ -43,3 +43,4 @@ Read first. Keep concise.
|
|||||||
| `codex-task74-launcher-tests-20260221T201635Z-10i6` | `codex-task74-launcher-tests` | `Implement TASK-74 launcher regression tests for config discovery + command branching end-to-end` | `done` | `docs/subagents/agents/codex-task74-launcher-tests-20260221T201635Z-10i6.md` | `2026-02-21T20:20:52Z` |
|
| `codex-task74-launcher-tests-20260221T201635Z-10i6` | `codex-task74-launcher-tests` | `Implement TASK-74 launcher regression tests for config discovery + command branching end-to-end` | `done` | `docs/subagents/agents/codex-task74-launcher-tests-20260221T201635Z-10i6.md` | `2026-02-21T20:20:52Z` |
|
||||||
| `opencode-task76-anki-workflows-20260221T201659Z-r4p1` | `opencode-task76-anki-workflows` | `Execute TASK-76 decompose anki-integration orchestrator into workflow services via plan-first workflow` | `done` | `docs/subagents/agents/opencode-task76-anki-workflows-20260221T201659Z-r4p1.md` | `2026-02-21T21:17:28Z` |
|
| `opencode-task76-anki-workflows-20260221T201659Z-r4p1` | `opencode-task76-anki-workflows` | `Execute TASK-76 decompose anki-integration orchestrator into workflow services via plan-first workflow` | `done` | `docs/subagents/agents/opencode-task76-anki-workflows-20260221T201659Z-r4p1.md` | `2026-02-21T21:17:28Z` |
|
||||||
| `opencode-task76-doc-boundaries-20260221T203558Z-h7q4` | `opencode-task76-doc-boundaries` | `Update Anki integration docs with post-decomposition ownership boundaries for TASK-76` | `done` | `docs/subagents/agents/opencode-task76-doc-boundaries-20260221T203558Z-h7q4.md` | `2026-02-21T20:36:55Z` |
|
| `opencode-task76-doc-boundaries-20260221T203558Z-h7q4` | `opencode-task76-doc-boundaries` | `Update Anki integration docs with post-decomposition ownership boundaries for TASK-76` | `done` | `docs/subagents/agents/opencode-task76-doc-boundaries-20260221T203558Z-h7q4.md` | `2026-02-21T20:36:55Z` |
|
||||||
|
| `codex-docs-unpushed-review-20260221T213707Z-lyej` | `codex-docs-unpushed-review` | `Review unpushed commits for docs drift; patch docs to reflect current code/state` | `in_progress` | `docs/subagents/agents/codex-docs-unpushed-review-20260221T213707Z-lyej.md` | `2026-02-21T21:37:07Z` |
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# Agent Session: codex-docs-unpushed-review-20260221T213707Z-lyej
|
||||||
|
|
||||||
|
- alias: `codex-docs-unpushed-review`
|
||||||
|
- mission: `Review unpushed commits for docs drift; patch docs to reflect current code/state`
|
||||||
|
- status: `in_progress`
|
||||||
|
- started_utc: `2026-02-21T21:37:07Z`
|
||||||
|
- heartbeat_minutes: `5`
|
||||||
|
|
||||||
|
## Intent
|
||||||
|
|
||||||
|
- audit `origin/main..HEAD` commit set
|
||||||
|
- compare code/runtime/test-script changes against user-facing docs
|
||||||
|
- patch stale docs only; avoid unrelated code churn
|
||||||
|
|
||||||
|
## Planned Files
|
||||||
|
|
||||||
|
- `docs/development.md` (verify test lane + build guidance)
|
||||||
|
- `docs/architecture.md` (verify runtime composer/domain registry narrative)
|
||||||
|
- `docs/configuration.md` (verify config discovery semantics if needed)
|
||||||
|
- `docs/launcher-script.md` (verify launcher test coverage + mpv socket behavior)
|
||||||
|
- `docs/subagents/INDEX.md` (own row heartbeat/status only)
|
||||||
|
- `docs/subagents/collaboration.md` (cross-agent notes/conflicts)
|
||||||
|
|
||||||
|
## Assumptions
|
||||||
|
|
||||||
|
- scope = unpushed commits (`origin/main..HEAD`) + doc drift for current working state
|
||||||
|
- Backlog MCP not initialized (`backlog://init-required`); no enforceable ticket link in this run
|
||||||
|
- existing dirty workspace includes other agents/user edits; do not revert or normalize unrelated files
|
||||||
|
|
||||||
|
## Log
|
||||||
|
|
||||||
|
- `2026-02-21T21:37:07Z` start; loaded subagent index/collaboration/backlog state; collecting unpushed commit/doc impact matrix.
|
||||||
@@ -8,6 +8,8 @@
|
|||||||
- heartbeat_minutes: `5`
|
- heartbeat_minutes: `5`
|
||||||
|
|
||||||
## Current Work (newest first)
|
## Current Work (newest first)
|
||||||
|
- [2026-02-21T07:16:33Z] handoff: added cleanup backlog set TASK-96..TASK-101 with implementation steps, AC, DoD, and dependency chain.
|
||||||
|
- [2026-02-21T07:15:00Z] intent: user requested backlog build-out; creating follow-on cleanup tasks with implementation steps and completion goals.
|
||||||
- [2026-02-21T06:25:27Z] handoff: review complete; no blocking/important defects found in refactor + launcher-workflow enforcement diff; targeted guardrails/tests passed.
|
- [2026-02-21T06:25:27Z] handoff: review complete; no blocking/important defects found in refactor + launcher-workflow enforcement diff; targeted guardrails/tests passed.
|
||||||
- [2026-02-21T06:25:27Z] test: `bun run check:main-fanin` and `bun run test:core:dist` passed on current tree.
|
- [2026-02-21T06:25:27Z] test: `bun run check:main-fanin` and `bun run test:core:dist` passed on current tree.
|
||||||
- [2026-02-21T06:24:30Z] progress: audited diffs in `.github/workflows/{ci,release}.yml`, `scripts/verify-generated-launcher.sh`, docs/task updates; validated launcher verifier behavior.
|
- [2026-02-21T06:24:30Z] progress: audited diffs in `.github/workflows/{ci,release}.yml`, `scripts/verify-generated-launcher.sh`, docs/task updates; validated launcher verifier behavior.
|
||||||
@@ -22,6 +24,18 @@
|
|||||||
- `docs/development.md` (reviewed)
|
- `docs/development.md` (reviewed)
|
||||||
- `docs/installation.md` (reviewed)
|
- `docs/installation.md` (reviewed)
|
||||||
- `backlog/tasks/task-85 - Refactor-large-files-for-maintainability-and-readability.md` (reviewed)
|
- `backlog/tasks/task-85 - Refactor-large-files-for-maintainability-and-readability.md` (reviewed)
|
||||||
|
- `backlog/tasks/task-96 - Split-config-resolve-into-domain-modules.md` (planned)
|
||||||
|
- `backlog/tasks/task-97 - Normalize-runtime-composer-contracts.md` (planned)
|
||||||
|
- `backlog/tasks/task-98 - Shift-core-tests-to-source-level-and-trim-dist-coupling.md` (planned)
|
||||||
|
- `backlog/tasks/task-99 - Expand-maintainability-guardrails-and-runtime-cycle-checks.md` (planned)
|
||||||
|
- `backlog/tasks/task-100 - Run-post-refactor-dead-code-prune-and-cleanup.md` (planned)
|
||||||
|
- `backlog/tasks/task-101 - Consolidate-architecture-docs-and-archive-task-noise.md` (planned)
|
||||||
|
- `backlog/tasks/task-96 - Split-config-resolve-into-domain-modules.md` (added)
|
||||||
|
- `backlog/tasks/task-97 - Normalize-runtime-composer-contracts.md` (added)
|
||||||
|
- `backlog/tasks/task-98 - Shift-core-tests-to-source-level-and-trim-dist-coupling.md` (added)
|
||||||
|
- `backlog/tasks/task-99 - Expand-maintainability-guardrails-and-runtime-cycle-checks.md` (added)
|
||||||
|
- `backlog/tasks/task-100 - Run-post-refactor-dead-code-prune-and-cleanup.md` (added)
|
||||||
|
- `backlog/tasks/task-101 - Consolidate-architecture-docs-and-archive-task-noise.md` (added)
|
||||||
|
|
||||||
## Assumptions
|
## Assumptions
|
||||||
- User asks for review only; no code changes requested.
|
- User asks for review only; no code changes requested.
|
||||||
@@ -31,4 +45,4 @@
|
|||||||
- None.
|
- None.
|
||||||
|
|
||||||
## Next Step
|
## Next Step
|
||||||
- Await user direction (fixes optional; no required corrections identified).
|
- Await prioritization/execution order from user.
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# Agent Log: codex-task74-launcher-tests-20260221T201635Z-10i6
|
||||||
|
|
||||||
|
- alias: `codex-task74-launcher-tests`
|
||||||
|
- mission: `Implement TASK-74 launcher regression tests for config discovery + command branching end-to-end`
|
||||||
|
- status: `done`
|
||||||
|
- last_update_utc: `2026-02-21T20:20:52Z`
|
||||||
|
|
||||||
|
## Intent
|
||||||
|
|
||||||
|
- add launcher regression coverage for config discovery matrix + command branching paths
|
||||||
|
- keep tests deterministic via fs/process/spawn mocks; no external process deps
|
||||||
|
- wire tests into existing launcher/core test workflow
|
||||||
|
|
||||||
|
## Planned Files
|
||||||
|
|
||||||
|
- `launcher/main.ts`
|
||||||
|
- `launcher/main.test.ts` (new)
|
||||||
|
- `launcher/config.test.ts` (extend if needed)
|
||||||
|
- `package.json` (only if test command wiring needed)
|
||||||
|
- `backlog/tasks/task-74 - Add-launcher-regression-tests-for-config-discovery-and-command-branching.md` (status/checklists evidence)
|
||||||
|
|
||||||
|
## Assumptions
|
||||||
|
|
||||||
|
- existing test runner: `bun test`
|
||||||
|
- task expects launcher tests in repo test gates (likely `test:launcher`)
|
||||||
|
- no behavior change needed unless tests expose branch gaps
|
||||||
|
|
||||||
|
## Progress
|
||||||
|
|
||||||
|
- `2026-02-21T20:16:35Z` started; protocol + task context loaded
|
||||||
|
- `2026-02-21T20:19:30Z` added `launcher/main.test.ts` regression suite (config discovery + command branching via child-process harness + fake app binary capture)
|
||||||
|
- `2026-02-21T20:20:02Z` wired launcher tests into scripts (`test:launcher:src`, `test:launcher`) and included launcher tests in `test:core:src`
|
||||||
|
- `2026-02-21T20:20:20Z` documented launcher test command in `docs/launcher-script.md`
|
||||||
|
- `2026-02-21T20:20:52Z` verification complete:
|
||||||
|
- `bun run test:launcher`
|
||||||
|
- `bun run test:core:src`
|
||||||
|
- both green
|
||||||
|
|
||||||
|
## Files Touched
|
||||||
|
|
||||||
|
- `launcher/main.test.ts` (new)
|
||||||
|
- `package.json`
|
||||||
|
- `docs/launcher-script.md`
|
||||||
|
- `backlog/tasks/task-74 - Add-launcher-regression-tests-for-config-discovery-and-command-branching.md`
|
||||||
|
- `docs/subagents/INDEX.md`
|
||||||
|
- `docs/subagents/agents/codex-task74-launcher-tests-20260221T201635Z-10i6.md`
|
||||||
|
|
||||||
|
## Handoff
|
||||||
|
|
||||||
|
- task status moved to `Done` in backlog markdown with AC/DoD checked
|
||||||
|
- no blockers
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
# Agent: `codex-task96-config-resolve-20260221T110058Z-k7m2`
|
||||||
|
|
||||||
|
- alias: `codex-task96-config-resolve`
|
||||||
|
- mission: `Execute TASK-96 by splitting src/config/resolve.ts into domain modules without behavior drift`
|
||||||
|
- status: `done`
|
||||||
|
- branch: `main`
|
||||||
|
- started_at: `2026-02-21T11:00:58Z`
|
||||||
|
- heartbeat_minutes: `5`
|
||||||
|
|
||||||
|
## Current Work (newest first)
|
||||||
|
|
||||||
|
- [2026-02-21T20:10:43Z] complete: reduced `src/config/resolve.ts` to 33 LOC orchestration facade over extracted domain modules; updated config test scripts to include resolve seam tests in src+dist lanes; ran required gates (`build`, `test:config:dist`, `check:file-budgets`) all green.
|
||||||
|
- [2026-02-21T20:10:43Z] backlog: finalized `TASK-96` as Done with AC/DoD checked and metrics evidence (LOC 1414 -> 33; budget over-limit files 18 -> 17).
|
||||||
|
- [2026-02-21T11:00:58Z] intent: load TASK-96 from Backlog MCP, draft execution plan with writing-plans skill, execute with executing-plans skill, no commit.
|
||||||
|
- [2026-02-21T11:00:58Z] context: read subagent index/collaboration + prior opencode TASK-96 planning handoff.
|
||||||
|
|
||||||
|
## Files Touched
|
||||||
|
|
||||||
|
- `docs/subagents/INDEX.md`
|
||||||
|
- `docs/subagents/collaboration.md`
|
||||||
|
- `docs/subagents/agents/codex-task96-config-resolve-20260221T110058Z-k7m2.md`
|
||||||
|
- `src/config/resolve.ts`
|
||||||
|
- `package.json`
|
||||||
|
|
||||||
|
## Assumptions
|
||||||
|
|
||||||
|
- User request grants consent to execute TASK-96 on current branch and run required verification gates.
|
||||||
|
|
||||||
|
## Open Questions / Blockers
|
||||||
|
|
||||||
|
- None.
|
||||||
|
|
||||||
|
## Next Step
|
||||||
|
|
||||||
|
- Handoff complete; await user review or next task.
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
# Agent: `opencode-task76-anki-workflows-20260221T201659Z-r4p1`
|
||||||
|
|
||||||
|
- alias: `opencode-task76-anki-workflows`
|
||||||
|
- mission: `Execute TASK-76 decompose anki-integration orchestrator into workflow services end-to-end without commit`
|
||||||
|
- status: `done`
|
||||||
|
- branch: `main`
|
||||||
|
- started_at: `2026-02-21T20:16:59Z`
|
||||||
|
- heartbeat_minutes: `5`
|
||||||
|
|
||||||
|
## Current Work (newest first)
|
||||||
|
|
||||||
|
- [2026-02-21T21:17:28Z] test: reran `bun run build && node --test dist/anki-integration.test.js dist/anki-integration/note-update-workflow.test.js dist/anki-integration/field-grouping-workflow.test.js` and `bun run build && bun run test:core:dist`; all pass.
|
||||||
|
- [2026-02-21T21:16:18Z] handoff: TASK-76 complete; extracted note-update and field-grouping workflow services, added workflow seam tests, updated Anki ownership docs, verified build + anki suites + core dist gate, and marked backlog task Done.
|
||||||
|
- [2026-02-21T20:40:00Z] progress: implemented `NoteUpdateWorkflow` and `FieldGroupingWorkflow` extraction; rewired `AnkiIntegration` to delegate `processNewCard` and grouping handlers.
|
||||||
|
- [2026-02-21T20:30:00Z] progress: created TASK-76 execution plan and moved backlog task to In Progress with baseline metrics.
|
||||||
|
- [2026-02-21T20:16:59Z] intent: load Backlog TASK-76 context, draft plan via writing-plans skill, execute via executing-plans with parallel subagents when safe.
|
||||||
|
|
||||||
|
## Files Touched
|
||||||
|
|
||||||
|
- `docs/subagents/INDEX.md`
|
||||||
|
- `docs/subagents/agents/opencode-task76-anki-workflows-20260221T201659Z-r4p1.md`
|
||||||
|
- `docs/subagents/collaboration.md`
|
||||||
|
- `docs/plans/2026-02-21-task-76-anki-workflow-services-plan.md`
|
||||||
|
- `src/anki-integration.ts`
|
||||||
|
- `src/anki-integration/note-update-workflow.ts`
|
||||||
|
- `src/anki-integration/note-update-workflow.test.ts`
|
||||||
|
- `src/anki-integration/field-grouping-workflow.ts`
|
||||||
|
- `src/anki-integration/field-grouping-workflow.test.ts`
|
||||||
|
- `docs/anki-integration.md`
|
||||||
|
- `backlog/tasks/task-76 - Decompose-anki-integration-orchestrator-into-workflow-services.md` (via MCP edits)
|
||||||
|
|
||||||
|
## Assumptions
|
||||||
|
|
||||||
|
- Backlog MCP is initialized and TASK-76 exists.
|
||||||
|
- Existing in-flight changes in repo are unrelated unless overlap found in `src/anki-integration.ts` and `src/anki-integration/*`.
|
||||||
|
|
||||||
|
## Open Questions / Blockers
|
||||||
|
|
||||||
|
- None.
|
||||||
|
|
||||||
|
## Next Step
|
||||||
|
|
||||||
|
- Await user review or follow-up requests (no commit performed).
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# Agent: `opencode-task76-doc-boundaries-20260221T203558Z-h7q4`
|
||||||
|
|
||||||
|
- alias: `opencode-task76-doc-boundaries`
|
||||||
|
- mission: `Update Anki integration docs with post-decomposition ownership boundaries for TASK-76`
|
||||||
|
- status: `done`
|
||||||
|
- branch: `main`
|
||||||
|
- started_at: `2026-02-21T20:35:58Z`
|
||||||
|
- heartbeat_minutes: `5`
|
||||||
|
|
||||||
|
## Current Work (newest first)
|
||||||
|
|
||||||
|
- [2026-02-21T20:35:58Z] intent: update `docs/anki-integration.md` with concise ownership boundaries for facade/workflows/collaborators after TASK-76 decomposition.
|
||||||
|
- [2026-02-21T20:36:55Z] progress: added ownership-boundary section in `docs/anki-integration.md` covering facade, note-update workflow, field-grouping workflow, and existing collaborators.
|
||||||
|
- [2026-02-21T20:36:55Z] handoff: docs-only change complete; no tests run per request.
|
||||||
|
|
||||||
|
## Files Touched
|
||||||
|
|
||||||
|
- `docs/subagents/INDEX.md`
|
||||||
|
- `docs/subagents/collaboration.md`
|
||||||
|
- `docs/subagents/agents/opencode-task76-doc-boundaries-20260221T203558Z-h7q4.md`
|
||||||
|
- `docs/anki-integration.md`
|
||||||
|
|
||||||
|
## Assumptions
|
||||||
|
|
||||||
|
- TASK-76 remains the source of truth for this documentation update.
|
||||||
|
- Requested scope is docs-only; no source-code behavior changes.
|
||||||
|
|
||||||
|
## Open Questions / Blockers
|
||||||
|
|
||||||
|
- None.
|
||||||
|
|
||||||
|
## Next Step
|
||||||
|
|
||||||
|
- Await user review; adjust wording if they want tighter or more code-facing phrasing.
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# Agent: `opencode-task96-config-resolve-20260221T094119Z-mbfo`
|
||||||
|
|
||||||
|
- alias: `opencode-task96-config-resolve`
|
||||||
|
- mission: `Execute TASK-96 by splitting src/config/resolve.ts into domain modules without behavior drift`
|
||||||
|
- status: `planning`
|
||||||
|
- branch: `main`
|
||||||
|
- started_at: `2026-02-21T09:41:19Z`
|
||||||
|
- heartbeat_minutes: `5`
|
||||||
|
|
||||||
|
## Current Work (newest first)
|
||||||
|
|
||||||
|
- [2026-02-21T09:41:19Z] intent: load TASK-96 from Backlog MCP, draft implementation plan via writing-plans skill, then execute via executing-plans skill (no commit).
|
||||||
|
- [2026-02-21T09:41:19Z] progress: read workflow overview + subagent protocol docs; creating session record and index row before code edits.
|
||||||
|
|
||||||
|
## Files Touched
|
||||||
|
|
||||||
|
- `docs/subagents/INDEX.md`
|
||||||
|
- `docs/subagents/agents/opencode-task96-config-resolve-20260221T094119Z-mbfo.md`
|
||||||
|
|
||||||
|
## Assumptions
|
||||||
|
|
||||||
|
- User request to execute TASK-96 implies consent to edit current branch state and run required verification commands.
|
||||||
|
|
||||||
|
## Open Questions / Blockers
|
||||||
|
|
||||||
|
- None.
|
||||||
|
|
||||||
|
## Next Step
|
||||||
|
|
||||||
|
- Load TASK-96 code context and write plan file under `docs/plans/`.
|
||||||
@@ -48,3 +48,4 @@ Shared notes. Append-only.
|
|||||||
- [2026-02-21T20:16:59Z] [opencode-task76-anki-workflows-20260221T201659Z-r4p1|opencode-task76-anki-workflows] starting TASK-76 via Backlog MCP + writing-plans/executing-plans; likely scope `src/anki-integration.ts` + new `src/anki-integration/*` workflow services, with overlap checks before edits.
|
- [2026-02-21T20:16:59Z] [opencode-task76-anki-workflows-20260221T201659Z-r4p1|opencode-task76-anki-workflows] starting TASK-76 via Backlog MCP + writing-plans/executing-plans; likely scope `src/anki-integration.ts` + new `src/anki-integration/*` workflow services, with overlap checks before edits.
|
||||||
- [2026-02-21T20:35:58Z] [opencode-task76-doc-boundaries-20260221T203558Z-h7q4|opencode-task76-doc-boundaries] overlap note: TASK-76 already has an active planning agent; this pass is docs-only (`docs/anki-integration.md`) to capture ownership boundaries after workflow decomposition.
|
- [2026-02-21T20:35:58Z] [opencode-task76-doc-boundaries-20260221T203558Z-h7q4|opencode-task76-doc-boundaries] overlap note: TASK-76 already has an active planning agent; this pass is docs-only (`docs/anki-integration.md`) to capture ownership boundaries after workflow decomposition.
|
||||||
- [2026-02-21T21:16:18Z] [opencode-task76-anki-workflows-20260221T201659Z-r4p1|opencode-task76-anki-workflows] completed TASK-76: extracted `note-update-workflow` + `field-grouping-workflow` services, delegated facade hotpaths in `src/anki-integration.ts`, added focused workflow seam tests, docs ownership boundaries updated, `bun run build && bun run test:core:dist` green, and backlog TASK-76 marked Done.
|
- [2026-02-21T21:16:18Z] [opencode-task76-anki-workflows-20260221T201659Z-r4p1|opencode-task76-anki-workflows] completed TASK-76: extracted `note-update-workflow` + `field-grouping-workflow` services, delegated facade hotpaths in `src/anki-integration.ts`, added focused workflow seam tests, docs ownership boundaries updated, `bun run build && bun run test:core:dist` green, and backlog TASK-76 marked Done.
|
||||||
|
- [2026-02-21T21:37:07Z] [codex-docs-unpushed-review-20260221T213707Z-lyej|codex-docs-unpushed-review] starting docs-drift audit for unpushed commits (`origin/main..HEAD`); scope docs alignment only, no behavior/code rewrites.
|
||||||
|
|||||||
209
launcher/main.test.ts
Normal file
209
launcher/main.test.ts
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
import test from 'node:test';
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import fs from 'node:fs';
|
||||||
|
import os from 'node:os';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { spawnSync } from 'node:child_process';
|
||||||
|
import { resolveConfigFilePath } from '../src/config/path-resolution.js';
|
||||||
|
|
||||||
|
type RunResult = {
|
||||||
|
status: number | null;
|
||||||
|
stdout: string;
|
||||||
|
stderr: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
function withTempDir<T>(fn: (dir: string) => T): T {
|
||||||
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'subminer-launcher-test-'));
|
||||||
|
try {
|
||||||
|
return fn(dir);
|
||||||
|
} finally {
|
||||||
|
fs.rmSync(dir, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function runLauncher(argv: string[], env: NodeJS.ProcessEnv): RunResult {
|
||||||
|
const result = spawnSync(process.execPath, ['run', path.join(process.cwd(), 'launcher/main.ts'), ...argv], {
|
||||||
|
env,
|
||||||
|
encoding: 'utf8',
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
status: result.status,
|
||||||
|
stdout: result.stdout || '',
|
||||||
|
stderr: result.stderr || '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeTestEnv(homeDir: string, xdgConfigHome: string): NodeJS.ProcessEnv {
|
||||||
|
return {
|
||||||
|
...process.env,
|
||||||
|
HOME: homeDir,
|
||||||
|
XDG_CONFIG_HOME: xdgConfigHome,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
test('config path uses XDG_CONFIG_HOME override', () => {
|
||||||
|
withTempDir((root) => {
|
||||||
|
const xdgConfigHome = path.join(root, 'xdg');
|
||||||
|
const homeDir = path.join(root, 'home');
|
||||||
|
fs.mkdirSync(path.join(xdgConfigHome, 'SubMiner'), { recursive: true });
|
||||||
|
fs.writeFileSync(path.join(xdgConfigHome, 'SubMiner', 'config.json'), '{"source":"xdg"}');
|
||||||
|
|
||||||
|
const result = runLauncher(['config', 'path'], makeTestEnv(homeDir, xdgConfigHome));
|
||||||
|
|
||||||
|
assert.equal(result.status, 0);
|
||||||
|
assert.equal(result.stdout.trim(), path.join(xdgConfigHome, 'SubMiner', 'config.json'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('config discovery ignores lowercase subminer candidate', () => {
|
||||||
|
const homeDir = '/home/tester';
|
||||||
|
const xdgConfigHome = '/tmp/xdg-config';
|
||||||
|
const expected = path.join(xdgConfigHome, 'SubMiner', 'config.jsonc');
|
||||||
|
const foundPaths = new Set([path.join(xdgConfigHome, 'subminer', 'config.json')]);
|
||||||
|
|
||||||
|
const resolved = resolveConfigFilePath({
|
||||||
|
xdgConfigHome,
|
||||||
|
homeDir,
|
||||||
|
existsSync: (candidate) => foundPaths.has(path.normalize(candidate)),
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.equal(resolved, expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('config path prefers jsonc over json for same directory', () => {
|
||||||
|
withTempDir((root) => {
|
||||||
|
const homeDir = path.join(root, 'home');
|
||||||
|
const xdgConfigHome = path.join(root, 'xdg');
|
||||||
|
fs.mkdirSync(path.join(xdgConfigHome, 'SubMiner'), { recursive: true });
|
||||||
|
fs.writeFileSync(path.join(xdgConfigHome, 'SubMiner', 'config.json'), '{"format":"json"}');
|
||||||
|
fs.writeFileSync(path.join(xdgConfigHome, 'SubMiner', 'config.jsonc'), '{"format":"jsonc"}');
|
||||||
|
|
||||||
|
const result = runLauncher(['config', 'path'], makeTestEnv(homeDir, xdgConfigHome));
|
||||||
|
|
||||||
|
assert.equal(result.status, 0);
|
||||||
|
assert.equal(result.stdout.trim(), path.join(xdgConfigHome, 'SubMiner', 'config.jsonc'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('config show prints config body and appends trailing newline', () => {
|
||||||
|
withTempDir((root) => {
|
||||||
|
const homeDir = path.join(root, 'home');
|
||||||
|
const xdgConfigHome = path.join(root, 'xdg');
|
||||||
|
fs.mkdirSync(path.join(xdgConfigHome, 'SubMiner'), { recursive: true });
|
||||||
|
fs.writeFileSync(path.join(xdgConfigHome, 'SubMiner', 'config.jsonc'), '{"logLevel":"debug"}');
|
||||||
|
|
||||||
|
const result = runLauncher(['config', 'show'], makeTestEnv(homeDir, xdgConfigHome));
|
||||||
|
|
||||||
|
assert.equal(result.status, 0);
|
||||||
|
assert.equal(result.stdout, '{"logLevel":"debug"}\n');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('mpv socket command returns socket path from plugin runtime config', () => {
|
||||||
|
withTempDir((root) => {
|
||||||
|
const homeDir = path.join(root, 'home');
|
||||||
|
const xdgConfigHome = path.join(root, 'xdg');
|
||||||
|
const expectedSocket = path.join(root, 'custom', 'subminer.sock');
|
||||||
|
fs.mkdirSync(path.join(xdgConfigHome, 'mpv', 'script-opts'), { recursive: true });
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(xdgConfigHome, 'mpv', 'script-opts', 'subminer.conf'),
|
||||||
|
`socket_path=${expectedSocket}\n`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = runLauncher(['mpv', 'socket'], makeTestEnv(homeDir, xdgConfigHome));
|
||||||
|
|
||||||
|
assert.equal(result.status, 0);
|
||||||
|
assert.equal(result.stdout.trim(), expectedSocket);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('mpv status exits non-zero when socket is not ready', () => {
|
||||||
|
withTempDir((root) => {
|
||||||
|
const homeDir = path.join(root, 'home');
|
||||||
|
const xdgConfigHome = path.join(root, 'xdg');
|
||||||
|
const result = runLauncher(['mpv', 'status'], makeTestEnv(homeDir, xdgConfigHome));
|
||||||
|
|
||||||
|
assert.equal(result.status, 1);
|
||||||
|
assert.match(result.stdout, /socket not ready/i);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('doctor reports checks and exits non-zero without hard dependencies', () => {
|
||||||
|
withTempDir((root) => {
|
||||||
|
const homeDir = path.join(root, 'home');
|
||||||
|
const xdgConfigHome = path.join(root, 'xdg');
|
||||||
|
const env = {
|
||||||
|
...makeTestEnv(homeDir, xdgConfigHome),
|
||||||
|
PATH: '',
|
||||||
|
};
|
||||||
|
const result = runLauncher(['doctor'], env);
|
||||||
|
|
||||||
|
assert.equal(result.status, 1);
|
||||||
|
assert.match(result.stdout, /\[doctor\] app binary:/);
|
||||||
|
assert.match(result.stdout, /\[doctor\] mpv:/);
|
||||||
|
assert.match(result.stdout, /\[doctor\] config:/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('jellyfin discovery routes to app --start with log-level forwarding', () => {
|
||||||
|
withTempDir((root) => {
|
||||||
|
const homeDir = path.join(root, 'home');
|
||||||
|
const xdgConfigHome = path.join(root, 'xdg');
|
||||||
|
const appPath = path.join(root, 'fake-subminer.sh');
|
||||||
|
const capturePath = path.join(root, 'captured-args.txt');
|
||||||
|
fs.writeFileSync(
|
||||||
|
appPath,
|
||||||
|
'#!/bin/sh\nif [ -n "$SUBMINER_TEST_CAPTURE" ]; then printf "%s\\n" "$@" > "$SUBMINER_TEST_CAPTURE"; fi\nexit 0\n',
|
||||||
|
);
|
||||||
|
fs.chmodSync(appPath, 0o755);
|
||||||
|
|
||||||
|
const env = {
|
||||||
|
...makeTestEnv(homeDir, xdgConfigHome),
|
||||||
|
SUBMINER_APPIMAGE_PATH: appPath,
|
||||||
|
SUBMINER_TEST_CAPTURE: capturePath,
|
||||||
|
};
|
||||||
|
const result = runLauncher(['jellyfin', 'discovery', '--log-level', 'debug'], env);
|
||||||
|
|
||||||
|
assert.equal(result.status, 0);
|
||||||
|
assert.equal(fs.readFileSync(capturePath, 'utf8'), '--start\n--log-level\ndebug\n');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('jellyfin login routes credentials to app command', () => {
|
||||||
|
withTempDir((root) => {
|
||||||
|
const homeDir = path.join(root, 'home');
|
||||||
|
const xdgConfigHome = path.join(root, 'xdg');
|
||||||
|
const appPath = path.join(root, 'fake-subminer.sh');
|
||||||
|
const capturePath = path.join(root, 'captured-args.txt');
|
||||||
|
fs.writeFileSync(
|
||||||
|
appPath,
|
||||||
|
'#!/bin/sh\nif [ -n "$SUBMINER_TEST_CAPTURE" ]; then printf "%s\\n" "$@" > "$SUBMINER_TEST_CAPTURE"; fi\nexit 0\n',
|
||||||
|
);
|
||||||
|
fs.chmodSync(appPath, 0o755);
|
||||||
|
|
||||||
|
const env = {
|
||||||
|
...makeTestEnv(homeDir, xdgConfigHome),
|
||||||
|
SUBMINER_APPIMAGE_PATH: appPath,
|
||||||
|
SUBMINER_TEST_CAPTURE: capturePath,
|
||||||
|
};
|
||||||
|
const result = runLauncher(
|
||||||
|
[
|
||||||
|
'jellyfin',
|
||||||
|
'login',
|
||||||
|
'--server',
|
||||||
|
'https://jf.example.test',
|
||||||
|
'--username',
|
||||||
|
'alice',
|
||||||
|
'--password',
|
||||||
|
'secret',
|
||||||
|
],
|
||||||
|
env,
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.equal(result.status, 0);
|
||||||
|
assert.equal(
|
||||||
|
fs.readFileSync(capturePath, 'utf8'),
|
||||||
|
'--jellyfin-login\n--jellyfin-server\nhttps://jf.example.test\n--jellyfin-username\nalice\n--jellyfin-password\nsecret\n',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -20,16 +20,18 @@
|
|||||||
"check:file-budgets:strict": "bun run scripts/check-file-budgets.ts --strict",
|
"check:file-budgets:strict": "bun run scripts/check-file-budgets.ts --strict",
|
||||||
"check:main-fanin": "bun run scripts/check-main-runtime-fanin.ts",
|
"check:main-fanin": "bun run scripts/check-main-runtime-fanin.ts",
|
||||||
"check:main-fanin:strict": "bun run scripts/check-main-runtime-fanin.ts --strict",
|
"check:main-fanin:strict": "bun run scripts/check-main-runtime-fanin.ts --strict",
|
||||||
"test:config:src": "bun test src/config/config.test.ts src/config/path-resolution.test.ts",
|
"test:config:src": "bun test src/config/config.test.ts src/config/path-resolution.test.ts src/config/resolve/anki-connect.test.ts src/config/resolve/subtitle-style.test.ts src/config/resolve/jellyfin.test.ts",
|
||||||
"test:config:dist": "node --test dist/config/config.test.js dist/config/path-resolution.test.js",
|
"test:config:dist": "node --test dist/config/config.test.js dist/config/path-resolution.test.js dist/config/resolve/anki-connect.test.js dist/config/resolve/subtitle-style.test.js dist/config/resolve/jellyfin.test.js",
|
||||||
"test:config:smoke:dist": "node --test dist/config/path-resolution.test.js",
|
"test:config:smoke:dist": "node --test dist/config/path-resolution.test.js",
|
||||||
"test:core:src": "bun test src/cli/args.test.ts src/cli/help.test.ts src/core/services/cli-command.test.ts src/core/services/field-grouping-overlay.test.ts src/core/services/numeric-shortcut-session.test.ts src/core/services/secondary-subtitle.test.ts src/core/services/mpv-render-metrics.test.ts src/core/services/overlay-content-measurement.test.ts src/core/services/mpv-control.test.ts src/core/services/mpv.test.ts src/core/services/runtime-options-ipc.test.ts src/core/services/runtime-config.test.ts src/core/services/config-hot-reload.test.ts src/core/services/tokenizer.test.ts src/core/services/subsync.test.ts src/core/services/overlay-bridge.test.ts src/core/services/overlay-shortcut-handler.test.ts src/core/services/mining.test.ts src/core/services/anki-jimaku.test.ts src/core/services/jellyfin.test.ts src/core/services/jellyfin-remote.test.ts src/core/services/immersion-tracker-service.test.ts src/core/services/app-ready.test.ts src/core/services/startup-bootstrap.test.ts src/core/services/subtitle-processing-controller.test.ts src/core/services/anilist/anilist-update-queue.test.ts src/renderer/error-recovery.test.ts src/subsync/utils.test.ts src/main/anilist-url-guard.test.ts src/window-trackers/x11-tracker.test.ts",
|
"test:launcher:src": "bun test launcher/config.test.ts launcher/parse-args.test.ts launcher/main.test.ts",
|
||||||
|
"test:core:src": "bun test src/cli/args.test.ts src/cli/help.test.ts src/core/services/cli-command.test.ts src/core/services/field-grouping-overlay.test.ts src/core/services/numeric-shortcut-session.test.ts src/core/services/secondary-subtitle.test.ts src/core/services/mpv-render-metrics.test.ts src/core/services/overlay-content-measurement.test.ts src/core/services/mpv-control.test.ts src/core/services/mpv.test.ts src/core/services/runtime-options-ipc.test.ts src/core/services/runtime-config.test.ts src/core/services/config-hot-reload.test.ts src/core/services/tokenizer.test.ts src/core/services/subsync.test.ts src/core/services/overlay-bridge.test.ts src/core/services/overlay-shortcut-handler.test.ts src/core/services/mining.test.ts src/core/services/anki-jimaku.test.ts src/core/services/jellyfin.test.ts src/core/services/jellyfin-remote.test.ts src/core/services/immersion-tracker-service.test.ts src/core/services/app-ready.test.ts src/core/services/startup-bootstrap.test.ts src/core/services/subtitle-processing-controller.test.ts src/core/services/anilist/anilist-update-queue.test.ts src/renderer/error-recovery.test.ts src/subsync/utils.test.ts src/main/anilist-url-guard.test.ts src/window-trackers/x11-tracker.test.ts launcher/config.test.ts launcher/parse-args.test.ts launcher/main.test.ts",
|
||||||
"test:core:dist": "node --test dist/cli/args.test.js dist/cli/help.test.js dist/core/services/cli-command.test.js dist/core/services/ipc.test.js dist/core/services/field-grouping-overlay.test.js dist/core/services/numeric-shortcut-session.test.js dist/core/services/secondary-subtitle.test.js dist/core/services/mpv-render-metrics.test.js dist/core/services/overlay-content-measurement.test.js dist/core/services/mpv-control.test.js dist/core/services/mpv.test.js dist/core/services/runtime-options-ipc.test.js dist/core/services/runtime-config.test.js dist/core/services/config-hot-reload.test.js dist/core/services/tokenizer.test.js dist/core/services/subsync.test.js dist/core/services/overlay-bridge.test.js dist/core/services/overlay-manager.test.js dist/core/services/overlay-shortcut-handler.test.js dist/core/services/mining.test.js dist/core/services/anki-jimaku.test.js dist/core/services/jellyfin.test.js dist/core/services/jellyfin-remote.test.js dist/core/services/immersion-tracker-service.test.js dist/core/services/app-ready.test.js dist/core/services/startup-bootstrap.test.js dist/core/services/subtitle-processing-controller.test.js dist/core/services/anilist/anilist-token-store.test.js dist/core/services/anilist/anilist-update-queue.test.js dist/renderer/error-recovery.test.js dist/subsync/utils.test.js dist/main/anilist-url-guard.test.js dist/window-trackers/x11-tracker.test.js",
|
"test:core:dist": "node --test dist/cli/args.test.js dist/cli/help.test.js dist/core/services/cli-command.test.js dist/core/services/ipc.test.js dist/core/services/field-grouping-overlay.test.js dist/core/services/numeric-shortcut-session.test.js dist/core/services/secondary-subtitle.test.js dist/core/services/mpv-render-metrics.test.js dist/core/services/overlay-content-measurement.test.js dist/core/services/mpv-control.test.js dist/core/services/mpv.test.js dist/core/services/runtime-options-ipc.test.js dist/core/services/runtime-config.test.js dist/core/services/config-hot-reload.test.js dist/core/services/tokenizer.test.js dist/core/services/subsync.test.js dist/core/services/overlay-bridge.test.js dist/core/services/overlay-manager.test.js dist/core/services/overlay-shortcut-handler.test.js dist/core/services/mining.test.js dist/core/services/anki-jimaku.test.js dist/core/services/jellyfin.test.js dist/core/services/jellyfin-remote.test.js dist/core/services/immersion-tracker-service.test.js dist/core/services/app-ready.test.js dist/core/services/startup-bootstrap.test.js dist/core/services/subtitle-processing-controller.test.js dist/core/services/anilist/anilist-token-store.test.js dist/core/services/anilist/anilist-update-queue.test.js dist/renderer/error-recovery.test.js dist/subsync/utils.test.js dist/main/anilist-url-guard.test.js dist/window-trackers/x11-tracker.test.js",
|
||||||
"test:core:smoke:dist": "node --test dist/cli/help.test.js dist/core/services/runtime-config.test.js dist/core/services/ipc.test.js dist/core/services/overlay-manager.test.js dist/core/services/anilist/anilist-token-store.test.js dist/core/services/startup-bootstrap.test.js dist/renderer/error-recovery.test.js dist/main/anilist-url-guard.test.js dist/window-trackers/x11-tracker.test.js",
|
"test:core:smoke:dist": "node --test dist/cli/help.test.js dist/core/services/runtime-config.test.js dist/core/services/ipc.test.js dist/core/services/overlay-manager.test.js dist/core/services/anilist/anilist-token-store.test.js dist/core/services/startup-bootstrap.test.js dist/renderer/error-recovery.test.js dist/main/anilist-url-guard.test.js dist/window-trackers/x11-tracker.test.js",
|
||||||
"test:smoke:dist": "bun run test:config:smoke:dist && bun run test:core:smoke:dist",
|
"test:smoke:dist": "bun run test:config:smoke:dist && bun run test:core:smoke:dist",
|
||||||
"test:subtitle:dist": "echo \"Subtitle tests are currently not configured\"",
|
"test:subtitle:dist": "echo \"Subtitle tests are currently not configured\"",
|
||||||
"test": "bun run test:config && bun run test:core",
|
"test": "bun run test:config && bun run test:core",
|
||||||
"test:config": "bun run test:config:src",
|
"test:config": "bun run test:config:src",
|
||||||
|
"test:launcher": "bun run test:launcher:src",
|
||||||
"test:core": "bun run test:core:src",
|
"test:core": "bun run test:core:src",
|
||||||
"test:subtitle": "bun run build && bun run test:subtitle:dist",
|
"test:subtitle": "bun run build && bun run test:subtitle:dist",
|
||||||
"test:fast": "bun run test:config:src && bun run test:core:src",
|
"test:fast": "bun run test:config:src && bun run test:core:src",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user