Agentic development workflow in Emacs — 20Y

4 min read Original article ↗

I’d seen friends use LLM-based code completion, but it didn’t really catch my attention. Typing speed was never my bottleneck–not because I type fast, but because it wasn’t the muda in my development process.

Then I noticed friends switching to Claude Code and Windsurf. They incorporated LLMs into their workflows to drive architectural decision-making or generate obvious code (e.g. automated test cases). Although it piqued my interest, the lack of ergonomics put me off. Claude Code’s TUI was terrible–some might argue that this didn’t change to date. I didn’t see myself switching to a VS Code-based editor from Emacs either.

It was only when I read Laurent Charignon’s essay, Building with LLMs at Scale, that I became curious about how to drive development mostly with LLMs. In his essay, Laurent describes several challenges he faced while setting up his AI development process. I found it very interesting to read how he orchestrated a dozen LLMs in his terminal-based workflow.

With this inspiration, I first explored working with LLMs via Claude Code. I soon realized I wanted tighter integration with Emacs, my main programming editor (file manager, version control interface, etc), so I sought alternatives.

I tried gptel next. It converts an Emacs buffer into an LLM chat window. You can choose to exchange messages with the chosen model in Markdown or Org markup. Conversations, therefore, can be saved into text files and later loaded from disk to provide fresh context.

I also tried claude-code.el as another alternative. It brings the Claude Code CLI into Emacs via a terminal backend. It indeed patches some of the ergonomic issues in Claude Code, but the overall experience still feels cluttered.

Today, I use agent-shell, an Emacs mode that can communicate with various LLM agents via ACP. ACP (Agent Client Protocol) was a much-needed protocol for the ecosystem that enables seamless LLM integration in any coding editor. With agent-shell, agentic coding becomes native to Emacs. I edit my AI prompts as regular buffer text. I monitor and curate the generated code changes with magit. Finally, with LSP support, I navigate the code as if I had written them myself.

agent-shell also addresses the “Long-Term Memory” problem that Laurent highlighted. It automatically saves all conversations as markdown files, which can then be searched or restored for continued work.

The best tool I found so far for the “Lost Context” problem was OpenSpec. It proposes a structured format for articulating problems and tasks. You no longer need context window compacting–the spec is the context. At work, I started to use OpenSpec to spot gaps in user stories, to guide architecture planning, and to generate implementations. This approach increases the time that LLM agents can operate without disruption, boosting autonomy and reliability for tools like Claude Code and Codex.

As my LLM-driven workflow matured, I increasingly struggled with managing parallel conversations. I needed an effective LLM session manager for Emacs, but the obvious choice, agent-shell-manager, was too limited. I wished there were clear visual and audible cues when an agent was waiting for input or had already finished—even if another application window was active.

Since I use KDE Plasma for window management, I decided to learn to create a plasmoid (a widget that can be anchored in a Plasma panel) that displays the status of running Emacs agent-shell sessions. This is how agent-shell-plasmoid was born. You can see at a glance which agents are ready, working, or waiting for permission — and clicking the status labels will bring you back to the relevant conversation in Emacs. It comes with an Emacs minor mode to enable audio feedback. For a familiar touch, I configured some of the voice files of Warcraft II.

agent-shell-plasmoid displaying LLM session status in the KDE panel
Displaying LLM session status in the KDE panel

Emacs, equipped with magit, LSP, and projectile, provides a strong foundation for navigating a software project. The spread of MCP (Model Context Protocol) greatly extended agent capabilities by bridging them with external tools, while ACP bridged agents with editors–enabling agent-shell to make agentic coding a native Emacs experience.

Moving from a single chat window to a multi-agent orchestration required me to adjust my development setup. agent-shell-plasmoid enabled me to monitor and respond to blocked or finished agents effectively. I’m currently learning how git worktree can help reduce merge conflicts. I’m also exploring how agent skills can help capture and share knowledge among human and agentic project members. This could also facilitate the correct implementation of OpenSpecs.