Files
deepseek-harness/apps/desktop/src/settings.ts
T

58 lines
2.6 KiB
TypeScript

/**
* Local Electron shell settings, loaded once per process independently of the Host.
* Ownership: .agents/notes/implemented/architecture/2026-10-08-desktop-shell-configuration.md.
*/
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'
import { join } from 'node:path'
/** Resolved shell preferences; absent fields use the defaults without rewriting existing files. */
export interface DesktopSettings {
readonly updates: {
readonly allowTestAuthPopupWindow: boolean
}
}
function record(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null && !Array.isArray(value)
}
/**
* Read shell settings, creating the default document exclusively when missing.
* @param userData - Electron's userData directory, independent of DSH_HOME.
* @returns Validated settings, or defaults when reading, creating or validating fails; changes require a restart.
*/
export function readDesktopSettings(userData: string): DesktopSettings {
const directory = join(userData, 'desktop')
const path = join(directory, 'settings.json')
const defaults: DesktopSettings = { updates: { allowTestAuthPopupWindow: false } }
try {
let raw: string
try { raw = readFileSync(path, 'utf8') } catch (error) {
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error
mkdirSync(directory, { recursive: true, mode: 0o700 })
try { writeFileSync(path, `${JSON.stringify(defaults, null, 2)}\n`, { flag: 'wx', mode: 0o600 }) } catch (error) {
// An existing document belongs to the user, including one created during initialization.
if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error
}
raw = readFileSync(path, 'utf8')
}
const value: unknown = JSON.parse(raw)
if (!record(value) || (value.updates !== undefined && !record(value.updates))) {
throw new Error('expected a JSON object with an optional updates object')
}
const allow = value.updates?.allowTestAuthPopupWindow
if (allow !== undefined && typeof allow !== 'boolean') {
throw new Error('updates.allowTestAuthPopupWindow must be true or false')
}
return { updates: { allowTestAuthPopupWindow: allow ?? false } }
} catch (error) {
try {
console.warn(`desktop settings: ${path}: using defaults because settings could not be loaded`, error)
} catch (_logError) {
// Diagnostic output is best effort; its failure must not make optional settings fatal.
// TODO: Persist settings diagnostics when console output is unavailable, without blocking startup.
}
return defaults
}
}