fix(logging): apply cli log level on second-instance commands

This commit is contained in:
2026-02-28 20:07:45 -08:00
parent 55c577e911
commit 4309e0dec3
8 changed files with 54 additions and 3 deletions

View File

@@ -220,6 +220,18 @@ test('handleCliCommand processes --start for second-instance when overlay runtim
); );
}); });
test('handleCliCommand applies cli log level for second-instance commands', () => {
const { deps, calls } = createDeps({
setLogLevel: (level) => {
calls.push(`setLogLevel:${level}`);
},
});
handleCliCommand(makeArgs({ start: true, logLevel: 'debug' }), 'second-instance', deps);
assert.ok(calls.includes('setLogLevel:debug'));
});
test('handleCliCommand runs texthooker flow with browser open', () => { test('handleCliCommand runs texthooker flow with browser open', () => {
const { deps, calls } = createDeps(); const { deps, calls } = createDeps();
const args = makeArgs({ texthooker: true }); const args = makeArgs({ texthooker: true });

View File

@@ -1,6 +1,7 @@
import { CliArgs, CliCommandSource, commandNeedsOverlayRuntime } from '../../cli/args'; import { CliArgs, CliCommandSource, commandNeedsOverlayRuntime } from '../../cli/args';
export interface CliCommandServiceDeps { export interface CliCommandServiceDeps {
setLogLevel?: (level: NonNullable<CliArgs['logLevel']>) => void;
getMpvSocketPath: () => string; getMpvSocketPath: () => string;
setMpvSocketPath: (socketPath: string) => void; setMpvSocketPath: (socketPath: string) => void;
setMpvClientSocketPath: (socketPath: string) => void; setMpvClientSocketPath: (socketPath: string) => void;
@@ -127,6 +128,7 @@ interface AppCliRuntime {
} }
export interface CliCommandDepsRuntimeOptions { export interface CliCommandDepsRuntimeOptions {
setLogLevel?: (level: NonNullable<CliArgs['logLevel']>) => void;
mpv: MpvCliRuntime; mpv: MpvCliRuntime;
texthooker: TexthookerCliRuntime; texthooker: TexthookerCliRuntime;
overlay: OverlayCliRuntime; overlay: OverlayCliRuntime;
@@ -149,6 +151,7 @@ export function createCliCommandDepsRuntime(
options: CliCommandDepsRuntimeOptions, options: CliCommandDepsRuntimeOptions,
): CliCommandServiceDeps { ): CliCommandServiceDeps {
return { return {
setLogLevel: options.setLogLevel,
getMpvSocketPath: options.mpv.getSocketPath, getMpvSocketPath: options.mpv.getSocketPath,
setMpvSocketPath: options.mpv.setSocketPath, setMpvSocketPath: options.mpv.setSocketPath,
setMpvClientSocketPath: (socketPath) => { setMpvClientSocketPath: (socketPath) => {
@@ -232,6 +235,10 @@ export function handleCliCommand(
source: CliCommandSource = 'initial', source: CliCommandSource = 'initial',
deps: CliCommandServiceDeps, deps: CliCommandServiceDeps,
): void { ): void {
if (args.logLevel) {
deps.setLogLevel?.(args.logLevel);
}
const hasNonStartAction = const hasNonStartAction =
args.stop || args.stop ||
args.toggle || args.toggle ||

View File

@@ -1255,6 +1255,17 @@ function getResolvedConfig() {
return configService.getConfig(); return configService.getConfig();
} }
function getRuntimeBooleanOption(
id:
| 'subtitle.annotation.nPlusOne'
| 'subtitle.annotation.jlpt'
| 'subtitle.annotation.frequency',
fallback: boolean,
): boolean {
const value = appState.runtimeOptionsManager?.getOptionValue(id);
return typeof value === 'boolean' ? value : fallback;
}
const { const {
getResolvedJellyfinConfig, getResolvedJellyfinConfig,
getJellyfinClientInfo, getJellyfinClientInfo,
@@ -2025,7 +2036,9 @@ const { reloadConfig: reloadConfigHandler, appReadyRuntimeRunner } = composeAppR
appState.ankiIntegration.applyRuntimeConfigPatch(patch); appState.ankiIntegration.applyRuntimeConfigPatch(patch);
} }
}, },
getSubtitleStyleConfig: () => configService.getConfig().subtitleStyle,
onOptionsChanged: () => { onOptionsChanged: () => {
subtitleProcessingController.invalidateTokenizationCache();
broadcastRuntimeOptionsChanged(); broadcastRuntimeOptionsChanged();
refreshOverlayShortcuts(); refreshOverlayShortcuts();
}, },
@@ -2296,13 +2309,21 @@ const {
getKnownWordMatchMode: () => getKnownWordMatchMode: () =>
appState.ankiIntegration?.getKnownWordMatchMode() ?? appState.ankiIntegration?.getKnownWordMatchMode() ??
getResolvedConfig().ankiConnect.nPlusOne.matchMode, getResolvedConfig().ankiConnect.nPlusOne.matchMode,
getNPlusOneEnabled: () => getResolvedConfig().ankiConnect.nPlusOne.highlightEnabled, getNPlusOneEnabled: () =>
getRuntimeBooleanOption(
'subtitle.annotation.nPlusOne',
getResolvedConfig().ankiConnect.nPlusOne.highlightEnabled,
),
getMinSentenceWordsForNPlusOne: () => getMinSentenceWordsForNPlusOne: () =>
getResolvedConfig().ankiConnect.nPlusOne.minSentenceWords, getResolvedConfig().ankiConnect.nPlusOne.minSentenceWords,
getJlptLevel: (text) => appState.jlptLevelLookup(text), getJlptLevel: (text) => appState.jlptLevelLookup(text),
getJlptEnabled: () => getResolvedConfig().subtitleStyle.enableJlpt, getJlptEnabled: () =>
getRuntimeBooleanOption('subtitle.annotation.jlpt', getResolvedConfig().subtitleStyle.enableJlpt),
getFrequencyDictionaryEnabled: () => getFrequencyDictionaryEnabled: () =>
getRuntimeBooleanOption(
'subtitle.annotation.frequency',
getResolvedConfig().subtitleStyle.frequencyDictionary.enabled, getResolvedConfig().subtitleStyle.frequencyDictionary.enabled,
),
getFrequencyDictionaryMatchMode: () => getFrequencyDictionaryMatchMode: () =>
getResolvedConfig().subtitleStyle.frequencyDictionary.matchMode, getResolvedConfig().subtitleStyle.frequencyDictionary.matchMode,
getFrequencyRank: (text) => appState.frequencyRankLookup(text), getFrequencyRank: (text) => appState.frequencyRankLookup(text),
@@ -2920,6 +2941,7 @@ const {
}); });
const createCliCommandContextHandler = createCliCommandContextFactory({ const createCliCommandContextHandler = createCliCommandContextFactory({
appState, appState,
setLogLevel: (level) => setLogLevel(level, 'cli'),
texthookerService, texthookerService,
getResolvedConfig: () => getResolvedConfig(), getResolvedConfig: () => getResolvedConfig(),
openExternal: (url: string) => shell.openExternal(url), openExternal: (url: string) => shell.openExternal(url),

View File

@@ -6,6 +6,7 @@ import {
} from './dependencies'; } from './dependencies';
export interface CliCommandRuntimeServiceContext { export interface CliCommandRuntimeServiceContext {
setLogLevel?: (level: NonNullable<CliArgs['logLevel']>) => void;
getSocketPath: () => string; getSocketPath: () => string;
setSocketPath: (socketPath: string) => void; setSocketPath: (socketPath: string) => void;
getClient: CliCommandRuntimeServiceDepsParams['mpv']['getClient']; getClient: CliCommandRuntimeServiceDepsParams['mpv']['getClient'];
@@ -55,6 +56,7 @@ function createCliCommandDepsFromContext(
context: CliCommandRuntimeServiceContext & CliCommandRuntimeServiceContextHandlers, context: CliCommandRuntimeServiceContext & CliCommandRuntimeServiceContextHandlers,
): CliCommandRuntimeServiceDepsParams { ): CliCommandRuntimeServiceDepsParams {
return { return {
setLogLevel: context.setLogLevel,
mpv: { mpv: {
getSocketPath: context.getSocketPath, getSocketPath: context.getSocketPath,
setSocketPath: context.setSocketPath, setSocketPath: context.setSocketPath,

View File

@@ -112,6 +112,7 @@ export interface AnkiJimakuIpcRuntimeServiceDepsParams {
} }
export interface CliCommandRuntimeServiceDepsParams { export interface CliCommandRuntimeServiceDepsParams {
setLogLevel?: CliCommandDepsRuntimeOptions['setLogLevel'];
mpv: { mpv: {
getSocketPath: CliCommandDepsRuntimeOptions['mpv']['getSocketPath']; getSocketPath: CliCommandDepsRuntimeOptions['mpv']['getSocketPath'];
setSocketPath: CliCommandDepsRuntimeOptions['mpv']['setSocketPath']; setSocketPath: CliCommandDepsRuntimeOptions['mpv']['setSocketPath'];
@@ -254,6 +255,7 @@ export function createCliCommandRuntimeServiceDeps(
params: CliCommandRuntimeServiceDepsParams, params: CliCommandRuntimeServiceDepsParams,
): CliCommandDepsRuntimeOptions { ): CliCommandDepsRuntimeOptions {
return { return {
setLogLevel: params.setLogLevel,
mpv: { mpv: {
getSocketPath: params.mpv.getSocketPath, getSocketPath: params.mpv.getSocketPath,
setSocketPath: params.mpv.setSocketPath, setSocketPath: params.mpv.setSocketPath,

View File

@@ -2,6 +2,7 @@ import type { CliArgs } from '../../cli/args';
import type { CliCommandContextFactoryDeps } from './cli-command-context'; import type { CliCommandContextFactoryDeps } from './cli-command-context';
export function createBuildCliCommandContextDepsHandler(deps: { export function createBuildCliCommandContextDepsHandler(deps: {
setLogLevel?: (level: NonNullable<CliArgs['logLevel']>) => void;
getSocketPath: () => string; getSocketPath: () => string;
setSocketPath: (socketPath: string) => void; setSocketPath: (socketPath: string) => void;
getMpvClient: CliCommandContextFactoryDeps['getMpvClient']; getMpvClient: CliCommandContextFactoryDeps['getMpvClient'];
@@ -45,6 +46,7 @@ export function createBuildCliCommandContextDepsHandler(deps: {
logError: (message: string, err: unknown) => void; logError: (message: string, err: unknown) => void;
}) { }) {
return (): CliCommandContextFactoryDeps => ({ return (): CliCommandContextFactoryDeps => ({
setLogLevel: deps.setLogLevel,
getSocketPath: deps.getSocketPath, getSocketPath: deps.getSocketPath,
setSocketPath: deps.setSocketPath, setSocketPath: deps.setSocketPath,
getMpvClient: deps.getMpvClient, getMpvClient: deps.getMpvClient,

View File

@@ -10,6 +10,7 @@ type CliCommandContextMainState = {
export function createBuildCliCommandContextMainDepsHandler(deps: { export function createBuildCliCommandContextMainDepsHandler(deps: {
appState: CliCommandContextMainState; appState: CliCommandContextMainState;
setLogLevel?: (level: NonNullable<CliArgs['logLevel']>) => void;
texthookerService: CliCommandContextFactoryDeps['texthookerService']; texthookerService: CliCommandContextFactoryDeps['texthookerService'];
getResolvedConfig: () => { texthooker?: { openBrowser?: boolean } }; getResolvedConfig: () => { texthooker?: { openBrowser?: boolean } };
openExternal: (url: string) => Promise<unknown>; openExternal: (url: string) => Promise<unknown>;
@@ -51,6 +52,7 @@ export function createBuildCliCommandContextMainDepsHandler(deps: {
logError: (message: string, err: unknown) => void; logError: (message: string, err: unknown) => void;
}) { }) {
return (): CliCommandContextFactoryDeps => ({ return (): CliCommandContextFactoryDeps => ({
setLogLevel: deps.setLogLevel,
getSocketPath: () => deps.appState.mpvSocketPath, getSocketPath: () => deps.appState.mpvSocketPath,
setSocketPath: (socketPath: string) => { setSocketPath: (socketPath: string) => {
deps.appState.mpvSocketPath = socketPath; deps.appState.mpvSocketPath = socketPath;

View File

@@ -7,6 +7,7 @@ import type {
type MpvClientLike = CliCommandRuntimeServiceContext['getClient'] extends () => infer T ? T : never; type MpvClientLike = CliCommandRuntimeServiceContext['getClient'] extends () => infer T ? T : never;
export type CliCommandContextFactoryDeps = { export type CliCommandContextFactoryDeps = {
setLogLevel?: (level: NonNullable<CliArgs['logLevel']>) => void;
getSocketPath: () => string; getSocketPath: () => string;
setSocketPath: (socketPath: string) => void; setSocketPath: (socketPath: string) => void;
getMpvClient: () => MpvClientLike; getMpvClient: () => MpvClientLike;
@@ -54,6 +55,7 @@ export function createCliCommandContext(
deps: CliCommandContextFactoryDeps, deps: CliCommandContextFactoryDeps,
): CliCommandRuntimeServiceContext & CliCommandRuntimeServiceContextHandlers { ): CliCommandRuntimeServiceContext & CliCommandRuntimeServiceContextHandlers {
return { return {
setLogLevel: deps.setLogLevel,
getSocketPath: deps.getSocketPath, getSocketPath: deps.getSocketPath,
setSocketPath: deps.setSocketPath, setSocketPath: deps.setSocketPath,
getClient: deps.getMpvClient, getClient: deps.getMpvClient,