feat: add auto update support

This commit is contained in:
2026-05-15 01:47:56 -07:00
parent d1ec678d7a
commit 094bcce0dc
101 changed files with 4978 additions and 163 deletions
+24
View File
@@ -51,6 +51,24 @@ test('parseArgs ignores missing value after --log-level', () => {
assert.equal(args.start, true);
});
test('parseArgs captures update command and internal launcher paths', () => {
const args = parseArgs([
'--update',
'--update-launcher-path',
'/home/kyle/.local/bin/subminer',
'--update-response-path',
'/tmp/subminer-update-response.json',
]);
assert.equal(args.update, true);
assert.equal(args.updateLauncherPath, '/home/kyle/.local/bin/subminer');
assert.equal(args.updateResponsePath, '/tmp/subminer-update-response.json');
assert.equal(hasExplicitCommand(args), true);
assert.equal(shouldStartApp(args), true);
assert.equal(commandNeedsOverlayRuntime(args), false);
assert.equal(shouldRunSettingsOnlyStartup(args), false);
});
test('parseArgs captures launch-mpv targets and keeps it out of app startup', () => {
const args = parseArgs(['--launch-mpv', 'C:\\a.mkv', 'C:\\b.mkv']);
assert.equal(args.launchMpv, true);
@@ -182,6 +200,12 @@ test('hasExplicitCommand and shouldStartApp preserve command intent', () => {
assert.equal(shouldStartApp(refreshKnownWords), true);
assert.equal(isHeadlessInitialCommand(refreshKnownWords), true);
const update = parseArgs(['--update']);
assert.equal(update.update, true);
assert.equal(hasExplicitCommand(update), true);
assert.equal(shouldStartApp(update), true);
assert.equal(isHeadlessInitialCommand(update), true);
const settings = parseArgs(['--settings']);
assert.equal(settings.settings, true);
assert.equal(hasExplicitCommand(settings), true);
+26 -3
View File
@@ -73,6 +73,9 @@ export interface CliArgs {
texthooker: boolean;
texthookerOpenBrowser: boolean;
help: boolean;
update?: boolean;
updateLauncherPath?: string;
updateResponsePath?: string;
autoStartOverlay: boolean;
generateConfig: boolean;
configPath?: string;
@@ -167,6 +170,9 @@ export function parseArgs(argv: string[]): CliArgs {
texthooker: false,
texthookerOpenBrowser: false,
help: false,
update: false,
updateLauncherPath: undefined,
updateResponsePath: undefined,
autoStartOverlay: false,
generateConfig: false,
backupOverwrite: false,
@@ -330,7 +336,20 @@ export function parseArgs(argv: string[]): CliArgs {
else if (arg === '--jellyfin-preview-auth') args.jellyfinPreviewAuth = true;
else if (arg === '--texthooker') args.texthooker = true;
else if (arg === '--open-browser') args.texthookerOpenBrowser = true;
else if (arg === '--auto-start-overlay') args.autoStartOverlay = true;
else if (arg === '--update') args.update = true;
else if (arg.startsWith('--update-launcher-path=')) {
const value = arg.split('=', 2)[1];
if (value) args.updateLauncherPath = value;
} else if (arg === '--update-launcher-path') {
const value = readValue(argv[i + 1]);
if (value) args.updateLauncherPath = value;
} else if (arg.startsWith('--update-response-path=')) {
const value = arg.split('=', 2)[1];
if (value) args.updateResponsePath = value;
} else if (arg === '--update-response-path') {
const value = readValue(argv[i + 1]);
if (value) args.updateResponsePath = value;
} else if (arg === '--auto-start-overlay') args.autoStartOverlay = true;
else if (arg === '--generate-config') args.generateConfig = true;
else if (arg === '--backup-overwrite') args.backupOverwrite = true;
else if (arg === '--help') args.help = true;
@@ -517,13 +536,14 @@ export function hasExplicitCommand(args: CliArgs): boolean {
args.jellyfinRemoteAnnounce ||
args.jellyfinPreviewAuth ||
args.texthooker ||
args.update ||
args.generateConfig ||
args.help
);
}
export function isHeadlessInitialCommand(args: CliArgs): boolean {
return args.refreshKnownWords;
return args.refreshKnownWords || args.update === true;
}
export function isStandaloneTexthookerCommand(args: CliArgs): boolean {
@@ -587,6 +607,7 @@ export function isStandaloneTexthookerCommand(args: CliArgs): boolean {
!args.jellyfinPlay &&
!args.jellyfinRemoteAnnounce &&
!args.jellyfinPreviewAuth &&
!args.update &&
!args.help &&
!args.autoStartOverlay &&
!args.generateConfig
@@ -638,7 +659,8 @@ export function shouldStartApp(args: CliArgs): boolean {
args.stats ||
args.jellyfin ||
args.jellyfinPlay ||
args.texthooker
args.texthooker ||
args.update
) {
if (args.launchMpv) {
return false;
@@ -708,6 +730,7 @@ export function shouldRunSettingsOnlyStartup(args: CliArgs): boolean {
!args.jellyfinRemoteAnnounce &&
!args.jellyfinPreviewAuth &&
!args.texthooker &&
!args.update &&
!args.help &&
!args.autoStartOverlay &&
!args.generateConfig &&
+1
View File
@@ -17,6 +17,7 @@ ${B}Session${R}
--stats Open the stats dashboard in your browser
--texthooker Start texthooker server only ${D}(no overlay)${R}
--open-browser Open texthooker in your default browser
--update Check for updates
${B}Overlay${R}
--toggle-visible-overlay Toggle subtitle overlay