refactor(config): make the settings contract frontend-agnostic
rhema-config held both vocabularies: the stored settings and the terminal UI's theme, palette, and onboarding state, under one Config type with a global directory. A second frontend had to take the UI settings to get the profiles, and every path helper resolved $XDG_CONFIG_HOME/rhema no matter who called. The crate now ships only the framework's contract. Settings is the stored section, flattenable as one serde field. Home carries the directory conventions as a value, so a frontend keeps its settings, skills, subagents, and SYSTEM.md under its own base while .agents/skills stays machine-global. Store is the seam a foreign frontend implements over its own file and format, YamlStore is the reference impl, and Platform collects home, store, and keychain namespace at one construction site. KeyringSecretStore::named gives each frontend its own OS keychain service, so two frontends never share credentials by accident. examples/godcode.rs builds the whole shape runnable: its own directory, its own JSON document, its own namespace. rhema-code's store::Document flattens the section beside its UI fields, the layout on disk unchanged. serde's flatten silently drops unknown keys, so the load path re-checks every leftover key against the section: a typo'd profiles: stays loud inside the bigger document. CodingAgentConfig gains home: Option<Home>, so a frontend redirects skill discovery without calling the framework. claw and acp name their keychain namespaces, and the mcp, coding-agent, and subagents crates read conventions from the Home they are handed.
This commit is contained in:
1 parent
d067f4632f
commit
df4cf87a20
2 files changed
+4
-4
No files matched your search
@@ -210,7 +210,7 @@ impl ClawConfig {
|
|||||||
/// The default config path: `<config-base>/rhema/claw.yaml`, the same
|
/// The default config path: `<config-base>/rhema/claw.yaml`, the same
|
||||||
/// base the stored rhema config lives under.
|
/// base the stored rhema config lives under.
|
||||||
pub fn default_path() -> Result<PathBuf, ConfigError> {
|
pub fn default_path() -> Result<PathBuf, ConfigError> {
|
||||||
Ok(rhema_config::Config::dir()?.join("claw.yaml"))
|
Ok(rhema_config::Home::discover()?.config.join("claw.yaml"))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The state dir: `$XDG_STATE_HOME/rhema/claw`, else
|
/// The state dir: `$XDG_STATE_HOME/rhema/claw`, else
|
||||||
|
|||||||
@@ -169,11 +169,11 @@ fn mock_backends() -> Arc<rhema_claw::BackendRegistry> {
|
|||||||
/// the keyless llama-cpp backend is always constructible — and a
|
/// the keyless llama-cpp backend is always constructible — and a
|
||||||
/// dispatch against an unreachable provider fails loudly per turn.
|
/// dispatch against an unreachable provider fails loudly per turn.
|
||||||
fn resolve_backends(config: &ClawConfig) -> Result<Arc<rhema_claw::BackendRegistry>, ClawError> {
|
fn resolve_backends(config: &ClawConfig) -> Result<Arc<rhema_claw::BackendRegistry>, ClawError> {
|
||||||
let stored = match rhema_config::Config::load() {
|
let stored = match rhema_config::Settings::load() {
|
||||||
Ok(stored) => stored,
|
Ok(stored) => stored,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("warning: ignoring unreadable rhema config: {err}");
|
eprintln!("warning: ignoring unreadable rhema config: {err}");
|
||||||
rhema_config::Config::default()
|
rhema_config::Settings::default()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let profile = stored.effective(None);
|
let profile = stored.effective(None);
|
||||||
@@ -205,7 +205,7 @@ fn resolve_backends(config: &ClawConfig) -> Result<Arc<rhema_claw::BackendRegist
|
|||||||
// included; it never writes it, so no migration runs here — the
|
// included; it never writes it, so no migration runs here — the
|
||||||
// file's logins belong to the frontends. In a container the
|
// file's logins belong to the frontends. In a container the
|
||||||
// keychain is unreachable and the literal tier serves.
|
// keychain is unreachable and the literal tier serves.
|
||||||
let secrets = rhema_config::secrets::KeyringSecretStore::new();
|
let secrets = rhema_config::secrets::KeyringSecretStore::named("claw");
|
||||||
let backends =
|
let backends =
|
||||||
rhema_claw::backends::discover(config, &profile, &env, &claw_rows, Some(&secrets));
|
rhema_claw::backends::discover(config, &profile, &env, &claw_rows, Some(&secrets));
|
||||||
// The config's provider/model pair seeds the active backend when it
|
// The config's provider/model pair seeds the active backend when it
|
||||||
|
|||||||
Reference in new issue
Block a user