anomalyco / anomalyco/opencode
tui: theme token rename in 2.0.9 silently breaks plugin text colors
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Summary
OpenCode 2.0.9 renamed the resolved text theme tokens (text.subdued → text.muted, text.feedback.<kind>.default → text.feedback.<kind>.base) without keeping aliases. TUI plugins that look up the old names get undefined, and their text falls back to the terminal's default foreground — every plugin-rendered cell (e.g. footer statusline segments) loses its muted/info/error colors on 2.0.9.
Environment
- opencode version: 2.0.9
- OS: Linux 6.18.33.2-microsoft-standard-WSL2 (linux x64)
- Terminal: TERM_PROGRAM=vscode, TERM=xterm-256color, COLORTERM=truecolor
- Shell: /usr/bin/zsh
- Install/channel: latest (global bun install)
- Active plugins: none needed for the reproduction below
Reproduction
Minimal probe plugin, no credentials or session required.
~/.config/opencode/plugins/token-probe/index.ts:
import { Plugin } from "@opencode/plugin"
export default Plugin.define({ id: "token-probe", setup() {} })
~/.config/opencode/plugins/token-probe/tui.tsx:
/** @jsxImportSource @opentui/solid */
import { Plugin, usePlugin } from "@opencode/plugin/tui"
function Probe() {
const ctx = usePlugin()
return (
<box flexDirection="row">
<text fg={ctx.theme.text.subdued}>subdued </text>
<text fg={ctx.theme.text.muted}>muted</text>
</box>
)
}
export default Plugin.define({
id: "token-probe.tui",
setup(context) {
const unregister = context.ui.slot({ append: "prompt.footer.status", render: () => <Probe /> })
return () => unregister()
},
})
- Open
opencodein a terminal. - Capture the footer with ANSI, e.g.
tmux capture-pane -eon the pane.
Expected Behavior
Both cells render with theme colors (both tokens should resolve to the same muted color), or the rename is surfaced as a breaking plugin API change.
Actual Behavior
On 2.0.9 only the new name resolves; the old name is undefined and fg={undefined} renders the terminal default color:
subdued ^[[38;2;255;255;255mmuted^[[38;2;128;128;128m
^ white (no token) ^ theme muted
ctx.theme.text.muted / ctx.theme.text.feedback.error.base exist, text.subdued / feedback.error.default do not. Comparing the published packages confirms the rename: @opencode/theme@2.0.8 defines text.default / text.subdued and feedback.*.default; 2.0.9 defines text.base / text.muted and feedback.*.base.
Same effect with a real published plugin (opencode-go-statusline@0.3.1, tmux capture-pane -e):
- 2.0.8:
Weekly 74%emitted as\x1b[38;2;86;182;194m(info color) - 2.0.9: the same segment emitted as
\x1b[38;2;255;255;255m
Additional Context
- Broke three independently published plugins the same way (OpenCode Go, GitHub Copilot, and Kimi For Coding statuslines); all are read-only consumers of
ctx.theme. - Downstream compatibility fix that reads both names, with live before/after captures: lnwu/opencode-statusline-plugins#50 — repo: https://github.com/lnwu/opencode-statusline-plugins
- Suggestion: keep
subdued/defaultas aliases in the resolved theme, or document the rename as a breaking change.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the published @opencode/theme token definitions and the TUI plugin ctx.theme lookup, then run the minimal token-probe reproduction from the issue. Done means the old token names resolve compatibly as aliases, or the rename is explicitly surfaced and documented as a breaking plugin API change.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, cli
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100