Skip to content

Flatten opencode config to ~/.ucode/opencode.json and reclaim the orphaned opencode-xdg folder #419

Description

@larsmoan

Background

#387 stopped ucode redirecting XDG_CONFIG_HOME and named its config file with
OPENCODE_CONFIG instead. That fix leaves two things behind.

  1. The directory is still called opencode-xdg, but ucode no longer exports it
    as an XDG config home. The name describes a job that no longer exists.
  2. OpenCode installed @opencode-ai/plugin into that folder while the redirect
    was active — about 62 MB in ~/.ucode/opencode-xdg/opencode/node_modules.
    After fix(opencode): honor the user's own opencode config #387, OpenCode uses ~/.config/opencode/ again, so that copy is unused.

OPENCODE_CONFIG names the file directly, so the two nested directory levels
no longer serve any lookup rule. The honest layout is a flat file beside the
backup that already lives there:

~/.ucode/
├── state.json
├── opencode.json                  ← moved here
├── opencode-config.backup.json    ← already at this level
└── opencode-xdg/                  ← removed, reclaims ~62 MB

Do not force a reinstall

The MCP server list lives in ~/.ucode/state.json under mcp_servers; ucode
renders it into opencode.json. The render is diff-gated in
apply_mcp_server_changes — it writes only when the server list changes. A path
change does not change state, so re-running ucode mcp add writes nothing. A
user could not repair a lost render by re-running the command. So the port must
carry the file across, not re-render it.

Plan

Move the file once, on the launch path, then delete the old folder.

_LEGACY_CONFIG_PATH = APP_DIR / "opencode-xdg" / "opencode" / "opencode.json"

def _adopt_legacy_config() -> None:
    if _LEGACY_CONFIG_PATH.exists() and not OPENCODE_CONFIG_PATH.exists():
        OPENCODE_CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
        _LEGACY_CONFIG_PATH.replace(OPENCODE_CONFIG_PATH)

Call it at the top of write_tool_config, write_mcp_server_config, and
remove_mcp_server_config. Then remove ~/.ucode/opencode-xdg/ once the file
is adopted, to reclaim the 62 MB. A move beats a re-render: it works offline, it
carries every key rather than only the ones state knows, and it stays
deterministic. The not OPENCODE_CONFIG_PATH.exists() guard makes it idempotent
and stops a new file being overwritten.

Tests

  • legacy file present, new file absent → file adopted, folder removed
  • both present → new file kept, legacy folder removed
  • neither present → no-op

Open item to confirm first

Verify where OpenCode installs node_modules once the config file sits at
~/.ucode/opencode.json. Evidence from #387 says OpenCode still treats
~/.config/opencode/ as its config home (it reads permissions and
disabled_providers from there), so the install should land there, not back in
~/.ucode/. Confirm with one run before deleting the old folder in code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions