Skip to content

Commit ade6bd8

Browse files
committed
fix(desktop): decouple Client settings from Host refresh
Keep Desktop appearance and client-setting events independent from Runtime Host availability. Make Host resource reloads settle through their owned error state so a failed refresh cannot misreport a successful mutation, and preserve newly submitted bot credentials at the update response boundary. Generated-by: Codex
1 parent b63e275 commit ade6bd8

5 files changed

Lines changed: 22 additions & 23 deletions

File tree

‎apps/desktop/src/main/__tests__/client-settings-ipc-main.test.ts‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
} from "@maka/core/settings";
88
import { registerClientSettingsIpc } from "../client-settings-ipc-main.js";
99

10-
test("client settings updates cannot mutate Runtime Host policy", async () => {
10+
test("client settings updates filter Host policy and return newly submitted secrets", async () => {
1111
const handlers = new Map<string, (...args: unknown[]) => unknown>();
1212
let settings = createDefaultSettings();
1313
let storedPatch: UpdateAppSettingsInput | undefined;
@@ -33,11 +33,19 @@ test("client settings updates cannot mutate Runtime Host policy", async () => {
3333

3434
const result = await handlers.get("settings:client:update")?.({}, {
3535
appearance: { theme: "dark" },
36+
botChat: { channels: { telegram: { token: "fresh-bot-token" } } },
3637
chatDefaults: { permissionMode: "bypass" },
3738
});
3839

39-
assert.deepEqual(storedPatch, { appearance: { theme: "dark" } });
40+
assert.deepEqual(storedPatch, {
41+
appearance: { theme: "dark" },
42+
botChat: { channels: { telegram: { token: "fresh-bot-token" } } },
43+
});
4044
assert.equal((result as { settings: typeof settings }).settings.appearance.theme, "dark");
45+
assert.equal(
46+
(result as { settings: typeof settings }).settings.botChat.channels.telegram.token,
47+
"fresh-bot-token",
48+
);
4149
assert.equal(settings.chatDefaults.permissionMode, "ask");
4250
assert.equal(applied, 1);
4351
});

‎apps/desktop/src/main/client-settings-ipc-main.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export function registerClientSettingsIpc(deps: {
3333
? await deps.settingsStore.update(clientPatch)
3434
: await deps.settingsStore.get();
3535
await deps.apply(settings);
36-
return buildSettingsUpdateResult(maskAppSettings(settings), clientPatch);
36+
return buildSettingsUpdateResult(settings, clientPatch);
3737
},
3838
);
3939
}

‎apps/desktop/src/renderer/app-shell-effects.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -404,15 +404,15 @@ export function useAppShellBootstrapSubscriptions(options: {
404404
const unsubscribeConnections = window.maka.connections.subscribeEvents(handleConnectionSubscriptionEvent);
405405
const unsubscribeRuntimeHostChanges =
406406
window.maka.runtimeHostProfiles.subscribeChanges(handleRuntimeHostChange);
407-
const refreshSettingsMirrors = () => {
407+
const refreshRuntimeHostSettingsMirrors = () => {
408408
void options.refreshShellSettings();
409409
void options.refreshConnections();
410410
};
411411
const unsubscribeSettingsExternal = window.maka.settings.subscribeExternalChanged(
412-
refreshSettingsMirrors,
412+
refreshRuntimeHostSettingsMirrors,
413413
);
414414
const unsubscribeClientSettings = window.maka.settings.subscribeClientChanged(
415-
refreshSettingsMirrors,
415+
() => void options.refreshShellSettings(),
416416
);
417417
const unsubscribeSessionChanges = window.maka.sessions.subscribeChanges(handleSessionChange);
418418
const unsubscribeScheduledTaskChanges = window.maka.scheduledTasks.subscribeChanges(handleScheduledTaskChange);

‎apps/desktop/src/renderer/settings/settings-surface.tsx‎

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,6 @@ export function SettingsSurface(props: {
343343
message: settingsActionErrorMessage(error, locale),
344344
});
345345
}
346-
throw error;
347346
}
348347
}
349348

@@ -395,7 +394,6 @@ export function SettingsSurface(props: {
395394
message: settingsActionErrorMessage(error, locale),
396395
});
397396
}
398-
throw error;
399397
}
400398
}
401399

@@ -543,21 +541,13 @@ export function SettingsSurface(props: {
543541
void Promise.all([
544542
reloadRuntimeHostSettings(selectedRuntimeHost),
545543
reloadConnections(connectionsBridge, selectedRuntimeHost),
546-
]).catch((error) => {
547-
if (settingsModalMountedRef.current) {
548-
toast.error(copy.settingsLoadFailed, settingsActionErrorMessage(error, locale));
549-
}
550-
});
544+
]);
551545
const unsubscribeSettings = window.maka.settings.subscribeExternalChanged(
552546
() => void reloadRuntimeHostSettings(selectedRuntimeHost),
553547
selectedRuntimeHost,
554548
);
555549
const unsubscribeConnections = connectionsBridge.subscribeEvents?.(() => {
556-
void reloadConnections(connectionsBridge, selectedRuntimeHost).catch((error) => {
557-
if (settingsModalMountedRef.current) {
558-
toast.error(copy.settingsLoadFailed, settingsActionErrorMessage(error, locale));
559-
}
560-
});
550+
void reloadConnections(connectionsBridge, selectedRuntimeHost);
561551
});
562552
return () => {
563553
unsubscribeSettings();

‎apps/desktop/src/renderer/use-shell-appearance.ts‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,15 @@ export function useShellAppearance({
4848

4949
async function refreshShellSettings() {
5050
const uiLocaleHydration = uiLocaleUpdateGate.beginHydration();
51-
const [clientResult, runtimeHostResult, fixtureState] = await Promise.all([
51+
const runtimeHostHydration = window.maka.settings.get().then(
52+
(settings) => ({ ok: true as const, settings }),
53+
() => ({ ok: false as const }),
54+
);
55+
const [clientResult, fixtureState] = await Promise.all([
5256
window.maka.settings.getClient().then(
5357
(settings) => ({ ok: true as const, settings }),
5458
(error: unknown) => ({ ok: false as const, error }),
5559
),
56-
window.maka.settings.get().then(
57-
(settings) => ({ ok: true as const, settings }),
58-
() => ({ ok: false as const }),
59-
),
6060
window.maka.e2eFixture.getState().catch(() => null),
6161
]);
6262

@@ -87,6 +87,7 @@ export function useShellAppearance({
8787
);
8888
}
8989

90+
const runtimeHostResult = await runtimeHostHydration;
9091
if (runtimeHostResult.ok) {
9192
const next = runtimeHostResult.settings;
9293
setUserLabel(next.personalization.displayName ?? '');

0 commit comments

Comments
 (0)