fix(tools): verify pinned archives before atomic install

Pin Streamlink and FFmpeg archives to verified manifests, stage replacements before promotion, and expose managed tool status with repair and reset controls. Keep updater checks exclusive until their underlying operation settles and restore default electron-builder certificate environment support.
This commit is contained in:
Sucukdeluxe
2026-08-12 00:59:45 +02:00
parent 421da7be77
commit d32f42746d
17 changed files with 822 additions and 89 deletions
+46
View File
@@ -344,6 +344,52 @@ async function runPreflight(autoFix = false): Promise<void> {
}
}
function getManagedToolStateLabel(state: ManagedToolStatus['state']): string {
const labels: Record<ManagedToolStatus['state'], string> = {
missing: UI_TEXT.static.managedToolsMissing,
installing: UI_TEXT.static.managedToolsInstalling,
verified: UI_TEXT.static.managedToolsVerified,
unverified: UI_TEXT.static.managedToolsUnverified,
corrupt: UI_TEXT.static.managedToolsCorrupt
};
return labels[state];
}
function renderManagedToolStatus(statuses: ManagedToolStatuses): void {
const lines = [statuses.streamlink, statuses.ffmpeg].map((status) => {
const verification = status.verified ? UI_TEXT.static.managedToolsVerified : UI_TEXT.static.managedToolsUnverified;
return `${status.id} ${status.version}: ${getManagedToolStateLabel(status.state)} · ${verification}`;
});
byId('managedToolStatus').textContent = lines.join('\n');
}
async function refreshManagedToolStatus(): Promise<void> {
const statuses = await window.api.getManagedToolStatus();
if (statuses) renderManagedToolStatus(statuses);
}
async function repairManagedTools(): Promise<void> {
const buttons = [
byId<HTMLButtonElement>('btnRefreshManagedTools'),
byId<HTMLButtonElement>('btnRepairManagedTools'),
byId<HTMLButtonElement>('btnResetManagedTools')
];
for (const button of buttons) button.disabled = true;
byId('managedToolStatus').textContent = UI_TEXT.static.managedToolsRepairing;
try {
const result = await window.api.repairManagedTools();
if (result) renderManagedToolStatus(result.statuses);
} finally {
for (const button of buttons) button.disabled = false;
}
}
async function resetManagedTools(): Promise<void> {
if (!confirm(UI_TEXT.static.managedToolsResetConfirm)) return;
const result = await window.api.resetManagedTools();
if (result) renderManagedToolStatus(result.statuses);
}
async function runCleanupDryRun(): Promise<void> {
await runCleanupOnce(true);
}