Claude Code interacting with a live Common Lisp REPL (including within Emacs)
Tags: #claude-code #commonlisp #emacs #sbcl
Claude Code may spawn a fresh process for every command it runs. Sensible for most languages, but a poor fit for Common Lisp, where the whole point is a long-lived image that grow function by function and instruction by instruction. Restarting SBCL on each step throws away the very state that makes Lisp REPL (Read-Eval-Print Loop) powerful.
So instead of letting Claude start its own throwaway process, let’s plug it to a REPL, the same running image we are working in. Then Claude defines functions, loads files and runs tests against live image; we watch the results appear, and can also type instructions ourselves.
The recipes live in a small repo, claude-lisp-repl, which holds almost no code. It is essentially a set of prompts: you paste one into Claude to set up the shared REPL, then talk to it in plain English from there, while manually inputing instructions in shared REPL if you wish so.
The simplest approach needs no Emacs at all: just a detached tmux session. We tell Claude, once:
Launch SBCL inside a detached tmux session named lisp.
The user may be interacting with the lisp image through the REPL on its own, independently from you.
In our future interactions, "stage" instructions would mean send instructions to the REPL without executing them (no 'Enter').
From then on, Claude drives the image through tmux send-keys and reads it back through tmux capture-pane. We attach whenever we like with tmux attach -t lisp and detach with C-b d.
A first interaction: “Create a foo function which doubles its argument. Apply it to 45. Stage (foo 15).”:

Every line in that screenshot was typed by Claude alone.
Loading a file works the same way: “In test.lisp, create a bar function which squares its argument. Load it in the image and apply it to 11.”:

For those of us who would rather not leave Emacs, two further recipes route everything through SLIME instead of raw tmux:
(i) one where swank runs in a tmux image and Emacs connects to it over a socket,
(ii) one where Emacs first launches the image itself, typically with M-x slime.
Same image and same shared REPL prompt for Claude and the user :
