AI-Repo-Commander/src/config.js

125 lines
3.7 KiB
JavaScript

// ==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==