Skip to content

refactor(config): Unify sub-configs behind CollectionConfig + utils.{Load,Save}YAML#445

Merged
edenreich merged 2 commits intomainfrom
refactor/config-collection-interface
Apr 26, 2026
Merged

refactor(config): Unify sub-configs behind CollectionConfig + utils.{Load,Save}YAML#445
edenreich merged 2 commits intomainfrom
refactor/config-collection-interface

Conversation

@edenreich
Copy link
Copy Markdown
Contributor

@edenreich edenreich commented Apr 26, 2026

Summary

  • Adds config/utils package with generic LoadYAML[T] / SaveYAML[T] helpers (always env-expanded, always emit ---\n doc marker). Five sub-configs (mcp, channels, agents, prompts, keybindings) each lose ~30 lines of Load/Save boilerplate.
  • Adds config.CollectionConfig[E] interface explicitly implemented by MCPConfig and AgentsConfig via compile-time assertions and per-method doc comments. Unified vocabulary: CreateEntry / ReadEntry / UpdateEntry / DeleteEntry / ListEntries.
  • Deletes all ten CRUD shims (AddMCPServer/AddAgent/etc.) and migrates every call site in cmd/mcp.go, cmd/agents.go, and the test files to call the methods directly via LoadX(). One way to do CRUD now.
  • Test files unified one-per-source: mcp_test.go and prompts_test.go absorb their *_persistence_test.go counterparts; agents/keybindings persistence files renamed.

Behavior changes (deliberate)

  • SaveAgents now writes a leading ---\n like the other four savers (cosmetic; YAML parsers ignore it).
  • LoadPrompts and LoadKeybindings now run their YAML body through os.ExpandEnv. Verified safe for current defaults (no $VAR/${VAR} patterns in prompts.go or keybindings.go). Future literal ${…} tokens must be escaped as $$….

…Load,Save}YAML

Five sub-configs (mcp, channels, agents, prompts, keybindings) each
duplicated a Load/Save/Defaults triple — ~200 lines of near-identical
boilerplate. MCP and Agents additionally duplicated CRUD over a named
collection (~80 lines each) under different names (AddMCPServer / AddAgent,
RemoveMCPServer / RemoveAgent, etc.).

This refactor introduces:

- config/utils package with generic LoadYAML[T] and SaveYAML[T] helpers
  (always env-expanded, always emit the YAML doc marker).
- config.CollectionConfig[E] interface explicitly implemented by MCPConfig
  and AgentsConfig with a unified vocabulary: CreateEntry, ReadEntry,
  UpdateEntry, DeleteEntry, ListEntries.
- All ten CRUD shims deleted; cmd/agents.go and cmd/mcp.go migrated to
  call the methods directly via LoadX().

Test files unified one-per-source: mcp_test.go and prompts_test.go absorb
their *_persistence_test.go counterparts; agents and keybindings persistence
files renamed.
Two gaps in `infer init` produced files inconsistent with the rest of
the .infer/ directory:

- config.yaml was written by writeConfigAsYAMLWithIndent (yaml.Encoder
  directly), so it never got the leading `---` doc marker that every
  other config emits.
- agents.yaml was never seeded by `infer init` at all — it appeared only
  after the first `infer agents add`, which used SaveAgents (which on
  main also did not emit `---`).

Replace writeConfigAsYAMLWithIndent with configutils.SaveYAML and add a
createAgentsConfigFile step. Now every file `infer init` writes goes
through the same generic helper and gains the document marker.
@edenreich edenreich force-pushed the refactor/config-collection-interface branch from 0cb50c3 to 495dea3 Compare April 26, 2026 23:47
@edenreich edenreich merged commit aab481c into main Apr 26, 2026
5 checks passed
@edenreich edenreich deleted the refactor/config-collection-interface branch April 26, 2026 23:52
ig-semantic-release-bot Bot pushed a commit that referenced this pull request Apr 27, 2026
## [0.104.1](v0.104.0...v0.104.1) (2026-04-27)

### 🐛 Bug Fixes

* **ui:** Restore typing while agent is busy ([#455](#455)) ([92840d6](92840d6)), closes [#410](#410)
* **services:** Trigger auto-compact from gateway-reported tokens ([#454](#454)) ([1fc19dd](1fc19dd))
* **config:** Update model context windows and pricing for current model lineup ([#452](#452)) ([655f9f8](655f9f8))

### ♻️ Code Refactoring

* **config:** Centralize config loading and remove service indirection ([#443](#443)) ([babf173](babf173))
* **config:** Centralize sub-config definitions and consolidate prompts ([#448](#448)) ([9979ac7](9979ac7))
* Extract keybindings configuration to separate file ([#438](#438)) ([6d04195](6d04195))
* **config:** Generate viper defaults via reflection over DefaultConfig() ([#436](#436)) ([85c6e0a](85c6e0a))
* **config:** Make tool prompts configurable via prompts.yaml ([#450](#450)) ([9fc1bb5](9fc1bb5)), closes [#446](#446)
* Move channels to separate channels.yaml config ([#444](#444)) ([aa43e0e](aa43e0e)), closes [#441](#441)
* Move computer_use to a separate config ([#447](#447)) ([a762c64](a762c64)), closes [#444](#444)
* Move prompts to separate prompts.yaml config ([#442](#442)) ([45e4fb6](45e4fb6))
* **config:** Unify sub-configs behind CollectionConfig + utils.{Load,Save}YAML ([#445](#445)) ([aab481c](aab481c))

### 📚 Documentation

* Add directory-structure reference ([#451](#451)) ([95d26f8](95d26f8))

### 👷 CI/CD

* Reduce runs of nix ([acac364](acac364))

### 🧹 Maintenance

* **deps:** Bump modernc.org/sqlite from 1.49.1 to 1.50.0 ([#449](#449)) ([06a535d](06a535d))
* **nix:** Update package to v0.104.0 ([#432](#432)) ([5564697](5564697))
@ig-semantic-release-bot
Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 0.104.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant