import { homedir } from 'node:os' import { resolve as resolvePath } from 'node:path' export interface SynthesisConfig { bridgePort: number bridgeToken: string claudePluginRef: string permissionMode: string idleKillMs: number maxProcesses: number mappingDbPath: string } const DEFAULTS: SynthesisConfig = { bridgePort: 18801, bridgeToken: 'synthesis-local', claudePluginRef: 'plugin:synthesis-claude@local', permissionMode: 'acceptEdits', idleKillMs: 3_600_000, maxProcesses: 16, mappingDbPath: '~/.openclaw/synthesis/sessions.json', } function expand(p: string): string { if (p.startsWith('~')) return resolvePath(homedir(), p.slice(2)) return resolvePath(p) } export function normalizeConfig(raw: unknown): SynthesisConfig { const r = (raw ?? {}) as Partial const merged: SynthesisConfig = { bridgePort: typeof r.bridgePort === 'number' ? r.bridgePort : DEFAULTS.bridgePort, bridgeToken: typeof r.bridgeToken === 'string' && r.bridgeToken ? r.bridgeToken : DEFAULTS.bridgeToken, claudePluginRef: typeof r.claudePluginRef === 'string' && r.claudePluginRef ? r.claudePluginRef : DEFAULTS.claudePluginRef, permissionMode: typeof r.permissionMode === 'string' && r.permissionMode ? r.permissionMode : DEFAULTS.permissionMode, idleKillMs: typeof r.idleKillMs === 'number' ? r.idleKillMs : DEFAULTS.idleKillMs, maxProcesses: typeof r.maxProcesses === 'number' ? r.maxProcesses : DEFAULTS.maxProcesses, mappingDbPath: typeof r.mappingDbPath === 'string' && r.mappingDbPath ? r.mappingDbPath : DEFAULTS.mappingDbPath, } merged.mappingDbPath = expand(merged.mappingDbPath) return merged }