fix(desktop): agent config panel ignores project-level Claude settings
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## Summary
The agent config panel shows Claude Code settings read **only** from `~/.claude/settings.json`, ignoring the project-level `.claude/settings.json` inside the agent's working directory. Claude Code itself merges user + project settings (project wins), so the panel displays values that are not the ones actually in effect.
Separately, the "From config file (…)" attribution line is a compile-time constant, not the path the value was actually read from — so even after fixing the merge, the panel would still name the wrong file.
Every field surfaced by the Claude bridge is affected: **Thinking effort, Cleanup period days, Enable workflows, and Theme.**
## Environment
- Buzz Desktop 0.5.11 (packaged OSS release), Windows 11
- Runtime: `claude`
## Reproduction
1. Have `~/.claude/settings.json` contain `{"effortLevel": "low"}`.
2. Create `~/.buzz/.claude/settings.json` containing `{"effortLevel": "medium"}` (`~/.buzz` is the agent nest, i.e. the agent's working directory).
3. Restart Buzz, open a managed Claude agent's config panel.
**Expected:** Thinking effort shows `medium`, attributed to the project file.
**Actual:** Thinking effort shows `low`, attributed to `~/.claude/settings.json`.
The agent genuinely runs at `medium` — `CLAUDE_EFFORT=medium` in the spawned process environment confirms the project file is applied at runtime. Only the panel is wrong.
## Root cause
**1. The bridge never sees the working directory.**
`desktop/src-tauri/src/managed_agents/config_bridge/claude.rs:4`
```rust
pub(super) fn read_config_file() -> Option {
let home = dirs::home_dir()?;
let settings_path = home.join(".claude").join("settings.json");
```
The function takes no arguments. The home directory is hardcoded, so a project-level settings file is not merely ignored — it is unreachable. Called from `config_bridge/reader.rs:25`, which also has no cwd to pass.
**2. The displayed path is a `&'static str`.**
`desktop/src-tauri/src/managed_agents/discovery/runtime_metadata.rs:45`
```rust
pub config_file_path: Option<&'static str>,
```
`desktop/src-tauri/src/managed_agents/discovery.rs:136`
```rust
config_file_path: Some("~/.claude/settings.json"),
```
Rendered verbatim at `desktop/src/features/agents/ui/AgentConfigPanel.tsx:157`:
```ts
case "configFile":
return configFilePath
? `From config file (${configFilePath})`
: "From config file";
```
So the attribution line is a per-runtime constant, not provenance. It reports the same path regardless of where the value came from.
**Why all four fields are affected:** none are special-cased. `claude.rs:26` passes the whole JSON object to `schema_walker::extract_config_fields`, which surfaces every key it finds. All four ride the same path.
## Suggested fix
1. Give `read_config_file()` the agent's working directory and merge project settings over user settings, matching Claude Code's own precedence.
2. Make the source path per-field rather than one constant for the whole panel, so each row can honestly name the file its value came from. This is the larger change — it touches `config_bridge/types.rs`, `reader.rs:148`, and the panel props, and the same shape likely applies to the `codex`, `goose`, and `buzz-agent` bridges.
(2) could reasonably ship separately; (1) alone would already make the displayed values correct.
`claude.rs` has an existing unit-test block that new merge cases could slot into.
Contributor guide
Research direction
Start with desktop/src-tauri/src/managed_agents/config_bridge/claude.rs and its existing unit-test block, then trace the call through config_bridge/reader.rs. Review runtime_metadata.rs, discovery.rs, and AgentConfigPanel.tsx for config-path handling; done means project settings are reflected with the correct precedence and the panel's attribution matches the value source.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust, typescript
- Domain
- backend, desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100