Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ An Emacs interface for AI-assisted software development. *The purpose is to prov
- [[https://github.com/google-gemini/gemini-cli][Gemini CLI]]
- [[https://github.com/openai/codex][OpenAI Codex]]
- [[https://docs.github.com/en/copilot/how-tos/use-copilot-agents/use-copilot-cli][GitHub Copilot CLI]]
- [[https://opencode.ai/][Opencode]]

- I switch across different CLI based AI tool in emacs: Claude Code / Gemini CLI / Aider / OpenAI Codex. If you also use different AI tools inside emacs, but want to keep same user interface and experience, this package is for you.

Expand Down Expand Up @@ -47,6 +48,7 @@ An Emacs interface for AI-assisted software development. *The purpose is to prov
- Gemini CLI (`[[https://github.com/linchen2chris/gemini-cli.el][gemini-cli.el]]`)
- [[https://github.com/openai/codex][OpenAI codex CLI]] (`[[./ai-code-codex-cli.el][ai-code-codex-cli.el]]`)
- [[https://docs.github.com/en/copilot/how-tos/use-copilot-agents/use-copilot-cli][GitHub Copilot CLI]] (`[[./ai-code-github-copilot-cli.el][ai-code-github-copilot-cli.el]]`)
- [[https://opencode.ai/][Opencode]] (`[[./ai-code-opencode.el][ai-code-opencode.el]]`)

You can add other backends by customizing the `ai-code-backends` variable.

Expand Down
12 changes: 11 additions & 1 deletion ai-code-backends.el
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,17 @@
:resume codex-cli-resume
:config "~/.codex/config.toml"
:upgrade "npm install -g @openai/codex@latest"
:cli "codex"))
:cli "codex")
(opencode
:label "ai-code-opencode.el"
:require ai-code-opencode
:start opencode
:switch opencode-switch-to-buffer
:send opencode-send-command
:resume opencode-resume
:config "~/.opencode/config.json"
:upgrade nil
:cli "opencode"))
"Available AI backends and how to integrate with them.
Each entry is (KEY :label STRING :require FEATURE :start FN :switch FN :send FN :resume FN-or-nil :upgrade STRING-or-nil :cli STRING).
The :upgrade property can be either a string shell command or nil."
Expand Down
1 change: 1 addition & 0 deletions ai-code-interface.el
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
(require 'ai-code-discussion)
(require 'ai-code-codex-cli)
(require 'ai-code-github-copilot-cli)
(require 'ai-code-opencode)
(require 'ai-code-file)
(require 'ai-code-ai)

Expand Down
73 changes: 73 additions & 0 deletions ai-code-opencode.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
;;; ai-code-opencode.el --- Thin wrapper for Opencode -*- lexical-binding: t; -*-

;;; Commentary:
;;
;; Thin wrapper that reuses `claude-code' to run Opencode.
;; Provides interactive commands and aliases for the AI Code suite.
;;
;; Opencode is an open-source alternative to Claude Code that provides
;; HTTP server APIs and customization features (LSP, custom LLM providers, etc.)
;; See: https://opencode.ai/
;;
;;; Code:

(require 'claude-code)

(declare-function claude-code--start "claude-code" (arg extra-switches &optional force-prompt force-switch-to-buffer))
(declare-function claude-code--term-send-string "claude-code" (backend string))
(defvar claude-code-terminal-backend)


(defgroup ai-code-opencode nil
"Opencode integration via `claude-code'."
:group 'tools
:prefix "opencode-")

(defcustom opencode-program "opencode"
"Path to the Opencode executable."
:type 'string
:group 'ai-code-opencode)

;;;###autoload
(defun opencode (&optional arg)
"Start Opencode (reuses `claude-code' startup logic)."
(interactive "P")
(let ((claude-code-program opencode-program) ; override dynamically
(claude-code-program-switches nil)) ; optional e.g.: '("exec" "--non-interactive")
(claude-code arg)))

;;;###autoload
(defun opencode-switch-to-buffer ()
(interactive)
(claude-code-switch-to-buffer))

;;;###autoload
(defun opencode-send-command (line)
(interactive "sOpencode> ")
(claude-code-send-command line))

;;;###autoload
(defun opencode-resume (&optional arg)
"Resume a previous Opencode session.

This command starts Opencode with the --resume flag to resume
a specific past session. The CLI will present an interactive list of past
sessions to choose from.

If current buffer belongs to a project, start in the project's root
directory. Otherwise start in the directory of the current buffer file,
or the current value of `default-directory' if no project and no buffer file.

With double prefix ARG (\\[universal-argument] \\[universal-argument]),
prompt for the project directory."
(interactive "P")
(let ((claude-code-program opencode-program)
(claude-code-program-switches nil))
(claude-code--start arg '("resume") nil t)
(claude-code--term-send-string claude-code-terminal-backend "")
(with-current-buffer claude-code-terminal-backend
(goto-char (point-min)))))

(provide 'ai-code-opencode)

;;; ai-code-opencode.el ends here