-
Notifications
You must be signed in to change notification settings - Fork 515
Expand file tree
/
Copy pathsettings.ts
More file actions
136 lines (115 loc) · 3.13 KB
/
settings.ts
File metadata and controls
136 lines (115 loc) · 3.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import fs from 'fs'
import path from 'path'
import { getConfigDir } from './auth'
import { AGENT_MODES } from './constants'
import { logger } from './logger'
import type { AgentMode } from './constants'
const DEFAULT_SETTINGS: Settings = {
mode: 'DEFAULT' as const,
adsEnabled: true,
}
// Note: FREE mode is now a valid AgentMode (was previously LITE)
/**
* Settings schema - add new settings here as the product evolves
*/
export interface Settings {
mode?: AgentMode
adsEnabled?: boolean
}
/**
* Get the settings file path
*/
export const getSettingsPath = (): string => {
return path.join(getConfigDir(), 'settings.json')
}
/**
* Ensure the config directory exists, creating it if necessary
*/
const ensureConfigDirExists = (): void => {
const configDir = getConfigDir()
if (!fs.existsSync(configDir)) {
fs.mkdirSync(configDir, { recursive: true })
}
}
/**
* Load all settings from file system
* @returns The saved settings object, with defaults for missing values
*/
export const loadSettings = (): Settings => {
const settingsPath = getSettingsPath()
if (!fs.existsSync(settingsPath)) {
ensureConfigDirExists()
// Create default settings file
fs.writeFileSync(settingsPath, JSON.stringify(DEFAULT_SETTINGS, null, 2))
return DEFAULT_SETTINGS
}
try {
const settingsFile = fs.readFileSync(settingsPath, 'utf8')
const parsed = JSON.parse(settingsFile)
return validateSettings(parsed)
} catch (error) {
logger.debug(
{
error: error instanceof Error ? error.message : String(error),
},
'Error reading settings',
)
return {}
}
}
/**
* Validate and sanitize settings from file
*/
const validateSettings = (parsed: unknown): Settings => {
if (typeof parsed !== 'object' || parsed === null) {
return {}
}
const settings: Settings = {}
const obj = parsed as Record<string, unknown>
// Validate mode
if (
typeof obj.mode === 'string' &&
AGENT_MODES.includes(obj.mode as AgentMode)
) {
settings.mode = obj.mode as AgentMode
}
// Validate adsEnabled
if (typeof obj.adsEnabled === 'boolean') {
settings.adsEnabled = obj.adsEnabled
}
return settings
}
/**
* Save settings to file system (merges with existing settings)
*/
export const saveSettings = (newSettings: Partial<Settings>): void => {
const settingsPath = getSettingsPath()
try {
ensureConfigDirExists()
// Load existing settings and merge
const existingSettings = loadSettings()
const mergedSettings = { ...existingSettings, ...newSettings }
fs.writeFileSync(settingsPath, JSON.stringify(mergedSettings, null, 2))
} catch (error) {
logger.debug(
{
error: error instanceof Error ? error.message : String(error),
},
'Error saving settings',
)
}
}
/**
* Load the saved agent mode preference
* @returns The saved mode, or 'DEFAULT' if not found or invalid
*/
export const loadModePreference = (): AgentMode => {
const settings = loadSettings()
return settings.mode ?? 'DEFAULT'
}
/**
* Save the agent mode preference
*/
export const saveModePreference = (mode: AgentMode): void => {
saveSettings({ mode })
}