Skip to content
Open
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
50 changes: 43 additions & 7 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,7 @@ For Goose CLI, install [[https://block.github.io/goose/docs/getting-started/inst

*** Cursor

For Cursor agent, install with:

#+begin_src bash
npm install -g @blowmage/cursor-agent-acp
#+end_src

See https://github.com/blowmage/cursor-agent-acp-npm for details.
For Cursor agent, install the official [[https://cursor.com/docs/cli/acp][Cursor CLI]] and ensure the `agent` executable is in PATH.

*** Kiro CLI

Expand Down Expand Up @@ -392,6 +386,48 @@ For API key authentication:
(shell-command-to-string "source ~/.vibe/.env; echo $MISTRAL_API_KEY")))))
#+end_src

*** Cursor

For login-based authentication (default):

#+begin_src emacs-lisp
(setq agent-shell-cursor-authentication
(agent-shell-cursor-make-authentication :login t))
#+end_src

For API key authentication:

#+begin_src emacs-lisp
;; With string
(setq agent-shell-cursor-authentication
(agent-shell-cursor-make-authentication :api-key "your-cursor-api-key-here"))

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

For auth token authentication:

#+begin_src emacs-lisp
;; With string
(setq agent-shell-cursor-authentication
(agent-shell-cursor-make-authentication :auth-token "your-cursor-auth-token"))

;; With function
(setq agent-shell-cursor-authentication
(agent-shell-cursor-make-authentication
:auth-token (lambda () (auth-source-pass-get "secret" "cursor-auth-token"))))
#+end_src

For no authentication (when already authenticated via =agent login=):

#+begin_src emacs-lisp
(setq agent-shell-cursor-authentication
(agent-shell-cursor-make-authentication :none t))
#+end_src

*** Customizing Available Agents

By default, =agent-shell= includes configurations for all supported agents (Claude Agent, Gemini CLI, Codex, Goose, Qwen Code, and Auggie). You can customize which agents are available through the =agent-shell-agent-configs= variable.
Expand Down
110 changes: 102 additions & 8 deletions agent-shell-cursor.el
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@

;;; Commentary:
;;
;; This file includes Cursor-specific configurations.
;; This file includes Cursor-specific configurations using the official
;; Cursor CLI (agent acp) for ACP (Agent Client Protocol) communication.
;;
;; See https://cursor.com/docs/cli/acp for more information about
;; Cursor's official ACP implementation.
;;

;;; Code:
Expand All @@ -36,8 +40,66 @@
(declare-function agent-shell--make-acp-client "agent-shell")
(declare-function agent-shell--dwim "agent-shell")

(cl-defun agent-shell-cursor-make-authentication (&key api-key auth-token login none)
"Create Cursor authentication configuration.

API-KEY is the Cursor API key string or function that returns it.
AUTH-TOKEN is the Cursor auth token string or function that returns it.
LOGIN when non-nil indicates to use cursor_login authentication.
NONE when non-nil indicates no authentication method is used.

Only one of API-KEY, AUTH-TOKEN, LOGIN, or NONE should be provided."
(when (> (seq-count #'identity (list api-key auth-token login)) 1)
(error "Cannot specify multiple authentication methods - choose one"))
(unless (> (seq-count #'identity (list api-key auth-token login none)) 0)
(error "Must specify one of :api-key, :auth-token, :login, or :none"))
(cond
(api-key `((:api-key . ,api-key)))
(auth-token `((:auth-token . ,auth-token)))
(login `((:login . t)))
(none `((:none . t)))))

(defcustom agent-shell-cursor-authentication
(agent-shell-cursor-make-authentication :login t)
"Configuration for Cursor authentication.

For login-based authentication (default):

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

For API key (string):

(setq agent-shell-cursor-authentication
(agent-shell-cursor-make-authentication :api-key \"your-key\"))

For API key (function):

(setq agent-shell-cursor-authentication
(agent-shell-cursor-make-authentication :api-key (lambda () ...)))

For auth token (string):

(setq agent-shell-cursor-authentication
(agent-shell-cursor-make-authentication :auth-token \"your-token\"))

For auth token (function):

(setq agent-shell-cursor-authentication
(agent-shell-cursor-make-authentication :auth-token (lambda () ...)))

For no authentication (already authenticated externally):

(setq agent-shell-cursor-authentication
(agent-shell-cursor-make-authentication :none t))

When using :api-key or :auth-token, the corresponding environment
variable (CURSOR_API_KEY or CURSOR_AUTH_TOKEN) will be set automatically."
:type 'alist
:group 'agent-shell)

(defcustom agent-shell-cursor-acp-command
'("cursor-agent-acp")
'("agent" "acp")
"Command and parameters for the Cursor agent client.

The first element is the command name, and the rest are command parameters."
Expand All @@ -49,7 +111,15 @@ The first element is the command name, and the rest are command parameters."
"Environment variables for the Cursor agent client.

This should be a list of environment variables to be used when
starting the Cursor agent process."
starting the Cursor agent process.

Cursor CLI supports the following authentication environment variables:
- CURSOR_API_KEY: API key for authentication
- CURSOR_AUTH_TOKEN: Auth token for authentication

These can be used for pre-authentication before the ACP session starts.
If not set, the authentication method specified in
`agent-shell-cursor-authentication' will be used."
:type '(repeat string)
:group 'agent-shell)

Expand All @@ -67,7 +137,12 @@ Returns an agent configuration alist using `agent-shell-make-agent-config'."
:welcome-function #'agent-shell-cursor--welcome-message
:client-maker (lambda (buffer)
(agent-shell-cursor-make-client :buffer buffer))
:install-instructions "Install with: npm install -g @blowmage/cursor-agent-acp\nSee https://github.com/blowmage/cursor-agent-acp-npm for details."))
:needs-authentication (not (map-elt agent-shell-cursor-authentication :none))
:authenticate-request-maker (lambda ()
(when (not (map-elt agent-shell-cursor-authentication :none))
(acp-make-authenticate-request
:method-id "cursor_login")))
:install-instructions "See https://cursor.com/docs/cli for installation."))

(defun agent-shell-cursor-start-agent ()
"Start an interactive Cursor agent shell."
Expand All @@ -81,10 +156,29 @@ Returns an agent configuration alist using `agent-shell-make-agent-config'."
(error "Missing required argument: :buffer"))
(when (and (boundp 'agent-shell-cursor-command) agent-shell-cursor-command)
(user-error "Please migrate to use agent-shell-cursor-acp-command and eval (setq agent-shell-cursor-command nil)"))
(agent-shell--make-acp-client :command (car agent-shell-cursor-acp-command)
:command-params (cdr agent-shell-cursor-acp-command)
:environment-variables agent-shell-cursor-environment
:context-buffer buffer))
(let* ((api-key-value (map-elt agent-shell-cursor-authentication :api-key))
(auth-token-value (map-elt agent-shell-cursor-authentication :auth-token))
(env-vars-overrides
(cond
(api-key-value
(list (format "CURSOR_API_KEY=%s"
(if (functionp api-key-value)
(funcall api-key-value)
api-key-value))))
(auth-token-value
(list (format "CURSOR_AUTH_TOKEN=%s"
(if (functionp auth-token-value)
(funcall auth-token-value)
auth-token-value))))
((map-elt agent-shell-cursor-authentication :login)
;; Set empty API key to force login flow if not already authenticated
(list "CURSOR_API_KEY="))
(t nil))))
(agent-shell--make-acp-client :command (car agent-shell-cursor-acp-command)
:command-params (cdr agent-shell-cursor-acp-command)
:environment-variables (append env-vars-overrides
agent-shell-cursor-environment)
:context-buffer buffer)))

(defun agent-shell-cursor--welcome-message (config)
"Return Cursor welcome message using `shell-maker' CONFIG."
Expand Down