// ==CONFIG START== (function () { const STORAGE_KEYS = { history: 'ai_repo_commander_executed', cfg: 'ai_repo_commander_cfg', panel: 'ai_repo_commander_panel_state' }; const DEFAULT_CONFIG = { meta: { version: '1.6.2' }, api: { enabled: true, timeout: 60000, maxRetries: 2, bridgeKey: '' }, debug: { enabled: true, level: 3, // 0=off, 1=errors, 2=warn, 3=info, 4=verbose, 5=trace watchMs: 120000, maxLines: 400, showPanel: true }, execution: { debounceDelay: 6500, settleCheckMs: 1300, settlePollMs: 250, requireTerminator: true, coldStartMs: 2000, stuckAfterMs: 10 * 60 * 1000, scanDebounceMs: 400, fastWarnMs: 50, slowWarnMs: 60000, clusterRescanMs: 1000, clusterMaxLookahead: 3 }, queue: { minDelayMs: 1500, maxPerMinute: 15, maxPerMessage: 5, waitForComposerMs: 12000 }, ui: { autoSubmit: true, appendTrailingNewline: true, postPasteDelayMs: 600, showExecutedMarker: true, processExisting: false, submitMode: 'button_first', maxComposerWaitMs: 15 * 60 * 1000, submitMaxRetries: 12 }, storage: { dedupeTtlMs: 30 * 24 * 60 * 60 * 1000, // 30 days cleanupAfterMs: 30000, cleanupIntervalMs: 60000 }, response: { bufferFlushDelayMs: 500, sectionHeadings: true, maxPasteChars: 250000, splitLongResponses: true }, // Runtime state (not persisted) runtime: { paused: false } }; class ConfigManager { constructor() { this.config = this.load(); } load() { try { const raw = localStorage.getItem(STORAGE_KEYS.cfg); if (!raw) return this.deepClone(DEFAULT_CONFIG); const saved = JSON.parse(raw); return this.mergeConfigs(DEFAULT_CONFIG, saved); } catch { return this.deepClone(DEFAULT_CONFIG); } } save() { try { const { runtime, ...persistable } = this.config; // do not persist runtime localStorage.setItem('ai_repo_commander_cfg', JSON.stringify(persistable)); } catch (e) { console.warn('Failed to save config:', e); } } get(keyPath) { return keyPath.split('.').reduce((obj, key) => obj?.[key], this.config); } set(keyPath, value) { const keys = keyPath.split('.'); const last = keys.pop(); const tgt = keys.reduce((o, k) => (o[k] = o[k] || {}), this.config); tgt[last] = value; this.save(); } mergeConfigs(defaults, saved) { const out = this.deepClone(defaults); for (const k of Object.keys(saved)) { if (k === 'runtime') continue; // never restore runtime if (typeof out[k] === 'object' && !Array.isArray(out[k])) { out[k] = { ...out[k], ...saved[k] }; } else { out[k] = saved[k]; } } return out; } deepClone(o) { return JSON.parse(JSON.stringify(o)); } } window.AI_REPO_CONFIG = new ConfigManager(); window.AI_REPO_STORAGE_KEYS = STORAGE_KEYS; })(); // ==CONFIG END==