2026-04-15 01:32:59 +08:00
import { redactSensitiveUrl } from '@/lib/desktopHosts' ;
export type RecoveryVariant =
| 'local-unavailable'
| 'remote-unreachable'
2026-06-02 00:43:05 +03:00
| 'remote-incompatible'
2026-04-15 01:32:59 +08:00
| 'remote-wrong-service'
| 'remote-missing'
| 'missing-default-host' ;
export type DesktopRecoveryConfig = {
title : string ;
description : string ;
2026-04-26 14:03:39 +03:00
titleKey : string ;
descriptionKey : string ;
descriptionParams? : Record < string , string >;
2026-04-15 01:32:59 +08:00
iconKey : 'local' | 'remote' ;
showRetry : boolean ;
retryLabel? : string ;
2026-04-26 14:03:39 +03:00
retryLabelKey? : string ;
2026-04-15 01:32:59 +08:00
showUseLocal : boolean ;
showUseRemote : boolean ;
/** Label for the "use local" primary action button */
useLocalLabel : string ;
2026-04-26 14:03:39 +03:00
useLocalLabelKey : string ;
2026-04-15 01:32:59 +08:00
/** Label for the "use remote" primary action button */
useRemoteLabel : string ;
2026-04-26 14:03:39 +03:00
useRemoteLabelKey : string ;
2026-04-15 01:32:59 +08:00
};
function formatHostDisplay ( hostLabel? : string , hostUrl? : string ) : string | undefined {
if ( hostLabel ? . trim ()) return redactSensitiveUrl ( hostLabel . trim ());
if ( hostUrl ) return redactSensitiveUrl ( hostUrl );
return undefined ;
}
export function getDesktopRecoveryConfig (
variant : RecoveryVariant ,
hostLabel? : string ,
hostUrl? : string ,
) : DesktopRecoveryConfig {
switch ( variant ) {
case 'local-unavailable' :
return {
title : 'Local OpenCode Unavailable' ,
2026-04-26 14:03:39 +03:00
description : 'OpenCode CLI could not be started or is not installed. Install OpenCode or connect to a remote server instead.' ,
titleKey : 'onboarding.desktopRecovery.localUnavailable.title' ,
descriptionKey : 'onboarding.desktopRecovery.localUnavailable.description' ,
2026-04-15 01:32:59 +08:00
iconKey : 'local' ,
showRetry : true ,
retryLabel : 'Retry Local' ,
2026-04-26 14:03:39 +03:00
retryLabelKey : 'onboarding.desktopRecovery.localUnavailable.retry' ,
2026-04-15 01:32:59 +08:00
showUseLocal : true ,
showUseRemote : true ,
useLocalLabel : 'Set Up Local' ,
2026-04-26 14:03:39 +03:00
useLocalLabelKey : 'onboarding.desktopRecovery.localUnavailable.useLocal' ,
2026-04-15 01:32:59 +08:00
useRemoteLabel : 'Use Remote' ,
2026-04-26 14:03:39 +03:00
useRemoteLabelKey : 'onboarding.desktopRecovery.common.useRemote' ,
2026-04-15 01:32:59 +08:00
};
case 'remote-missing' :
return {
title : 'No Default Connection' ,
description : 'Your saved default connection could not be found. Choose how you want to connect.' ,
2026-04-26 14:03:39 +03:00
titleKey : 'onboarding.desktopRecovery.noDefaultConnection.title' ,
descriptionKey : 'onboarding.desktopRecovery.noDefaultConnection.description' ,
2026-04-15 01:32:59 +08:00
iconKey : 'local' ,
showRetry : false ,
showUseLocal : true ,
showUseRemote : true ,
useLocalLabel : 'Use Local' ,
2026-04-26 14:03:39 +03:00
useLocalLabelKey : 'onboarding.desktopRecovery.common.useLocal' ,
2026-04-15 01:32:59 +08:00
useRemoteLabel : 'Use Remote' ,
2026-04-26 14:03:39 +03:00
useRemoteLabelKey : 'onboarding.desktopRecovery.common.useRemote' ,
2026-04-15 01:32:59 +08:00
};
case 'remote-unreachable' : {
const host = formatHostDisplay ( hostLabel , hostUrl );
return {
title : 'Remote Server Unreachable' ,
description : `Could not connect to " ${ host || 'the remote server' } ". Check your network connection and verify the server address.` ,
2026-04-26 14:03:39 +03:00
titleKey : 'onboarding.desktopRecovery.remoteUnreachable.title' ,
descriptionKey : 'onboarding.desktopRecovery.remoteUnreachable.description' ,
descriptionParams : host ? { host } : undefined ,
2026-04-15 01:32:59 +08:00
iconKey : 'remote' ,
showRetry : true ,
retryLabel : 'Retry Connection' ,
2026-04-26 14:03:39 +03:00
retryLabelKey : 'onboarding.desktopRecovery.remoteUnreachable.retry' ,
2026-04-15 01:32:59 +08:00
showUseLocal : true ,
showUseRemote : true ,
useLocalLabel : 'Use Local' ,
2026-04-26 14:03:39 +03:00
useLocalLabelKey : 'onboarding.desktopRecovery.common.useLocal' ,
2026-04-15 01:32:59 +08:00
useRemoteLabel : 'Use Remote' ,
2026-04-26 14:03:39 +03:00
useRemoteLabelKey : 'onboarding.desktopRecovery.common.useRemote' ,
2026-04-15 01:32:59 +08:00
};
}
case 'remote-wrong-service' : {
const host = formatHostDisplay ( hostLabel , hostUrl );
return {
title : 'Incompatible Server' ,
description : `The server at " ${ host || 'unknown' } " is not running OpenChamber. Verify the address points to an OpenChamber server.` ,
2026-04-26 14:03:39 +03:00
titleKey : 'onboarding.desktopRecovery.incompatibleServer.title' ,
descriptionKey : 'onboarding.desktopRecovery.incompatibleServer.description' ,
descriptionParams : host ? { host } : undefined ,
2026-04-15 01:32:59 +08:00
iconKey : 'remote' ,
showRetry : false ,
showUseLocal : true ,
showUseRemote : true ,
useLocalLabel : 'Use Local' ,
2026-04-26 14:03:39 +03:00
useLocalLabelKey : 'onboarding.desktopRecovery.common.useLocal' ,
2026-06-02 00:43:05 +03:00
useRemoteLabel : 'Use Remote' ,
useRemoteLabelKey : 'onboarding.desktopRecovery.common.useRemote' ,
};
}
case 'remote-incompatible' : {
const host = formatHostDisplay ( hostLabel , hostUrl );
return {
title : 'Server Update Required' ,
description : `The OpenChamber server at " ${ host || 'unknown' } " is not compatible with this app version. Update OpenChamber on the server, then try again.` ,
titleKey : 'onboarding.desktopRecovery.remoteIncompatible.title' ,
descriptionKey : 'onboarding.desktopRecovery.remoteIncompatible.description' ,
descriptionParams : host ? { host } : undefined ,
iconKey : 'remote' ,
showRetry : true ,
retryLabel : 'Retry Connection' ,
retryLabelKey : 'onboarding.desktopRecovery.remoteUnreachable.retry' ,
showUseLocal : true ,
showUseRemote : true ,
useLocalLabel : 'Use Local' ,
useLocalLabelKey : 'onboarding.desktopRecovery.common.useLocal' ,
2026-04-15 01:32:59 +08:00
useRemoteLabel : 'Use Remote' ,
2026-04-26 14:03:39 +03:00
useRemoteLabelKey : 'onboarding.desktopRecovery.common.useRemote' ,
2026-04-15 01:32:59 +08:00
};
}
case 'missing-default-host' :
return {
title : 'No Default Connection' ,
description : 'Your saved default connection could not be found. Choose how you want to connect.' ,
2026-04-26 14:03:39 +03:00
titleKey : 'onboarding.desktopRecovery.noDefaultConnection.title' ,
descriptionKey : 'onboarding.desktopRecovery.noDefaultConnection.description' ,
2026-04-15 01:32:59 +08:00
iconKey : 'local' ,
showRetry : false ,
showUseLocal : true ,
showUseRemote : true ,
useLocalLabel : 'Use Local' ,
2026-04-26 14:03:39 +03:00
useLocalLabelKey : 'onboarding.desktopRecovery.common.useLocal' ,
2026-04-15 01:32:59 +08:00
useRemoteLabel : 'Use Remote' ,
2026-04-26 14:03:39 +03:00
useRemoteLabelKey : 'onboarding.desktopRecovery.common.useRemote' ,
2026-04-15 01:32:59 +08:00
};
default : {
// TypeScript exhaustive check - this should never be reached
const exhaustive : never = variant ;
throw new Error ( `Unknown recovery variant: ${ exhaustive } ` );
}
}
}