diff --git a/docs/subagents/INDEX.md b/docs/subagents/INDEX.md index 8404fcb..3e3eaf2 100644 --- a/docs/subagents/INDEX.md +++ b/docs/subagents/INDEX.md @@ -6,7 +6,7 @@ Read first. Keep concise. | ------------ | -------------- | ---------------------------------------------------- | --------- | ------------------------------------- | ---------------------- | | `codex-generate-minecard-image-20260220T112900Z-vsxr` | `codex-generate-minecard-image` | `Generate media fallbacks (GIF) from assets/minecard.webm and wire README/docs fallback markup` | `done` | `docs/subagents/agents/codex-generate-minecard-image-20260220T112900Z-vsxr.md` | `2026-02-20T11:35:30Z` | | `codex-main` | `planner-exec` | `Fix frequency/N+1 regression in plugin --start flow` | `in_progress` | `docs/subagents/agents/codex-main.md` | `2026-02-19T19:36:46Z` | -| `codex-task85-20260219T233711Z-46hc` | `codex-task85` | `Resume TASK-85 maintainability refactor from latest handoff point` | `in_progress` | `docs/subagents/agents/codex-task85-20260219T233711Z-46hc.md` | `2026-02-20T10:15:51Z` | +| `codex-task85-20260219T233711Z-46hc` | `codex-task85` | `Resume TASK-85 maintainability refactor from latest handoff point` | `in_progress` | `docs/subagents/agents/codex-task85-20260219T233711Z-46hc.md` | `2026-02-20T10:17:29Z` | | `codex-config-validation-20260219T172015Z-iiyf` | `codex-config-validation` | `Find root cause of config validation error for ~/.config/SubMiner/config.jsonc` | `completed` | `docs/subagents/agents/codex-config-validation-20260219T172015Z-iiyf.md` | `2026-02-19T17:26:17Z` | | `codex-task85-20260219T233711Z-46hc` | `codex-task85` | `Resume TASK-85 maintainability refactor from latest handoff point` | `in_progress` | `docs/subagents/agents/codex-task85-20260219T233711Z-46hc.md` | `2026-02-20T02:56:34Z` | | `codex-anilist-deeplink-20260219T233926Z` | `anilist-deeplink` | `Fix external subminer:// AniList callback handling from browser` | `done` | `docs/subagents/agents/codex-anilist-deeplink-20260219T233926Z.md` | `2026-02-19T23:59:21Z` | diff --git a/docs/subagents/agents/codex-task85-20260219T233711Z-46hc.md b/docs/subagents/agents/codex-task85-20260219T233711Z-46hc.md index 07f0a9e..582498f 100644 --- a/docs/subagents/agents/codex-task85-20260219T233711Z-46hc.md +++ b/docs/subagents/agents/codex-task85-20260219T233711Z-46hc.md @@ -9,6 +9,10 @@ ## Current Work (newest first) +- [2026-02-20T10:17:29Z] progress: extracted Yomitan settings opener composition from `src/main.ts` into `src/main/runtime/yomitan-settings-runtime.ts`; `main.ts` now uses `createYomitanSettingsRuntime(...)` and consumes `openYomitanSettings` from that runtime. +- [2026-02-20T10:17:29Z] progress: added `src/main/runtime/yomitan-settings-runtime.test.ts` for composed runtime behavior. +- [2026-02-20T10:17:29Z] test: `bun run build` pass (expected macOS helper Swift cache fallback) + focused suites pass for `yomitan-settings-runtime*`, `yomitan-settings-opener*`, `yomitan-extension-runtime*`, `cli-command-context-factory*`, and `tray-runtime-handlers*` (7/7). +- [2026-02-20T10:17:29Z] scope: staging `src/main.ts`, new yomitan settings runtime module/tests, and subagent bookkeeping only. - [2026-02-20T10:15:51Z] progress: extracted overlay window factory composition from `src/main.ts` into `src/main/runtime/overlay-window-runtime-handlers.ts`; `main.ts` now composes overlay/main/invisible window handlers via one runtime factory. - [2026-02-20T10:15:51Z] progress: added `src/main/runtime/overlay-window-runtime-handlers.test.ts` for composed window handler wiring. - [2026-02-20T10:15:51Z] test: `bun run build` pass (expected macOS helper Swift cache fallback) + focused suites pass for `overlay-window-runtime-handlers*`, `overlay-window-factory*`, `overlay-runtime-bootstrap*`, `tray-runtime-handlers*`, and `cli-command-context-factory*` (9/9). diff --git a/src/main.ts b/src/main.ts index 432dec2..41ba599 100644 --- a/src/main.ts +++ b/src/main.ts @@ -290,7 +290,6 @@ import { } from './main/runtime/overlay-window-layout-main-deps'; import { buildTrayMenuTemplateRuntime, resolveTrayIconPathRuntime } from './main/runtime/tray-runtime'; import { createInitializeOverlayRuntimeHandler } from './main/runtime/overlay-runtime-bootstrap'; -import { createOpenYomitanSettingsHandler } from './main/runtime/yomitan-settings-opener'; import { createGetConfiguredShortcutsHandler, createRefreshGlobalAndOverlayShortcutsHandler, @@ -384,10 +383,10 @@ import { createBuildMpvCommandFromIpcRuntimeMainDepsHandler } from './main/runti import { createOverlayWindowRuntimeHandlers } from './main/runtime/overlay-window-runtime-handlers'; import { createBuildInitializeOverlayRuntimeBootstrapMainDepsHandler, - createBuildOpenYomitanSettingsMainDepsHandler, } from './main/runtime/app-runtime-main-deps'; import { createTrayRuntimeHandlers } from './main/runtime/tray-runtime-handlers'; import { createYomitanExtensionRuntime } from './main/runtime/yomitan-extension-runtime'; +import { createYomitanSettingsRuntime } from './main/runtime/yomitan-settings-runtime'; import { createBuildInitializeOverlayRuntimeOptionsHandler } from './main/runtime/overlay-runtime-options'; import { createBuildInitializeOverlayRuntimeMainDepsHandler } from './main/runtime/overlay-runtime-options-main-deps'; import { @@ -3126,24 +3125,22 @@ const initializeOverlayRuntimeHandler = createInitializeOverlayRuntimeHandler( startBackgroundWarmups: () => startBackgroundWarmups(), })(), ); -const openYomitanSettingsHandler = createOpenYomitanSettingsHandler( - createBuildOpenYomitanSettingsMainDepsHandler({ - ensureYomitanExtensionLoaded: () => ensureYomitanExtensionLoaded(), - openYomitanSettingsWindow: ({ yomitanExt, getExistingWindow, setWindow }) => { - openYomitanSettingsWindow({ - yomitanExt: yomitanExt as Extension, - getExistingWindow: () => getExistingWindow() as BrowserWindow | null, - setWindow: (window) => setWindow(window as BrowserWindow | null), - }); - }, - getExistingWindow: () => appState.yomitanSettingsWindow, - setWindow: (window) => { - appState.yomitanSettingsWindow = window as BrowserWindow | null; - }, - logWarn: (message) => logger.warn(message), - logError: (message, error) => logger.error(message, error), - })(), -); +const { openYomitanSettings: openYomitanSettingsHandler } = createYomitanSettingsRuntime({ + ensureYomitanExtensionLoaded: () => ensureYomitanExtensionLoaded(), + openYomitanSettingsWindow: ({ yomitanExt, getExistingWindow, setWindow }) => { + openYomitanSettingsWindow({ + yomitanExt: yomitanExt as Extension, + getExistingWindow: () => getExistingWindow() as BrowserWindow | null, + setWindow: (window) => setWindow(window as BrowserWindow | null), + }); + }, + getExistingWindow: () => appState.yomitanSettingsWindow, + setWindow: (window) => { + appState.yomitanSettingsWindow = window as BrowserWindow | null; + }, + logWarn: (message) => logger.warn(message), + logError: (message, error) => logger.error(message, error), +}); async function updateLastCardFromClipboard(): Promise { await updateLastCardFromClipboardHandler(); diff --git a/src/main/runtime/yomitan-settings-runtime.test.ts b/src/main/runtime/yomitan-settings-runtime.test.ts new file mode 100644 index 0000000..f5b843b --- /dev/null +++ b/src/main/runtime/yomitan-settings-runtime.test.ts @@ -0,0 +1,31 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { createYomitanSettingsRuntime } from './yomitan-settings-runtime'; + +test('yomitan settings runtime composes opener with built deps', async () => { + let existingWindow: { id: string } | null = null; + const calls: string[] = []; + + const runtime = createYomitanSettingsRuntime({ + ensureYomitanExtensionLoaded: async () => ({ id: 'ext' }), + openYomitanSettingsWindow: ({ getExistingWindow, setWindow }) => { + calls.push('open-window'); + const current = getExistingWindow(); + if (!current) { + setWindow({ id: 'settings' }); + } + }, + getExistingWindow: () => existingWindow as never, + setWindow: (window) => { + existingWindow = window as { id: string } | null; + }, + logWarn: (message) => calls.push(`warn:${message}`), + logError: (message) => calls.push(`error:${message}`), + }); + + runtime.openYomitanSettings(); + await new Promise((resolve) => setTimeout(resolve, 0)); + + assert.deepEqual(existingWindow, { id: 'settings' }); + assert.deepEqual(calls, ['open-window']); +}); diff --git a/src/main/runtime/yomitan-settings-runtime.ts b/src/main/runtime/yomitan-settings-runtime.ts new file mode 100644 index 0000000..4671678 --- /dev/null +++ b/src/main/runtime/yomitan-settings-runtime.ts @@ -0,0 +1,13 @@ +import { createBuildOpenYomitanSettingsMainDepsHandler } from './app-runtime-main-deps'; +import { createOpenYomitanSettingsHandler } from './yomitan-settings-opener'; + +type OpenYomitanSettingsMainDeps = Parameters[0]; + +export function createYomitanSettingsRuntime(deps: OpenYomitanSettingsMainDeps) { + const openYomitanSettingsMainDeps = createBuildOpenYomitanSettingsMainDepsHandler(deps)(); + const openYomitanSettings = createOpenYomitanSettingsHandler(openYomitanSettingsMainDeps); + + return { + openYomitanSettings, + }; +}