Expose backend settings in UI (System→Runtime tab) + fix config clobbering#262
Merged
Conversation
… tab A settings audit found the backend AppSettings (global defaults, session/GC lifecycle, limits) had NO UI — they were only editable by hand-editing ~/.kaitencode/settings.json, even though the app already has get_app_settings/update_app_settings commands. The "raise mcp_max_recursion_depth" error even told users to change a setting with no control. Adds Settings → System → Runtime exposing every previously-UI-less AppSettings, grouped: - Global defaults: default agent CLI, model, session strategy, advance mode. - Sessions & cleanup: max agent sessions, GC interval, idle sleep/kill, archive purge. - Limits: MCP recursion depth, claude/codex min versions. Text/number fields commit on blur (no settings.json write per keystroke); selects commit on change. Extends the AppSettings IPC type with claude_min_version / codex_min_version / mcp_max_recursion_depth (all already handled by the backend merge_update). Verified merge_update covers every exposed key. Audit corrections: the Voice tab already exposes language/hotkey/push-to-talk/ sensitivity (audit was wrong), and advanced.notesDebounceMs/outputBufferIntervalMs are dead settings (unused anywhere) so deliberately not surfaced. tsc · lint · settings tests green.
The workspace `config` JSON has two writers and they overwrote each other's
keys (last-write-wins on the whole blob — silent settings loss):
- The Workspace tab spreads the full current config (`{...config, ...patch}`),
so it preserved everything.
- `useSettingsSync` serialized ONLY its nested `{agent,git,voice,model}` slices
and wrote that as the entire config — wiping the flat keys the Workspace tab
sets (defaultModel, maxConcurrentAgents, defaultBaseBranch, autoAdvance,
persistentAgentLifecycle, autoArchive…).
Fix: `useSettingsSync` now re-reads the current config and MERGES its slices in
(symmetric with the Workspace tab) instead of replacing the blob. The backend
`effective_pipeline_settings` already reads both the flat and nested shapes, so
they coexist safely.
Also reconciles the branchPrefix split-brain: DEFAULT_SETTINGS.git.branchPrefix
was 'feat/' while the backend DEFAULT_BRANCH_PREFIX and workspaceDefaults both
use 'kaitencode/' — three defaults for one concept. Aligned to 'kaitencode/'.
tsc · lint · vitest (419) green.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
From a settings-exposure audit. Two commits.
feat: System → Runtime tab
The backend
AppSettings(global defaults, session/GC lifecycle, limits) had no UI — only hand-editable insettings.json, despiteget_app_settings/update_app_settingsalready existing. The "raise mcp_max_recursion_depth" error even pointed at a setting with no control.New Settings → System → Runtime tab exposes them all:
Commits on blur (no
settings.jsonwrite per keystroke). Extends theAppSettingsIPC type; verifiedmerge_updatecovers every exposed key.fix: workspace-config clobbering (a real latent bug the audit found)
The workspace
configJSON had two writers that overwrote each other (last-write-wins → silent settings loss): the Workspace tab preserved everything, butuseSettingsSyncserialized only its{agent,git,voice,model}slices and replaced the whole blob, wiping the flat keys (defaultModel,maxConcurrentAgents,autoAdvance, …). Now it re-reads + merges instead of replacing. Also reconciles thebranchPrefixsplit-brain (feat/vskaitencode/— three defaults → one).Audit corrections
The audit overstated the "small gaps": the Voice tab already exposes language/hotkey/push-to-talk/sensitivity, and
advanced.notesDebounceMs/outputBufferIntervalMsare dead settings (unused) — deliberately not surfaced.tsc · lint · vitest (419) green.