Efrit
A native elisp coding agent running in Emacs
Install / Use
/learn @steveyegge/EfritREADME
Efrit - AI-Powered Emacs Coding Assistant
Version 0.4.1
Efrit is an AI coding agent that brings Claude's intelligence directly into Emacs. It can execute natural language commands, explore codebases, run shell commands, and have multi-turn conversations - all while you stay in your editor.
Core principle: Zero client-side intelligence. Claude makes all decisions, Efrit executes.
⚠️ Security Note: Efrit executes AI-generated code in your Emacs. See SECURITY.md for trust model and recommended practices.
Features
Conversational Chat (efrit-chat)
Multi-turn conversations with Claude that understand your Emacs context:
- Ask questions about code, get explanations
- Refactor with guidance
- Debug issues interactively
Agentic Task Execution (efrit-do)
Execute natural language commands that Claude translates to actions:
- "Create a buffer with today's date"
- "List all elisp files in this directory and count them"
- "Search for the function definition of
efrit-execute" - "Run git status and show me the output"
Agent Session Buffer (efrit-agent)
A structured, real-time view of agentic sessions with:
- Session status and elapsed time in header-line
- Task progress tracking (TODOs) updated by Claude
- Conversation view with expandable tool calls
- Interactive input for follow-up commands and mid-session guidance
Agent Buffer Keybindings:
| Key | Action |
|-----|--------|
| n / M-n | Next tool call |
| p / M-p | Previous tool call |
| RET | Expand/collapse tool at point |
| E | Expand all tool calls |
| C | Collapse all tool calls |
| w | Copy tool output to kill ring |
| v | Cycle verbosity (minimal/normal/verbose) |
| i | Inject guidance mid-session |
| r | Resume paused session |
| k | Cancel session |
| g | Refresh display |
| q | Quit buffer (session continues) |
| 1-4 | Select option when Claude asks |
| ? | Show help |
Rich Tool Suite
Efrit provides Claude with 35+ tools:
| Category | Tools |
|----------|-------|
| Code Execution | eval_sexp (elisp), shell_exec (shell commands) |
| File Editing | edit_file, create_file, undo_edit, format_file |
| Codebase Exploration | search_content, read_file, project_files, glob_files, file_info |
| Version Control | vcs_status, vcs_diff, vcs_log, vcs_blame |
| Task Management | todo_write, session_complete, request_user_input |
| Safety | confirm_action, checkpoint, restore_checkpoint, show_diff_preview |
| Diagnostics | get_diagnostics, elisp_docs |
| Issue Tracking | beads_ready, beads_create, beads_update, beads_close, beads_list |
| External | web_search, fetch_url, read_image |
| Buffer Management | buffer_create, display_in_buffer |
Robust Error Handling
- Circuit breaker prevents infinite loops
- Automatic error recovery and retry
- Security controls on shell commands
AI-to-AI Communication
Other AI agents (Claude Code, Cursor, etc.) can interact with Efrit via file-based JSON queue for autonomous development.
Installation
Prerequisites
- Emacs 28.1+
- Anthropic API key from console.anthropic.com
Quick Start
git clone https://github.com/steveyegge/efrit.git
cd efrit
Add to ~/.emacs.d/init.el:
(add-to-list 'load-path "/path/to/efrit/lisp")
(require 'efrit)
API Key Configuration
Option A: Encrypted authinfo (recommended)
Create ~/.authinfo.gpg:
machine api.anthropic.com login personal password YOUR_API_KEY_HERE
Option B: Environment variable
export ANTHROPIC_API_KEY="sk-your-key-here"
Option C: Plain authinfo
Create ~/.authinfo:
machine api.anthropic.com login personal password YOUR_API_KEY_HERE
Verify with M-x efrit-doctor.
Usage
When to Use Each Mode
| Mode | Use When | Tools Available |
|------|----------|-----------------|
| efrit-chat | Multi-turn conversations, asking questions, explanations | Buffer-centric (read buffer, search) |
| efrit-do | Quick agentic commands, shows progress in minibuffer | Full suite (35+ tools) |
| efrit-agent | Complex tasks needing visibility and interaction | Full suite + structured UI |
Decision guide:
- Just asking? →
efrit-chat(conversational, no file changes) - Quick command? →
efrit-do(runs in background, shows progress buffer) - Complex task? →
efrit-agent(real-time visibility, can guide mid-session)
Key differences:
efrit-chat: Read-only context, conversational UI, retains historyefrit-do: Fire-and-forget, progress buffer with raw outputefrit-agent: Interactive session buffer with expandable tool calls, TODO tracking, and mid-session guidance (ikey)
Commands
| Command | Description |
|---------|-------------|
| M-x efrit-chat | Multi-turn conversational interface |
| M-x efrit-do | Execute natural language command asynchronously with progress buffer |
| M-x efrit-agent | Open the structured agent session buffer |
| M-x efrit-do-sync | Execute natural language command synchronously (blocking) |
| M-x efrit-do-silently | Execute command asynchronously without showing progress buffer |
| M-x efrit-do-show-progress | Show the progress buffer for the active command |
| M-x efrit-do-show-queue | Show commands queued for execution |
| M-x efrit-doctor | Run diagnostics |
| M-x efrit-help | Show help |
Examples
Simple queries:
M-x efrit-do RET
> what buffer am I in?
Code exploration:
M-x efrit-do RET
> search for all uses of 'defcustom' in this project and list them
Multi-step tasks:
M-x efrit-do RET
> create a new elisp file with a function that reverses a string, include proper headers
Shell integration:
M-x efrit-do RET
> run git log --oneline -10 and summarize the recent changes
Conversational:
M-x efrit-chat RET
You: Help me understand how the error handling works in this file
Assistant: [analyzes current buffer and explains]
You: Can you refactor it to use condition-case-unless-debug instead?
Agentic Workflows
Bug fix workflow:
M-x efrit-agent RET
> The function `my-parse-data` throws an error on empty input. Find and fix it.
Claude will:
1. Search for the function definition
2. Analyze the code
3. Identify the bug
4. Create the fix with edit_file
5. Show you the diff for review
Refactoring workflow:
M-x efrit-agent RET
> Refactor all uses of deprecated `my-old-api` to use `my-new-api` in this project
Claude will:
1. Find all occurrences with search_content
2. Create a TODO list for each file
3. Edit each file, showing progress
4. Verify changes compile
Mid-session guidance: While Claude is working, you can:
- Press
ito inject guidance: "Focus on the src/ directory only" - Press
kto cancel if going wrong direction - Wait for questions - Claude will ask via
request_user_inputand you can respond directly in the buffer
Providing corrections: When Claude asks a question, you can:
- Type your response after the
>prompt and pressC-c C-sto send - Press
1,2,3, or4to select from offered options - Type "actually, I meant..." to correct course
Async Execution (Default Behavior)
By default, efrit-do executes asynchronously:
M-x efrit-do RET
> create a buffer with a function to reverse strings
Efrit automatically:
- Displays a progress buffer with real-time updates on Claude's thinking and tool execution
- Supports interruption with
C-g(keyboard-quit) - Queues commands if another command is already running (use
efrit-do-show-queueto view) - Shows session status in the minibuffer and modeline
The progress buffer shows:
- Claude's reasoning and tool calls
- Results from each step
- Time elapsed
Synchronous Execution (Legacy)
For simpler tasks or scripting, use efrit-do-sync for blocking execution:
(efrit-do-sync "list all python files in current directory")
This is the older API that waits for completion before returning.
Background Execution
To run a command without showing the progress buffer:
M-x efrit-do-silently RET
> long running task...
Progress is visible in the minibuffer. Show the buffer later with M-x efrit-do-show-progress.
Key Bindings
Enable the global keymap:
(efrit-setup-keybindings) ; Binds C-c C-e prefix
Then use:
C-c C-e c- Chat interfaceC-c C-e d- Async command with progress bufferC-c C-e D- Async command in backgroundC-c C-e q- Start remote queueC-c C-e Q- Queue status
Agent Communication (MCP)
AI agents can interact with Efrit via the Model Context Protocol:
(efrit-remote-queue-start) ; Start the queue
Request format:
{
"id": "req_001",
"version": "1.0.0",
"type": "eval",
"content": "(buffer-name)",
"timestamp": "2025-11-28T20:00:00Z"
}
Types: eval (elisp), command (natural language), chat (conversation), status (health check)
Response format:
{
"id": "req_001",
"version": "1.0.0",
"status": "success",
"result": "*scratch*",
"timestamp": "2025-11-28T20:00:01Z"
}
See mcp/README.md for MCP server setup.
Migration Guide
If you have existing keybindings or configurations using older Efrit APIs:
Old name → New name | Status
--- | --- | ---
efrit-do (sync) | efrit-do-sync | Deprecated
efrit-do-async | efrit-do | Primary interface
efrit-do-async-legacy | — | Do not use
If you have in your init.el:
;; OLD: sync command (blocking)
(global-set-key (kbd "C-c C-e d") 'efrit-do)
;; NEW: use async command with progress buffer
(global-set-key (kbd "C-c C-e d") 'efrit-do)
Or if you have code calling efrit-do-async:
;; OLD: explicit async
(efrit-do-async "your comm
Related Skills
node-connect
349.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
349.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
349.0kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
