A comprehensive port of opencode's sophisticated tools and agent system to Emacs via gptel integration.
- Overview
- Architecture
- Core Features
- Installation
- Configuration
- Usage
- Tool Reference
- LSP Integration
- Agent System
- Permission System
- Migration Guide
- Troubleshooting
- Contributing
opencode.el brings the power of opencode's advanced LLM tooling to Emacs, providing a seamless integration between AI assistance and your development workflow. Unlike simple chat interfaces, opencode.el provides sophisticated tools that understand your codebase, integrate with language servers, and maintain context across complex multi-step tasks.
- Rich Tool Descriptions: Each tool includes comprehensive usage instructions that guide LLM behavior
- Deep Emacs Integration: Native buffer operations, LSP integration, and Emacs-specific functionality
- Intelligent Code Understanding: LSP-powered error detection, symbol search, and real-time diagnostics
- Task Management: Structured todo system for complex, multi-step development tasks
- Permission System: Safe command execution with configurable security policies
- Agent Specialization: Different presets optimized for coding, research, or general tasks
opencode.el follows a modular architecture that cleanly separates concerns while providing seamless integration:
┌─────────────────────────────────────────────────────────────┐
│ User Interface │
│ (Emacs + gptel) │
└─────────────────────┬───────────────────────────────────────┘
│
┌─────────────────────▼───────────────────────────────────────┐
│ opencode.el │
│ (Main Package) │
│ ┌─────────────────┬─────────────────┬─────────────────┐ │
│ │ Setup & │ Agent │ Integration │ │
│ │ Autoloads │ Presets │ Functions │ │
│ └─────────────────┴─────────────────┴─────────────────┘ │
└─────────────────────┬───────────────────────────────────────┘
│
┌─────────────────────▼───────────────────────────────────────┐
│ Tool Layer │
│ ┌─────────────────┬─────────────────┬─────────────────┐ │
│ │ opencode-tools │ opencode-lsp │ opencode-agents │ │
│ │ │ │ │ │
│ │ • File Ops │ • Diagnostics │ • System │ │
│ │ • Commands │ • Symbols │ Prompts │ │
│ │ • Search │ • Hover Info │ • Presets │ │
│ │ • Editing │ • Auto-start │ • Specialization│ │
│ │ • Tasks │ │ │ │
│ └─────────────────┴─────────────────┴─────────────────┘ │
└─────────────────────┬───────────────────────────────────────┘
│
┌─────────────────────▼───────────────────────────────────────┐
│ Description Layer │
│ opencode-descriptions │
│ │
│ Rich, comprehensive tool descriptions that guide LLM │
│ behavior with usage patterns, constraints, and examples │
└─────────────────────┬───────────────────────────────────────┘
│
┌─────────────────────▼───────────────────────────────────────┐
│ Integration Layer │
│ ┌─────────────────┬─────────────────┬─────────────────┐ │
│ │ gptel │ lsp-mode │ Emacs Core │ │
│ │ │ │ │ │
│ │ • Tool System │ • Language │ • Buffer Ops │ │
│ │ • LLM Backends │ Servers │ • File System │ │
│ │ • Streaming │ • Diagnostics │ • Process Mgmt │ │
│ │ • Presets │ • Symbols │ • Async Ops │ │
│ └─────────────────┴─────────────────┴─────────────────┘ │
└─────────────────────────────────────────────────────────────┘
- User Interface: Standard gptel interface enhanced with opencode tools and presets
- Main Package: Coordinates setup, configuration, and integration between components
- Tool Layer: Implements sophisticated tools with rich functionality
- Description Layer: Provides comprehensive guidance for LLM tool usage
- Integration Layer: Connects to Emacs internals, LSP, and external systems
User Input → gptel → opencode Tools → Emacs/LSP/System → Results → LLM → User
↑ ↓
└─────────────── Rich Context & Tool Descriptions ──────────────────┘
- Intelligent Reading: Line-numbered output with LSP integration for code understanding
- Sophisticated Editing: Multiple replacement strategies with real-time error detection
- Pattern Matching: Fast glob and grep operations using ripgrep
- Safe Creation: File creation with automatic LSP startup and validation
- Real-time Diagnostics: Automatic error detection after file operations
- Symbol Navigation: Workspace-wide symbol search and code understanding
- Language Server Integration: Automatic startup and management of language servers
- Code Intelligence: Hover information, document symbols, and semantic analysis
- Structured Todos: JSON-based task tracking with status management
- Progress Visibility: Real-time updates on complex multi-step tasks
- Priority Management: High/medium/low priority task organization
- State Tracking: Pending, in-progress, completed, and cancelled states
- Command Filtering: Configurable allow/deny/ask policies for shell commands
- File Protection: Permission checks for file editing operations
- Safe Defaults: Conservative security settings with user override options
- Audit Trail: Clear visibility into what operations are being performed
- Coding Agent: Optimized for software development with LSP tools
- General Agent: Research and analysis focused with comprehensive tools
- Minimal Agent: Essential tools only for lightweight usage
- Custom Agents: User-configurable tool sets and system prompts
# Required
brew install ripgrep # or apt install ripgrep
# Optional but recommended for full functionality
# LSP servers for your languages (e.g., typescript-language-server, pylsp, etc.)
;; Required
(use-package gptel
:ensure t)
;; Optional but recommended
(use-package lsp-mode
:ensure t)
git clone https://github.com/opencode/opencode.el.git ~/.emacs.d/opencode.el
(add-to-list 'load-path "~/.emacs.d/opencode.el")
(require 'opencode)
(opencode-setup)
(use-package opencode
:load-path "~/.emacs.d/opencode.el"
:after gptel
:config
(opencode-setup-coding)) ; or opencode-setup, opencode-setup-minimal
(use-package opencode
:straight (:host github :repo "opencode/opencode.el")
:after gptel
:config
(opencode-setup))
;; Full opencode experience
(opencode-setup)
;; Coding-focused (recommended for development)
(opencode-setup-coding)
;; Minimal tools only
(opencode-setup-minimal)
;; Custom configuration
(setq opencode-enabled-tools 'coding)
(setq opencode-default-preset 'opencode-coding)
(opencode-setup-custom)
;; Configure command permissions
(setq opencode-bash-permissions
'(("ls*" . "allow") ; Allow ls commands
("git*" . "allow") ; Allow git commands
("npm*" . "allow") ; Allow npm commands
("rm*" . "ask") ; Ask before rm commands
("sudo*" . "deny") ; Deny sudo commands
("*" . "ask"))) ; Ask for everything else
;; Configure file edit permissions
(setq opencode-edit-permissions "ask") ; "allow", "deny", or "ask"
;; Enable LSP features (default: enabled)
(setq opencode-lsp-enabled t)
;; Show diagnostics in tool output (default: enabled)
(setq opencode-lsp-show-diagnostics t)
;; Auto-start LSP servers when needed (default: enabled)
(setq opencode-lsp-auto-start t)
;; Choose which tools to enable
(setq opencode-enabled-tools 'all) ; All tools
(setq opencode-enabled-tools 'coding) ; Coding-focused
(setq opencode-enabled-tools 'essential) ; Essential only
(setq opencode-enabled-tools '("read_file" "edit" "run_command")) ; Custom list
;; Set default preset
(setq opencode-default-preset 'opencode-coding)
;; Start gptel with opencode tools
M-x gptel
;; Or use specific preset
M-x gptel-menu ; then select opencode preset
The updated configuration adds opencode-specific bindings:
SPC l o ; opencode-setup (full)
SPC l c ; opencode-setup-coding
SPC l n ; opencode-setup-minimal
SPC l b ; gptel buffer
SPC l m ; gptel menu
SPC l s ; gptel send
File Analysis:
User: Analyze the main.py file and suggest improvementsAssistant: I'll read the main.py file and analyze it for potential improvements.
[Uses read_file tool to read main.py with line numbers]
[Uses lsp_diagnostics tool to check for errors]
[Provides detailed analysis with specific suggestions]
Complex Refactoring:
User: Refactor the authentication system to use JWT tokensAssistant: I'll help you refactor the authentication system to use JWT tokens. Let me break this down into manageable tasks.
[Uses todowrite to create structured task list]
[Uses glob to find authentication-related files]
[Uses grep to search for current auth patterns]
[Uses edit to implement JWT changes step by step]
[Shows LSP diagnostics after each change]
Bug Investigation:
User: There's a memory leak in the user service, can you find it?Assistant: I'll investigate the memory leak in the user service systematically.
[Uses lsp_symbols to find user service components]
[Uses grep to search for memory allocation patterns]
[Uses read_file to examine suspicious code sections]
[Provides detailed analysis of potential leak sources]
Tool | Description | LSP Integration |
---|---|---|
read_file |
Read files with line numbers and offset/limit support | ✅ Warms LSP client |
edit |
Sophisticated string replacement with multiple strategies | ✅ Shows diagnostics after edit |
create_file |
Create new files with content validation | ✅ Auto-starts LSP |
list_directory |
List directory contents with enhanced descriptions | - |
apply_diff_fenced |
Apply unified diff patches to files | - |
Tool | Description | Backend |
---|---|---|
glob |
Fast file pattern matching | find/ripgrep |
grep |
Content search with regex support | ripgrep |
lsp_symbols |
Workspace symbol search | LSP |
Tool | Description | Security |
---|---|---|
run_command |
Execute shell commands with timeout | ✅ Permission system |
Tool | Description | Format |
---|---|---|
todowrite |
Create and update structured task lists | JSON |
todoread |
Read current task list | JSON |
Tool | Description | Native |
---|---|---|
read_buffer |
Read Emacs buffer contents | ✅ |
edit_buffer |
Edit Emacs buffers with error handling | ✅ |
append_to_buffer |
Append text to buffers | ✅ |
list_buffers |
List all open buffers | ✅ |
read_documentation |
Access Emacs function/variable docs | ✅ |
Tool | Description | Backend |
---|---|---|
search_web |
Web search with formatted results | SearXNG |
opencode.el's LSP integration (opencode-lsp.el
) provides a bridge between opencode tools and Emacs' lsp-mode:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ opencode Tool │───▶│ opencode-lsp │───▶│ lsp-mode │
│ │ │ │ │ │
│ • read_file │ │ • touch_file │ │ • Language │
│ • edit │ │ • diagnostics │ │ Servers │
│ • create_file │ │ • symbols │ │ • Workspace │
│ │ │ • formatting │ │ • Diagnostics │
└─────────────────┘ └─────────────────┘ └─────────────────┘
- Automatic LSP Startup: Language servers start automatically when files are accessed
- Real-time Diagnostics: Errors and warnings appear in tool output
- Symbol Intelligence: Workspace-wide symbol search and navigation
- Code Understanding: Enhanced context for LLM through LSP information
;; Enable/disable LSP integration
(setq opencode-lsp-enabled t)
;; Control diagnostic display
(setq opencode-lsp-show-diagnostics t)
;; Auto-start language servers
(setq opencode-lsp-auto-start t)
- File Reading: Warms LSP client for better subsequent operations
- File Editing: Shows compilation errors and warnings after changes
- File Creation: Starts appropriate language server for new files
- Symbol Search: Find functions, classes, variables across workspace
- Diagnostics: Get real-time error information for any file
opencode.el provides specialized agent presets via gptel's preset system:
;; Agent presets are defined using gptel-make-preset
(gptel-make-preset 'opencode-coding
:description "Optimized for coding tasks"
:system opencode-coding-system-prompt
:tools '("read_file" "edit" "run_command" "lsp_diagnostics" ...))
- Purpose: Complete opencode functionality
- Tools: All available tools including LSP, web search, and task management
- System Prompt: Comprehensive coding assistant with task management
- Best For: Complex development projects, research, and multi-step tasks
- Purpose: Optimized for software development
- Tools: File operations, LSP tools, command execution, task management
- System Prompt: Coding-focused with emphasis on code quality and testing
- Best For: Daily development work, debugging, refactoring
- Purpose: Information gathering and analysis
- Tools: File reading, search tools, web search, task management
- System Prompt: Research-focused with systematic approach
- Best For: Code analysis, documentation, investigation tasks
- Purpose: Essential functionality only
- Tools: Basic file operations and command execution
- System Prompt: Concise and direct
- Best For: Simple tasks, resource-constrained environments
Create your own specialized presets:
(gptel-make-preset 'my-custom-preset
:description "Custom preset for my workflow"
:system "You are a specialized assistant for..."
:tools '("read_file" "edit" "run_command" "lsp_symbols"))
opencode.el implements a comprehensive permission system to ensure safe operation:
User Request → Tool Invocation → Permission Check → Execution/Denial
↓
┌─────────────────┐
│ Permission │
│ Policies │
│ │
│ • allow │
│ • deny │
│ • ask │
└─────────────────┘
Configure shell command execution policies:
(setq opencode-bash-permissions
'(("ls*" . "allow") ; Allow listing commands
("git*" . "allow") ; Allow git operations
("npm*" . "allow") ; Allow npm commands
("pip*" . "allow") ; Allow pip commands
("rm*" . "ask") ; Confirm deletions
("sudo*" . "deny") ; Block privileged commands
("curl*" . "ask") ; Confirm network requests
("wget*" . "ask") ; Confirm downloads
("*" . "ask"))) ; Ask for everything else
Control file modification operations:
;; Global file edit policy
(setq opencode-edit-permissions "ask") ; "allow", "deny", or "ask"
;; Per-directory policies (future enhancement)
(setq opencode-edit-directory-permissions
'(("/tmp/*" . "allow")
("/etc/*" . "deny")
("~/.config/*" . "ask")))
- Glob Patterns: Use shell-style wildcards (
*
,?
,[...]
) - Precedence: More specific patterns override general ones
- Default Policy: The
"*"
pattern sets the default behavior
- Start Restrictive: Begin with
"ask"
for most operations - Allow Common Operations: Permit safe, frequently-used commands
- Deny Dangerous Operations: Block privileged and destructive commands
- Regular Review: Periodically audit and update permission policies
If you're migrating from the original llm.el configuration:
;; Save your current llm.el configuration
cp ~/.emacs.d/llm.el ~/.emacs.d/llm.el.backup
;; Add opencode.el to your configuration
(use-package opencode
:load-path "~/.emacs.d/opencode.el"
:after gptel
:config
(opencode-setup-coding))
Replace your llm.el with the updated version that focuses on LLM backend configuration and integrates with opencode.el.
;; Test that tools are working
M-x gptel
;; In the gptel buffer, try: "List the files in the current directory"
Original llm.el Tool | opencode.el Equivalent | Enhancements |
---|---|---|
read_file |
read_file |
✅ Line numbers, LSP integration |
run_command |
run_command |
✅ Permission system, security |
edit_buffer |
edit_buffer |
✅ Better error handling |
create_file |
create_file |
✅ LSP integration, validation |
apply_diff_fenced |
apply_diff_fenced |
✅ Enhanced error handling |
- | glob |
✨ NEW: Pattern matching |
- | grep |
✨ NEW: Content search |
- | edit |
✨ NEW: Sophisticated editing |
- | todowrite /todoread |
✨ NEW: Task management |
- | lsp_diagnostics |
✨ NEW: Error detection |
- | lsp_symbols |
✨ NEW: Symbol search |
;; Check if lsp-mode is installed
(featurep 'lsp-mode) ; Should return t
;; Verify LSP is enabled
opencode-lsp-enabled ; Should be t
;; Check if language server is available
M-x lsp-doctor
;; Check permission configuration
opencode-bash-permissions
;; Temporarily allow all commands (not recommended for production)
(setq opencode-bash-permissions '(("*" . "allow")))
;; Verify opencode is loaded
(featurep 'opencode) ; Should return t
;; Check tool registration
(length gptel-tools) ; Should show multiple tools
;; Re-register tools
(opencode-setup)
# Install ripgrep
brew install ripgrep # macOS
sudo apt install ripgrep # Ubuntu/Debian
sudo dnf install ripgrep # Fedora
Enable detailed logging for troubleshooting:
;; Enable gptel debug logging
(setq gptel-log-level 'debug)
;; Check opencode configuration
(opencode-debug-info) ; Custom debug function
If tools are slow:
;; Disable LSP integration temporarily
(setq opencode-lsp-enabled nil)
;; Use minimal tool set
(opencode-setup-minimal)
;; Check ripgrep performance
(benchmark-run 10 (opencode-grep "function" "*.py"))
# Clone the repository
git clone https://github.com/opencode/opencode.el.git
cd opencode.el
# Install development dependencies
# (Add any specific development setup here)
- Follow Emacs Lisp conventions
- Use
lexical-binding: t
- Include comprehensive docstrings
- Add type hints where appropriate
- Follow the existing code organization
;; Run tests (when test suite is available)
M-x ert RET opencode-test-* RET
;; Manual testing
(opencode-test-tool-integration)
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Update documentation
- Submit a pull request
- Additional LSP Features: Hover information, code actions, formatting
- More Tool Integrations: Git operations, package managers, build systems
- Performance Optimizations: Caching, async operations, lazy loading
- Security Enhancements: Sandboxing, audit logging, policy management
- Documentation: Examples, tutorials, best practices
- Testing: Unit tests, integration tests, performance benchmarks
This package uses code from opencode which is licensed under the MIT License.
This project is licensed under the MIT License - see the LICENSE file for details.
- opencode - Original tool system and sophisticated LLM integration
- gptel - Excellent Emacs LLM integration framework
- lsp-mode - Comprehensive LSP support for Emacs
- The Emacs Community - Feedback, contributions, and continuous improvement
opencode.el brings the power of sophisticated LLM tooling to your Emacs workflow, enabling AI-assisted development that understands your code, respects your security, and scales with your projects.