feat IDE Integration: Live text selection and diff review/approval.
Forgive me for being a Claude Code user up until this point; excited about being able to contribute to an open workflow instead of opening tickets and watching them go stale. One aspect of my workflow I really enjoy is the ability to send my highlights directly into context, and also have diffs appear in my IDE.
This patch uses the existing coder/claudecode.nvim (and probably the existing VSCode extension I haven't tested yet) to connect opencode to the websocket server they provide.
After installing the plugin, launch opencode and use the /ide command to select from the available open sockets. In nvim visual mode your selection will be automatically updated in the prompt window. When the agent proposes a change the diff will appear in the IDE and can either be approved inside the IDE or in the terminal session.
In order to not hard-code any third party references, I made a couple config updates to opencode.json that are necessary for this to work:
{
"ide": {
"lockfile_dir": "/Users/tcdent/.claude/ide/",
"auth_header_name": "x-claude-code-ide-authorization"
}
}
Also, in order to get diff approval to wait for input, setting permission is necessary:
{
"permission": {
"edit": "ask"
}
}
This is more of a PoC than a production-ready feature and I'm sure everyone on the team here has some opinion about this, so I'm happy to continue working on this. For one thing, we should coordinate with an existing plugin maintainer for an opencode-specific integration. For now, this has made opencode a drop-in replacement for my existing workflow, and I'm excited to own my entire dev environment again.
Suggested UX improvements for IDE selection display
Hey @tcdent, great work on this PR! I've been testing it and made a few UX improvements that make the selection behavior closer to Claude Code:
Changes:
1. Compact footer display (local.tsx)
- Shows
X linesinstead of full path + line numbers - Less cluttered, easier to read
2. Persistent selection (prompt/index.tsx)
- Selection stays visible after sending a message
- Only updates when you select new text in IDE
3. Invisible context for model (prompt/index.tsx)
- Selection content sent as
synthetic: truepart - Model can read it, but it doesn't clutter the chat history
Code changes:
local.tsx - simplified formatted()
formatted: () => {
const sel = selStore.current
if (!sel || !sel.text) return null
const lines = sel.text.split("\n").length
return \
},
prompt/index.tsx - synthetic part for selection
parts: [
{
id: Identifier.ascending("part"),
type: "text",
text: inputText,
},
...(local.selection.current()?.text ? [{
id: Identifier.ascending("part"),
type: "text" as const,
text: \,
synthetic: true,
}] : []),
...nonTextParts.map((x) => ({
id: Identifier.ascending("part"),
...x,
})),
],
prompt/index.tsx - remove selection.clear() after submit
- local.selection.clear()
Let me know if you'd like me to open a separate PR with these changes!
Update: Also added IDE/selection display to \ footer, so it's visible from launch (not just inside sessions).
@tofunori Stoked you're finding use for it. By all means continue to improve on this PR; I'm not emotionally attached to any of the implementation details.
Cheers! Hope it could get merged !