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
@@ -21,9 +21,26 @@ export const createSettingsHelpers = (dependencies) => {
const STT_SERVER_URL_MAX_LENGTH = 2048;
const STT_MODEL_MAX_LENGTH = 256;
const STT_LANGUAGE_MAX_LENGTH = 64;
const VERSION_STRING_MAX_LENGTH = 128;
const SHORTCUT_OVERRIDE_KEY_MAX_LENGTH = 128;
const SHORTCUT_OVERRIDE_VALUE_MAX_LENGTH = 128;
const PWA_ORIENTATION_VALUES = new Set(['system', 'portrait', 'landscape']);
const MOBILE_KEYBOARD_MODE_VALUES = new Set(['native', 'resize-content']);
const sanitizeShortcutOverrides = (value) => {
if (!value || typeof value !== 'object' || Array.isArray(value)) {
return null;
}
const result = {};
for (const [rawKey, rawValue] of Object.entries(value)) {
const key = typeof rawKey === 'string' ? rawKey.trim() : '';
const combo = typeof rawValue === 'string' ? rawValue.trim() : '';
if (!key || !combo) continue;
result[key.slice(0, SHORTCUT_OVERRIDE_KEY_MAX_LENGTH)] = combo.slice(0, SHORTCUT_OVERRIDE_VALUE_MAX_LENGTH);
}
return result;
};
const normalizePwaAppName = (value, fallback = '') => {
if (typeof value !== 'string') {
return fallback;
@@ -350,7 +367,7 @@ export const createSettingsHelpers = (dependencies) => {
result.pwaOrientation = normalizePwaOrientation(candidate.pwaOrientation, undefined);
}
if (typeof candidate.mobileKeyboardMode === 'string') {
const mode = normalizeMobileKeyboardMode(candidate.mobileKeyboardMode, undefined);
const mode = normalizeMobileKeyboardMode(candidate.mobileKeyboardMode, null);
if (mode) {
result.mobileKeyboardMode = mode;
}
@@ -364,6 +381,13 @@ export const createSettingsHelpers = (dependencies) => {
if (typeof candidate.inputSpellcheckEnabled === 'boolean') {
result.inputSpellcheckEnabled = candidate.inputSpellcheckEnabled;
}
if (typeof candidate.showOpenCodeUpdateNotifications === 'boolean') {
result.showOpenCodeUpdateNotifications = candidate.showOpenCodeUpdateNotifications;
}
if (typeof candidate.openCodeUpdateToastDismissedVersion === 'string') {
const version = candidate.openCodeUpdateToastDismissedVersion.trim();
result.openCodeUpdateToastDismissedVersion = version.slice(0, VERSION_STRING_MAX_LENGTH);
}
if (typeof candidate.showToolFileIcons === 'boolean') {
result.showToolFileIcons = candidate.showToolFileIcons;
}
@@ -437,6 +461,11 @@ export const createSettingsHelpers = (dependencies) => {
result.inputBarOffset = Math.max(0, Math.min(100, Math.round(candidate.inputBarOffset)));
}
const shortcutOverrides = sanitizeShortcutOverrides(candidate.shortcutOverrides);
if (shortcutOverrides) {
result.shortcutOverrides = shortcutOverrides;
}
const favoriteModels = sanitizeModelRefs(candidate.favoriteModels, 64);
if (favoriteModels) {
result.favoriteModels = favoriteModels;