This file provides guidance to coding agents working with code in this repository.
emacs -batch -f batch-byte-compile *.el- Treat new byte-compilation warnings as regressions when touching Emacs Lisp code.
- Prefer reproducible batch verification first, ideally
emacs -Qwith the necessary load-path and dependencies configured for the target file. - If batch compilation fails to load required files or packages, treat that as a verification failure to resolve or report, not as a clean pass.
- If
emacs -Qcannot be made to work cleanly, compile files individually throughemacsclientas a fallback to match the active Emacs session more closely. - For documentation hygiene on touched files, also run
M-x checkdoc(or batchcheckdoc-file) before wrapping up changes.
# Run a specific test file
emacs -batch -L . -l ert -l test/test_ai-code-change.el -f ert-run-tests-batch-and-exit
# Run all tests
emacs -batch -L . -l ert --eval "(mapc #'load-file (file-expand-wildcards \"test/test_*.el\"))" -f ert-run-tests-batch-and-exitThe project uses melpazoid for CI checks. The workflow is defined in .github/workflows/melpazoid.yml.
This is a unified interface package for AI-assisted software development that abstracts over multiple AI coding CLI backends (Claude Code, Gemini CLI, OpenAI Codex, GitHub Copilot CLI, Opencode, Kilo, Grok CLI, Cursor CLI, CodeBuddy Code CLI, Kiro CLI). The package provides a consistent user experience across different AI tools while maintaining context-aware code actions and agile development workflows.
The backend system is pluggable and defined in ai-code-backends.el. Each backend is registered as a property list in ai-code-backends:
(ai-code-backends
'((claude-code
:label "Claude Code"
:require ai-code-claude-code
:start ai-code-claude-code
:switch ai-code-claude-code-switch-to-buffer
:send ai-code-claude-code-send-command
:resume ai-code-claude-code-resume
:config "~/.claude.json"
:upgrade "npm install -g @anthropic-ai/claude-code@latest"
:cli "claude")
;; ... other backends
))Backend switching is handled via ai-code-set-backend, which:
- Loads the backend's requirement (e.g.,
ai-code-claude-code) - Sets up function aliases for common operations
- Updates the UI to reflect the current backend
Backend implementations fall into two categories:
- Native backends (in this repo): Implemented in files like
ai-code-codex-cli.el,ai-code-github-copilot-cli.el,ai-code-gemini-cli.el,ai-code-codebuddy-cli.el, etc. - External backends: Packages like
claude-code-ide.elandclaude-code.elthat provide backend functions
ai-code-backends-infra.el provides a unified abstraction over terminal emulators:
- Default:
vterm(libvterm-based) - Alternative:
eat(Embraced as Terminal) - Configuration via
ai-code-backends-infra-terminal-backend
Key infrastructure features:
- Session management (multiple concurrent AI sessions)
- Window management (side windows, focus control)
- Performance optimizations (anti-flicker, reflow glitch prevention)
- Input handling (@-completion, clipboard integration)
The codebase is organized into focused modules:
ai-code.el: Main entry point, defines the transient menu (C-c a) and top-level commandsai-code-backends.el: Backend registration and selection systemai-code-backends-infra.el: Terminal abstraction (vterm/eat) and session managementai-code-change.el: Code manipulation operations (change code, implement TODOs, explain code)ai-code-discussion.el: Ask questions, explain code functionalityai-code-agile.el: Refactoring techniques catalog and TDD cycle workflowai-code-git.el: Git integration (diff review, recent files, branch operations)ai-code-file.el: File operations (copy paths, recent files, sed-based prompt application)ai-code-prompt-mode.el: Prompt file management (.ai.code.prompt.org), @-completion, yasnippet integrationai-code-input.el: User input handling, context gathering, completion utilitiesai-code-notifications.el: Desktop notifications for AI session completion- Backend implementations:
ai-code-codex-cli.el,ai-code-github-copilot-cli.el,ai-code-gemini-cli.el,ai-code-codebuddy-cli.el,ai-code-opencode.el,ai-code-kilo.el,ai-code-grok-cli.el,ai-code-cursor-cli.el,ai-code-kiro-cli.el,ai-code-claude-code.el
The main entry point is ai-code-menu (bound to C-c a), which uses the transient package to create an interactive menu with four sections:
- AI CLI Session: Start, resume, switch, select backend, upgrade, open config, apply prompt on file
- AI Code Actions With Context: Code change, implement TODO, ask question, explain, send command, add context, create task file
- AI Agile Development With Harness: Refactor, TDD cycle, pull/review diff, run file, build project, open prompt file, insert function
- Other Tools: Init project, debug exception, fix Flycheck errors, copy file name, toggle dedicated, open recent file, debug MCP, take notes, toggle notifications
All context-aware actions automatically include:
- Current file path
- Visible buffers (context files)
- Function or region at point
- Stored repo context (
ai-code--repo-context-info) - Optional clipboard context (with
C-uprefix)
Context engineering is a core concept - the package provides tools to automatically assemble precise context blocks:
- Automatic file context:
ai-code--get-context-files-stringincludes visible buffers - Function/region scoping: Most actions capture
which-functionresult or active region - Manual context curation:
ai-code-context-action(C-c a @) stores file paths, function anchors, or region ranges inai-code--repo-context-info - @-completion: Type
@to open file completion list, inserts relative paths with@prefix - Prompt suffix:
ai-code-prompt-suffixappends persistent constraints to all prompts
ai-code-agile.el contains a comprehensive catalog of refactoring techniques following Martin Fowler's book. Each technique has:
:name- Display name:scopes- Where it applies (region/global):description- The prompt template sent to AI:parameters(optional) - Interactive parameters with placeholders, prompts, and default value functions
The Test Driven Development cycle (ai-code-tdd-cycle) integrates with test frameworks:
- Python:
python-pytest - JavaScript/TypeScript:
jest
The workflow guides through writing tests, running them, implementing code, and refactoring.
- All files use
lexical-binding: t - Header includes Author, Version (for main file), Package-Requires, SPDX-License-Identifier: Apache-2.0
- Commentary section describes the module's purpose
- Code section follows
- Public functions:
ai-code-function-name - Private functions:
ai-code--function-name(double dash) - Custom variables:
ai-code-variable-name - Backends: Use kebab-case symbols like
claude-code,github-copilot-cli
- Use
defcustomfor user-configurable variables with:group 'ai-code - Use
;;;###autoloadcookies for interactive commands that should be available when the package is loaded - Use
declare-functiononly for functions defined in other files or loaded later. - Do not add
declare-functionentries for functions defined later in the same file; that can trigger duplicate-definition byte-compilation warnings. - For dynamically bound external variables referenced from optional packages, add
explicit
defvardeclarations instead of leaving them free. - Use
cl-labelsfor local helper functions - Prefix arguments (
C-u) are used to modify behavior (e.g., append clipboard context, force full paths)
When adding a new backend:
- Create
ai-code-<backend-name>.elfollowing the pattern of existing backends - Implement required functions:
ai-code-<backend>-start,ai-code-<backend>-switch-to-buffer,ai-code-<backend>-send-command,ai-code-<backend>-resume(optional) - Add backend definition to
ai-code-backendsinai-code-backends.el - Update README.org with backend setup instructions
- Test files:
test_ai-code-<module>.el - Use
ert-deftestfor test definitions - Test names:
test-module--function-name-scenario - Use
with-temp-bufferfor buffer-related tests - Mock functions with
cl-letfwhen needed - Mock
which-functionfor function context testing
.ai.code.files/: Created automatically in project root, contains.ai.code.prompt.orgfor prompt historysnippets/ai-code-prompt-mode/: Yasnippet templates for common promptsexamples/: Example projects demonstrating usage (Battleship, Connect4)test/: ERT test files
ai-code-magit-setup-transientsadds AI commands to Magit popups- Functions use
magit-toplevelto find git root - Diff review integrates with Magit's diff generation
gptel: Optional, used for AI-generated headlines in prompt filehelm: Optional, for enhanced completionyasnippet: Optional, for prompt templatesflycheck: Optional, forai-code-flycheck-fix-errors-in-scopeprojectile: Optional, for project root detection inai-code-init-project
Each backend requires the corresponding CLI to be installed and available on PATH:
- Claude Code:
claude - Gemini CLI:
gemini - OpenAI Codex:
codex - GitHub Copilot CLI:
copilot - Opencode:
opencode - Kilo:
kilo - Grok CLI:
grok - Cursor CLI:
cursor - Kiro CLI:
kiro - CodeBuddy Code CLI:
codebuddy