Skip to content

cmacrae/agent-shell

 
 

Repository files navigation

Emacs Agent Shell

agent-shell.png

This project needs your funding

As you pay for those useful LLM tokens, consider sponsoring development and maintenance of this project.

agent-shell is in its infancy. It’s got rough edges and lots of features to implement still. With your help, I can make this effort more sustainable.

Thank you!

Alvaro

agent-shell

A native Emacs shell to interact with LLM agents powered by ACP (Agent Client Protocol).

With agent-shell, you can chat with the likes of Gemini CLI, Claude Code, or any other ACP-driven agent.

Note: This package is in the very early stages and is likely incomplete or may have some rough edges.

Setup

External dependencies

ACP adapter for Claude Code

For Anthropic’s Claude Code, install Zed’s claude-code-acp.

Gemini CLI

For Google’s Gemini CLI, be sure to get a recent release supporting the --experimental-acp flag.

Codex

For OpenAI’s Codex, install codex-acp and ensure the `codex-acp` executable is in PATH.

Goose

For Goose CLI, install goose and ensure the `goose` executable is in PATH.

Installation

agent-shell is powered by built-in comint-shell, via shell-maker, available on MELPA.

You can install shell-maker via:

(use-package shell-maker
  :ensure t)

agent-shell also depends on acp.el, which isn’t yet on MELPA. You can install with:

(use-package acp
  :vc (:url "https://github.com/xenodium/acp.el"))

If you run into an error like use-package: Keyword :vc received unknown argument, ensure you’re using the built-in :vc syntax shown above. Earlier guides relied on the external vc-use-package extension, which accepted :fetcher=/:repo keywords, but Emacs 30+ expects ELPA-style specs such as :url.

Finally, install agent-shell with:

(use-package agent-shell
  :vc (:url "https://github.com/xenodium/agent-shell"))

Doom Emacs

If you are using Doom Emacs and would like to use the package! macro:

(package! shell-maker)
(package! acp :recipe (:host github :repo "xenodium/acp.el"))
(package! agent-shell :recipe (:host github :repo "xenodium/agent-shell"))

Run doom sync and restart.

Include require before configuration:

(require 'acp)
(require 'agent-shell)
;; rest of config...

Configuration

Configure authentication for the agent providers you want to use.

Environment variables

Pass environment variables to the spawned agent process by customizing the `agent-shell-*-environment` variable with `agent-shell-make-environment-variables`. The helper accepts key/value pairs and exports them when the agent starts.

(setq agent-shell-anthropic-claude-environment
      (agent-shell-make-environment-variables
       "ANTHROPIC_API_KEY" (auth-source-pass-get "secret" "anthropic-api-key")
       "HTTPS_PROXY" "http://proxy.example.com:8080"))

Inheriting environment variables

By default, the agent process starts with a minimal environment. To inherit environment variables from the parent Emacs process, use the `:inherit-env t` parameter in `agent-shell-make-environment-variables`:

(setenv "ANTHROPIC_API_KEY" (auth-source-pass-get "secret" "anthropic-api-key"))

(setq agent-shell-anthropic-claude-environment
      (agent-shell-make-environment-variables :inherit-env t))

This ensures that environment variables like `PATH`, `HOME`, and others from your Emacs session are available to the agent process, while still allowing you to override or add specific variables.

Anthropic Claude

For login-based authentication (default):

(setq agent-shell-anthropic-authentication
      (agent-shell-anthropic-make-authentication :login t))

For API key authentication:

;; With string
(setq agent-shell-anthropic-authentication
      (agent-shell-anthropic-make-authentication :api-key "your-anthropic-api-key-here"))

;; With function
(setq agent-shell-anthropic-authentication
      (agent-shell-anthropic-make-authentication
       :api-key (lambda () (auth-source-pass-get "secret" "anthropic-api-key"))))

For alternative Anthropic-compatible API endpoints, configure via environment variables:

(setq agent-shell-anthropic-claude-environment
      (agent-shell-make-environment-variables
       "ANTHROPIC_BASE_URL" "https://api.moonshot.cn/anthropic"
       "ANTHROPIC_MODEL" "kimi-k2-turbo-preview"
       "ANTHROPIC_SMALL_FAST_MODEL" "kimi-k2-turbo-preview"))

Google Gemini

For login-based authentication (default):

(setq agent-shell-google-authentication
      (agent-shell-google-make-authentication :login t))

For API key authentication:

;; With string
(setq agent-shell-google-authentication
      (agent-shell-google-make-authentication :api-key "your-google-api-key-here"))

;; With function
(setq agent-shell-google-authentication
      (agent-shell-google-make-authentication
       :api-key (lambda () (auth-source-pass-get "secret" "google-api-key"))))

For Vertex AI authentication:

(setq agent-shell-google-authentication
      (agent-shell-google-make-authentication :vertex-ai t))

OpenAI Codex

For API key authentication:

;; With string
(setq agent-shell-openai-authentication
      (agent-shell-openai-make-authentication :api-key "your-openai-api-key-here"))

;; With function
(setq agent-shell-openai-authentication
      (agent-shell-openai-make-authentication
       :api-key (lambda () (auth-source-pass-get "secret" "openai-api-key"))))

Goose

For OpenAI API key authentication:

;; With string
(setq agent-shell-goose-authentication
      (agent-shell-make-goose-authentication :openai-api-key "your-openai-api-key-here"))

;; With function
(setq agent-shell-goose-authentication
      (agent-shell-make-goose-authentication
       :openai-api-key (lambda () (auth-source-pass-get "secret" "openai-api-key"))))

Usage

Start an agent shell session:

  • M-x agent-shell-anthropic-start-claude-code - Start a Claude Code agent session
  • M-x agent-shell-openai-start-codex - Start a Codex agent session
  • M-x agent-shell-google-start-gemini - Start a Gemini agent session
  • M-x agent-shell-goose-start-agent - Start a Goose agent session

Sidebar

agent-shell-sidebar provides a persistent side panel interface. Each project gets its own independent sidebar that maintains separate state across visibility toggles.

Commands:

  • M-x agent-shell-sidebar-toggle - Toggle sidebar visibility for current project
  • M-x agent-shell-sidebar-toggle-focus - Toggle focus between sidebar and last buffer
  • M-x agent-shell-sidebar-change-provider - Switch to a different agent provider
  • M-x agent-shell-sidebar-reset - Reset sidebar for current project

Configuration options:

;; Sidebar width (default: "25%")
;; Integer for absolute columns or string with % for percentage of frame
(setq agent-shell-sidebar-width "25%")

;; Minimum width (default: 80)
(setq agent-shell-sidebar-minimum-width 80)

;; Maximum width (default: "50%")
(setq agent-shell-sidebar-maximum-width "50%")

;; Position: 'left or 'right (default: 'right)
(setq agent-shell-sidebar-position 'right)

;; Default provider (default: nil - prompt user)
;; Values: 'anthropic-claude-code, 'google-gemini, 'openai-codex, 'goose-agent
(setq agent-shell-sidebar-default-provider 'anthropic-claude-code)

;; Lock sidebar position and size (default: t)
(setq agent-shell-sidebar-locked t)

Running agents in Devcontainers / Docker containers (Experimental)

agent-shell provides rudimentary support for running agents in containers.

Adapt the command that starts the agent so it is executed inside the container; for example:

(setq agent-shell-anthropic-claude-command '("devcontainer" "exec" "--workspace-folder" "." "claude-code-acp"))

Note that any :environment-variables you may have passed to acp-make-client will not apply to the agent process running inside the container. It’s expected to inject environment variables by means of your devcontainer configuration / Dockerfile.

Next, set an agent-shell-path-resolver-function that resolves container paths in the local working directory, and vice versa. Agent shell provides the agent-shell--resolve-devcontainer-path function for use with devcontainers:

(setq agent-shell-path-resolver-function #'agent-shell--resolve-devcontainer-path)

Note that this allows the agent to access files on your local file-system. While care has been taken to restrict access to files in the local working directory, it’s probably possible for a malicious agent to circumvent this restriction.

Optional: to prevent the agent running inside the container to access your local file-system altogether and to have it read/modify files inside the container directly, in addition to setting the resolver function, disable the “read/write text file” client capabilities:

(setq agent-shell-text-file-capabilities nil)

All of the above settings can be applied on a per-project basis using directory-local variables.

Keybindings

  • C-c C-c - Interrupt current agent operation
  • TAB and Shift-TAB - Navigate interactive elements

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Emacs Lisp 100.0%