feat(config): split API keys into a sidecar secrets.toml#6
Merged
Conversation
42cde4a to
3f854a4
Compare
There was a problem hiding this comment.
Pull request overview
This PR updates clisense’s configuration model so API keys are no longer stored in the main config.toml, but instead are split into a sidecar secrets.toml (with load-time merge + one-time migration of inline keys). It also updates the TUI to better support multi-cluster workflows (setup form cluster selection + global cluster picker overlay) and makes tab ordering configurable via tabs.order.
Changes:
- Split API keys into
secrets.tomlon save; merge them back intoConfigon load; migrate inlineapi_keyvalues intosecrets.tomlon first load. - Add a global cluster picker (
c) rendered as an overlay, and update setup to allow choosing/creating a cluster. - Add configurable tab ordering via
tabs.order, with validation and updated tab activation/routing.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Documents TOML config layout, cluster picker keys, and the new secrets.toml sidecar + migration behavior. |
| main.go | Enters setup when the loaded config is present but incomplete (NeedsSetup). |
| internal/tui/screens/setup.go | Extends setup flow to include cluster selection/creation and cycling through existing clusters. |
| internal/tui/overlay.go | Introduces helpers to render a centered overlay on top of existing screen content. |
| internal/tui/app.go | Adds cluster picker state/handlers, routes by tab IDs, supports configurable tab order, and overlays picker UI. |
| internal/tui/app_test.go | Adds coverage for tab order, settings save, cluster switching, overlay behavior, and Ctrl+C quit in setup. |
| internal/config/config.go | Switches config persistence to TOML, adds tabs validation, implements secrets sidecar split/merge + migration and legacy YAML fallback. |
| internal/config/config_test.go | Updates/expands tests for TOML paths, legacy YAML fallback, tabs validation, secrets sidecar split/merge, and migration. |
| go.mod | Adds TOML dependency requirement. |
| go.sum | Adds TOML dependency checksums. |
Comments suppressed due to low confidence (1)
internal/tui/app.go:253
- Esc in Settings is documented to "return to Collections", but this handler always activates tab index 0. With a configurable tabs.order, index 0 may not be Collections (and if Settings is first, Esc becomes a no-op). Consider activating the "collections" tab by ID when present, and fall back to index 0 otherwise.
// Settings is a form, so keep Tab/digits/q available for the inputs.
// Esc returns to Collections.
if a.activeTabID() == "settings" {
switch m.String() {
case "esc":
return a, a.activateTab(0)
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+155
to
+160
| public, secrets := splitSecrets(c) | ||
| if err := writeTOML(path, public); err != nil { | ||
| return err | ||
| } | ||
| return writeTOML(SecretsPath(path), secrets) | ||
| } |
Comment on lines
+448
to
+456
| a.cfg.Global.DefaultCluster = names[a.pickIx] | ||
| if err := config.Save(a.cfgPath, a.cfg); err != nil { | ||
| a.pickErr = "save failed: " + err.Error() | ||
| return nil | ||
| } | ||
| a.picking = false | ||
| a.pickErr = "" | ||
| a.c = client.New(a.cfg.URL(), a.cfg.APIKey()) | ||
| a.buildTabs() |
Comment on lines
+209
to
211
| if wasSettings { | ||
| return a, a.activateTab(0) | ||
| } |
Comment on lines
+99
to
+105
| [clusters.local] | ||
| url = "http://localhost:8108" | ||
| api_key = "your-local-admin-api-key" | ||
|
|
||
| [clusters.production] | ||
| url = "https://typesense.example.com" | ||
| api_key = "your-production-admin-api-key" |
|
|
||
| A legacy `config.yaml` at the same path is still loaded if no `config.toml` is present. | ||
|
|
||
| The file is written with `0600` permissions since it holds your API key. |
| github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect | ||
| github.com/muesli/cancelreader v0.2.2 // indirect | ||
| github.com/muesli/termenv v0.16.0 // indirect | ||
| github.com/pelletier/go-toml/v2 v2.2.4 // indirect |
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.
secrets.tomlnext toconfig.tomlon every save, so the main config can be committed to dotfilessecrets.tomlAPI keys back into the loadedConfigon loadapi_keyvalues from an existingconfig.tomlinto a freshly writtensecrets.tomlon first loadClusterConfig.APIKeyasomitemptyso the rewrittenconfig.tomldoes not leave behind emptyapi_key = ""lines.gitignorerecommendation in the READMEdepends on: #5