feat: add obk settings interactive TUI#103
Merged
priyanshujain merged 31 commits intomasterfrom Mar 19, 2026
Merged
Conversation
Pure service layer for browsing and editing all obk settings via Get/Set closures on config fields. Includes full tree of categories (General, Models, Channels, Data Sources, Integrations, Advanced) with nil-pointer safety and credential store abstraction.
Tree browser with expand/collapse categories, inline value display, and huh form editing. Supports string, select, bool, number, and password field types with viewport scrolling.
Wires settings service and TUI into the CLI with credential store/load from keychain.
These are now directly imported by the settings TUI package.
…cases Covers save error propagation, nil credential handlers, select field round-trips (profile, auth method), context window/compaction threshold, nil-pointer safety for integrations/websearch/daemon, telegram owner_id, password empty-set noop, loadCred failure fallback, and GWS fields.
- Move Providers category above model fields in the tree - Model tier fields are now TypeSelect with OptionsFunc that shows only models from providers with configured API keys - Profile select filters to profiles whose required providers are all configured - API key fields get AfterSet hook for live verification - Add OptionsFunc, AfterSet, verifyProvider to service types
- editor.go passes svc to resolve OptionsFunc at form build time - model.go calls AfterSet on successful save, appends status to flash
Registers provider factories and adds live API key verification using a tiny test call (5 tokens, 10s timeout) with the cheapest model for each provider.
Tests for: providers before models in tree, model tiers are selects, options filtered by configured providers, empty-providers placeholder, profile filtering, AfterSet verify success/failure, ResolvedOptions fallback, nil verifyProvider handler.
Support custom edit handlers (wizards) and conditional read-only fields for the profile-first settings flow.
Helpers for profile selection with dynamic preview, API key prompts, provider selection, and model selection forms.
Rewrite registry to use profile wizard as primary entry point. Fixed profiles lock model tiers. Custom profiles allow per-tier model selection. Provider auth verified before saving. Providers moved to bottom of tree.
Support EditFunc wizards by quitting bubbletea, running the wizard synchronously, then restarting TUI. Add ReadOnly flash message for locked fields.
Replace provider-first tests with profile display, EditFunc, ReadOnly, masked key, and dynamic model options tests.
…-flash gemini-2.0-flash-lite is deprecated/404. Replace all references across profiles, model catalog, context windows, test models, and docs.
Models → LLM Models, Profile → LLM Cost Profile, "(1 API key)" → "(single provider)" on all single-provider profiles.
Cost profiles (starter/standard/premium) first, single-provider next. Profile list labels simplified to just p.Label; description shown via ProfilePreview in DescriptionFunc.
ListModels calls each provider's free list-models API to enumerate available models. VerifyModelAccess sends a minimal chat to confirm the API key has access to a specific model. Includes httptest tests for all 5 providers including Anthropic pagination.
JSON-based cache at ~/.obk/models/<provider>.json with TTL staleness check and per-model verification tracking keyed by API key hash.
Replace chat-based verification (sends "Reply with OK") with the free ListModels API. Results are cached to ~/.obk/models/ for later use.
modelOptionsForTier and buildTierOptions now read from the model cache populated by ListModels instead of the static ModelCatalog. ModelCatalog, ModelsForProviders, and ModelsForTier removed. ModelInfo type kept.
EditFunc is no longer needed — profile wizard now runs inline in the bubbletea TUI. Save() exposes saveFn for the TUI model.
Remove profileWizard, setupFixedProfile, setupCustomProfile, configureProviderAuth, buildProfileSelectOptions — all replaced by inline TUI state machine in model.go.
Huh form wrappers (runProfileSelect, promptAPIKey, selectProvider, selectModel) are no longer needed — forms are built inline in TUI.
EditFunc field was removed from Field struct.
Single tea.NewProgram run — profile wizard now runs inline as TUI state transitions instead of quitting and restarting.
Add wizard states (profileSelect, providerAuth, verifying, modelSelect) to TUI model. Background model cache loading on init. Async provider verification via tea.Cmd. No more screen flicker from quitting and restarting bubbletea.
Bubbletea uses value receivers — pointers to model struct fields become dangling after Update copies. Allocate wizardProfile and wizardAPIKey on the heap so huh forms write to a stable address. This fixes profile selection picking the wrong profile.
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.
Summary
obk settingscommand — an interactive TUI tree browser for browsing and editing all settings after initial setupsettings/) with Get/Set closures on*config.Config— no reflection, no UI deps — ready for web UI or HTTP API laterinternal/settings/tui/) with expand/collapse categories, inline values, huh form editing, and viewport scrolling*)Test plan
go build ./...compilesgo test ./settings/...— 31 tests passobk settingsappears inobk --helpobk settings— TUI launches, tree renders with current config values~/.obk/config.yamlEsc/qexits cleanly