anomalyco / anomalyco/opencode

cli: saving preferences replaces symlinked cli.json

Open
#45,067 2 comments 0 reactions 1 assignee View on GitHub

@jlongster is already working on this.

Since Aug 25, 2026.

2.0
Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Summary

Saving CLI preferences replaces a symlinked ~/.config/opencode/cli.json with a regular file. This breaks dotfile management tools such as GNU Stow and causes the live preferences to diverge from the version-controlled target.

Environment

  • opencode version: opencode2 v0.0.0-beta-18219
  • OS: Ubuntu Linux 6.8.0-124-generic x86_64
  • Terminal: TERM=xterm-256color
  • Shell: /usr/bin/zsh
  • Install/channel: npm beta, managed by mise
  • Active plugins: ~/.config/opencode/plugins/herdr-agent-state.js, @plannotator/opencode@latest

Reproduction

  1. Store cli.json in a dotfiles repository and symlink it to ~/.config/opencode/cli.json (for example, with GNU Stow).
  2. Open OpenCode v2 and change a CLI preference such as the theme.
  3. Inspect ~/.config/opencode/cli.json with ls -l or test -L.

Expected Behavior

OpenCode should preserve the symlink and update its target, or otherwise avoid replacing the user-managed configuration path.

Actual Behavior

OpenCode removes the symlink and creates a regular ~/.config/opencode/cli.json containing the updated preferences. The Stow-managed target remains unchanged, so subsequent dotfile reconciliation reports a conflict or must preserve the new file and recreate the symlink.

Additional Context

This reproduces when changing preferences through the v2 CLI UI. A reconciliation adapter currently works around it by diffing and backing up the replacement file, removing it, and letting Stow restore the symlink.

Example before changing a preference:

~/.config/opencode/cli.json -> ../../.dotfiles/stow/opencode/.config/opencode/cli.json

After changing a preference, cli.json is a regular file rather than that symlink. This is likely caused by an atomic write implemented as writing a temporary file and renaming it over cli.json; symlink-aware persistence would avoid disconnecting the managed target.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.