From 93d293f0c9a4639e7dc78bdde5f215b3a57d3e9a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 17 Oct 2025 00:41:23 +0000 Subject: [PATCH 1/2] Initial plan From 2536508cce767fa129b5e77c4eb747c758620d55 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 17 Oct 2025 00:44:40 +0000 Subject: [PATCH 2/2] Add opencode support to ai-code-interface.el Co-authored-by: tninja <714625+tninja@users.noreply.github.com> --- README.org | 2 ++ ai-code-backends.el | 12 +++++++- ai-code-interface.el | 1 + ai-code-opencode.el | 73 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 ai-code-opencode.el diff --git a/README.org b/README.org index 48ea370..a8f8afc 100644 --- a/README.org +++ b/README.org @@ -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. @@ -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. diff --git a/ai-code-backends.el b/ai-code-backends.el index 5b89379..9ce1499 100644 --- a/ai-code-backends.el +++ b/ai-code-backends.el @@ -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." diff --git a/ai-code-interface.el b/ai-code-interface.el index 58e79c0..899a46b 100644 --- a/ai-code-interface.el +++ b/ai-code-interface.el @@ -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) diff --git a/ai-code-opencode.el b/ai-code-opencode.el new file mode 100644 index 0000000..a294b01 --- /dev/null +++ b/ai-code-opencode.el @@ -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