It's October. New month, new agent-shell update. If you missed the last post, have a look at the 0.78 update. While the latest changes are focused primarily on bugfixes and polish, we have a handful of new features too.
As usual, this post showcases highlights, but please check out the full list of changes if you're after the nitty-gritty.
agent-shell?
agent-shell brings your favorite AI agents to Emacs, keeping you at home: familiar buffers and bindings, no terminal emulation. All powered by ACP, the Agent Client Protocol.
I introduced agent-shell just over a year ago, with support for two agents: Claude and Gemini. Today, it speaks to 23.
Development hasn't let up either. Improvements and new features land every month.
Thank you to all users, contributors, and sponsors.
A couple more join the family, bringing it to 23 agents. As usual, they're all reachable via M-x agent-shell, or go straight to the new ones:
M-x agent-shell-junie-start-agent. M-x agent-shell-openclaw-start-agent.
With the ability to prompt at any time (see my last post), you can queue prompts or steer agents straight from the persistent shell prompt. Animating the prompt ties it all together: it's now obvious at a glance that the agent is busy, and that anything else you submit will queue.
Check out agent-shell-prompt-busy-frames for relevant customizations (more on that shortly).
Thanks to @cark for the proposal.
The header's busy indicator has been animated for some time now. Amongst the existing customizations, agent-shell-show-busy-indicator could turn it off altogether. Having said that, there's now a middle ground: use static text via agent-shell-busy-indicator-frames.
Just set it to a string like so:
(setopt agent-shell-busy-indicator-frames "(busy)")
If you'd like to use smarter logic, you can now set it to a function as follows:
(setopt agent-shell-busy-indicator-frames
(lambda ()
(if (agent-shell-session-id)
"(busy)"
"(connecting)")))
agent-shell-prompt-busy-frames takes all the same forms, so the prompt's own animation can also be a list of frames, a static string, or a function.
With the new agent-shell-prompt-queue-merge setting (enabled by default), pending prompts are joined (separated by blank lines) and submitted as a single turn. Queued prompts are typically follow-ups to the same instruction, so the agent now sees them together rather than acting on the first before reading the rest.
If you prefer the previous behaviour, disable it with:
(setopt agent-shell-prompt-queue-merge nil)
Thank you @Gleek for the proposal.
While on the subject of queueing, cancelling now offers to continue with the queue rather than quietly dropping it, and killing a shell now warns you about the pending work you'd lose.
@ and / completion used to bundle two things: how to complete, and when to pop up. Turning the popping off lost completion altogether, leaving corfu and company users out.
They're now decoupled. The completion functions are always registered, so completion-at-point, corfu and company work either way. Two options decide whether completion pops as you type: agent-shell-file-completion-enabled for @ and agent-shell-command-completion-enabled for /. For example, listing files can be slow in a large project, so to only complete @ on demand while / keeps popping:
(setopt agent-shell-file-completion-enabled nil)
Trailing spaces (and @ mention quoting) are now only inserted on a finished completion, fixing the stray spaces corfu and company users were seeing.
Thanks to @bcc32 for proposing the split and separate @ and / options in #537, and to @jcubic for filing it and flagging the stray spaces.
C-M-a and C-M-e (beginning-of-defun and end-of-defun) now move between blocks. Thank you @OSadovy for #876.
Chat mode draws "Me" and "Agent" labels (or rather "Claude", "Codex" etc.). If the current style isn't your jam, agent-shell-chat-label-function now lets you draw them yourself. It's handed an alist with :text and :role (either user or agent), and must return a single-line propertized string.
The display property is honored, so labels can also be rendered as images. Thanks to @nhojb for the idea.
Transcripts now open with YAML frontmatter, including a start timestamp as follows:
---
agent: "Claude"
started: "2026-10-11T09:30:12+01:00"
working_directory: "~/stuff/active/code/agent-shell"
session_id: "0f3c9a1e-5b7d-4e2a-9c81-6d4f2b8e7a35"
model: "claude-opus-4-5"
---
Thank you @vermiculus for #854.
While on topic, transcripts also got a little sturdier, thanks to @mrcnski's proposal.
M-x yank-media support
M-x yank-media now pastes images straight from the system clipboard (#853), no external utilities needed, the same way Org mode handles it. Pasted image previews also survive being queued or steered, thanks to @Gleek for #852.
Codex gained agent-shell-openai-default-config-options for setting config options at session start, reasoning effort included. For example:
(setopt agent-shell-openai-default-config-options
'(("reasoning_effort" . "high")))
Thank you @ianthetechie for #855.
Tool call output can be fairly long. A single chunky line was enough to bog a buffer down. Long tool output lines are now limited (#844 by @Gleek), and fallback titles are truncated so they no longer flash chunkily as they stream.
File summaries also count distinct files now, so reading the same file three times counts as one file rather than three (#863, also by @Gleek).
While we have a handful of new features, the bulk of this release went into fixes.
Rendering:
M-x agent-shell-copy-as-markdown no longer mangles bullets carrying bold text (
Performance and responsiveness:
path:line references are now found in linear time (visual-wrap-prefix-mode enabled no longer hangs Emacs (
Elsewhere:
display-buffer-overriding-action is preserved when displaying asynchronously (tramp-remote-path and direct async processes rather than a bug.
New shells now show the last few release posts on the welcome screen, so they are a little more discoverable.
A few additions for package authors building on agent-shell.
agent-shell-initialized-p returns non-nil once the handshake, authentication, session and any default options are all done. Until then, subscribe to the new init-finished event via agent-shell-subscribe-to (#860).
Agent config options are now reachable from elisp rather than the UI alone:
(agent-shell-config-options)
(agent-shell-config-option :category "thought_level")
(agent-shell-config-option-value :id "effort")
(agent-shell-set-config-option-value :id "effort" :value "high"
:on-success (lambda (_) (message "Set")))
agent-shell-last-activity-time returns when the shell last saw a submitted prompt or an incoming notification (M-x agent-shell-save-traffic writes the session's ACP traffic to a .traffic file and reveals it in dired, simplifying the bug-filing process.
agent-shell-gc joins the lot, bringing buffer garbage collection (auto-kill) to agent-shell.
If you peeked at the commit logs for the period, you'll see it's been a busy few weeks. Since the last post, 125 commits shipped, 33 issues have been closed and 15 pull requests merged. As of this writing, the backlog sits at 4 open issues and 6 open PRs (versus 16 and 6 last time around).
Zooming out a little, here's how the backlog has tracked:
As usual, this chart was generated using the /github-activity skill shared in my emacs-skills repo.
Four open issues is the lowest it's been since the project's first week, which I'm pleased about.
All of this requires daily attention.
Tokens keep your agents running. Sponsors keep agent-shell running.
agent-shell is built and maintained by me, an indie dev, while the tools it competes with have well-funded teams behind them. Vendor-neutral tooling matters more than ever.
Using agent-shell at work? Ask your employer to sponsor too. Companies can contribute at a scale individuals can't.
Thank you to all contributors for these improvements!
agent-shell stands on acp.el to speak ACP and shell-maker for its shell foundations, so fixes landing there reach you just the same:
As of this writing, we're 88% of the way to the 150 monthly sponsors goal. If agent-shell is part of your daily workflow, please consider becoming a monthly sponsor (or ask your employer to).
Not in a position to sponsor? A GitHub star helps with exposure and brings in new users.