feat: comprehensive settings screen#27
Merged
Merged
Conversation
Add the codeoid-ui (TUI) counterpart to the config-file-driven settings
surface — a tabbed screen that renders whatever manifest the daemon serves
over `settings.schema`, so a new knob appears with no client changes.
Protocol crate:
- ClientMessage: settings.schema / settings.get / settings.set (+ SettingPatch).
- DaemonMessage: settings.{schema,get,set}.result + the manifest/snapshot
types (SettingsManifest / Tab / Group / Field / Option / Snapshot / State /
SecretStatus / Error). kind/backing/source kept as strings so a new value
never breaks deserialization.
- connection.rs: client_kind / daemon_kind arms for the new messages.
TUI:
- SettingsModal state — tabs, field cursor, staged edits (dirty map), an
inline text-edit buffer, secret status, and save/restart tracking.
- keymap: ModalKind::Settings (nav) + ModalKind::SettingsEdit (text buffer),
with resolve blocks + tests.
- app reducer: open_settings (fetch manifest + values), field nav, activate
(toggle bool / cycle enum / open buffer for text/number/secret), clear,
save (settings.set batch), refresh, and the three result arms in
apply_daemon (staleness-guarded like Capabilities).
- renderer: tab pills + grouped fields with per-kind control display,
provenance / secret-source / restart badges, edit buffer, and a footer with
the on-disk config.json + .env paths.
- `/settings` (aliases `/config`, `/prefs`) slash command + catalog entry.
Renders against a daemon carrying the settings RPC; on an older daemon the
fetch simply errors and the modal shows it. fmt + build + clippy + test clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
🤖 Gemini code reviewThis PR implements a comprehensive, interactive terminal settings UI for Codeoid, allowing users to view and modify daemon-wide configuration fields, environment variables, and secrets. It correctly handles various input types (booleans, enums, numbers, arrays, and masked secrets), leverages asynchronous state updates with request/response correlation, and includes robust keymaps and unit tests. No bugs or security issues were found. Findings: 🔴 0 · 🟠 0 · 🟡 0 · 🟢 0 Tokens spent · ⬆️ Input: 15,888 · ⬇️ Output: 95 · Σ Total: 22,266 |
- SettingsEdit no longer feeds Ctrl/Alt-modified chars into the field buffer, so a shortcut chord (Ctrl+A, Alt+F, …) can't insert its base letter. - render_settings now scrolls: a fixed tab-rail header + a fixed footer, with the field body in its own viewport that follows the selected field. Tabs with more fields than fit no longer clip the selection off-screen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Collaborator
Author
|
/gemini-review |
Address the second Gemini pass on #27: edit_string_to_value returned Null on a parse failure, and Null clears the setting — so a typo like "12a" would silently delete the value on save. Return the raw string instead; the daemon's schema validation then rejects it with a visible error. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Collaborator
Author
|
/gemini-review |
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.
What
PR 3 of 3 — the codeoid-ui (TUI) counterpart to the config-file-driven settings surface. A tabbed settings screen that is a pure renderer of whatever manifest the daemon serves over
settings.schema(daemon-wide — no session needed). Companion to the daemon (highflame-ai/codeoid#186) + web (highflame-ai/codeoid#187).How
codeoid-protocolClientMessage:settings.schema/settings.get/settings.set(+SettingPatch).DaemonMessage:settings.{schema,get,set}.result+ the manifest/snapshot types (SettingsManifest/Tab/Group/Field/Option/Snapshot/State/SecretStatus/Error).kind/backing/sourceare strings so a new value the daemon introduces never breaks deserialization.connection.rs:client_kind/daemon_kindarms for the new messages.codeoid-tuiSettingsModalstate — tabs, field cursor, staged edits (dirty), an inline text-edit buffer, secret status, save + restart tracking.ModalKind::Settings(nav) +ModalKind::SettingsEdit(text buffer), each with aresolveblock + tests — mirrors the existing UiDialog choice/text split.app.rs):open_settings(fetch manifest + values), field/tab nav, activate (toggle boolean · cycle enum · open the buffer for text/number/secret), clear, save (onesettings.setbatch), refresh, and the three result arms inapply_daemon(staleness-guarded like Capabilities).ui/modal.rs): tab pills + grouped fields, per-kindcontrol display, provenance / secret-source /⟳restartbadges, the edit buffer, and a footer showing the on-diskconfig.json+.envpaths./settings(aliases/config,/prefs) slash command + catalog entry.Interactions
↑↓/jkfield ·←→/hltab ·Enter/Spacetoggle-cycle-or-edit ·ssave ·aadvanced ·xclear ·rrefresh ·Esc/qclose. In edit mode: type,Entercommits,Esccancels. Secret values are never fetched or shown — only presence + source, with a write-only buffer.Wire-additive: against an older daemon without the settings RPC, the fetch simply errors and the modal surfaces it.
Checks
cargo fmt --all -- --check✅ ·cargo build --all-targets✅ ·cargo test✅ (314+ pass) ·cargo clippy— only the repo's pre-existing pedantic warnings.🤖 Generated with Claude Code