anomalyco / anomalyco/opencode
opencode attach discovers project-local tui.json but never invokes the plugin's tui() export
@simonklee is already working on this.
Since Sep 1, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Version: opencode-ai 1.18.25 (also reproduced on 1.18.21 — same behavior across both, not a fresh regression tied to a specific patch release)
Environment: opencode attach <url> (run from the host machine) vs. running opencode directly, both against the same already-running opencode web server process, on the same machine, same OpenCode version. In our setup that server happens to run inside a Docker container, but that's a deployment detail — attach-vs-direct-run is what differs here, not the server's hosting environment, and nothing in the reproduction depends on containerization.
Expected: a tui.json-declared plugin's tui(api) export runs when connecting via opencode attach, same as it does when running opencode directly against the same server.
Actual: tui.json is discovered and applied by attach — confirmed in the client-side log:
timestamp=2026-09-01T06:43:16.786Z level=INFO run=2874087d message="loading tui config" path=/home/kufi/Projects/kufis-ai-forge/.opencode/tui.json
timestamp=2026-09-01T06:43:16.798Z level=INFO run=2874087d message="applying tui config" path=/home/kufi/Projects/kufis-ai-forge/.opencode/tui.json order=2
but tui() is never invoked — verified with a plugin that only writes a result file on invocation; no file ever appears via attach, across three attempts with increasing wait times (20s / 20s / 55s, ruling out a timing/race issue), both with and without the plugin's local deps pre-cached. The identical plugin, identical tui.json, loads and runs correctly when the same OpenCode instance is driven via opencode directly instead of attach.
Repro: exact plugin used (project-local, declared in tui.json as "plugin": ["./plugins-tui-test/test-sidebar.tsx"]):
/** @jsxImportSource @opentui/solid */
import type { TuiPluginModule } from "@opencode-ai/plugin/tui"
import { writeFileSync } from "node:fs"
const RESULT_FILE = "/path/to/project/.opencode/plugins-tui-test/result.json"
const plugin: TuiPluginModule = {
id: "invocation-probe",
async tui(api) {
try {
api.slots.register({
slots: { sidebar_content(_ctx, _props) { return <text>probe</text> } },
})
writeFileSync(RESULT_FILE, JSON.stringify({ invoked: true, registerOk: true }))
} catch (error) {
writeFileSync(RESULT_FILE, JSON.stringify({ invoked: true, registerOk: false, error: String(error) }))
}
},
}
export default plugin
The slots.register/JSX call isn't required to demonstrate the gap (only the file write matters) — kept as-is because it's the exact code that was run, not a simplified rewrite. Start the server (opencode web or equivalent), then compare opencode attach <url> --dir <project> against running opencode directly in that project directory — check for RESULT_FILE after each.
Note: not the same issue as #36525 (that's about opencode2 next-builds never invoking any TUI plugin at all, including local); this is specifically about attach behaving differently from direct invocation on the same stable (1.x) line — discovery works, invocation doesn't, only over attach.
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.
Assessment
This issue has not been assessed yet.