fix(launcher): address code review findings in stats sync

- merge-catalog: stop dropping anilist_id on every new anime insert
  (bun:sqlite .get() returns null, so the old !== undefined guard always
  fired); the guard was dead anyway since a colliding id is caught earlier
- sync-command: throw instead of fail() inside runHostSync so the finally
  block runs and temp dirs holding snapshot data are cleaned up on failure
- ssh: shell-quote the user-supplied --remote-cmd in the probe, and reject
  option-like (-prefixed) SSH hosts that ssh/scp would parse as flags
- sync-db: close the remote handle if opening the local DB throws
- sync-shared: treat EPERM from process.kill(pid, 0) as alive, not dead
- cli-parser: trim the sync host before the mode-exclusivity check
- tests: cover anilist_id preservation, anilist-based anime matching, and
  the SSH host/shell-quote guards
This commit is contained in:
2026-07-08 23:51:46 -07:00
parent be31f96f02
commit 58d54311d8
8 changed files with 131 additions and 21 deletions
+3 -2
View File
@@ -316,7 +316,8 @@ export function parseCliPrograms(
.option('--remote-cmd <cmd>', 'subminer command to run on the remote host')
.option('-f, --force', 'Skip the running-app safety check')
.option('--log-level <level>', 'Log level')
.action((host: string | undefined, options: Record<string, unknown>) => {
.action((rawHost: string | undefined, options: Record<string, unknown>) => {
const host = typeof rawHost === 'string' ? rawHost.trim() : '';
const snapshot = typeof options.snapshot === 'string' ? options.snapshot.trim() : '';
const merge = typeof options.merge === 'string' ? options.merge.trim() : '';
const modes = [Boolean(host), Boolean(snapshot), Boolean(merge)].filter(Boolean).length;
@@ -327,7 +328,7 @@ export function parseCliPrograms(
throw new Error('Sync host, --snapshot, and --merge cannot be combined.');
}
syncTriggered = true;
syncHost = host?.trim() || null;
syncHost = host || null;
syncSnapshotPath = snapshot || null;
syncMergePath = merge || null;
syncRemoteCmd = typeof options.remoteCmd === 'string' ? options.remoteCmd.trim() || null : null;