Files
openchamber/packages/ui/src/lib/opencode/deferredRestart.ts
T

82 lines
2.4 KiB
TypeScript
Raw Normal View History

import {
usePendingOpenCodeRestartStore,
type PendingOpenCodeRestartScope,
} from '@/stores/usePendingOpenCodeRestartStore';
export type ConfigMutationPayload = {
requiresReload?: boolean;
requiresRestart?: boolean;
restartDeferred?: boolean;
requiresManualRestart?: boolean;
reloadFailed?: boolean;
message?: string;
warning?: string;
reloadDelayMs?: number;
} | null | undefined;
export function isDeferredRestartPayload(payload: ConfigMutationPayload): boolean {
if (!payload || typeof payload !== 'object') {
return false;
}
if (payload.requiresManualRestart === true) {
return false;
}
return payload.restartDeferred === true || (payload.requiresRestart === true && payload.requiresReload !== true);
}
export function recordDeferredOpenCodeRestart(
scope: PendingOpenCodeRestartScope,
options?: { id?: string; label?: string },
): void {
usePendingOpenCodeRestartStore.getState().recordChange({
scope,
id: options?.id,
label: options?.label,
});
}
/**
* If the mutation response deferred the OpenCode restart, record it and return true.
* Callers should skip immediate refresh overlays when this returns true.
*/
export function noteDeferredRestartFromPayload(
payload: ConfigMutationPayload,
scope: PendingOpenCodeRestartScope,
options?: { id?: string; label?: string },
): boolean {
if (!isDeferredRestartPayload(payload)) {
return false;
}
recordDeferredOpenCodeRestart(scope, options);
return true;
}
export async function applyPendingOpenCodeRestart(options?: {
message?: string;
}): Promise<{ ok: boolean; requiresManualRestart?: boolean }> {
const store = usePendingOpenCodeRestartStore.getState();
if (store.isApplying) {
return { ok: false };
}
store.setApplying(true);
try {
const { reloadOpenCodeConfiguration } = await import('@/stores/useAgentsStore');
await reloadOpenCodeConfiguration({
message: options?.message,
mode: 'projects',
scopes: ['all'],
});
usePendingOpenCodeRestartStore.getState().clear();
return { ok: true };
} catch (error) {
if ((error as Error & { requiresManualRestart?: boolean })?.requiresManualRestart) {
2026-08-03 08:56:05 +00:00
// Changes are already on disk; clear the badge after delivering manual-restart guidance.
usePendingOpenCodeRestartStore.getState().clear();
return { ok: false, requiresManualRestart: true };
}
2026-08-03 08:56:05 +00:00
usePendingOpenCodeRestartStore.getState().setApplying(false);
throw error;
}
}