fix: improve OpenCode settings handling

Improves OpenCode CLI and shortcut settings flows
Updates runtime API and persistence handling
Adds coverage for settings helper behavior
This commit is contained in:
Bohdan Triapitsyn
2026-06-03 16:00:32 +03:00
parent 570ae9dbc8
commit 8e2c7549ca
9 changed files with 197 additions and 10 deletions
@@ -125,6 +125,10 @@ const issueDesktopClientToken = async (): Promise<string> => {
return typeof payload?.token === 'string' ? payload.token.trim() : '';
};
const shouldUseDesktopShellPasswordLogin = (): boolean => {
return isDesktopShell() && !isLocalDesktopRuntime();
};
const issueDesktopClientTokenViaShell = async (password: string, trustDevice: boolean): Promise<string> => {
if (!isDesktopShell() || typeof window === 'undefined') {
return '';
@@ -220,7 +224,7 @@ const LoadingScreen: React.FC = () => (
</div>
);
const ErrorScreen: React.FC<ErrorScreenProps> = ({ onRetry, errorType = 'network', retryAfter }) => {
const ErrorScreen: React.FC<ErrorScreenProps> = ({ onRetry, errorType = 'network', retryAfter, children }) => {
const { t } = useI18n();
const isRateLimit = errorType === 'rate-limit';
const minutes = retryAfter ? Math.ceil(retryAfter / 60) : 1;
@@ -243,6 +247,7 @@ const ErrorScreen: React.FC<ErrorScreenProps> = ({ onRetry, errorType = 'network
<Button type="button" onClick={onRetry} className="w-full max-w-xs">
{t('sessionAuth.error.retry')}
</Button>
{children}
</div>
</AuthShell>
);
@@ -258,6 +263,7 @@ interface ErrorScreenProps {
onRetry: () => void;
errorType?: 'network' | 'rate-limit';
retryAfter?: number;
children?: React.ReactNode;
}
export const SessionAuthGate: React.FC<SessionAuthGateProps> = ({ children }) => {
@@ -381,6 +387,12 @@ export const SessionAuthGate: React.FC<SessionAuthGateProps> = ({ children }) =>
setIsTunnelLocked(false);
} catch (error) {
console.warn('Failed to check session status:', error);
if (shouldUseDesktopShellPasswordLogin()) {
setState('locked');
setRetryAfter(undefined);
setIsTunnelLocked(false);
return;
}
setState('error');
setIsTunnelLocked(false);
}
@@ -529,6 +541,16 @@ export const SessionAuthGate: React.FC<SessionAuthGateProps> = ({ children }) =>
setState('error');
} catch (error) {
console.warn('Failed to submit UI password:', error);
const clientToken = shouldUseDesktopShellPasswordLogin()
? await issueDesktopClientTokenViaShell(password, trustDevice)
: '';
if (clientToken) {
setPassword('');
setIsTunnelLocked(false);
await applyDesktopClientToken(clientToken);
setState('authenticated');
return;
}
setErrorMessage(t('sessionAuth.error.networkRetry'));
setIsTunnelLocked(false);
setState('error');
@@ -620,7 +642,18 @@ export const SessionAuthGate: React.FC<SessionAuthGateProps> = ({ children }) =>
}
if (state === 'error') {
return <ErrorScreen onRetry={() => void checkStatus()} errorType="network" />;
return (
<ErrorScreen onRetry={() => void checkStatus()} errorType="network">
{showHostSwitcher && (
<div className="w-full max-w-xs">
<DesktopHostSwitcherInline />
<p className="mt-1 text-center typography-micro text-muted-foreground">
{t('sessionAuth.locked.hostSwitcherHint')}
</p>
</div>
)}
</ErrorScreen>
);
}
if (state === 'rate-limited') {