chore(task-85): update launcher workflow and backlog tracking

This commit is contained in:
2026-02-20 03:51:38 -08:00
parent 06892b4838
commit 28d2da1e64
15 changed files with 373 additions and 12 deletions

View File

@@ -2,6 +2,7 @@
APP_NAME := subminer
THEME_SOURCE := assets/themes/subminer.rasi
LAUNCHER_OUT := dist/launcher/$(APP_NAME)
THEME_FILE := subminer.rasi
PLUGIN_LUA := plugin/subminer.lua
PLUGIN_CONF := plugin/subminer.conf
@@ -134,11 +135,13 @@ build-macos-unsigned: deps
build-launcher:
@printf '%s\n' "[INFO] Bundling launcher script"
@bun build ./launcher/main.ts --target=bun --packages=bundle --outfile=subminer
@if ! head -1 subminer | grep -q '^#!/usr/bin/env bun'; then \
{ printf '#!/usr/bin/env bun\n'; cat subminer; } > subminer.tmp && mv subminer.tmp subminer; \
@install -d "$(dir $(LAUNCHER_OUT))"
@bun build ./launcher/main.ts --target=bun --packages=bundle --outfile="$(LAUNCHER_OUT)"
@if ! head -1 "$(LAUNCHER_OUT)" | grep -q '^#!/usr/bin/env bun'; then \
{ printf '#!/usr/bin/env bun\n'; cat "$(LAUNCHER_OUT)"; } > "$(LAUNCHER_OUT).tmp" && mv "$(LAUNCHER_OUT).tmp" "$(LAUNCHER_OUT)"; \
fi
@chmod +x subminer
@chmod +x "$(LAUNCHER_OUT)"
@printf '%s\n' "[INFO] Launcher artifact: $(LAUNCHER_OUT)"
clean:
@printf '%s\n' "[INFO] Removing build artifacts"
@@ -180,7 +183,7 @@ dev-stop: ensure-bun
install-linux: build-launcher
@printf '%s\n' "[INFO] Installing Linux wrapper/theme artifacts"
@install -d "$(BINDIR)"
@install -m 0755 "./$(APP_NAME)" "$(BINDIR)/$(APP_NAME)"
@install -m 0755 "$(LAUNCHER_OUT)" "$(BINDIR)/$(APP_NAME)"
@install -d "$(LINUX_DATA_DIR)/themes"
@install -m 0644 "./$(THEME_SOURCE)" "$(LINUX_DATA_DIR)/themes/$(THEME_FILE)"
@if [ -n "$(APPIMAGE_SRC)" ]; then \
@@ -194,7 +197,7 @@ install-linux: build-launcher
install-macos: build-launcher
@printf '%s\n' "[INFO] Installing macOS wrapper/theme/app artifacts"
@install -d "$(BINDIR)"
@install -m 0755 "./$(APP_NAME)" "$(BINDIR)/$(APP_NAME)"
@install -m 0755 "$(LAUNCHER_OUT)" "$(BINDIR)/$(APP_NAME)"
@install -d "$(MACOS_DATA_DIR)/themes"
@install -m 0644 "./$(THEME_SOURCE)" "$(MACOS_DATA_DIR)/themes/$(THEME_FILE)"
@install -d "$(MACOS_APP_DIR)"

View File

@@ -4,7 +4,7 @@ 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'
updated_date: '2026-02-20 11:42'
labels:
- architecture
- refactor
@@ -31,14 +31,24 @@ Several core files are oversized and high-coupling (`src/main.ts`, `src/anki-int
<!-- 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.
2. Split `src/main.ts` into runtime domain modules (ongoing; major wiring extracted).
3. Split `src/anki-integration.ts` into focused collaborators (started; constructor composition decomposed).
4. Split `src/config/service.ts` by load/migrate/validate/warn phases (started; load/apply flow decomposition in place).
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 -->
## Progress Notes
<!-- SECTION:PROGRESS:BEGIN -->
- 2026-02-20: Large `src/main.ts` composition slices extracted into runtime handler modules (startup, CLI, tray/window/bootstrap, shortcuts, OSD/secondary-sub, numeric/overlay shortcut lifecycle, and related seams) with focused parity tests.
- 2026-02-20: `src/anki-integration.ts` constructor decomposed into targeted private factory/config methods (`normalizeConfig`, `createKnownWordCache`, `createPollingRunner`, `createCardCreationService`, `createFieldGroupingService`) to reduce orchestration complexity.
- 2026-02-20: `src/config/service.ts` load/apply duplication reduced by introducing `applyResolvedConfig`, `resolveExistingConfigPath`, and `parseConfigContent`.
- Validation checkpoint: `bun run build` and focused suites (`dist/config/config.test.js`, `dist/anki-integration.test.js`) passing.
- Current strategy: prioritize high-ROI extractions (behavioral seams and churn-heavy hotspots) over further low-impact micro-shuffles.
<!-- SECTION:PROGRESS:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 `src/main.ts` reduced to orchestration-focused module with extracted runtime domains

View File

@@ -0,0 +1,46 @@
---
id: TASK-88
title: Remove MeCab fallback tokenizer and simplify Yomitan token flow
status: To Do
assignee: []
created_date: '2026-02-20 00:00'
labels:
- tokenizer
- refactor
dependencies: []
priority: medium
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Remove the MeCab fallback tokenization path and associated merge-selection complexity in subtitle tokenization. Treat Yomitan parser output as the single source of token boundaries/grouping, and keep only minimal normalization needed for downstream known-word, JLPT, and frequency annotation.
<!-- SECTION:DESCRIPTION:END -->
## Action Steps
<!-- SECTION:PLAN:BEGIN -->
1. Remove MeCab fallback execution from `tokenizeSubtitle` and delete dead fallback-specific branches.
2. Remove merge/candidate-selection code that is only needed to reconcile MeCab-vs-Yomitan tokenization strategies.
3. Keep Yomitan parsing pipeline with minimal structural token normalization only.
4. Update MeCab usage so it is no longer required for tokenization fallback (retain only explicitly needed behavior, if any).
5. Update docs/config notes to reflect Yomitan-only tokenization flow.
6. Add regression tests for Yomitan-only success/failure paths and token annotation continuity.
<!-- SECTION:PLAN:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 Subtitle tokenization no longer falls back to MeCab when Yomitan parsing fails.
- [ ] #2 Token grouping logic is simplified to rely on Yomitan structure; redundant custom merge-selection logic removed.
- [ ] #3 Known-word, JLPT, frequency, and N+1 annotations still work on Yomitan-derived tokens.
- [ ] #4 If Yomitan parsing fails, behavior is explicit and tested (for example `tokens: null` without MeCab fallback path).
- [ ] #5 Documentation reflects that tokenization flow is Yomitan-first and Yomitan-only.
<!-- AC:END -->
## Definition of Done
<!-- DOD:BEGIN -->
- [ ] #1 `src/core/services/tokenizer.ts` no longer contains MeCab fallback tokenization branch.
- [ ] #2 Tests cover Yomitan-only pipeline and failure behavior regressions.
- [ ] #3 Any removed MeCab-only merge helpers are deleted with no unused exports/imports.
- [ ] #4 Build and relevant tokenizer/subtitle tests pass.
<!-- DOD:END -->

View File

@@ -22,6 +22,10 @@ cd vendor/texthooker-ui && pnpm install --frozen-lockfile
# TypeScript compile (fast, for development)
bun run build
# Generate launcher wrapper artifact
make build-launcher
# output: dist/launcher/subminer
# Full platform build (includes texthooker-ui + AppImage/DMG)
make build
@@ -31,6 +35,20 @@ make build-macos # macOS DMG + ZIP (signed)
make build-macos-unsigned # macOS DMG + ZIP (unsigned)
```
## Launcher Artifact Workflow
- Source of truth: `launcher/*.ts`
- Generated output: `dist/launcher/subminer`
- Do not hand-edit generated launcher output.
- Install targets (`make install-linux`, `make install-macos`) copy from `dist/launcher/subminer`.
Verify the workflow:
```bash
make build-launcher
bash scripts/verify-generated-launcher.sh
```
## Running Locally
```bash

View File

@@ -58,11 +58,14 @@ The `subminer` wrapper uses a Bun shebang (`#!/usr/bin/env bun`), so [Bun](https
git clone https://github.com/ksyasuda/SubMiner.git
cd SubMiner
make build
make build-launcher
# Install platform artifacts (wrapper + theme + AppImage)
make install
```
`make build-launcher` generates the wrapper at `dist/launcher/subminer`. The checked-in launcher source remains `launcher/*.ts`.
## macOS
### DMG (Recommended)

View File

@@ -23,4 +23,5 @@ Read first. Keep concise.
| `codex-jellyfin-secret-store-20260220T101428Z-om4z` | `codex-jellyfin-secret-store` | `Verify whether Jellyfin token can use same secret-store path as AniList token` | `completed` | `docs/subagents/agents/codex-jellyfin-secret-store-20260220T101428Z-om4z.md` | `2026-02-20T10:22:45Z` |
| `codex-vitepress-subagents-ignore-20260220T101755Z-k2m9` | `codex-vitepress-subagents-ignore` | `Exclude docs/subagents from VitePress build` | `completed` | `docs/subagents/agents/codex-vitepress-subagents-ignore-20260220T101755Z-k2m9.md` | `2026-02-20T10:18:30Z` |
| `codex-preserve-linebreak-display-20260220T110436Z-r8f1` | `codex-preserve-linebreak-display` | `Fix visible overlay display artifact when subtitleStyle.preserveLineBreaks is disabled` | `completed` | `docs/subagents/agents/codex-preserve-linebreak-display-20260220T110436Z-r8f1.md` | `2026-02-20T11:10:51Z` |
| `codex-review-refactor-cleanup-20260220T113818Z-i2ov` | `codex-review-refactor-cleanup` | `Review recent TASK-85 refactor effort and identify remaining cleanup work` | `handoff` | `docs/subagents/agents/codex-review-refactor-cleanup-20260220T113818Z-i2ov.md` | `2026-02-20T11:40:15Z` |
| `codex-review-refactor-cleanup-20260220T113818Z-i2ov` | `codex-review-refactor-cleanup` | `Review recent TASK-85 refactor effort and identify remaining cleanup work` | `handoff` | `docs/subagents/agents/codex-review-refactor-cleanup-20260220T113818Z-i2ov.md` | `2026-02-20T11:48:28Z` |
| `codex-commit-unstaged-20260220T115057Z-k7q2` | `codex-commit-unstaged` | `Commit all current unstaged repository changes with content-derived conventional message` | `in_progress` | `docs/subagents/agents/codex-commit-unstaged-20260220T115057Z-k7q2.md` | `2026-02-20T11:51:18Z` |

View File

@@ -0,0 +1,26 @@
# Agent: `codex-commit-unstaged-20260220T115057Z-k7q2`
- alias: `codex-commit-unstaged`
- mission: `Commit all current unstaged repository changes with content-derived conventional message`
- status: `editing`
- branch: `main`
- started_at: `2026-02-20T11:51:18Z`
- heartbeat_minutes: `5`
## Current Work (newest first)
- [2026-02-20T11:51:18Z] intent: review unstaged diff; derive concise conventional commit message; commit requested changes.
- [2026-02-20T11:51:18Z] progress: inspected unstaged set (Makefile/docs/backlog/submodule/new script/new task metadata/subagent records).
## Files Touched
- `docs/subagents/INDEX.md`
- `docs/subagents/agents/codex-commit-unstaged-20260220T115057Z-k7q2.md`
## Assumptions
- user asked to commit all unstaged changes currently in working tree.
- single commit acceptable for mixed docs/build/backlog/submodule updates.
## Open Questions / Blockers
- none
## Next Step
- stage all current unstaged changes and commit with content-derived Conventional Commit message.

View File

@@ -0,0 +1,42 @@
# Agent Log — codex-nplusone-pos1-20260220T012300Z-c5he
- alias: `codex-nplusone-pos1`
- mission: `Fix N+1 false-negative when known sentence fails due to Yomitan functional token counting`
- status: `completed`
- started_utc: `2026-02-20T01:23:00Z`
- heartbeat_minutes: `5`
## Intent
- reproduce user-reported case: known `私/あの/欲しい`, unknown `仮面`, no N+1 color
- add failing regression test first
- patch N+1 candidate filter to ignore functional `pos1` from MeCab enrichment for Yomitan tokens
- run focused tests
## Planned Files
- `src/core/services/tokenizer.test.ts`
- `src/token-merger.ts`
## Assumptions
- issue path: Yomitan tokens have `partOfSpeech=other`; candidate exclusion relies mostly on `partOfSpeech`
- MeCab enrichment supplies `pos1`; N+1 filter currently underuses it
## Progress
- 2026-02-20T01:23:00Z: started; context loaded; preparing RED test
- 2026-02-20T01:28:02Z: RED confirmed; new regression test fails (`targets.length` expected 1, got 0)
- 2026-02-20T01:28:14Z: GREEN confirmed; patched N+1 candidate filter to ignore functional `pos1` (`助詞`,`助動詞`,`記号`,`補助記号`); tokenizer test file all pass
## Files Touched
- `src/core/services/tokenizer.test.ts`
- `src/token-merger.ts`
- `docs/subagents/INDEX.md`
- `docs/subagents/agents/codex-nplusone-pos1-20260220T012300Z-c5he.md`
## Handoff
- regression covered for user-reported case pattern (`私も あの仮面が欲しいです` with known `私/あの/欲しい`)
- no blockers

View File

@@ -0,0 +1,36 @@
# Agent: codex-review-refactor-cleanup-20260220T113818Z-i2ov
- alias: codex-review-refactor-cleanup
- mission: Review recent TASK-85 refactor commits; identify remaining cleanup work with concrete evidence
- status: handoff
- branch: main
- started_at: 2026-02-20T11:38:18Z
- heartbeat_minutes: 5
## Current Work (newest first)
- [2026-02-20T11:48:28Z] progress: executed cleanup item #4 first: reconciled launcher generated-artifact policy by moving `build-launcher` output to `dist/launcher/subminer` and making install targets consume that path.
- [2026-02-20T11:48:28Z] progress: added `scripts/verify-generated-launcher.sh` and documented canonical workflow in `docs/development.md` + `docs/installation.md`.
- [2026-02-20T11:48:28Z] test: `make build-launcher && ls -la dist/launcher/subminer && bash scripts/verify-generated-launcher.sh` passes (warns if stale `./subminer` exists locally).
- [2026-02-20T11:40:15Z] test: full gate pass for current tree (`bun run build && bun run test:config:dist && bun run test:core:dist`); cleanup debt remains structural/tracking, not immediate red tests.
- [2026-02-20T11:39:33Z] handoff: review complete; TASK-85 refactor made strong `src/main/runtime/*` progress but cleanup not complete. Remaining priorities: finish decomposing oversized hotspots (`src/main.ts`, `src/anki-integration.ts`, `src/config/service.ts`, `src/core/services/immersion-tracker-service.ts`), reduce `main.ts` import/deps-builder fan-in, and close TASK-85 AC/DoD tracking gaps.
- [2026-02-20T11:39:33Z] progress: ran maintainability guardrail (`bun run check:file-budgets`) and confirmed 17 files still >500 LOC including primary TASK-85 targets.
- [2026-02-20T11:38:18Z] intent: run requesting-code-review pass over latest refactor series, focus on remaining maintainability/quality gaps and missing tests.
- [2026-02-20T11:38:18Z] planned files: `src/main.ts`, `src/main/runtime/*`, `src/anki-integration.ts`, `src/config/service.ts`, `src/core/services/immersion-tracker-service.ts`, `backlog/tasks/task-85 - Refactor-large-files-for-maintainability-and-readability.md`.
- [2026-02-20T11:38:18Z] assumptions: backlog MCP resource says uninitialized; use existing local `backlog/tasks/task-85 - Refactor-large-files-for-maintainability-and-readability.md` for ticket association/context.
## Files Touched
- `docs/subagents/agents/codex-review-refactor-cleanup-20260220T113818Z-i2ov.md`
- `docs/subagents/INDEX.md`
- `Makefile`
- `scripts/verify-generated-launcher.sh`
- `docs/development.md`
- `docs/installation.md`
## Assumptions
- Review scope = recent TASK-85 refactor commits on `main` (mostly 2026-02-20 series touching `src/main.ts` and `src/main/runtime/*`).
## Open Questions / Blockers
- none
## Next Step
- Convert review findings into concrete child backlog tasks under TASK-85 (domain-by-domain extraction + import-fan-in reduction + AC/DoD closeout pass).

View File

@@ -0,0 +1,36 @@
# Agent: codex-texthooker-color-ws-20260220T005844Z-r7m2
- alias: codex-texthooker-color-ws
- mission: Fix texthooker websocket payload so token highlight colors render
- status: completed
- branch: main
- started_at: 2026-02-20T00:58:44Z
- heartbeat_minutes: 5
## Current Work (newest first)
- [2026-02-20T01:01:00Z] handoff: implemented websocket subtitle serialization with token markup classes (`word-known`, `word-n-plus-one`, `word-frequency-*`, `word-jlpt-*`) so texthooker-ui receives color metadata.
- [2026-02-20T01:01:00Z] change: `subtitle-change` now sends immediate plain overlay update while async processing path publishes tokenized/fallback payloads to both overlay and websocket; tokenization now runs when texthooker websocket has clients even without overlay windows.
- [2026-02-20T01:01:00Z] test: `bun test src/core/services/subtitle-processing-controller.test.ts src/core/services/subtitle-ws.test.ts` pass (7/7); `bun run build` pass (expected macOS helper swiftcache sandbox fallback).
- [2026-02-20T00:58:44Z] intent: debug missing texthooker colors after UI update; patch SubMiner websocket/tokenization integration path.
- [2026-02-20T00:58:44Z] progress: root cause found: `SubtitleWebSocket.broadcast()` sends only plain sentence text while token classes are generated only in renderer overlay path; texthooker never receives token-markup metadata.
- [2026-02-20T00:58:44Z] planned files: `src/core/services/subtitle-ws.ts`, `src/main.ts`, `src/core/services/subtitle-processing-controller.ts`, tests under `src/core/services/*`.
- [2026-02-20T00:58:44Z] backlog: associated with existing `TASK-87` (frequency/N+1 init + highlighting behavior).
## Files Touched
- `docs/subagents/INDEX.md`
- `docs/subagents/agents/codex-texthooker-color-ws-20260220T005844Z-r7m2.md`
- `src/main.ts`
- `src/core/services/subtitle-ws.ts`
- `src/core/services/subtitle-ws.test.ts`
- `src/core/services/subtitle-processing-controller.ts`
- `src/core/services/subtitle-processing-controller.test.ts`
## Open Questions / Blockers
- none
## Next Step
- none

View File

@@ -0,0 +1,27 @@
# Agent: codex-texthooker-highlights-20260220T002342Z-ugna
- alias: codex-texthooker-highlights
- mission: Add optional texthooker highlight toggles (known/n+1/frequency/JLPT) in settings with realtime forward-only behavior.
- status: in_progress
- branch: main
- started_at: 2026-02-20T00:23:42Z
- heartbeat_minutes: 5
## Current Work (newest first)
- [2026-02-20T00:23:42Z] intent: implement texthooker-ui enhancements for optional known/n+1/frequency/JLPT coloring with runtime settings toggles that apply only to new incoming lines.
- [2026-02-20T00:23:42Z] planned files: texthooker-ui source for line rendering/highlighting + settings page/state store + tests covering toggle behavior.
- [2026-02-20T00:23:42Z] assumptions: user wants per-feature on/off switches; turning off stops applying color to new lines while existing rendered lines remain unchanged.
## Files Touched
- docs/subagents/INDEX.md
- docs/subagents/agents/codex-texthooker-highlights-20260220T002342Z-ugna.md
## Open Questions / Blockers
- none
## Next Step
- inspect texthooker-ui highlight/settings architecture and map minimal-change implementation path.

View File

@@ -0,0 +1,41 @@
# Agent: codex-texthooker-highlights-20260220T002354Z-927c
- alias: codex-texthooker-highlights
- mission: Add optional texthooker highlight toggles (known/n+1/frequency/JLPT) in settings with realtime forward-only behavior.
- status: completed
- branch: main
- started_at: 2026-02-20T00:23:54Z
- heartbeat_minutes: 5
## Current Work (newest first)
- [2026-02-20T00:30:49Z] change: added texthooker-ui highlight toggles (known/n+1/frequency/jlpt) in stores/types/settings/presets and ingest-time markup filtering with safe span whitelist.
- [2026-02-20T00:30:49Z] change: switched line rendering to sanitized html content and added word class styles + plain-text copy behavior.
- [2026-02-20T00:30:49Z] test: `cd texthooker-ui && bun test src/util.test.ts` pass (7/7).
- [2026-02-20T00:30:49Z] note: full TypeScript check blocked locally because texthooker-ui dependencies/tsconfig base package are not installed in this environment.
- [2026-02-20T00:26:28Z] phase: plan complete; starting code edits in texthooker-ui (stores/settings/line markup filter/styles/tests).
- [2026-02-20T00:23:54Z] intent: implement texthooker-ui enhancements for optional known/n+1/frequency/JLPT coloring with runtime settings toggles that apply only to new incoming lines.
- [2026-02-20T00:23:54Z] planned files: texthooker-ui source for line rendering/highlighting + settings page/state store + tests covering toggle behavior.
- [2026-02-20T00:23:54Z] assumptions: user wants per-feature on/off switches; turning off stops applying color to new lines while existing rendered lines remain unchanged.
## Files Touched
- docs/subagents/INDEX.md
- docs/subagents/agents/codex-texthooker-highlights-20260220T002354Z-927c.md
- texthooker-ui/src/types.ts
- texthooker-ui/src/stores/stores.ts
- texthooker-ui/src/components/Settings.svelte
- texthooker-ui/src/components/Presets.svelte
- texthooker-ui/src/components/App.svelte
- texthooker-ui/src/components/Line.svelte
- texthooker-ui/src/line-markup.ts
- texthooker-ui/src/util.test.ts
- texthooker-ui/src/app.css
## Open Questions / Blockers
- none
## Next Step
- wait for user validation in running texthooker session; if requested, regenerate bundled `texthooker-ui/docs/index.html`.

View File

@@ -0,0 +1,32 @@
# Agent: codex-texthooker-ui-playwright-20260220T003827Z-k3p9
- alias: codex-texthooker-ui-playwright
- mission: Run Playwright MCP smoke/regression checks for texthooker-ui changes
- status: completed
- branch: main
- started_at: 2026-02-20T00:38:27Z
- heartbeat_minutes: 5
## Current Work (newest first)
- [2026-02-20T00:42:09Z] handoff: Playwright MCP smoke run complete on local `texthooker-ui` (`http://127.0.0.1:4174`) with injected markup fixtures for highlight behavior and copy flow.
- [2026-02-20T00:42:09Z] test: `bun install` (deps restored), `bun run dev --host 127.0.0.1 --port 4174` (manual run), Playwright checks (UI load/settings toggles/persistence/copy), `bun test src/util.test.ts` pass (7/7).
- [2026-02-20T00:42:09Z] result: new settings toggles render and persist (`bannou-texthooker-enable{KnownWord|NPlusOne|Frequency|Jlpt}Coloring` saved as `0/1`); copy button writes plain text from markup (`既知 新語 頻度 級`).
- [2026-02-20T00:42:09Z] observation: disabling toggles does not retroactively re-render already persisted lines; existing HTML markup remains unchanged until new line ingestion path runs.
- [2026-02-20T00:38:27Z] intent: execute browser-based checks against local `texthooker-ui` for recent highlight-toggle related changes; capture failures with reproducible steps and logs.
- [2026-02-20T00:38:27Z] planned files: `texthooker-ui/src/**/*` (read-only inspection), `docs/subagents/INDEX.md`, `docs/subagents/agents/codex-texthooker-ui-playwright-20260220T003827Z-k3p9.md`.
- [2026-02-20T00:38:27Z] backlog: associated validation run with existing `TASK-87` (`backlog/tasks/task-87 - Fix-plugin-start-flow-so-tokenization-frequency-N1-initialize-correctly.md`) because scope is frequency/N+1 highlighting behavior verification.
- [2026-02-20T00:38:27Z] assumptions: local `texthooker-ui` dev/preview server starts with project scripts and exposes stable UI hooks for smoke checks.
## Files Touched
- `docs/subagents/INDEX.md`
- `docs/subagents/agents/codex-texthooker-ui-playwright-20260220T003827Z-k3p9.md`
## Open Questions / Blockers
- none
## Next Step
- none

View File

@@ -0,0 +1,40 @@
#!/usr/bin/env bash
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
LAUNCHER_OUT="$REPO_ROOT/dist/launcher/subminer"
if [[ ! -f "$REPO_ROOT/launcher/main.ts" ]]; then
echo "[FAIL] launcher source missing: launcher/main.ts"
exit 1
fi
if ! rg -n --fixed-strings -- "--outfile=\"\$(LAUNCHER_OUT)\"" "$REPO_ROOT/Makefile" >/dev/null; then
echo "[FAIL] Makefile build-launcher target is not writing to dist/launcher/subminer"
exit 1
fi
if [[ ! -f "$LAUNCHER_OUT" ]]; then
echo "[FAIL] generated launcher not found at dist/launcher/subminer"
echo " run: make build-launcher"
exit 1
fi
if [[ ! -x "$LAUNCHER_OUT" ]]; then
echo "[FAIL] generated launcher is not executable: dist/launcher/subminer"
exit 1
fi
if [[ -f "$REPO_ROOT/subminer" ]]; then
echo "[WARN] stale repo-root launcher artifact found: ./subminer"
echo " expected generated location: dist/launcher/subminer"
fi
if git -C "$REPO_ROOT" ls-files --error-unmatch dist/launcher/subminer >/dev/null 2>&1; then
echo "[FAIL] dist/launcher/subminer is tracked by git; generated artifacts must remain untracked"
exit 1
fi
echo "[OK] launcher workflow verified"
echo " source: launcher/*.ts"
echo " generated artifact: dist/launcher/subminer"