Skip to content
alvarmacielPublic

About

Deep integration of Sourcegraph Amp with Emacs, inspired by amp.nvim.

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

amp-emacs

Deep integration of Sourcegraph Amp with Emacs, inspired by amp.nvim.

Status: ✅ Working and Tested

amp-emacs is fully functional! All core features have been implemented and tested with Amp CLI v0.0.1763121689.

This implementation uses WebSocket communication (matching amp.nvim) and follows the IDE integration protocol spec.

Features

Core Functionality

  • ✅ Bidirectional communication with amp --ide via WebSocket
  • ✅ Port-based connection with authentication token (auto-finds port 9000-9999)
  • ✅ File tracking - Amp knows what files you're viewing
  • ✅ Selection notifications - Amp sees selected code
  • ✅ User messages - Send messages directly to Amp
  • ✅ File reading - Amp can read files from your workspace
  • ✅ File editing - Amp can edit files directly in your Emacs buffers (with automatic backups)
  • ✅ Region commands - Fix, explain, and improve code selections

Security & Safety

  • ✅ Path traversal protection - Validates all file paths, prevents access outside workspace
  • ✅ Sensitive directory blocking - Blocks access to .git, .ssh, .gnupg directories
  • ✅ Cryptographically secure tokens - Uses /dev/urandom on Unix for 256-bit tokens
  • ✅ Atomic file writes - Uses temporary files + rename to prevent corruption
  • ✅ Automatic backups - Creates timestamped backups before editing files
  • ✅ Content validation - Checks file size limits (default 10MB), null bytes, UTF-8 encoding
  • ✅ Sanitized logging - Removes sensitive data from logs (tokens, passwords, etc.)
  • ✅ Symlink protection - Prevents editing symbolic links
  • ✅ Rate limiting - DoS protection (configurable requests/second per client)
  • ✅ Client connection limits - Configurable maximum concurrent connections
  • ✅ Message size limits - Validates WebSocket message sizes (default 15MB)
  • ✅ Rollback on error - Restores buffer state if edit fails
  • ✅ Read-only buffer respect - Won't edit buffers marked as read-only

Diagnostics

  • ⚠️ Diagnostics API - Implemented but returns empty (needs flycheck/flymake integration)

Quick Start

Prerequisites

# Install Amp CLI
npm install -g @sourcegraph/amp

# Verify
amp --version

Installation

Doom Emacs

  1. Add to ~/.config/doom/packages.el:
(package! websocket)

;; Option A: Install from GitHub (recommended)
(package! amp
  :recipe (:host github :repo "alvarmaciel/amp-emacs"))

;; Option B: Install from local clone
;; (package! amp
;;   :recipe (:local-repo "local-packages/amp-emacs"))
  1. If using local clone (Option B), clone the repository:
mkdir -p ~/.config/doom/local-packages
cd ~/.config/doom/local-packages
git clone https://github.com/alvarmaciel/amp-emacs.git
  1. Configure in ~/.config/doom/config.el:
(use-package! amp
  :after websocket
  :config
  (setq amp-auto-start t)
  (setq amp-server-log-level 'info))
  1. Sync and restart:
doom sync

Regular Emacs

  1. Install websocket package:
M-x package-install RET websocket RET
  1. Clone and configure:
git clone https://github.com/yourusername/amp-emacs.git ~/.emacs.d/lisp/amp-emacs

Add to your init.el:

(add-to-list 'load-path "~/.emacs.d/lisp/amp-emacs")
(require 'websocket)
(require 'amp)
(setq amp-auto-start t)
  1. Restart Emacs

Quick Test (No Installation)

cd amp-emacs
emacs -Q --eval "(progn (require 'package) (add-to-list 'package-archives '(\"melpa\" . \"https://melpa.org/packages/\")) (package-initialize) (unless (package-installed-p 'websocket) (package-refresh-contents) (package-install 'websocket)) (add-to-list 'load-path \"$(pwd)\") (load \"amp\") (amp-start))"

Usage

Basic Workflow

  1. Open a file in your project:

    C-x C-f /path/to/your/project/file.txt
    

    This establishes the project context for Amp.

  2. Start Amp server in Emacs:

    M-x amp-start
    

    You'll see: Amp server started on port 9000. Run 'amp --ide' in your project.

  3. Connect Amp CLI:

    cd /your/project
    amp --ide
  4. Enable notifications (if not auto-enabled):

    M-x amp-client-enable
    
  5. Start using Amp:

    • Ask about code: Select text, then M-x amp-client-send-message (or C-c a m / SPC A m in Doom) while selection is active
    • Current context: Send messages - Amp sees your current file, cursor position, and any selected text
    • Fix code: Select region, then use the fix command
    • Explain code: Select region, then use the explain command
    • Custom prompts: Select region, then use the prompt command

    See the Commands table below for specific keybindings.

Commands

Command Regular Emacs Doom (evil) Doom (non-evil) Description
amp-start C-c a s SPC A s C-c A s Start Amp server
amp-stop C-c a q SPC A q C-c A q Stop Amp server
amp-status C-c a ? SPC A ? C-c A ? Show connection status
amp-client-send-message C-c a m SPC A m C-c A m Send message to Amp
amp-fix-region C-c a f SPC A f C-c A f Fix selected code
amp-improve-region C-c a i SPC A i C-c A i Improve selected code
amp-explain-region C-c a e SPC A e C-c A e Explain selected code
amp-prompt-for-region C-c a p SPC A p C-c A p Send region with custom prompt
amp-client-enable M-x M-x M-x Enable file/selection tracking
amp-client-disable M-x M-x M-x Disable notifications

Note: Doom Emacs keybindings require the map! configuration shown in the Doom Emacs Configuration section.

Example Workflow

;; 1. Start the server
M-x amp-start

;; 2. In terminal: amp --ide

;; 3. Enable notifications
M-x amp-client-enable

;; 4. Send a message
M-x amp-send-message RET hello from emacs! RET

;; 5. Ask Amp about current file
;; In Amp CLI: "what file am I looking at?"

;; 6. Fix some code
;; Select code, then: C-c a f

;; 7. Watch Amp edit the file directly!

Configuration

Basic Configuration

;; Auto-start Amp server when Emacs starts
(setq amp-auto-start t)

;; Log level: 'debug, 'info, 'warn, or 'error
(setq amp-server-log-level 'info)

;; Throttle notifications (seconds)
(setq amp-client-throttle-interval 0.1)

;; Custom data directory (optional)
;; (setq amp-server-data-home "~/.config/amp")

Security Configuration

;; Create backups before editing files (default: t)
(setq amp-server-backup-on-edit t)

;; Maximum file size for edits (default: 10MB)
(setq amp-server-max-file-size (* 10 1024 1024))

;; Maximum number of concurrent connections (default: 5)
(setq amp-server-max-clients 5)

;; Maximum requests per second per client (default: 100)
(setq amp-server-max-request-rate 100)

;; Maximum WebSocket message size (default: 15MB)
(setq amp-server-max-message-size (* 15 1024 1024))

Recommended Configuration (use-package)

(use-package websocket :ensure t)

(use-package amp
  :load-path "~/path/to/amp-emacs"
  :after websocket
  :config
  (setq amp-auto-start t)
  (setq amp-server-log-level 'info)
  (setq amp-client-throttle-interval 0.1)
  :bind-keymap
  ("C-c a" . amp-mode-map))

Doom Emacs Configuration

;; In config.el
(use-package! amp
  :after websocket
  :config
  (setq amp-auto-start t)
  (setq amp-server-log-level 'info))

;; Amp keybindings (Doom-compatible)
;; For evil-mode users: Use SPC A prefix (SPC A m, SPC A f, etc.)
;; For non-evil users: Use C-c A prefix (C-c A m, C-c A f, etc.)
(map! :leader
      :prefix ("A" . "amp")
      :desc "Send message" "m" #'amp-client-send-message
      :desc "Fix region" "f" #'amp-fix-region
      :desc "Improve region" "i" #'amp-improve-region
      :desc "Explain region" "e" #'amp-explain-region
      :desc "Prompt for region" "p" #'amp-prompt-for-region
      :desc "Start server" "s" #'amp-start
      :desc "Stop server" "q" #'amp-stop
      :desc "Restart" "r" #'amp-restart
      :desc "Status" "?" #'amp-status)

Note: In Doom Emacs, the minor mode keybindings (C-c a) may not work. Use the map! configuration above instead:

  • With evil-mode: SPC A prefix (e.g., SPC A m to send message)
  • Without evil-mode: C-c A prefix (e.g., C-c A m to send message)

Architecture

Three Main Components

1. amp-server.el (~25KB, ~844 lines)

  • WebSocket server on TCP localhost
  • Port discovery - automatically finds available port (9000-9999)
  • Authentication - generates cryptographically secure 256-bit tokens via /dev/urandom
  • Lockfile management - creates JSON lockfile with port + token
  • Message protocol - handles IDE protocol requests/responses
  • Request handlers:
    • ping - health check
    • authenticate - token validation
    • readFile - read file contents (with path validation)
    • editFile - apply edits to buffers (with backups, validation, atomic writes)
    • getDiagnostics - return diagnostics
  • Security layer:
    • Path traversal protection (validates relative to project root)
    • Symlink resolution and security checks
    • Sensitive directory blocking (.git, .ssh, .gnupg)
    • Content validation (size, encoding, null bytes)
    • Atomic file operations with rollback
    • Automatic backups with timestamps
  • Safety & reliability:
    • Rate limiting (DoS protection)
    • Client connection limits
    • Message size validation
    • Sanitized logging (no sensitive data)
    • Read-only buffer respect

2. amp-client.el (~6KB, ~185 lines)

  • Notifications to Amp:
    • visibleFilesDidChange - file tracking
    • selectionDidChange - text selections
    • userSentMessage - direct messages
  • Event hooks with throttling for performance
  • Client enable/disable control

3. amp.el (~5KB, ~184 lines)

  • User interface and commands
  • Minor mode (amp-mode) for easy enable/disable
  • Keybindings (C-c a prefix)
  • Integration with projectile/project.el

Communication Flow

Emacs (amp-emacs)          Amp CLI
─────────────────          ────────
1. Start WebSocket server
2. Create lockfile ──────> Read lockfile
3. Wait for connection <── Connect via WebSocket
4. Authenticate <────────> Send auth token
5. Send notifications ───> Receive file/selection info
6. Receive requests <───── Send readFile/editFile
7. Send responses ──────> Process responses

Protocol

Communication uses WebSocket with JSON messages in IDE protocol format.

Lockfile (~/.local/share/amp/ide/{port}.json)

{
  "port": 9000,
  "authToken": "abc123...",
  "pid": 12345,
  "workspaceFolders": ["/path/to/project"],
  "ideName": "emacs 29.1"
}

Server Notifications (Emacs → Amp)

{"serverNotification": {"visibleFilesDidChange": {"uris": ["file:///path/to/file"]}}}
{"serverNotification": {"userSentMessage": {"message": "Fix this code"}}}

Client Requests (Amp → Emacs)

{"clientRequest": {"id": "1", "ping": {"message": "hello"}}}
{"clientRequest": {"id": "2", "readFile": {"path": "/path/to/file.py"}}}
{"clientRequest": {"id": "3", "editFile": {"path": "/path/to/file.py", "fullContent": "..."}}}

Server Responses (Emacs → Amp)

{"serverResponse": {"id": "1", "ping": {"message": "hello"}}}
{"serverResponse": {"id": "2", "readFile": {"content": "file contents..."}}}
{"serverResponse": {"id": "3", "editFile": {"success": true, "message": "File updated"}}}

Troubleshooting

Server won't start

  1. Enable debug logging:

    M-: (setq amp-server-log-level 'debug)
    M-x amp-start
    M-x view-echo-area-messages
  2. Check for websocket package:

    M-x package-install RET websocket RET

Amp CLI doesn't connect

  1. Check server status:

    M-x amp-status
    

    Should show: Amp server running on port XXXX (project: /path, 0 clients)

  2. Verify lockfile:

    cat ~/.local/share/amp/ide/*.json

    Should show port, authToken, and other fields.

  3. Check you're in the right directory: The Amp CLI needs to run in a directory under your project workspace.

  4. Restart both sides:

    M-x amp-stop
    M-x amp-start

    Then restart amp --ide

Messages not appearing in Amp CLI

  1. Check client is enabled:

    M-: amp-client--enabled RET

    Should return t. If nil:

    M-x amp-client-enable
    
  2. Test with a simple message:

    M-x amp-send-message RET test RET
    

    Check debug messages:

    M-x view-echo-area-messages
    
  3. Verify connection:

    M-x amp-status
    

    Should show "1 clients" if Amp CLI is connected.

Port conflicts

The server automatically finds an available port (9000-9999). If all ports are in use, you'll see an error. Check what's using those ports:

netstat -tuln | grep '900[0-9]'

Performance issues

Reduce notification frequency:

(setq amp-client-throttle-interval 0.5)  ; Default is 0.1

Backup files appearing

Amp creates automatic backups before editing files (e.g., file.txt.amp-backup-20251121-143022). If you want to disable this:

(setq amp-server-backup-on-edit nil)

To clean up old backup files:

# Remove all amp backup files in a directory
find . -name "*.amp-backup-*" -delete

Development

Project Structure

amp-emacs/
├── amp-server.el       # WebSocket server and protocol
├── amp-client.el       # Editor state notifications
├── amp.el              # User interface
├── install-deps.el     # Dependency installer
├── README.md           # This file
├── INSTALL.org         # Detailed installation guide
├── QUICKSTART.md       # Quick start guide
├── TODO.org            # Development roadmap
└── SUMMARY.org         # Project summary

Running Tests

Currently manual testing only. Start development environment:

cd amp-emacs
emacs -Q --eval "(progn ...install websocket... (load \"amp\") (setq amp-server-log-level 'debug) (amp-start))"

Contributing

Contributions welcome! Areas of interest:

  1. Diagnostics integration - Connect flycheck/flymake
  2. Tests - Automated test suite
  3. Performance - Optimize notification frequency
  4. Documentation - Improve guides and examples
  5. Features - Mode line indicator, better UX

See TODO.org for full roadmap.

Comparison with amp.nvim

Feature amp.nvim amp-emacs Status
WebSocket server ✓ ✓ ✅ Complete
Port + auth token ✓ ✓ ✅ Complete
File tracking ✓ ✓ ✅ Complete
Selection tracking ✓ ✓ ✅ Complete
User messages ✓ ✓ ✅ Complete
Read files ✓ ✓ ✅ Complete
Edit files ✓ ✓ ✅ Complete
Diagnostics ✓ Partial ⚠️ Returns empty
Multi-project ✓ Untested ⚠️ Needs testing
Official support ✓ ✗ Community

What's Working

✅ Core functionality:

  • Amp CLI connects to Emacs via WebSocket
  • Messages sent from Emacs appear in Amp CLI
  • Amp knows what file you're viewing
  • Amp can read any file in your workspace
  • Amp can edit files directly in your buffers
  • All user commands work as expected

✅ Security & Safety (enterprise-ready):

  • Path traversal protection prevents accessing files outside workspace
  • Sensitive directories (.git, .ssh, .gnupg) are blocked
  • Cryptographically secure token generation (256-bit)
  • Atomic file writes prevent corruption
  • Automatic backups created before edits
  • Rate limiting prevents DoS attacks
  • Sanitized logging prevents credential leaks
  • Read-only buffers are respected

✅ Tested with:

  • Amp CLI v0.0.1763121689 (2025-11-14)
  • Emacs 28.1+
  • Doom Emacs
  • Regular Emacs with use-package

Known Limitations

  • Selection display: Amp uses selection notifications silently (doesn't display them in UI)
  • Diagnostics: Returns empty array (needs flycheck/flymake integration)
  • Multi-project: Untested with multiple simultaneous projects

Documentation

Resources

License

MIT License (or GPL-3.0+ to match Emacs conventions)

See LICENSE file for details.

Credits

Built by: Alvar (@alvarmaciel) and Claude (Anthropic)

Collaboration Disclaimer

This project was developed through a collaborative partnership between Alvar and Claude (an AI assistant by Anthropic). The implementation, architecture decisions, debugging, and documentation were created through an iterative conversation, combining:

  • Alvar's vision: Deep Emacs integration for Amp, matching the functionality of amp.nvim
  • Alvar's expertise: Emacs/Doom configuration, workflow requirements, and testing
  • Claude's contribution: Code implementation, protocol research, debugging assistance, and documentation writing
  • Joint effort: Architecture design, problem-solving, and iterative refinement

The entire development process, from initial concept to working implementation, happened in a single extended conversation where both participants contributed to the design and implementation decisions.

Inspiration & Thanks

Inspired by: amp.nvim by Sourcegraph

Special thanks to:

  • Sourcegraph team for creating Amp
  • amp.nvim contributors for the reference implementation
  • Emacs community for excellent tools and libraries
  • The WebSocket package maintainers

Status: Production-ready! 🎉

Questions? Issues? Contributions? Open an issue on GitHub!

About

Deep integration of Sourcegraph Amp with Emacs, inspired by amp.nvim.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages