refactor: remove legacy youtube launcher mode plumbing

This commit is contained in:
2026-03-23 19:18:04 -07:00
parent d9489c0033
commit e487998c40
20 changed files with 18 additions and 210 deletions

View File

@@ -10,7 +10,6 @@ test('launcher root help lists subcommands', () => {
assert.match(output, /Commands:/);
assert.match(output, /jellyfin\|jf/);
assert.match(output, /yt\|youtube/);
assert.match(output, /doctor/);
assert.match(output, /config/);
assert.match(output, /mpv/);

View File

@@ -111,7 +111,6 @@ export function createDefaultArgs(launcherConfig: LauncherYoutubeSubgenConfig):
youtubeSubgenAudioFormat: process.env.SUBMINER_YT_SUBGEN_AUDIO_FORMAT || 'm4a',
youtubeSubgenKeepTemp: process.env.SUBMINER_YT_SUBGEN_KEEP_TEMP === '1',
youtubeFixWithAi: launcherConfig.fixWithAi === true,
youtubeMode: undefined,
jimakuApiKey: process.env.SUBMINER_JIMAKU_API_KEY || '',
jimakuApiKeyCommand: process.env.SUBMINER_JIMAKU_API_KEY_COMMAND || '',
jimakuApiBaseUrl: process.env.SUBMINER_JIMAKU_API_BASE_URL || DEFAULT_JIMAKU_API_BASE_URL,
@@ -250,29 +249,6 @@ export function applyInvocationsToArgs(parsed: Args, invocations: CliInvocations
parsed.jellyfinLogout = Boolean(modeFlags.logout);
}
if (invocations.ytInvocation) {
if (invocations.ytInvocation.mode) {
parsed.youtubeMode = invocations.ytInvocation.mode;
}
if (invocations.ytInvocation.logLevel)
parsed.logLevel = parseLogLevel(invocations.ytInvocation.logLevel);
if (invocations.ytInvocation.outDir)
parsed.youtubeSubgenOutDir = invocations.ytInvocation.outDir;
if (invocations.ytInvocation.keepTemp) parsed.youtubeSubgenKeepTemp = true;
if (invocations.ytInvocation.whisperBin)
parsed.whisperBin = invocations.ytInvocation.whisperBin;
if (invocations.ytInvocation.whisperModel)
parsed.whisperModel = invocations.ytInvocation.whisperModel;
if (invocations.ytInvocation.whisperVadModel)
parsed.whisperVadModel = invocations.ytInvocation.whisperVadModel;
if (invocations.ytInvocation.whisperThreads)
parsed.whisperThreads = invocations.ytInvocation.whisperThreads;
if (invocations.ytInvocation.ytSubgenAudioFormat) {
parsed.youtubeSubgenAudioFormat = invocations.ytInvocation.ytSubgenAudioFormat;
}
if (invocations.ytInvocation.target) ensureTarget(invocations.ytInvocation.target, parsed);
}
if (invocations.dictionaryLogLevel) {
parsed.logLevel = parseLogLevel(invocations.dictionaryLogLevel);
}

View File

@@ -14,19 +14,6 @@ export interface JellyfinInvocation {
logLevel?: string;
}
export interface YtInvocation {
target?: string;
mode?: 'download' | 'generate';
outDir?: string;
keepTemp?: boolean;
whisperBin?: string;
whisperModel?: string;
whisperVadModel?: string;
whisperThreads?: number;
ytSubgenAudioFormat?: string;
logLevel?: string;
}
export interface CommandActionInvocation {
action: string;
logLevel?: string;
@@ -34,7 +21,6 @@ export interface CommandActionInvocation {
export interface CliInvocations {
jellyfinInvocation: JellyfinInvocation | null;
ytInvocation: YtInvocation | null;
configInvocation: CommandActionInvocation | null;
mpvInvocation: CommandActionInvocation | null;
appInvocation: { appArgs: string[] } | null;
@@ -90,8 +76,6 @@ function getTopLevelCommand(argv: string[]): { name: string; index: number } | n
const commandNames = new Set([
'jellyfin',
'jf',
'yt',
'youtube',
'doctor',
'config',
'mpv',
@@ -143,7 +127,6 @@ export function parseCliPrograms(
invocations: CliInvocations;
} {
let jellyfinInvocation: JellyfinInvocation | null = null;
let ytInvocation: YtInvocation | null = null;
let configInvocation: CommandActionInvocation | null = null;
let mpvInvocation: CommandActionInvocation | null = null;
let appInvocation: { appArgs: string[] } | null = null;
@@ -218,43 +201,6 @@ export function parseCliPrograms(
};
});
commandProgram
.command('yt')
.alias('youtube')
.description('YouTube workflows')
.argument('[target]', 'YouTube URL or ytsearch: query')
.option('--mode <mode>', 'YouTube subtitle acquisition mode')
.option('-o, --out-dir <dir>', 'Subtitle output dir')
.option('--keep-temp', 'Keep temp files')
.option('--whisper-bin <path>', 'whisper.cpp CLI path')
.option('--whisper-model <path>', 'whisper model path')
.option('--whisper-vad-model <path>', 'whisper.cpp VAD model path')
.option('--whisper-threads <n>', 'whisper.cpp thread count')
.option('--yt-subgen-audio-format <format>', 'Audio extraction format')
.option('--log-level <level>', 'Log level')
.action((target: string | undefined, options: Record<string, unknown>) => {
ytInvocation = {
target,
mode:
typeof options.mode === 'string' && (options.mode === 'download' || options.mode === 'generate')
? options.mode
: undefined,
outDir: typeof options.outDir === 'string' ? options.outDir : undefined,
keepTemp: options.keepTemp === true,
whisperBin: typeof options.whisperBin === 'string' ? options.whisperBin : undefined,
whisperModel: typeof options.whisperModel === 'string' ? options.whisperModel : undefined,
whisperVadModel:
typeof options.whisperVadModel === 'string' ? options.whisperVadModel : undefined,
whisperThreads:
typeof options.whisperThreads === 'number' && Number.isFinite(options.whisperThreads)
? Math.floor(options.whisperThreads)
: undefined,
ytSubgenAudioFormat:
typeof options.ytSubgenAudioFormat === 'string' ? options.ytSubgenAudioFormat : undefined,
logLevel: typeof options.logLevel === 'string' ? options.logLevel : undefined,
};
});
commandProgram
.command('dictionary')
.alias('dict')
@@ -388,7 +334,6 @@ export function parseCliPrograms(
rootTarget: rootProgram.processedArgs[0],
invocations: {
jellyfinInvocation,
ytInvocation,
configInvocation,
mpvInvocation,
appInvocation,

View File

@@ -362,7 +362,7 @@ ${bunBinary} -e "const net=require('node:net'); const fs=require('node:fs'); con
});
});
test('launcher disables plugin startup pause gate for app-owned youtube flow', { timeout: 15000 }, () => {
test('launcher routes youtube urls through regular playback startup', { timeout: 15000 }, () => {
withTempDir((root) => {
const homeDir = path.join(root, 'home');
const xdgConfigHome = path.join(root, 'xdg');
@@ -430,13 +430,16 @@ ${bunBinary} -e "const net=require('node:net'); const fs=require('node:fs'); con
SUBMINER_TEST_MPV_ARGS: mpvArgsPath,
SUBMINER_TEST_CAPTURE: path.join(root, 'captured-args.txt'),
};
const result = runLauncher(['yt', 'https://www.youtube.com/watch?v=abc123'], env);
const result = runLauncher(['https://www.youtube.com/watch?v=abc123'], env);
assert.equal(result.status, 0, `stdout:\n${result.stdout}\nstderr:\n${result.stderr}`);
assert.match(
fs.readFileSync(mpvArgsPath, 'utf8'),
/--script-opts=.*subminer-auto_start_pause_until_ready=no/,
);
const forwardedArgs = fs
.readFileSync(mpvArgsPath, 'utf8')
.trim()
.split('\n')
.map((item) => item.trim())
.filter(Boolean);
assert.equal(forwardedArgs.includes('https://www.youtube.com/watch?v=abc123'), true);
});
});

View File

@@ -85,13 +85,6 @@ test('parseArgs maps mpv idle action', () => {
assert.equal(parsed.mpvStatus, false);
});
test('parseArgs captures youtube mode forwarding', () => {
const parsed = parseArgs(['youtube', 'https://example.com', '--mode', 'generate'], 'subminer', {});
assert.equal(parsed.target, 'https://example.com');
assert.equal(parsed.youtubeMode, 'generate');
});
test('parseArgs maps dictionary command and log-level override', () => {
const parsed = parseArgs(['dictionary', '.', '--log-level', 'debug'], 'subminer', {});