Skip to content

fix(opencode): honor the user's own opencode config - #387

Open
larsmoan wants to merge 8 commits into
databricks:mainfrom
larsmoan:fix/opencode-honor-user-config
Open

fix(opencode): honor the user's own opencode config#387
larsmoan wants to merge 8 commits into
databricks:mainfrom
larsmoan:fix/opencode-honor-user-config

Conversation

@larsmoan

@larsmoan larsmoan commented Aug 25, 2026

Copy link
Copy Markdown

Fixes #391.

Before this, ucode opencode ignored your ~/.config/opencode/. Now it honors it.

The fix

One line, in build_runtime_env:

-    env["XDG_CONFIG_HOME"] = str(OPENCODE_XDG_CONFIG_HOME)
+    env["OPENCODE_CONFIG"] = str(OPENCODE_CONFIG_PATH)

The two variables answer different questions. XDG_CONFIG_HOME answers "where is
the config folder?". OPENCODE_CONFIG answers "which extra config file should I
also read?".

ucode set the first one to its own folder. OpenCode then appended opencode to
that folder and read from there, so ~/.config/opencode/ was not a config
location at all. The user's permissions, MCP servers, disabled_providers,
skills, agents, plugins and global AGENTS.md all disappeared.

OPENCODE_CONFIG names one file instead. ucode leaves XDG_CONFIG_HOME alone,
so OpenCode still reads the user's folder and merges ucode's file on top.

Before and after

Before: ucode replaced the config location. Your config was invisible.

After: ucode adds one file at slot 3. Both are read and merged. ucode
outranks your global config, and a project config still outranks ucode.

Where slot 3 is

OpenCode has eight config sources. A later source overrides an earlier one:

# Source
1 Remote config
2 Global config — ~/.config/opencode/opencode.json ← the user's
3 Custom config via OPENCODE_CONFIG ← ucode's
4 Project config — opencode.json in the repo
5 .opencode/ directories
6 Inline config env var
7 Managed config files
8 macOS MDM preferences

"Overrides" means the later source wins a conflict. It does not replace the file.
A scalar from the higher layer wins, so ucode keeps model. Objects merge key by
key, so the user's MCP servers and ucode's both survive. Arrays are replaced
whole, which is why ucode writes no top-level array — one would wipe the user's
disabled_providers.

ucode still writes only its own file, and the path is unchanged, so servers from
ucode mcp add survive.

Verification

opencode debug config before the change shows only ucode's keys. After the
change it shows the user's permission, disabled_providers and MCP servers
merged with ucode's model, provider and MCP server. A launched
ucode opencode run still reaches the gateway and returns a normal reply.

Tests

uv run --frozen pytest: 1989 passed, 41 skipped. ruff check .: clean.

Three new tests cover the swap: ucode names its own file, it passes an existing
XDG_CONFIG_HOME through unchanged, and it never adds that variable itself.

larsmoan and others added 2 commits August 25, 2026 14:31
ucode exported XDG_CONFIG_HOME to send opencode to its own directory. That
removed all of ~/.config/opencode from opencode's load path. Thus the user's
permission rules, MCP servers, disabled_providers, global skills, agents,
commands, plugins, tui.json and global AGENTS.md had no effect in a ucode
session.

Name ucode's file with OPENCODE_CONFIG in place of the redirect. OPENCODE_CONFIG
is a config layer above the user's global config, and opencode merges the layers.
Objects merge one key at a time and the later scalar wins. Thus ucode keeps
control of `model` and `provider`, and the user keeps everything else. ucode
still writes to its own file only.

The config file path does not change, so MCP servers that `ucode mcp add`
registered survive the upgrade.
@larsmoan
larsmoan marked this pull request as ready for review August 25, 2026 20:11
Copilot AI lite review requested due to automatic review settings August 25, 2026 20:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the OpenCode agent integration so ucode opencode no longer hides the developer’s existing OpenCode config under ~/.config/opencode/. Instead of redirecting XDG_CONFIG_HOME, ucode now points OpenCode at ucode’s generated config via OPENCODE_CONFIG, allowing OpenCode to merge configs as intended while keeping ucode’s config written under ~/.ucode/.

Changes:

  • Stop exporting XDG_CONFIG_HOME for OpenCode; set OPENCODE_CONFIG to ucode’s generated config file instead.
  • Update e2e/unit tests to avoid reading the developer’s real ~/.config/opencode by setting XDG_CONFIG_HOME to a test-only empty location.
  • Document the OpenCode managed file path as a layering config in the README.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/ucode/agents/opencode.py Switch runtime env construction from XDG_CONFIG_HOME redirection to OPENCODE_CONFIG layering.
tests/test_agent_opencode.py Adjust unit tests to assert OPENCODE_CONFIG is used and XDG_CONFIG_HOME is not overridden.
tests/test_e2e.py Update OpenCode e2e launches to keep tests hermetic now that XDG_CONFIG_HOME isn’t redirected by ucode.
tests/test_e2e_user_agent.py Update OpenCode user-agent e2e test env to use OPENCODE_CONFIG plus an empty XDG_CONFIG_HOME.
README.md Update managed-local-files table to reflect OpenCode’s config layering behavior and ucode-managed path.
Suppressed comments (1)

tests/test_e2e.py:872

  • Same hermeticity concern here: XDG_CONFIG_HOME is pointed at tmp_path/empty-xdg but the directory isn’t created, which can allow fallbacks to the developer’s real config depending on opencode’s lookup behavior.
        monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path / "empty-xdg"))

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tests/test_e2e.py
Comment thread tests/test_e2e_user_agent.py
Copilot AI review requested due to automatic review settings August 25, 2026 23:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Comment thread tests/test_agent_opencode.py Outdated
The single test asserted only that build_runtime_env adds no
XDG_CONFIG_HOME when the variable is absent. A reintroduced redirect
that overwrites a value the user already set would have passed. Split
the case in two so the pass-through is asserted with a sentinel.
Copilot AI review requested due to automatic review settings August 25, 2026 23:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings August 26, 2026 20:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings August 27, 2026 07:34

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Comment thread tests/test_agent_opencode.py Outdated
The old test restated the module constants and over-reached by asserting
~/.config is not a parent. Pin the literal path instead: a rename orphans
the MCP servers that ucode mcp add wrote there. Rewrite two comments to
state the constraint, not the history or the design rationale.
Copilot AI review requested due to automatic review settings August 31, 2026 07:34

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings August 31, 2026 08:48
@larsmoan

larsmoan commented Aug 31, 2026

Copy link
Copy Markdown
Author

@rohita5l @AarushiShah-db @lilly-luo @Edwinhe03 this is ready for review. The one-line fix swaps XDG_CONFIG_HOME for OPENCODE_CONFIG so ucode layers its config over the user's own ~/.config/opencode instead of replacing it. All four Copilot threads are resolved, pytest is green (1989 passed) and ruff is clean. I cannot add reviewers from my fork, so a formal request from someone with write access would help.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ucode opencode ignores the user's own OpenCode config

2 participants