Updated: 2026-06-01
Magent is an Emacs Lisp AI coding agent with multi-agent architecture and permission-based tool access.
Magent has a Magent-owned agent loop and a durable child-agent lifecycle for collaborative work. Root agents can spawn, message, wait for, list, inspect/resume, and close child-agent jobs.
Read docs/AGENT_JOBS.md before changing child-agent behavior, session persistence, or agent-related tools. Codex sandbox behavior is explicitly out of scope.
The foundation layer that initializes the system and manages settings.
Key Files:
magent.el — Main entry point, defines magent-mode minor mode with C-c m prefixmagent-config.el — All defcustom variables, defface definitions, shared utilitiesmagent-pkg.el — Package metadataWhat it does: Lazy initialization triggered on first command via magent--ensure-initialized. Mode enable only adds modeline construct; full setup (agent registry, skills) happens on demand.
Manages conversation history, scoped overlays, and runtime state.
Key Files:
magent-session.el — Conversation state with message list, JSON persistence, per-project sessionsmagent-agent-job.el — Durable child-agent job records and JSON shapemagent-runtime.el — Static initialization plus project-local overlay activation for agents, skills, and capabilitiesmagent-audit.el — Persistent JSONL audit logging for permissions and sensitive actionsWhat it does: Maintains conversation history scoped by project, persists to ~/.emacs.d/magent-sessions/, stores raw buffer content for lossless restore, persists child-agent jobs under agent-jobs, and activates or unloads project-local overlays as scope changes. Request serialization itself lives in magent-ui.el via a single in-flight processing lock.
Multi-agent architecture with specialized agents for different tasks.
Key Files:
magent-agent.el — Core agent processing: builds gptel prompts, applies overrides, calls gptel-requestmagent-agent-registry.el — Agent struct definitions, 7 built-in agents, hash-table registrymagent-agent-file.el — Loads custom agents from .magent/agent/*.md filesmagent-permission.el — Rule-based tool access control (allow/deny/ask with glob patterns)What it does: Provides specialized agents (build, plan, explore, general, etc.) with different capabilities. Permission system filters tools per agent. Custom agents extend functionality via markdown files with YAML frontmatter.
Current behavior: Magent replaced the old one-shot delegate surface with durable child-agent jobs that have stable ids, status, transcript/result storage, and parent/child session relationships.
The action layer that executes operations requested by agents.
Key Files:
magent-tools.el — 14 gptel-tool structs: read_file, write_file, edit_file, grep, glob, bash, emacs_eval, spawn_agent, send_agent_message, wait_agent, list_agents, close_agent, skill_invoke, web_searchmagent-skills.el — Skill registry, built-in skills, file loading, inspection commandsmagent-capability.el — Capability definitions, resolution, and file-backed loadingmagent-approval.el — User approval prompts for sensitive operationsWhat it does: Tools provide concrete actions (file I/O, shell commands, web search) and child-agent coordination (spawn_agent, send_agent_message, wait_agent, list_agents, close_agent). Skills extend agent behavior (instruction-type injected into prompts, tool-type invoked via skill_invoke). Approval system gates dangerous operations.
Orchestrates the tool-calling loop and LLM communication.
Key Files:
magent-agent-loop.el — Active Magent-owned loop, tool dispatch, serial queueing, abort helpers, continuationmagent-llm.el — Provider-neutral request/event protocolmagent-llm-gptel.el — Thin gptel-request sampling adapterWhat it does: magent-agent-loop.el consumes normalized LLM events, records assistant/tool state into the session, dispatches tools through magent-tool-orchestrator, handles visible tool rendering, abort cleanup, and Codex-style continuation. Tool results are fed back to the model rather than being stopped by an emacs_eval call-count guard. magent-llm-gptel.el still calls gptel-request; Magent does not rewrite provider transport.
Org-mode derived buffer for interaction and output rendering.
Key Files:
magent-ui.el — In-buffer input/output, org-mode derived, streaming sections, transient menumagent-evil.el — Optional Evil integration loaded explicitly by Evil usersmagent-md2org.el — Markdown → org-mode conversion for assistant outputmagent-file-loader.el — Shared frontmatter parser for agent/skill/capability filesWhat it does: *magent* buffer uses org-mode with custom faces. In-buffer input via * [USER] sections. Tool calls render as #+begin_tool/#+end_tool blocks, reasoning as #+begin_think/#+end_think, and child-agent lifecycle events as #+begin_agent/#+end_agent. Streaming uses chunk batching and async fontification. magent-show-agent-transcript (C-c m j) opens persisted child job details.
Key Files:
magent-events.el — Event system for extensibilityWhat it does: Provides structured lifecycle hooks for turns, subagents, and tool calls.
Magent uses specialized agents with different capabilities:
.magent/plan/*.md)Agents have modes: primary (user-facing), subagent (internal), all (either).
Current child-agent architecture is documented in docs/AGENT_JOBS.md. The Codex workflow alignment plan remains useful as implementation history.
Fine-grained control over tool access per agent:
((read_file . allow) ; Allow all reads
(write_file . ((deny "*.env") ; Deny .env files
(deny "*.key") ; Deny .key files
(allow "*"))) ; Allow others
(bash . ask)) ; Prompt user
Resolution order: exact tool match → file-pattern rules → wildcard (*) → default allow.
Two skill types:
skill_invoke toolInstruction skills can be explicitly enabled in the input area with @skill-name.
Skills that define default-prompt can be submitted alone; built-in @init
initializes or refreshes the project root AGENTS.md, similar to Codex /init.
Submit @clear as the whole input to clear the current session context,
similar to Codex /clear, without sending a request to the model.
Skills load from: (1) built-in skills/, (2) user ~/.emacs.d/magent-skills/, (3) project .magent/skills/.
Sessions are project-aware:
~/.emacs.d/magent-sessions/projects/<sha1>/agent-jobsMode enable is lightweight (modeline only). Full initialization (registry, skills) happens on first command via magent--ensure-initialized.
Begin at magent.el to understand how the mode is activated and what commands are available. The C-c m prefix map shows all interactive entry points.
Read magent-ui.el to see how the *magent* buffer works. Key insight: it derives from org-mode, so all org features (folding, fontification) apply. The magent-ui--with-insert macro is critical for understanding how streaming works.
Trace a request through these files in order:
magent-agent.el — magent-agent-process builds the promptmagent-agent-loop.el — Owns normalized events, tool dispatch, queueing, abort, and continuationmagent-llm-gptel.el — Calls gptel-request for one sampling requestmagent-tool-orchestrator.el / magent-tools.el — Resolve permissions and execute tool implementationsmagent-ui.el — Results render in bufferRead magent-permission.el to see how tool access is controlled. The magent-permission-resolve function shows the resolution order. Then look at magent-agent-registry.el to see how built-in agents define their permissions.
Check out:
magent-agent-file.el — How custom agents load from .magent/agent/*.mdmagent-skills.el — How skills extend agent capabilitiesmagent-file-loader.el — The shared frontmatter parser used by bothRead magent-tools.el to understand the available tools. Pay attention to:
emacs_eval — Executes in the request buffer context (uses magent-tools--request-buffer-name)spawn_agent / send_agent_message / wait_agent / list_agents / close_agent — Coordinate durable child-agent jobsweb_search — DuckDuckGo integration via url-retrieveThen read docs/AGENT_JOBS.md for the lifecycle contract and persistence boundaries.
Look at test/magent-test.el to see how the codebase is tested. Tests mock gptel-request and use cl-letf to isolate state. This shows you the public API surface.
.magent/agent/*.mdgptel-request adapterThese areas require careful attention when modifying:
Why it’s complex: Owns the active request/tool loop: normalized event accumulation, tool-call batching, serial execution, permission orchestration, UI tool rendering, abort cleanup, tool-result session recording, and continuation.
Approach carefully: Any changes to loop state, tool callback ordering, or abort handling can hang a turn or corrupt session history. Add focused ERT coverage first, then verify live with tool-use prompts when Emacs is available.
Why it’s complex: It is intentionally the only place that may touch gptel callback/FSM details. It converts provider callback shapes into normalized Magent events without letting gptel’s tool-loop semantics leak into the main loop.
Approach carefully: Keep provider transport concerns here and loop behavior in magent-agent-loop.el. Do not add new main-loop dependencies on gptel private FSM handlers.
Why it’s complex: Org-mode derived buffer with custom insertion logic, async fontification, chunk batching, and read-only region management. The magent-ui--with-insert macro suppresses buffer-boundary signals from process filters and active minor modes.
Approach carefully: Insertions must use inhibit-read-only. Org fontification can trigger re-entrancy. Request generation counter prevents stale callbacks.
Why it’s complex: Order-dependent file-pattern matching with glob syntax. Resolution order matters: exact match → file patterns → wildcard → default allow.
Approach carefully: More specific patterns must come before less specific ones. Test with various glob patterns.
Why it’s complex: 14 different tool implementations with varying side effects, timeouts, child-agent runtime state, and error handling. emacs_eval uses magent-tools--request-buffer-name to execute in correct buffer context.
Approach carefully: Tools run in process filters. Timeout handling must be robust. Context capture for emacs_eval, child-agent status persistence, and parent/child request-context inheritance are critical.
Why it’s complex: Per-project session scoping with global fallback, JSON persistence, buffer-content restoration, child-agent job persistence, and history trimming.
Approach carefully: Session directory calculation uses SHA1 of project root. Buffer content and agent-jobs must be preserved for lossless restore and child transcript inspection.
# Byte-compile all files
make compile
# Run full test suite
make test
# Clean compiled files
make clean
Test changes in running Emacs:
# Reload a changed file
emacsclient --eval '(load "/path/to/magent-foo.el" nil t)'
# Clear session state
emacsclient --eval '(magent-clear-session)'
# Check logs
emacsclient --eval '(with-current-buffer "*magent-log*" (buffer-string))'
After changes, verify with:
"你好" — Tests streaming and assistant sections"帮我看下 emacs 里面有多少 buffer" — Tests emacs_eval tool"帮我在 emacs 里面打开 magent 的 magit buffer" — Tests chained executionCheck *magent*, *magent-log*, and *Messages* buffers for errors.
magent-tools.el:
(defun magent-tools--my-tool (args)
;; Implementation
)
(defvar magent-tools--my-tool-tool
(gptel-make-tool :function #'magent-tools--my-tool
:name "my_tool"
:description "What it does"))
magent-enable-tools default in magent-config.elmagent-agent-registry.elFor agent lifecycle tools such as spawn_agent, send_agent_message, wait_agent, list_agents, or close_agent, update docs/AGENT_JOBS.md and related tests. These tools should remain one coherent job lifecycle rather than unrelated standalone tools.
Create .magent/agent/my-agent.md:
---
description: Agent purpose
mode: primary
temperature: 0.7
permissions:
- (read_file . allow)
- (write_file . ask)
- (bash . deny)
---
System prompt goes here.
Create skills/my-skill/SKILL.md:
---
name: my-skill
description: Brief description
type: instruction
tools: read_file, grep
---
Skill instructions for the agent.
README.org, AGENTS.md in repo rootdocs/AGENT_JOBS.mdM-x magent-doctor for self-diagnosticsC-c m l to view request/response logC-c m v to list agents, C-c m i for current agentmake test to verify your environmentmagent-mode and run C-c m pWelcome to magent! This guide should help you get oriented. The codebase follows clear separation of concerns with each module handling a specific responsibility. Start with the guided tour and don’t hesitate to dive into the code—it’s well-structured and documented.