refactor: extract cli command runtime wiring

This commit is contained in:
2026-02-20 03:16:16 -08:00
parent 2b70b54faf
commit 2ffd503898
5 changed files with 76 additions and 14 deletions

View File

@@ -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-20T11:14:14Z` |
| `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-20T11:15:54Z` |
| `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` |

View File

@@ -9,6 +9,10 @@
## Current Work (newest first)
- [2026-02-20T11:15:54Z] progress: extracted CLI command composition from `src/main.ts` into `src/main/runtime/cli-command-runtime-handler.ts`; `main.ts` now creates `handleCliCommand` via one runtime factory (precheck + context + runtime dispatch wiring).
- [2026-02-20T11:15:54Z] progress: added `src/main/runtime/cli-command-runtime-handler.test.ts` to lock composed behavior around texthooker precheck, context creation, and `'initial'` source forwarding.
- [2026-02-20T11:15:54Z] test: `bun run build` pass (expected macOS helper Swift cache fallback) + focused suites pass for `cli-command-runtime-handler*`, `cli-command-prechecks*`, `cli-command-context-factory*`, `initial-args-runtime-handler*`, and `startup-runtime-handlers*` (7/7).
- [2026-02-20T11:15:54Z] scope: staging `src/main.ts`, new cli-command runtime handler module/test, and subagent bookkeeping only.
- [2026-02-20T11:14:14Z] progress: extracted startup/app-lifecycle composition from `src/main.ts` into `src/main/runtime/startup-runtime-handlers.ts`; rewired `main.ts` to inject `createAppLifecycleRuntimeRunner` + `createStartupBootstrapRuntimeDeps` into `createStartupRuntimeHandlers(...)`.
- [2026-02-20T11:14:14Z] progress: extracted initial-args composition from `src/main.ts` into `src/main/runtime/initial-args-runtime-handler.ts`; `main.ts` now constructs `handleInitialArgsRuntimeHandler` with one runtime factory call.
- [2026-02-20T11:14:14Z] progress: added parity tests `src/main/runtime/startup-runtime-handlers.test.ts` and `src/main/runtime/initial-args-runtime-handler.test.ts` (fixing previous `node:sqlite` test-import leak by removing direct runtime imports from startup handler module).

View File

@@ -243,9 +243,8 @@ import {
createBuildStartJellyfinRemoteSessionMainDepsHandler,
createBuildStopJellyfinRemoteSessionMainDepsHandler,
} from './main/runtime/jellyfin-remote-session-main-deps';
import { createCliCommandRuntimeHandler } from './main/runtime/cli-command-runtime-handler';
import { createInitialArgsRuntimeHandler } from './main/runtime/initial-args-runtime-handler';
import { createHandleTexthookerOnlyModeTransitionHandler } from './main/runtime/cli-command-prechecks';
import { createBuildHandleTexthookerOnlyModeTransitionMainDepsHandler } from './main/runtime/cli-command-prechecks-main-deps';
import {
createGetFieldGroupingResolverHandler,
createSetFieldGroupingResolverHandler,
@@ -2190,8 +2189,8 @@ runAndApplyStartupState();
void refreshAnilistClientSecretState({ force: true });
anilistStateRuntime.refreshRetryQueueState();
const handleTexthookerOnlyModeTransitionHandler = createHandleTexthookerOnlyModeTransitionHandler(
createBuildHandleTexthookerOnlyModeTransitionMainDepsHandler({
const handleCliCommand = createCliCommandRuntimeHandler({
handleTexthookerOnlyModeTransitionMainDeps: {
isTexthookerOnlyMode: () => appState.texthookerOnlyMode,
setTexthookerOnlyMode: (enabled) => {
appState.texthookerOnlyMode = enabled;
@@ -2199,15 +2198,11 @@ const handleTexthookerOnlyModeTransitionHandler = createHandleTexthookerOnlyMode
commandNeedsOverlayRuntime: (inputArgs) => commandNeedsOverlayRuntime(inputArgs),
startBackgroundWarmups: () => startBackgroundWarmups(),
logInfo: (message: string) => logger.info(message),
})(),
);
function handleCliCommand(args: CliArgs, source: CliCommandSource = 'initial'): void {
handleTexthookerOnlyModeTransitionHandler(args);
const cliContext = createCliCommandContextHandler();
handleCliCommandRuntimeServiceWithContext(args, source, cliContext);
}
},
createCliCommandContext: () => createCliCommandContextHandler(),
handleCliCommandRuntimeServiceWithContext: (args, source, cliContext) =>
handleCliCommandRuntimeServiceWithContext(args, source, cliContext),
});
const handleInitialArgsRuntimeHandler = createInitialArgsRuntimeHandler({
getInitialArgs: () => appState.initialArgs,

View File

@@ -0,0 +1,33 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { createCliCommandRuntimeHandler } from './cli-command-runtime-handler';
test('cli command runtime handler applies precheck and forwards command with context', () => {
const calls: string[] = [];
const handler = createCliCommandRuntimeHandler({
handleTexthookerOnlyModeTransitionMainDeps: {
isTexthookerOnlyMode: () => true,
setTexthookerOnlyMode: () => calls.push('set-mode'),
commandNeedsOverlayRuntime: () => true,
startBackgroundWarmups: () => calls.push('warmups'),
logInfo: (message) => calls.push(`log:${message}`),
},
createCliCommandContext: () => {
calls.push('context');
return { id: 'ctx' };
},
handleCliCommandRuntimeServiceWithContext: (_args, source, context) => {
calls.push(`cli:${source}:${context.id}`);
},
});
handler({ start: true } as never);
assert.deepEqual(calls, [
'set-mode',
'log:Disabling texthooker-only mode after overlay/start command.',
'warmups',
'context',
'cli:initial:ctx',
]);
});

View File

@@ -0,0 +1,30 @@
import type { CliArgs, CliCommandSource } from '../../cli/args';
import { createHandleTexthookerOnlyModeTransitionHandler } from './cli-command-prechecks';
import { createBuildHandleTexthookerOnlyModeTransitionMainDepsHandler } from './cli-command-prechecks-main-deps';
type HandleTexthookerOnlyModeTransitionMainDeps = Parameters<
typeof createBuildHandleTexthookerOnlyModeTransitionMainDepsHandler
>[0];
export function createCliCommandRuntimeHandler<TCliContext>(deps: {
handleTexthookerOnlyModeTransitionMainDeps: HandleTexthookerOnlyModeTransitionMainDeps;
createCliCommandContext: () => TCliContext;
handleCliCommandRuntimeServiceWithContext: (
args: CliArgs,
source: CliCommandSource,
cliContext: TCliContext,
) => void;
}) {
const handleTexthookerOnlyModeTransitionHandler =
createHandleTexthookerOnlyModeTransitionHandler(
createBuildHandleTexthookerOnlyModeTransitionMainDepsHandler(
deps.handleTexthookerOnlyModeTransitionMainDeps,
)(),
);
return (args: CliArgs, source: CliCommandSource = 'initial'): void => {
handleTexthookerOnlyModeTransitionHandler(args);
const cliContext = deps.createCliCommandContext();
deps.handleCliCommandRuntimeServiceWithContext(args, source, cliContext);
};
}