/** * @fileoverview Settings "Apply": saves like Save but keeps the modal open and refreshes the * groups that depend on a saved value (MCP sync, custom model endpoints, CLI management). */ import { readFileSync } from 'node:fs'; import { resolve } from 'node:path'; import vm from 'node:vm'; import { describe, expect, it, vi } from 'vitest'; const publicDir = resolve(import.meta.dirname, '../src/web/public'); const html = readFileSync(resolve(publicDir, 'index.html'), 'utf8'); const settingsUi = readFileSync(resolve(publicDir, 'settings-ui.js'), 'utf8'); function loadApp() { const CodemanApp = function CodemanApp() {} as unknown as { prototype: Record }; const context = vm.createContext({ CodemanApp, localStorage: { getItem: () => null, setItem: () => {} }, document: { getElementById: () => null, querySelectorAll: () => [], addEventListener: () => {} }, window: {}, console, }); vm.runInContext(settingsUi, context, { filename: 'settings-ui.js' }); return new (CodemanApp as unknown as new () => Record)(); } describe('Settings Apply button', () => { it('sits next to Save in the footer and the phone header, wired to applyAppSettings', () => { const start = html.indexOf('