An LLM-augmented Lisp machine environment built with Common Lisp and McCLIM.
  • Common Lisp 92.4%
  • Python 4.1%
  • Shell 3.5%
Find a file
Tay 2854fd1d38
fix(ui): Preserve updates through native error recovery
Replace the private redisplay scheduler with queued CLIM updates so a
failed display cannot consume the final worker notification. Keep native
pane recovery restarts live in the graphical debugger, preserve drafts
on abort, and avoid replaying failed domain actions.

Add a real graphical recovery probe and tighten GUI error checks. Repair
stale container migration assumptions and record the stability audit.

Validation on the final tree: 6051 FiveAM checks, 32 Python tests,
launcher and legacy-name checks, and all four graphical recovery
scenarios pass through the repository wrappers.
2026-09-13 03:56:19 -04:00
docs fix(ui): Preserve updates through native error recovery 2026-09-13 03:56:19 -04:00
packages/channels/default chore(brand): Present RPLACA across public surfaces 2026-07-29 13:22:31 -04:00
scripts fix(ui): Preserve updates through native error recovery 2026-09-13 03:56:19 -04:00
src fix(ui): Preserve updates through native error recovery 2026-09-13 03:56:19 -04:00
tests fix(ui): Preserve updates through native error recovery 2026-09-13 03:56:19 -04:00
vendor/cl-community-spec chore(licensing): add AGPL and vendor notices 2026-04-10 02:45:08 -04:00
.envrc fix(env): Prefer the available Guix environment 2026-09-13 03:56:19 -04:00
.gitignore refactor(core): Cut over technical namespace to RPLACA 2026-07-29 11:03:48 -04:00
AGENTS.md docs(migration): Document and enforce RPLACA cutover 2026-07-29 13:59:43 -04:00
app-server.sh refactor(core): Cut over technical namespace to RPLACA 2026-07-29 11:03:48 -04:00
clim-presentations.md chore(brand): Present RPLACA across public surfaces 2026-07-29 13:22:31 -04:00
guix.scm fix(harness): Isolate GUI stability runs 2026-07-14 17:59:45 -04:00
LICENSE chore(licensing): add AGPL and vendor notices 2026-04-10 02:45:08 -04:00
lispi.asd fix(migration): Harden RPLACA state cutover 2026-07-29 11:39:14 -04:00
prompt.sh refactor(core): Cut over technical namespace to RPLACA 2026-07-29 11:03:48 -04:00
README.org feat(ui): Expose native interactive CLIM facilities 2026-09-13 03:56:19 -04:00
rplaca.asd feat(ui): Expose native interactive CLIM facilities 2026-09-13 03:56:19 -04:00
run-native.sh feat(recovery): Supervise fatal crash repair 2026-09-13 03:56:19 -04:00
run.sh feat(recovery): Supervise fatal crash repair 2026-09-13 03:56:19 -04:00
session-prompt.sh refactor(core): Cut over technical namespace to RPLACA 2026-07-29 11:03:48 -04:00
shell.nix refactor(core): Cut over technical namespace to RPLACA 2026-07-29 11:03:48 -04:00
todo-parity.md chore(brand): Present RPLACA across public surfaces 2026-07-29 13:22:31 -04:00

RPLACA

WARNING: This project is pre-dogfood and under active development.

Macros for your agent!

Repository: github.com/htayj/rplaca

Users of pre-rename builds should follow the Clawmacs-to-RPLACA migration guide before moving configuration or sessions.

Introduction

Anyone who has used Emacs before knows the benefit of a tight feedback loop. Write lisp code, eval it, instant results. RPLACA brings that same philosophy to agentic programming: the tighter the feedback loop between you and the agent, and the more the agent can introspect its own environment, the more powerful the collaboration becomes.

RPLACA is a Lisp-native, Emacs-inspired LLM chat interface written entirely in Common Lisp. It gives you and your AI agent a shared, programmable environment while keeping ordinary provider work off the CLIM frame process. Explicit UI tools cross onto the frame process at its managed update boundary. The agent can read, write, and edit files directly through Lisp data mode, use isolated lisp_eval workers, attach live Lisp buttons, and open independent windows.

/tay/rplaca/media/branch/master/docs/img/genera-style.png

Features

Multi-Provider LLM Support

RPLACA supports multiple LLM providers, switchable per buffer:

  • Z.AI (Zhipu AI) — GLM models
  • OpenAI Codex — with shared Codex OAuth/API-key auth and the Responses API
  • OpenRouter — access to hundreds of models with dynamic model discovery

Switch agents on the fly with C-c A. Switch models on the fly with C-c C-m (fuzzy minibuffer selector) or C-c M (overlay selector). Run interactive commands with M-x using fuzzy command-name completion, candidate rows, Tab=/=Down and Backtab=/=Up navigation, and minibuffer prompting for command arguments.

OpenAI Codex Auth

OpenAI Codex auth follows Codex's own credential layout:

  • ~/.config/rplaca/openai-codex-token is the highest-precedence raw bearer override.
  • Otherwise RPLACA reads and refreshes shared Codex credentials from ~/.codex/auth.json.
  • The browser login flow uses a localhost callback at http://localhost:1455/auth/callback and falls back to another local port if 1455 is busy.
  • ChatGPT-backed Codex auth uses https://chatgpt.com/backend-api/codex, while API-key auth uses https://api.openai.com/v1.

Agent Tools

The default built-in agent tool surface follows Pi-style coding tools, with provider tools as the primary action surface:

Tool Description
read Read text files
find Search files by name or wildcard
grep Search file contents by literal text
write Create or overwrite text files
edit Replace exact text in text files
lisp_eval Evaluate Common Lisp in an isolated worker (mode=isolated required for provider calls)
attach_lisp_button Add a transcript button that evaluates arbitrary live Lisp when clicked
open_window Open an independent McCLIM text window
recovery_list Inspect recent durable tool/eval/checkpoint journal events

RPLACA is a full-trust application. Agent tools, package code, init files, shell commands, and live Lisp all run with the operating-system authority of the RPLACA process. There is deliberately no in-application permission prompt or sandbox policy. If containment is required, run the entire application in a user-controlled container, VM, restricted account, or OS sandbox. Tool and package selection controls workflow composition and prompt exposure; it is not a security boundary.

By default, agents use exposed provider tools for workspace search and text changes. Tool inputs and tool results are represented as Lisp data, for example (edit :path "src/foo.lisp" :old-text "old" :new-text "new"). The write and edit tools reject content that leaves Lisp parentheses unbalanced. Custom tools may be registered explicitly with register-tool or tagged through deftool. Imported packages contribute tools as soon as their deftool forms are evaluated.

The lisp_eval tool is the fallback for Common Lisp tests and isolated introspection when no exposed tool fits. Provider calls must pass :mode "isolated"; live evaluation is refused at the provider boundary because arbitrary immediate code can block or terminate the CLIM frame process. The attach_lisp_button tool deliberately stores arbitrary live Lisp for a later user click, without an approval prompt or allowlist. Standard Common Lisp reference lookup is available through a vendored offline snapshot of cl-community-spec, and imported library discovery is handled locally through ASDF metadata, package exports, docstrings, and source/doc search helpers.

lisp_eval captures printed output, error output, and multiple return values. Its tool result is a printed Lisp plist. Recent calls are available with (eval-history-to-string), and the latest success/error are exposed through *last-eval-result* and *last-eval-condition*. Isolated mode evaluates in a fresh SBCL worker process without mutating or crashing the live RPLACA image. The worker inherits the user's filesystem and network authority; this separation is for application stability, not containment.

The safe-reload-rplaca-command gives users a deliberate development hot-reload path for updated RPLACA source. It is not exposed as a provider tool because live class and method redefinition cannot be safely interleaved with a background agent tool worker. The command first loads the current checkout in an isolated SBCL worker; only if that preflight succeeds does it reload :rplaca in the live image, refresh command/tool/package registrations, and insert a visible system message in the current buffer. Existing buffers, sessions, the frame, and compose draft are not reset. Preflight, busy, and live reload failures are returned as Lisp data instead of crashing the app.

Agent tool calls are durably journaled in the session transcript. File mutation tools record before/after checkpoint metadata and diffs, and lisp_eval records before/after recovery checkpoints. If a turn is interrupted, recovery_list can summarize recent tool, file, and eval recovery events for repair.

Skills

RPLACA supports Codex-style local skills: a skill is a directory containing a SKILL.md file with YAML frontmatter and task-specific instructions. Enabled skills are listed in the agent system prompt, can be selected from the UI, and can be invoked in chat with $skill-name. When a user message mentions a skill, RPLACA injects a Codex-compatible contextual block for that turn:

<skill>
<name>demo</name>
<path>/path/to/demo/SKILL.md</path>
...
</skill>

Skill discovery scans repo-local .agents/skills/ directories, then ~/.rplaca.d/skills/, ~/.agents/skills/, ~/.rplaca.d/skills/.system/, and roots registered from Lisp. Use C-c s to insert an exact linked skill mention and C-c S to toggle skills.

(list-skills)
(describe-skill-to-string "common-lisp")
(read-skill-instructions "common-lisp")
(skill-list-files "common-lisp")
(skill-read-file "common-lisp" "references/notes.md")
(skill-search-to-string "common-lisp" "hash table")

Skills do not add new agent tools by themselves. Agents inspect skill instructions and resources through lisp_eval, and scripts/assets are local resources unless other RPLACA APIs explicitly execute or use them. Skill instructions are trusted input to the full-trust agent workflow.

Built-in Packages

RPLACA ships with a package system for optional tool and UI surfaces. Built-in packages cover structural Lisp editing and lookup (sexed, slop), web access (netcons), TODO/project management (organa), self-observation (speculum), testing (prove), subagents (subagent), deterministic pipelines (pipelines), Git workflows (git), prompt templates (templata), model-routing helpers (modelaria), artifacts (artifactum), structured user questions and message queues (quaestor), and MCP bridging (mcp-bridge).

Packages can be installed without being enabled. Enablement is scoped per global config, agent, or buffer. Use M-x package-dashboard-command for a presentation-driven browser, or M-x minibuffer-toggle-package-command to cycle enablement from the selector.

Project Resources

Project resources back file buffers, structured project APIs, and package-aware workflows. They coexist with direct provider tools like read, write, and edit. Project definitions can be registered from ~/.rplaca.d/init.lisp with define-project, and inert manifest files are autoloaded from *project-definitions-directory*, which defaults to ~/.rplaca.projects.d/. The user configuration directory is always available as the config project unless init defines config first.

(define-project "rplaca" :root #P"/path/to/rplaca/")
(create-project "scratch-work" :root #P"/tmp/scratch-work/" :persist nil)
(list-projects)
(project-list-files "rplaca")
(project-search-to-string "rplaca" "send-message")
(project-read-file "rplaca" "src/main.lisp")
(project-save-file "rplaca" "notes.org" "* Notes\n")
(project-open-file "rplaca" "src/main.lisp")

Open project resources become editable file buffers. C-x C-f opens a project file, C-x p selects the current buffer's project, and C-x C-s saves a file buffer back to its project resource. Programmatic project writes synchronize any already-open file buffer for the same resource; agents can inspect unsaved buffer state with (file-buffer-dirty-p BUFFER).

For durable coding work, agents should prefer transactional change sets. A change set stages project edits, exposes a Lisp-readable diff, and can be applied, discarded, or reverted:

(let ((cs (begin-change-set :name "demo-edit")))
  (stage-project-file "rplaca" "notes/demo.lisp" "(defun demo () :ok)"
                      :change-set cs)
  (change-set-diff-to-string cs)
  (apply-change-set cs))

Projects can also expose validation and reload hooks through define-project:

(define-project "rplaca"
  :root #P"/path/to/rplaca/"
  :systems '("rplaca" "rplaca/tests")
  :check-functions
  (list (lambda (project)
          (declare (ignore project))
          ;; Project-specific checks can call FiveAM, ASDF, or other Lisp APIs.
          :ok)))

(run-project-checks "rplaca")
(reload-project-system "rplaca")

Agent Structural Editing

RPLACA includes sexed, an agent-oriented s-expression editor inspired by Paredit but exposed as Lisp functions instead of cursor commands. It lets agents inspect, select, and edit Lisp forms by structure while rejecting edits that would leave unbalanced text.

(sexed-project-outline-to-string "rplaca" "src/main.lisp" :head "defun" :limit 20)
(sexed-project-form-text "rplaca" "src/main.lisp"
                         '(:head "defun" :name "ensure-scratch-buffer"))
(sexed-replace-project-form
 "rplaca"
 "src/foo.lisp"
 '(:head "defun" :name "foo")
 "(defun foo () :ok)")

(sexed-stage-replace-project-form
 "rplaca"
 "src/foo.lisp"
 '(:head "defun" :name "foo")
 "(defun foo () :better)")
(change-set-diff-to-string)
(apply-change-set)

(ensure-scratch-buffer)
(setf (scratch-buffer-text) "(workspace (todo alpha) (todo beta))")
(sexed-replace-scratch-form '(:head "todo" :nth 1) "(done beta)")
(sexed-insert-after-scratch-form '(:head "done") "(note \"checked\")")
(scratch-buffer-text)

Selectors are plists such as (:head "defun" :name "foo"), (:head "let*" :nth 0), or (:id 7). The :nth selector is zero-based. Pure functions such as sexed-replace-form return edited strings; project, file, message, and scratch adapters validate the full result before mutating resources or editable RPLACA messages. Insert helpers add separator whitespace when adjacent forms would otherwise touch.

McCLIM Chat Interface

The current McCLIM interface is a small presentation-based chat frame. It has a transcript pane, a Drei-backed compose pane, an info line, and a minibuffer pane for prompts and fuzzy completion rows. Transcript messages are CLIM presentations, and middle-clicking a message opens a one-pane metadata help window.

Editing Keybindings

Key Action
C-a / C-e Beginning / end of line
C-f / C-b Forward / backward char
M-f / M-b Forward / backward word
C-d Delete char forward
Backspace Delete char backward
C-k Kill line
C-u Kill backward line
M-d Kill word forward
C-w Kill word backward
C-y Yank (paste)
M-y Yank pop (cycle kill ring)
C-o Insert newline
Esc Stop active LLM response
RET Send message

Buffer Management

Key Action
C-x n New buffer
C-x l Open native McCLIM Listener
C-x k Kill buffer
C-x b Buffer selector (minibuffer)
C-x C-b Buffer selector (minibuffer)
C-x C-s Save session
C-x C-r Load session
C-x t Session tree
C-x T Fork session
C-x C-c Quit

Window Management

Key Action
C-x 2 Split window below
C-x 3 Split window right
C-x 0 Delete selected window
C-x 1 Delete other windows
C-x o Select other window

Navigation

Key Action
Page-Up / M-v Scroll up (history)
Page-Down / C-v Scroll down

Model & Provider

Key Action
C-c A Select agent (fuzzy minibuffer)
C-c C-m Select model (fuzzy minibuffer)
C-c M Select model (overlay)
C-c C-r Select think level (fuzzy minibuffer)
C-c t Toggle tool result display
C-c V Toggle reasoning display
C-c I Toggle metadata display
C-c C-d Toggle API debug mode

Help & Introspection

Key Action
M-x Fuzzy execute command
C-h b Describe keybindings
C-h f Describe function
C-h v Describe variable
C-h i Info directory
C-h I RPLACA manual buffer
C-h T Describe type
C-h F Customize face (interactive)
C-h D McCLIM debug status

Shell Prefix

Type ! followed by a shell command (e.g., !ls -la) to execute it directly. Output is inserted as a system message in the buffer without being sent to the agent. You can then discuss the output with the agent by sending a follow-up message.

Streaming Responses

Agent responses stream in real time via background threads. The event loop polls for updates, so you see tokens as they arrive.

Face System

RPLACA has a full face (color/attribute) system inspired by Emacs:

  • Per-sender color schemes (user messages on blue, agent on black, system in cyan)
  • Global faces for modeline, minibuffer, selectors, structured question prompts, and diff highlighting
  • Face inheritance chains with full resolution
  • Interactive face customization via C-h F
  • Supports CGA (16-color), 256-color, and hex (#RRGGBB) color specs

Bitmap Font Editor

The bitmap font editor saves its native editable format as .rplacafont using write-rplacafont-file and read-rplacafont-file. It can import legacy .clawfont files for compatibility, but saves only the canonical RPLACA format. BDF and CADR AST font import remain available through read-font-file.

Session Persistence

Chat buffers attach durable sessions by default. C-x C-s writes a manifest, and transcripts are appended to on-disk JSONL sidecars under ~/.config/rplaca/sessions/. Session history is branch-shaped rather than a flat list, and the session tree can be navigated or forked from the UI. On compaction, transcript writing rolls to a new segment and records the previous segment location. Snapshots are also autosaved as chat buffers change, and each interactive chat buffer shows its current full system prompt as a synthetic header at the top of the transcript.

Scratch Buffer

RPLACA keeps a process-local *scratch* buffer loaded in the buffer list for temporary notes and programmatic coordination. It is editable, never killed by normal buffer-kill commands, and lasts only until RPLACA exits.

Listener and Manuals

RPLACA opens McCLIM's native Listener application (C-x l) in its own window for direct evaluation, Listener commands, graphical presentations, and #!-prefixed shell commands. The older RPLACA listener-buffer data model is retained for loading existing sessions but is no longer opened by C-x l. C-h i opens the system Info directory, and C-h I opens the RPLACA manual buffer placeholder or manual when one is installed.

McCLIM Interface

RPLACA runs as a McCLIM application frame with a presentation-rich transcript pane, a Drei-backed compose pane, an info line, and a minibuffer pane. The transcript uses CLIM output records, message presentations, and incremental redisplay; the minibuffer uses normal CLIM stream output for prompt and candidate rows. Async provider updates are bridged back into McCLIM by queueing a small frame event that calls redisplay-frame-pane for the transcript.

Boot Files

RPLACA loads optional markdown files at startup to customize the agent's system prompt:

  • AGENTS.md, SOUL.md, USER.md, IDENTITY.md, TOOLS.md

Checked in the working directory first, then ~/.config/rplaca/. Compatible with OpenClaw workspace conventions.

Installation

Prerequisites

  • GNU Guix (for the containerized environment)
  • An X11 display (for the McCLIM application)

Running

./run.sh
./run.sh --clean-build

This launches RPLACA in a Guix container with all dependencies (SBCL, McCLIM, OpenSSL, fonts) automatically provisioned. Quicklisp is bootstrapped on first run.

run.sh and run-native.sh also supervise fatal crashes. After RPLACA publishes a private crash report and repair request, the launcher starts a fresh non-interactive Codex session inside the dedicated Guix repair container, gives it the report, debug log, and append-only repair history, and asks it to fix and validate the bug. RPLACA is relaunched only when Codex returns a schema-validated fixed result. Two repair attempts are allowed per launch chain by default; repeated failure stops the loop and leaves all evidence under .cache/crash-repair/. Set RPLACA_CRASH_REPAIR=0 to disable repair, or RPLACA_CRASH_REPAIR_MAX_ATTEMPTS=1..10 to change the cap. Codex progress, JSONL events, and errors are echoed into the terminal that launched RPLACA as well as retained in the per-attempt logs.

A native, non-container launcher is also available for machines with local SBCL and GUI dependencies installed:

./run-native.sh

Native runs need SBCL, a Quicklisp-compatible setup file, OpenSSL, X11 client libraries, fontconfig/freetype/Xft-style font libraries, and TrueType fonts. The native launcher uses the Ultralisp Quicklisp-compatible distribution via scripts/run-ultralisp.lisp, so it can resolve newer Common Lisp dependencies without entering the Guix container. It also constrains McCLIM's native TrueType scan to the DejaVu font bundle by default; set RPLACA_TRUETYPE_FONT_PATH to a compact font directory if you need an override. Set RPLACA_SBCL_DYNAMIC_SPACE_SIZE to adjust SBCL's heap size in MiB; the default is 2048.

By default, run.sh reuses cached ASDF/FASL build artifacts for fast startup. Pass --clean-build, or its alias --force-clean-build, to clear the local Common Lisp output cache before loading RPLACA.

For one-shot, non-interactive harness checks, use prompt.sh. It runs inside the same Guix container and prints only the final assistant response to stdout by default:

./prompt.sh 'Use lisp_eval with mode="isolated" to inspect the current default provider.'
./prompt.sh --show-tools --show-metadata "List the exported rplaca functions."
./prompt.sh --json --provider openai-codex --model gpt-5.6-sol "Summarize this repo."
./prompt.sh --clean-build "Run this prompt after clearing cached Lisp build artifacts."
./prompt.sh --isolated --show-tools "Exercise project APIs without user config state."
./prompt.sh --isolated --skill-root /tmp/my-skills 'Use $demo to answer.'

Plain prompt.sh runs default to openai-codex/gpt-5.6-sol. Passing --agent lets that agent's routing decide unless --provider or --model is also supplied. Interactive run.sh sessions use the normal RPLACA defaults and any overrides from ~/.rplaca.d/init.lisp.

By default, prompt.sh reuses cached ASDF/FASL build artifacts for fast iterations. Pass --clean-build, or its alias --force-clean-build, to clear the local Common Lisp output cache before loading RPLACA. If no prompt argument is supplied, prompt.sh reads non-interactive stdin.

Live harness regression probes are available through:

scripts/prompt-probes.sh
scripts/prompt-probes.sh --only transaction --keep-logs

GUI E2E runs are opt-in and documented in docs/GUI-E2E.md:

./scripts/run-gui-e2e.sh --preflight-only
./scripts/run-gui-e2e.sh --suite smoke
./scripts/run-gui-e2e.sh --suite mx
./scripts/run-gui-e2e.sh --suite features
./scripts/run-gui-e2e.sh --suite keybinds
./scripts/run-gui-e2e.sh --suite reload
./scripts/run-gui-e2e.sh --suite stability

The crash and lifecycle hardening plan, implemented findings, residual risks, and validation evidence are recorded in docs/STABILITY.md. Suspected framework failures are classified separately, with minimal controls and a strict fork threshold, in docs/MCCLIM-ISSUES.md.

The probes run through prompt.sh --isolated, write logs under /tmp, and check real agent behavior for docs discovery, skill loading, transactional project edits, and scratch/file-buffer workflows. By default they use openai-codex/gpt-5.6-sol first, then retry with openrouter/openai/gpt-5.6-sol if the primary provider fails.

Provider Credentials

Set provider credentials through the supported provider-specific sources. Z.AI and OpenRouter can use environment variables:

export ZAI_CODING_MAX_API_KEY="..."
# or
export OPENROUTER_API_KEY="..."

OpenAI Codex uses the shared Codex auth store or a token file as described above.

Interactive sessions default to zai/glm-5.2. The model selector retains older GLM releases for explicitly pinned configurations; GLM-5.2 exposes its documented high and max reasoning-effort choices.

OpenRouter model discovery uses its live /api/v1/models catalog when an API key is configured. Without a successful live fetch, RPLACA falls back to a curated tool-capable catalog containing the GPT-5.6 family, GLM-5.2, current Claude models, and current Gemini Flash models. Anthropic and Google models are OpenRouter routes; RPLACA does not provide direct adapters for them.

User Init File

The openai-codex model selector includes gpt-6-astra, using the existing Responses API transport with low, medium, high, xhigh, and max reasoning. Astra does not support none reasoning; see the official model documentation.

Customize RPLACA by creating ~/.rplaca.d/init.lisp:

;; Switch default provider and model
(setf rplaca:*default-provider* :openai-codex)
(setf rplaca:*default-model* "gpt-5.6-sol")

;; Override the default personality prompt or point to a different prompt file
(setf rplaca:*default-personality-prompt* "You are a pragmatic pair programmer.")
(setf rplaca:*personality-prompt-path* #P"/home/tay/.config/rplaca/pair-system-prompt.txt")
(rplaca:load-personality-prompt-file)

;; Register custom agents for the C-c A selector
(rplaca:register-agent-definition
 "writer"
 :provider :openai-codex
 :model "gpt-5.6-sol"
 :think-level "high"
 :core-prompt "Use lisp_eval only with mode=isolated for concrete work. Inspect first, then modify."
 :personality-prompt "You are a concise writing partner focused on structure and tone.")

;; Register additional skill roots or programmatic skills
(rplaca:register-skill-root #P"/home/tay/.local/share/rplaca/skills/")
(rplaca:register-skill-definition
 "repo-review"
 :description "Review Common Lisp changes in this repository."
 :contents
 (format nil "---~%name: repo-review~%description: Review Common Lisp changes.~%---~%Use project APIs, run tests, and report risks first."))

;; Customize seeded defaults after startup initialization
(rplaca:add-hook
 'rplaca:*startup-hook*
 (lambda ()
   (rplaca:keymap-bind rplaca:*default-keymap*
                         '(:ctrl-c #\z)
                         'rplaca:toggle-debug-mode-command)))

;; Customize the initial buffer before the McCLIM interface starts
(rplaca:add-hook
 'rplaca:*initial-buffer-hook*
 (lambda (buffer)
   (rplaca:buffer-insert-system-message
    buffer
    "init.lisp customized this buffer")))

Packages

Install and load a package from a git repository in ~/.rplaca.d/init.lisp:

(rplaca-use-package :src-type :git
                      :repo "https://example.com/user/cool-plugin.git")

Packages are cloned into ~/.rplaca.d/packages/ and must contain a manifest.lisp file at the repo root. The manifest is a property list that declares the package name and entrypoint file:

(:name "cool-plugin"
 :entrypoint "cool-plugin.lisp")

After installation, enable packages globally, per agent, or per buffer. The fastest user-facing path is the package dashboard:

(package-dashboard-command (current-buffer))
(set-package-enablement-scope "cool-plugin" :global)

Architecture

src/
  packages.lisp        Package definition and exports
  faces.lisp           Color specs, faces, face sets, global registry
  message.lisp         Line/message data structures, editing operations
  buffer.lisp          Buffer ring, conversation management, display state
  session.lisp         Durable sessions, transcripts, branch tree
  commands.lisp        defcommand macro and command metadata
  keymap.lisp          Keymap data structure, default bindings
  windows.lisp         Logical window model and split management
  projects.lisp        Project/resource registry, manifests, file buffers
  skills.lisp          Codex-style local skill discovery and resource access
  matching-core.lisp   Fuzzy matching implementation
  matching.lisp        Common Lisp wrappers for minibuffer matching
  minibuffer.lisp      Selector and minibuffer state machines
  llm.lisp             Multi-provider LLM integration, streaming, OAuth
  tools.lisp           Agent tool definitions and execution
  prefix.lisp          Chat prefix command dispatch (for =!shell= and peers)
  package-manager.lisp Package discovery, install, enablement, prompt injection
  pipelines.lisp       Deterministic pipeline runtime
  info.lisp            Texinfo/Info browser support
  hooks.lisp           Hook and advice system
  sexed.lisp           Agent-oriented structural s-expression editing
  slop.lisp            Common Lisp symbol lookup and reference analysis
  listener.lisp        In-buffer Common Lisp listener state and commands
  prompt-core.lisp     Shared prompt harness option parsing and defaults
  prompt-runner.lisp   Non-interactive prompt/session execution path
  session-export.lisp  HTML session export and share handlers
  mcclim-interface.lisp Fresh presentation-based McCLIM chat frame
  debug.lisp           Debug logging helpers
  main.lisp            Commands, key dispatch, startup, prompt entrypoints
  docs.lisp            Extended documentation entries

The core architecture follows Emacs patterns: buffers hold messages (not file lines), keymaps dispatch to commands, and commands operate on buffer state.

vs Emacs

RPLACA is not intended to replace GNU Emacs. It is another of the Emacsen — built from the same philosophical foundations (extensibility, introspection, Lisp as the extension language) but purpose-built for conversational agent interaction rather than text editing.

Where Emacs operates on files and buffers of text, RPLACA operates on conversations and messages. RPLACA now has both M-x for user-facing interactive commands and an agent that can eval arbitrary Lisp. The feedback loop is the same; the domain is different.

Future Plans

RPLACA takes its name from Common Lisp's destructive list update operation. It is designed to bridge the gap between current agentic editors and OpenClaw by providing a truly introspective and recursive agentic editor — one where the agent can modify the editor itself, inspect its own tool definitions, customize its own rendering, and evolve the environment collaboratively with the user.

License

RPLACA itself is licensed under the GNU Affero General Public License v3.0 only. See LICENSE for the full text.

Third-party vendored material may use different licenses. In particular, vendor/cl-community-spec is kept under its upstream MIT license; see vendor/cl-community-spec/LICENSE.