u/CosmicMarvel

▲ 30 r/lisp

I built a coding agent in CL to see how far the live Lisp image idea can go

I’ve been building kli, a terminal coding agent written in Common Lisp, and I’m now putting it out publicly.

Just to address the obvious right of the gate. kli was built with AI assistance, it is sort of the point of all of this. However, I’m not very interested in vibecoding as "accept whatever blob the model emits and pray for the best". What I wanted to explore is whether a coding agent can be a live Lisp system where changes are inspectable, retractable, authority-scoped, testable, and patchable? And where those changes are changes to the coding assistant itself.

The core of kli is not really a coding assistant though. The boot kernel knows about live objects, a registry, an active protocol, and three verbs:

install-protocol
switch-protocol
rollback-protocol

It does not know what a model provider is. It does not know what a tool is. It does not know what a terminal UI is. It does not even know what an extension system is.

The extension protocol is the first thing installed through those verbs. After that, the system is extensions all the way down. This means that contribution kinds, capabilities, tools, model providers, commands, session logs, the agent loop, the TUI, and user extensions are all installed into the live protocol and can be retracted through it.

A small trimmed example from the editor extension:

(defextension tui-editor
  (:provides
   (method render-lines () (editor-view t) (view width)
     (render-editor-lines view width))
   (method handle-input () (editor-view t) (view input)
     (handle-editor-input view input))
   (method recode-tui-behavior () (editor-view) (editor &rest args)
     (apply #'recode-editor editor args))))

The method forms are contribution forms. Installing the extension installs methods into the running image; retracting it removes exactly those methods again. Other contribution kinds install tools, commands, event handlers, providers, settings schemas, grants, and effects with explicit retractors.

The design deliberately mixes CLOS and Let Over Lambda / pandoric closures. CLOS handles image-level, per-class behavior: generic functions, methods, live objects, protocol objects. Pandoric closures handle per-instance behavior cells which are small pieces of mutable policy or runtime behavior that can be inspected and hotpatched while keeping closed-over state.

So the editor can keep its buffer while behavior changes underneath. The transcript can keep scrollback. The agent session can recode prompt expansion, context transforms, retry policy, and compaction policy without replacing the whole session object.

To give an example of the more user-facing kind of extension one can build on top of kli I have also released cairn. It gives the agent a durable task graph to plan in and resume into. It hosts tasks, phases, dependencies, observations, handoffs, status, and a small query language over the graph. When the conversation resets, the agent reloads the plan from the graph instead of reconstructing it from old chat.

cairn started as a workflow system I developed around Claude Code, then stripped down to the pieces that kept proving useful over thousands of tasks. In kli it is not a sidecar. If installed, it is as native as the TUI (which is the main advantage of everything being an extension). It contributes tools like observe, task_bootstrap, task_query, and handoff; adds slash commands like /workon; recodes the session context transform so the current task appears in model turns; and recodes compaction so observations and handoffs survive context cuts.

Some practical notes:

  • kli is MIT licensed and built on SBCL.
  • It supports Anthropic, OpenAI, Codex, and OpenAI-compatible providers.
  • Tools carry capability metadata which is authority control, not a sandbox; shell/eval/file-write authority still runs with the process’s authority.
  • The file editing tool uses hashline anchors, so edits reject if the file drifted under the agent.

Install:

curl -fsSL https://kli.kleisli.io | sh

or:

nix run github:kleisli-io/kli

Links in comment.

reddit.com
u/CosmicMarvel — 17 hours ago