mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-06-26 18:26:38 +00:00
remove developer-specific tabs, hooks, and APIs including debug status, update checks, and system diagnostics simplify tab configuration to only support user mode clean up unused code, routes and update types accordingly
294 lines
8.8 KiB
TypeScript
294 lines
8.8 KiB
TypeScript
import { atom, map } from 'nanostores';
|
|
import { PROVIDER_LIST } from '~/shared/utils/constants';
|
|
import type { IProviderConfig } from '~/shared/types/model';
|
|
import type { TabVisibilityConfig, TabWindowConfig, UserTabConfig } from '~/settings/core/types';
|
|
import { DEFAULT_TAB_CONFIG } from '~/settings/core/constants';
|
|
import Cookies from 'js-cookie';
|
|
import { toggleTheme } from '~/shared/stores/theme';
|
|
import { create } from 'zustand';
|
|
|
|
export interface Shortcut {
|
|
key: string;
|
|
ctrlKey?: boolean;
|
|
shiftKey?: boolean;
|
|
altKey?: boolean;
|
|
metaKey?: boolean;
|
|
ctrlOrMetaKey?: boolean;
|
|
action: () => void;
|
|
description?: string; // Description of what the shortcut does
|
|
isPreventDefault?: boolean; // Whether to prevent default browser behavior
|
|
}
|
|
|
|
export interface Shortcuts {
|
|
toggleTheme: Shortcut;
|
|
toggleTerminal: Shortcut;
|
|
}
|
|
|
|
export const URL_CONFIGURABLE_PROVIDERS = ['Ollama', 'LMStudio', 'OpenAILike'];
|
|
export const LOCAL_PROVIDERS = ['OpenAILike', 'LMStudio', 'Ollama'];
|
|
|
|
export type ProviderSetting = Record<string, IProviderConfig>;
|
|
|
|
// Simplified shortcuts store with only theme toggle
|
|
export const shortcutsStore = map<Shortcuts>({
|
|
toggleTheme: {
|
|
key: 'd',
|
|
metaKey: true,
|
|
altKey: true,
|
|
shiftKey: true,
|
|
action: () => toggleTheme(),
|
|
description: 'Toggle theme',
|
|
isPreventDefault: true,
|
|
},
|
|
toggleTerminal: {
|
|
key: '`',
|
|
ctrlOrMetaKey: true,
|
|
action: () => {
|
|
// This will be handled by the terminal component
|
|
},
|
|
description: 'Toggle terminal',
|
|
isPreventDefault: true,
|
|
},
|
|
});
|
|
|
|
// Create a single key for provider settings
|
|
const PROVIDER_SETTINGS_KEY = 'provider_settings';
|
|
|
|
// Add this helper function at the top of the file
|
|
const isBrowser = typeof window !== 'undefined';
|
|
|
|
// Initialize provider settings from both localStorage and defaults
|
|
const getInitialProviderSettings = (): ProviderSetting => {
|
|
const initialSettings: ProviderSetting = {};
|
|
|
|
// Start with default settings
|
|
PROVIDER_LIST.forEach((provider) => {
|
|
initialSettings[provider.name] = {
|
|
...provider,
|
|
settings: {
|
|
// Local providers should be disabled by default
|
|
enabled: !LOCAL_PROVIDERS.includes(provider.name),
|
|
},
|
|
};
|
|
});
|
|
|
|
// Only try to load from localStorage in the browser
|
|
if (isBrowser) {
|
|
const savedSettings = localStorage.getItem(PROVIDER_SETTINGS_KEY);
|
|
|
|
if (savedSettings) {
|
|
try {
|
|
const parsed = JSON.parse(savedSettings);
|
|
Object.entries(parsed).forEach(([key, value]) => {
|
|
if (initialSettings[key]) {
|
|
initialSettings[key].settings = (value as IProviderConfig).settings;
|
|
}
|
|
});
|
|
} catch (error) {
|
|
console.error('Error parsing saved provider settings:', error);
|
|
}
|
|
}
|
|
}
|
|
|
|
return initialSettings;
|
|
};
|
|
|
|
export const providersStore = map<ProviderSetting>(getInitialProviderSettings());
|
|
|
|
// Create a function to update provider settings that handles both store and persistence
|
|
export const updateProviderSettings = (provider: string, settings: ProviderSetting) => {
|
|
const currentSettings = providersStore.get();
|
|
|
|
// Create new provider config with updated settings
|
|
const updatedProvider = {
|
|
...currentSettings[provider],
|
|
settings: {
|
|
...currentSettings[provider].settings,
|
|
...settings,
|
|
},
|
|
};
|
|
|
|
// Update the store with new settings
|
|
providersStore.setKey(provider, updatedProvider);
|
|
|
|
// Save to localStorage
|
|
const allSettings = providersStore.get();
|
|
localStorage.setItem(PROVIDER_SETTINGS_KEY, JSON.stringify(allSettings));
|
|
};
|
|
|
|
export const isDebugMode = atom(false);
|
|
|
|
// Define keys for localStorage
|
|
const SETTINGS_KEYS = {
|
|
LATEST_BRANCH: 'isLatestBranch',
|
|
AUTO_SELECT_TEMPLATE: 'autoSelectTemplate',
|
|
CONTEXT_OPTIMIZATION: 'contextOptimizationEnabled',
|
|
EVENT_LOGS: 'isEventLogsEnabled',
|
|
PROMPT_ID: 'promptId',
|
|
DEVELOPER_MODE: 'isDeveloperMode',
|
|
} as const;
|
|
|
|
// Initialize settings from localStorage or defaults
|
|
const getInitialSettings = () => {
|
|
const getStoredBoolean = (key: string, defaultValue: boolean): boolean => {
|
|
if (!isBrowser) {
|
|
return defaultValue;
|
|
}
|
|
|
|
const stored = localStorage.getItem(key);
|
|
|
|
if (stored === null) {
|
|
return defaultValue;
|
|
}
|
|
|
|
try {
|
|
return JSON.parse(stored);
|
|
} catch {
|
|
return defaultValue;
|
|
}
|
|
};
|
|
|
|
return {
|
|
latestBranch: getStoredBoolean(SETTINGS_KEYS.LATEST_BRANCH, false),
|
|
autoSelectTemplate: getStoredBoolean(SETTINGS_KEYS.AUTO_SELECT_TEMPLATE, true),
|
|
contextOptimization: getStoredBoolean(SETTINGS_KEYS.CONTEXT_OPTIMIZATION, true),
|
|
eventLogs: getStoredBoolean(SETTINGS_KEYS.EVENT_LOGS, true),
|
|
promptId: isBrowser ? localStorage.getItem(SETTINGS_KEYS.PROMPT_ID) || 'default' : 'default',
|
|
developerMode: getStoredBoolean(SETTINGS_KEYS.DEVELOPER_MODE, false),
|
|
};
|
|
};
|
|
|
|
// Initialize stores with persisted values
|
|
const initialSettings = getInitialSettings();
|
|
|
|
export const latestBranchStore = atom<boolean>(initialSettings.latestBranch);
|
|
export const autoSelectStarterTemplate = atom<boolean>(initialSettings.autoSelectTemplate);
|
|
export const enableContextOptimizationStore = atom<boolean>(initialSettings.contextOptimization);
|
|
export const isEventLogsEnabled = atom<boolean>(initialSettings.eventLogs);
|
|
export const promptStore = atom<string>(initialSettings.promptId);
|
|
|
|
// Helper functions to update settings with persistence
|
|
export const updateLatestBranch = (enabled: boolean) => {
|
|
latestBranchStore.set(enabled);
|
|
localStorage.setItem(SETTINGS_KEYS.LATEST_BRANCH, JSON.stringify(enabled));
|
|
};
|
|
|
|
export const updateAutoSelectTemplate = (enabled: boolean) => {
|
|
autoSelectStarterTemplate.set(enabled);
|
|
localStorage.setItem(SETTINGS_KEYS.AUTO_SELECT_TEMPLATE, JSON.stringify(enabled));
|
|
};
|
|
|
|
export const updateContextOptimization = (enabled: boolean) => {
|
|
enableContextOptimizationStore.set(enabled);
|
|
localStorage.setItem(SETTINGS_KEYS.CONTEXT_OPTIMIZATION, JSON.stringify(enabled));
|
|
};
|
|
|
|
export const updateEventLogs = (enabled: boolean) => {
|
|
isEventLogsEnabled.set(enabled);
|
|
localStorage.setItem(SETTINGS_KEYS.EVENT_LOGS, JSON.stringify(enabled));
|
|
};
|
|
|
|
export const updatePromptId = (id: string) => {
|
|
promptStore.set(id);
|
|
localStorage.setItem(SETTINGS_KEYS.PROMPT_ID, id);
|
|
};
|
|
|
|
// Initialize tab configuration from localStorage or defaults
|
|
const getInitialTabConfiguration = (): TabWindowConfig => {
|
|
const defaultConfig: TabWindowConfig = {
|
|
userTabs: DEFAULT_TAB_CONFIG.filter((tab): tab is UserTabConfig => tab.window === 'user'),
|
|
};
|
|
|
|
if (!isBrowser) {
|
|
return defaultConfig;
|
|
}
|
|
|
|
try {
|
|
const saved = localStorage.getItem('bolt_tab_configuration');
|
|
|
|
if (!saved) {
|
|
return defaultConfig;
|
|
}
|
|
|
|
const parsed = JSON.parse(saved);
|
|
|
|
if (!parsed?.userTabs || !parsed?.developerTabs) {
|
|
return defaultConfig;
|
|
}
|
|
|
|
// Ensure proper typing of loaded configuration
|
|
return {
|
|
userTabs: parsed.userTabs.filter((tab: TabVisibilityConfig): tab is UserTabConfig => tab.window === 'user'),
|
|
};
|
|
} catch (error) {
|
|
console.warn('Failed to parse tab configuration:', error);
|
|
return defaultConfig;
|
|
}
|
|
};
|
|
|
|
// console.log('Initial tab configuration:', getInitialTabConfiguration());
|
|
|
|
export const tabConfigurationStore = map<TabWindowConfig>(getInitialTabConfiguration());
|
|
|
|
// Helper function to update tab configuration
|
|
export const updateTabConfiguration = () => {
|
|
const currentConfig = tabConfigurationStore.get();
|
|
console.log('Current tab configuration before update:', currentConfig);
|
|
|
|
// Create new config, only updating the target window's tabs
|
|
const newConfig: TabWindowConfig = {
|
|
...currentConfig,
|
|
};
|
|
|
|
console.log('New tab configuration after update:', newConfig);
|
|
|
|
tabConfigurationStore.set(newConfig);
|
|
Cookies.set('tabConfiguration', JSON.stringify(newConfig), {
|
|
expires: 365, // Set cookie to expire in 1 year
|
|
path: '/',
|
|
sameSite: 'strict',
|
|
});
|
|
};
|
|
|
|
// Helper function to reset tab configuration
|
|
export const resetTabConfiguration = () => {
|
|
const defaultConfig: TabWindowConfig = {
|
|
userTabs: DEFAULT_TAB_CONFIG.filter((tab): tab is UserTabConfig => tab.window === 'user'),
|
|
};
|
|
|
|
tabConfigurationStore.set(defaultConfig);
|
|
localStorage.setItem('bolt_tab_configuration', JSON.stringify(defaultConfig));
|
|
};
|
|
|
|
// First, let's define the SettingsStore interface
|
|
interface SettingsStore {
|
|
isOpen: boolean;
|
|
selectedTab: string;
|
|
openSettings: () => void;
|
|
closeSettings: () => void;
|
|
setSelectedTab: (tab: string) => void;
|
|
}
|
|
|
|
export const useSettingsStore = create<SettingsStore>((set) => ({
|
|
isOpen: false,
|
|
selectedTab: 'user', // Default tab
|
|
|
|
openSettings: () => {
|
|
set({
|
|
isOpen: true,
|
|
selectedTab: 'user', // Always open to user tab
|
|
});
|
|
},
|
|
|
|
closeSettings: () => {
|
|
set({
|
|
isOpen: false,
|
|
selectedTab: 'user', // Reset to user tab when closing
|
|
});
|
|
},
|
|
|
|
setSelectedTab: (tab: string) => {
|
|
set({ selectedTab: tab });
|
|
},
|
|
}));
|