THU-504: Local settings store#857
Conversation
Semgrep Security ScanNo security issues found. |
PR Metrics
Updated Wed, 13 May 2026 21:10:50 GMT · run #1492 |
ital0
left a comment
There was a problem hiding this comment.
Just pointed out some details I noticed.
I completetly ignore files under eval since they should be used only internally.
|
Preview environment deployed 🚀
Stack: Auto-destroys on PR close/merge. Login via the bundled Keycloak realm — |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 521a8aa. Configure here.
| const setLocalSetting = useLocalSettingsStore((s) => s.setLocalSetting) | ||
|
|
||
| const isModified = <K extends keyof typeof initialLocalSettings>(key: K) => | ||
| useLocalSettingsStore.getState()[key] !== initialLocalSettings[key] |
There was a problem hiding this comment.
Store read via getState() during render risks tearing
Low Severity
The isModified helper calls useLocalSettingsStore.getState() directly during render to check whether a value differs from its default. Under React 18 concurrent rendering, getState() can return a newer snapshot than the one the component is rendering with (from useShallow), causing the modification indicator to be inconsistent with the displayed value. Deriving isModified from the already-subscribed values instead of a separate getState() call would keep everything consistent within the same render pass.
Reviewed by Cursor Bugbot for commit 521a8aa. Configure here.


Summary
local-settings-store.ts) for device-specific settings that shouldn't sync across devicescloud_url,debug_posthog,is_native_fetch_enabled,haptics_enabled,syncEnabled, andthemefrom the PowerSync DB / raw localStorage to the new storedefaults/settings.tsand the unusedui-themeDB settingThemeProviderto read/write via the Zustand store instead of its own localStorage keyWhy
cloud_urlcreates a bootstrap circular dependency — needed before DB init, but stored in DBis_native_fetch_enabledwas read via async DB query on every fetch request — now synchronousui-themeDB setting was dead code —ThemeProviderused its own localStoragepowersync_sync_enabledwas a scattered raw localStorage flagTest plan
cloud_urlavailable at Step 0 without DBcloudUrl(citations, tool icons, link previews) render correctlylocalStoragehasthunderbolt-local-settingskey with correct shapeNote
Medium Risk
Touches initialization, networking base URL selection, SSO redirect, analytics init, and sync enablement by moving several settings off the DB/localStorage flags into a new persisted store; mis-migration or missing test updates could break startup/auth flows or point clients at the wrong backend.
Overview
Introduces a new persisted Zustand store (
src/stores/local-settings-store.ts) for device-local settings and switches multiple call sites to readcloudUrl,theme,syncEnabled,hapticsEnabled,isNativeFetchEnabled, anddebugPosthogfrom it instead of the PowerSync DB or ad-hoclocalStoragekeys.This rewires startup/bootstrap paths to use the store (e.g.
fetchConfig(...)now usesgetLocalSetting('cloudUrl')), updatesThemeProviderand the pre-paint theme script inindex.htmlto use the newthunderbolt-local-settingspersisted shape, and updates UI surfaces (Dev Settings, Preferences, chat citation/link preview/tool icon components, SSO redirect, sign-in) to use store values.Cleans up removed/dead DB defaults in
defaults/settings.ts, moves PowerSync sync enablement to the store, and resets local settings back toinitialLocalSettingswhen clearing local data.Reviewed by Cursor Bugbot for commit 521a8aa. Bugbot is set up for automated code reviews on this repo. Configure here.