1
0
Fork
You've already forked opencode.el
0
forked from sczi/opencode.el
Emacs interface to opencode
  • Emacs Lisp 100%
Hayato Kajiyama 05fdd7cb36 Drop opencode-add-clipboard-screenshot in favor of upstream yank-media
Upstream now supports clipboard image paste via the built-in yank-media
handler, which is cross-platform and does not require pngpaste.
2026年05月07日 15:06:43 +09:00
.opencode enable emacs skill always for build agent 2026年04月18日 17:24:37 -04:00
screenshots update session_with_diff screenshot 2026年04月19日 22:43:31 -04:00
.dir-locals.el minor edits 2026年01月14日 18:15:28 -05:00
.gitattributes add README 2026年01月14日 16:01:57 -05:00
.gitignore initial opencode-mode 2025年12月25日 18:05:06 -05:00
AGENTS.md replace elisp-dev-mcp with skill to use emacsclient 2026年04月17日 19:58:13 -04:00
LICENSE start 2025年12月25日 17:27:27 -05:00
opencode-api.el add opencode-delete-message command C-c D 2026年04月19日 22:43:31 -04:00
opencode-common.el Improve session recovery, todo discovery, and title handling 2026年05月07日 15:04:29 +09:00
opencode-format-tool-calls.el Unify directory and model metadata handling 2026年05月07日 15:03:29 +09:00
opencode-permission.el toast and add to alerted sessions when buffer inactive 2026年04月22日 19:25:13 -04:00
opencode-question.el open session on question or permission request 2026年04月22日 19:10:12 -04:00
opencode-sessions.el Drop opencode-add-clipboard-screenshot in favor of upstream yank-media 2026年05月07日 15:06:43 +09:00
opencode.el Improve session recovery, todo discovery, and title handling 2026年05月07日 15:04:29 +09:00
README.org Improve session recovery, todo discovery, and title handling 2026年05月07日 15:04:29 +09:00

Emacs OpenCode UI

An emacs UI to opencode - an open source AI coding agent. This provides two sets of advantages over the official TUI:

  1. A better TUI and GUI

    Emacs is a mature TUI and GUI framework, that while janky in its own way, is far less janky than the TUIs the new agentic coding tools have written from scratch. This package builds on a solid foundation of comint, vtable, diff-mode, markdown-mode, emacs' completion system, and more, to offer a (IMO) nicer UI. Also if you're an emacs user, the UI is more consistent: goto next or previous prompt, comint-kill-output-to-kill-ring, and everything else works the same as in any other repl or shell based on comint mode, completion and filtering works the same as everywhere else in emacs, and everything is just a text buffer where all your usual editing and other commands work as expected.

  2. Emacs integration

    • add any emacs buffer to chat context with opencode-add-buffer-dwim
    • add files from dired to context with opencode-add-file-dwim
    • add selected region to context with opencode-add-region
    • integration with magit is possible, opencode-new-worktree will create a new git branch and worktree for the current project, and start an opencode session in it
    • file:line references in LLM output are turned into clickable buttons
    • use dabbrev-expand in the chat window to complete long variable or function names from your code buffers

    Not much so far, but my initial focus has just been to make a usable UI, while deeper emacs integration will come over time.

Demo

A brief demo showing starting opencode, viewing a past session, sharing it, toggling an MCP, selecting the agent, model, and variant, performing some edits, receiving a notification when the response is finished if the session buffer isn't focused, reverting edits, and forking the session.

Installation

When this package is a bit more stable I'll package it on MELPA, for now install from git. This package depends on magit, plz, plz-media-type, plz-event-source, and markdown-mode.

Manual

Clone this repository and add it to your load path.

(add-to-list 'load-path "/path/to/opencode.el")
(require 'opencode)

With straight.el

(use-package opencode
 :straight (opencode :type git :host codeberg :repo "sczi/opencode.el"))

Emacs use-package (as of Emacs 30+)

(use-package opencode 
 :vc (:url "https://codeberg.org/sczi/opencode.el.git" :rev :newest))

In Doom Emacs

add to packages.el and run doom sync

(package! opencode
 :recipe (:host codeberg :repo "sczi/opencode.el"))

Connecting

Automatic

M-x opencode will try to connect to an opencode server at opencode-host:opencode-port or will start a headless opencode server if one isn't already running. Then it opens a Session Management buffer for the current project.

Manual

M-x opencode-connect will prompt for the host and port of an opencode server to connect to.

Project Management

In opencode, sessions are grouped by project, where each git repository is a different project. Different git worktrees for the same repository will be grouped in the same project. Sessions started in directories outside of any git repository will go in the global / project. opencode-select-project will fuzzy complete on all projects and open the Session Management buffer for the project you select.

Session Management

/hyakt/opencode.el/media/branch/main/screenshots/session_management.png

Here you see a table view with information on all sessions for a given project.

Shortcuts to act on the session at point:

Key Description
x kill session
R rename session
s share session, copies a URL to the clipboard that will give a read-only view of the session
u unshare session
t show TODO list for the session
RET or o open the session

Buffer-wide shortcuts:

Key Description
n new session
M toggle MCP - fuzzy completes on all available MCPs
U unshare all shared sessions for this project
v toggle verbose - whether to show subagent sessions

Chat Sessions

/hyakt/opencode.el/media/branch/main/screenshots/session.png /hyakt/opencode.el/media/branch/main/screenshots/session_with_diff.png

This is what session buffers look like. In the modeline at the bottom right we see the current agent, current model, model variant if one is selected (like low/medium/high thinking level), the percent of context used up so far, and an indicator for if the session is idle or busy. User prompts are shown with a blue margin highlight, information about tool calls in green, and reasoning in brown. These colors can be configured through the opencode-*-margin-highlight faces.

Key Description
C-c C-y yank code block at point
C-c C-c cancel the current request
C-c x delete this session
TAB cycle through available primary agents
C-c r rename this session
C-c n start a new session in the same project
C-c c fuzzy select a child session to open - children are all subagent sessions spawned by this session
C-c l list and select from all sessions in the same project
C-c p open parent session - when in a subagent session, open the session that spawned it
C-c f select a file to add to context
C-c b select a buffer to add to context
M-x yank-media add an image from clipboard to context
C-c s share session - copy a URL to the clipboard with a read-only view of the session
C-c u unshare session
C-c U unshare all sessions
C-c m select model
C-c v select model variant
C-c M select an MCP to toggle
C-c F fork session from message at point - use this when a model responds badly to avoid polluting context with the bad response
C-c D delete a message (user prompt and assistant response) from context
C-c R revert all edits done by this session after the message at point
C-c t show TODO list for the current session
/ when at the start of a user prompt, select a slash command to run

Notifications

If a session buffer and frame is not active, emacs will show a notification when that session's response has finished, so that you can go work on other stuff and be notified when the agent has finished.

Commands

Command Description
opencode Open opencode sessions control buffer for the current project directory. Connects to an existing server if one is running, otherwise starts a new one if ‘opencode-auto-start-server’ is non-nil.
opencode-connect Connect to opencode server, prompting for HOST and PORT.
opencode-disconnect Disconnect from opencode server, optionally log EVENT.
opencode-select-project Completing read to prompt which project to select.
opencode-select-open-session Select among open session buffers.
opencode-new-worktree Create a new git branch, and worktree prompting for a name. Then open an opencode session in it.
opencode-new-session Create a new session. With a prefix argument it will ask for TITLE. Without it will use a default title and then automatically generate one.
opencode-select-idle Select a session that hasn’t been visited since it went idle.
opencode-visit-last-idle Open the most recent session to notify as idle.
opencode-add-file-dwim If in Dired, add all marked files, or file at point if none marked. Otherwise add the current buffer’s file. Otherwise prompt for file in current project.
opencode-add-region Add the active region to context.
opencode-add-buffer-dwim Add current buffer or prompt for one to add.

Question Tool

/hyakt/opencode.el/media/branch/main/screenshots/single_choice_question.png
Single choice question
/hyakt/opencode.el/media/branch/main/screenshots/multiple_choice_question.png
Multiple choice question

OpenCode includes a question tool that models can use to ask clarifying questions of the user. If the session buffer is active when the questions are raised, it will immediately prompt each question with options for responses. The options the model provides are suggestions, feel free to type your own answer. If the session buffer or frame is not active at the time, then emacs will notify that a question is awaiting response. You can switch to the session buffer that most recently raised a notification with opencode-visit-last-idle, and as soon as you visit the buffer it will prompt the questions. For single choice questions, selecting an option will immediately submit that response. For multiple choice questions, select the options you want and then press C-c C-c to submit.

Security

Opencode's permission system, especially for bash, is not nearly as fine-grained as claude's. However, I don't think this really matters. Any coding agent with the ability to write and execute code can execute potentially malicious code by design and should be untrusted. One approach I'd recommend is to develop inside virtual machines or at least unprivileged containers managed by incus. If you use btrfs or ZFS for your incus storage pool, then incus copy is almost instant. So you can have a VM with emacs and opencode and your project, but without secrets or sensitive data, and spawn a copy to do agent-assisted development in. When you finish, push the changes to a git repo in a shared folder, and delete the VM. If you only need one copy at a time, you can just snapshot and restore rather than creating and deleting copies. Then from your somewhat more secure and non AI-infected development environment, review and then pull the changes from the shared folder.

Configuration

  • opencode-command and opencode-serve-command can be used to configure how to run a headless opencode server
  • opencode-host and opencode-port are the default host and port to use with M-x opencode-connect
  • opencode-server-username and opencode-server-password configure how to authenticate to the opencode server
  • the opencode-faces group configures faces used when displaying sessions
  • opencode-toast-function is used to show toast notifications