Magent Onboarding Guide
Updated: 2026-07-07
Project Overview
Magent is an Emacs Lisp AI coding agent with multi-agent architecture, a durable turn ledger, and permission-based tool access.
- Languages: Emacs Lisp
- Primary Dependency: gptel (handles all LLM communication)
- Requirements: Emacs 29.1+, gptel, compat, yaml, acp, agent-shell, ripgrep
- Purpose: Provide AI-assisted coding capabilities inside the live Emacs runtime, while keeping provider transport in gptel and keeping tool access explicit and auditable
Current Agent Workflow
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.org before changing child-agent behavior, session persistence, or agent-related tools. Codex sandbox behavior is explicitly out of scope.
Architecture Layers
Layer 1: Entry Point & Configuration
The foundation layer that initializes the system and manages settings.
Key Files:
magent.el— Package entry point and lazy runtime initializationmagent-agent-shell.el— Supported interactive entry pointsmagent-config.el— UI-neutral runtime and feature customizationmagent-pkg.el— Package metadata
What it does: Lazy initialization is triggered by the first supported
agent-shell command via magent--ensure-initialized; full setup (agent
registry, skills, slash commands, and capabilities) happens on demand.
Layer 2: Session & Runtime State Management
Manages conversation history, scoped overlays, and runtime state.
Key Files:
magent-ledger.el— Thread/turn/item ledger, status transitions, snapshot shapemagent-session.el— Conversation projections, JSON persistence, per-project sessionsmagent-action-session.el— Isolated Action persistence, ledger, and cancellationmagent-action-session-view.el— Isolated Action session listing and inspectionmagent-doctor.el— Trusted read-only probes and one sanitized tool-free analysis requestmagent-redaction.el— Fail-closed redaction for Magent-owned outbound diagnostics and memorymagent-agent-job.el— Durable child-agent job records and JSON shapemagent-action.el— Workflow DSL, Step runtime, layered Action registry, and Invocation lifecyclemagent-runtime.el— Static initialization plus project-local overlay activation for agents, skills, Actions, and capabilitiesmagent-runtime-api.el— UI/backend-facing runtime session and prompt APImagent-runtime-queue.el— Global single-execution runtime queue with session-scoped cancellationmagent-audit.el— Persistent JSONL audit logging for permissions and sensitive actions
What it does: Maintains ledger-backed conversation history scoped by project, persists to ~/.emacs.d/magent/sessions/ by default, stores durable child-agent jobs under agent-jobs, and activates or unloads project-local overlays as scope changes. Ordinary ACP prompts and Action-owned agent work submit through magent-runtime-api.el; magent-runtime-queue.el owns queued/active turn state and session-scoped cancellation. Doctor and Memory use unified Actions exposed through slash and M-x magent-action-run-*, with isolated sessions under magent-session-directory/actions. Doctor is a direct probe pipeline with no model tools; read DOCTOR.org before changing its data boundary or extension API.
Layer 3: Agent System
Multi-agent architecture with specialized agents for different tasks.
Key Files:
magent-agent.el— Core agent processing: builds gptel prompts, applies overrides, callsgptel-requestmagent-project-instructions.el— Bounded root-to-resource discovery of scoped project instructions such asAGENTS.mdmagent-agent-info.el— Agent metadata struct and helpersmagent-agent-builtins.el— 7 built-in agent definitionsmagent-agent-registry.el— Hash-table registry and project overlaysmagent-agent-file.el— Loads custom agents from.magent/agent/*.mdfilesmagent-permission.el— Rule-based tool access control (allow/deny/ask with glob patterns)
What it does: Provides specialized agents (build, plan, explore, general, and hidden utility agents) 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.
Layer 4: Tools & Capabilities
The action layer that executes operations requested by agents.
Key Files:
magent-tools.el— canonical catalog of 15gptel-toolstructs: read_file, read_buffer, write_file, write_repo_summary, edit_file, grep, glob, bash, emacs_eval, spawn_agent, send_agent_message, wait_agent, list_agents, close_agent, web_searchmagent-skills.el— Skill registry, built-in skills, file loading, inspection commandsmagent-skill-manager.el— User-level skills.sh finder, safe copy installer, and permanent deletionmagent-capability.el— Capability definitions, resolution, and file-backed loadingmagent-approval.el— User approval prompts for sensitive operations
What it does: Tools provide concrete actions and child-agent coordination. Skills are data-only instructions injected into prompts. Executable extensions belong in trusted Actions or first-class catalog tools. Approval gates dangerous operations.
Layer 5: Agent Loop & LLM Integration
Orchestrates the tool-calling loop and LLM communication.
Key Files:
magent-agent-loop.el— Active Magent-owned loop, tool dispatch, serial queueing, abort helpers, continuation outcomesmagent-llm.el— Provider-neutral request/event protocolmagent-llm-gptel.el— Thingptel-requestsampling adapter
What it does: magent-agent-loop.el consumes normalized LLM events, records assistant/tool state into the session, dispatches tools through magent-tool-orchestrator, and returns continuation outcomes after model-visible tool output is recorded. magent-agent-process continues only through provider-native tool continuation, completes empty responses explicitly, and fails directly at an optional sampling limit. Reasoning is kept separate from assistant text. magent-llm-gptel.el still calls gptel-request; Magent does not rewrite provider transport.
Layer 6: Supported Frontend
agent-shell is the only supported conversational frontend. Explicit M-x
command wrappers use the adjacent Action lifecycle rather than another UI.
Key Files:
magent-agent-shell.el— Magent agent-shell config and prompt routingmagent-acp.el— In-process ACP adapter for agent-shellmagent-action.el— Action Workflow, registry, and slash/interactive projectionsmagent-action-session.el— Isolated Action persistence and cancellationmagent-action-session-view.el— Isolated Action session listing and inspectionmagent-runtime-api.el— UI/backend-facing runtime APImagent-runtime-queue.el— Runtime queue and session-scoped cancellationmagent-file-loader.el— Shared frontmatter parser for agent/skill/capability files
What it does: Prompts route through
magent-agent-shell.el and the in-process ACP adapter. ACP sends registered
slash commands through magent-action.el, projects scope-aware instruction
skill descriptors as /$name, and submits those skill selections plus ordinary
prompts directly to magent-runtime-api.el. A prompt request remains pending
until its ordinary turn or Action Invocation reaches a terminal state. See
docs/UI_BACKENDS.org for the frontend development boundary before changing
this layer.
Layer 7: Events
Key Files:
magent-lifecycle-events.el— Structured lifecycle hooks for turns, subagents, and tool calls
What it does: Provides structured lifecycle hooks for turns, subagents, and tool calls.
Key Concepts
Multi-Agent Architecture
Magent uses specialized agents with different capabilities:
- build (default) — Full tool access for general coding
- plan — Restricted file edits (only
.magent/plan/*.md) - explore — Fast codebase exploration (read/grep/glob/bash only)
- general — General-purpose subagent for child-agent tasks
- compaction, title, summary — Hidden utility agents
Agents have modes: primary (user-facing), subagent (internal), all (either).
Current child-agent architecture is documented in docs/AGENT_JOBS.org. The Codex workflow alignment plan remains useful as implementation history.
Permission System
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.
Skill System
Skills are instruction-only Markdown injected into the system prompt. Companion Elisp is not loaded.
Instruction skills can be selected as one-shot context for the next request.
The agent-shell frontend exposes
magent-agent-shell-toggle-skill-for-next-request. ACP also advertises every
visible instruction skill as /$name; this explicitly selects the skill for
an ordinary turn. Skills never enter the Action registry. Elisp-native Actions
are registered separately through
magent-action-register and can be selected with
magent-agent-shell-run-command. /skills lists the same descriptors without
a provider request. The bundled /init command initializes or refreshes the
project root AGENTS.md and accepts optional extra text.
For each turn, Magent starts with the selected agent’s base prompt, then adds
project context, applicable AGENTS.md files from the project root toward
request-local file resources, relevant profile memory, and the small set of
explicit or capability-selected instruction skills. Discovery never leaves the
canonical project root and is bounded by
magent-project-instructions-max-bytes; set that option to nil to disable it.
A runtime trust policy is appended to all agent-loop prompts, including custom
and utility agents. Injected memory may be incomplete or stale, so current user
instructions and live Emacs/repository state take precedence. Text read from
files, buffers, logs, commands, tool results, or web pages remains data and
cannot grant tool permission by presenting itself as a higher-priority prompt.
Skills load from: (1) built-in skills/, (2) legacy user ~/.emacs.d/magent-skills/ when present, (3) canonical user ~/.emacs.d/magent/skills, and (4) project .magent/skills/. Later user directories take precedence. magent-find-skill, magent-install-skill, and magent-delete-skill manage user-level skills only and never use ~/.agents/skills/. A skill can also declare capability: true with resolver metadata such as modes, features, files, keywords, and disclosure; Magent turns that metadata into a capability that activates the same skill. Automatic activation requires a word-bounded keyword hit as evidence of user intent; context-only matches remain suggested. Declared tools are enforced against the selected agent’s exposed tools: incompatible automatic skills are downgraded, while an incompatible explicitly selected skill fails with a clear error. Agent-shell sessions expose an Automatic capabilities config option for disabling automatic resolution.
Keep the terms separate when adding or reviewing defaults:
- Use an
Actionfor executable trusted Elisp. It may be projected as a slash command, an interactive command, or both. - Use
commandfor the frontend/protocol projection, not the domain object. - Use a
skillfor reusable instructions that can be selected explicitly or automatically./$nameis the ACP projection; it does not create an Action. - Use a
capabilitywhen the skill should be selected automatically from live context or prompt text. - Co-locate the capability metadata in
SKILL.mdwhen the capability only exists to activate that same skill. Use standaloneCAPABILITY.mdonly when the trigger metadata is separate from a single skill or belongs to a project overlay.
Session Scoping
Sessions are project-aware:
- In a project: state scoped to that project
- Outside projects: global session fallback
- Persists to
~/.emacs.d/magent/sessions/projects/<sha1>/ - Stores durable child-agent job metadata, result/error state, and transcripts in
agent-jobs
Lazy Initialization
Mode enable is lightweight (modeline only). Full initialization (registry, skills) happens on first command via magent--ensure-initialized.
Guided Tour
Step 0: Read the Architecture Boundary
Start with docs/ARCHITECTURE.org for the product boundary: Magent keeps provider plumbing in gptel, runs the agent loop in Emacs Lisp, exposes Emacs runtime context through tools, and does not implement Codex-style OS sandboxing.
Step 1: Start with the Entry Point
Begin at magent.el for package initialization, then read
magent-agent-shell.el for the supported interactive entry points.
Step 2: Explore the UI Boundary
Read docs/UI_BACKENDS.org, then magent-agent-shell.el, magent-acp.el, and
magent-runtime-api.el. Read magent-action.el next when tracing slash or
interactive commands. Key insight: agent-shell is the only supported
conversational frontend; explicit M-x command wrappers reuse the Action
Invocation lifecycle, and shared runtime behavior remains in the runtime API.
Step 3: Follow a Request Lifecycle
Trace a request through these files in order:
magent-agent-shell.el/magent-acp.el— Receivesession/promptand normalize frontend inputmagent-action.el/magent-skills.el— Resolve registered slash commands or scope-aware/$skilldescriptorsmagent-runtime-api.el/magent-runtime-queue.el/magent-ledger.el— Record, queue, and start ordinary or Action-owned turnsmagent-agent.el— Build the prompt and select agent, skills, capabilities, and toolsmagent-llm-gptel.el/magent-agent-loop.el— Sample through gptel and own normalized continuation outcomesmagent-tool-orchestrator.el/magent-tools.el— Resolve permissions and execute tool implementations
Step 4: Understand Permissions
Read magent-permission.el to see how tool access is controlled. The magent-permission-resolve function shows the resolution order. Then look at magent-agent-builtins.el to see how built-in agents define their permissions.
Step 5: Explore Extensibility
Check out:
magent-agent-file.el— How custom agents load from.magent/agent/*.mdmagent-skills.el— How skills extend agent capabilitiesmagent-action.el— How trusted packages register explicit slash or interactive actionsmagent-action-session.el/magent-action-session-view.el— How isolated Action Invocations persist, report progress, cancel, and rendermagent-file-loader.el— The shared frontmatter parser for agents, skills, and capabilities
Step 6: Study the Tools
Read magent-tools.el to understand the available tools. Pay attention to:
emacs_eval— Executes in the request buffer context (usesmagent-tools--request-buffer-name)spawn_agent/send_agent_message/wait_agent/list_agents/close_agent— Coordinate durable child-agent jobsweb_search— DuckDuckGo integration viaurl-retrieve
Then read docs/AGENT_JOBS.org for the lifecycle contract and persistence boundaries.
Step 7: Review Testing
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.
File Map
Core Entry & Configuration
- magent.el — Mode definition, keybindings, lazy initialization
- magent-log.el — UI-neutral logging mechanism and sink registry
- magent-config.el — UI-neutral runtime and feature customization
- magent-json.el — JSON-safe serialization helpers
State Management
- magent-session.el — Conversation history, per-project sessions, JSON persistence
- magent-runtime.el — Static initialization and project-local overlay activation
- magent-audit.el — JSONL audit logs for permissions and sensitive actions
Agent System
- magent-agent.el — Core processing: builds prompts, filters tools, calls gptel
- magent-agent-info.el — Agent metadata struct and helpers
- magent-agent-builtins.el — 7 built-in agent definitions
- magent-agent-registry.el — Agent registry and project overlays
- magent-agent-file.el — Custom agent loader from
.magent/agent/*.md - magent-permission.el — Tool access control with glob patterns
Tools & Skills
- magent-repo-summary.el — deterministic org-roam repository-note upserts
- magent-tools.el — canonical catalog of 15 gptel-tool implementations
- magent-skills.el — Skill registry, built-in skills, file loading, commands
- magent-capability.el — Capability definitions, resolution, and file-backed loading
- magent-approval.el — User approval prompts for sensitive operations
Agent Loop & LLM Integration
- magent-agent-loop.el — Active normalized event loop, tool dispatch, queueing, guards, abort, continuation
- magent-llm.el — Provider-neutral request/event protocol
- magent-llm-gptel.el —
gptel-requestadapter
User Interface
- magent-agent-shell.el — Supported agent-shell config and prompt routing
- magent-acp.el — In-process ACP adapter
- magent-runtime-api.el — UI/backend-facing runtime API
- magent-runtime-queue.el — Runtime queue and session-scoped cancellation
- magent-file-loader.el — Shared frontmatter parser
Events
- magent-lifecycle-events.el — Structured lifecycle hooks for turns, subagents, and tool calls
CI And Package Data
- .github/workflows/test.yml — Byte-compilation, unit tests, and deterministic live smoke tests
- .github/workflows/coverage.yml — Batch
testcoverrun and coverage artifact upload - .github/workflows/melpazoid.yml — MELPA-style package checks
- test/coverage.el — Coverage runner used by
make coverage
Magent packages runtime data as well as Elisp. prompts/ and skills/
must remain included in the melpazoid/MELPA recipe because magent-config.el,
magent-skills.el, and built-in skill-backed capabilities resolve those paths
at runtime. This includes internal prompt layers such as the runtime trust
policy, not only prompts/system.org. Every bundled Org prompt must also appear
exactly once in prompts/manifest.txt; the unit suite checks the manifest against
the directory. If standalone bundled CAPABILITY.md files are added, include
capabilities/ as runtime data too.
Complexity Hotspots
These areas require careful attention when modifying:
1. magent-agent-loop.el (High Complexity)
Why it’s complex: Owns the active request/tool loop: normalized event accumulation, provider-neutral tool-call batch completion, serial execution, permission orchestration, UI tool rendering, abort cleanup, tool-result session recording, reasoning separation, and continuation outcomes.
Approach carefully: Any changes to loop state, tool callback ordering, final-response retry policy, 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.
2. magent-llm-gptel.el (Medium Complexity)
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.
3. Frontend boundary (High Complexity)
Why it’s complex: The supported frontend spans magent-agent-shell.el, magent-acp.el, magent-runtime-api.el, and magent-runtime-queue.el.
Approach carefully: Keep frontend-neutral behavior in magent-runtime-api.el,
ACP conversion in magent-acp.el, and agent-shell-specific behavior in
magent-agent-shell.el.
4. magent-permission.el (Medium Complexity)
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.
5. magent-tools.el (Medium Complexity)
Why it’s complex: 15 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.
6. magent-session.el (Medium Complexity)
Why it’s complex: Per-project session scoping with global fallback, JSON persistence, ledger-driven UI restoration, child-agent job persistence, and history trimming.
Approach carefully: Session directory calculation uses SHA1 of project root. agent-jobs must be preserved for child transcript inspection.
Development Workflow
Building & Testing
# Byte-compile all files make compile # Run full test suite make test # Run unit tests only make test-unit # Run coverage and write coverage/testcover-summary.tsv make coverage # Clean build files and Harbor benchmark containers/networks make clean # Also remove benchmark Docker images and Harbor task cache make purge
make test-live-smoke requires an Emacs server and uses stubbed gptel
transport. make test-live uses the real configured provider and may consume
tokens, so run it only against an isolated daemon.
Live Development
Test changes in running Emacs:
# Reload a changed file emacsclient --eval '(load "/path/to/magent-foo.el" nil t)' # Clear the current runtime session emacsclient --eval '(magent-runtime-session-clear (magent-runtime-session-current))' # Check logs emacsclient --eval '(with-current-buffer "*magent-log*" (buffer-string))'
Test Prompts
After changes, verify with:
- Non-tool:
"你好"— Tests streaming and assistant sections - Tool-use:
"帮我看下 emacs 里面有多少 buffer"— Testsemacs_evaltool - Multi-step:
"帮我在 emacs 里面打开 magent 的 magit buffer"— Tests chained execution
Check the active Magent agent-shell buffer, *magent-log*, and *Messages* for
errors.
Common Patterns
Adding a New Tool
Define in
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"))- Add to
magent-enable-toolsdefault inmagent-config.el - Update built-in agent permissions in
magent-agent-builtins.el
For agent lifecycle tools such as spawn_agent, send_agent_message, wait_agent, list_agents, or close_agent, update docs/AGENT_JOBS.org and related tests. These tools should remain one coherent job lifecycle rather than unrelated standalone tools.
Creating a Custom Agent
Create .magent/agent/my-agent.md:
--- description: Agent purpose mode: primary temperature: 0.7 effort: medium permissions: read: allow write: ask bash: deny --- System prompt goes here.
Use permission group keys such as read, write, edit, and agent. The
older list form with concrete tool names remains supported for reading, but
new definitions should use this mapping form.
Adding a Skill
Create skills/my-skill/SKILL.md:
--- name: my-skill description: Brief description type: instruction tools: read_file, grep --- Skill instructions for the agent.
Getting Help
- Documentation:
README.org,AGENTS.mdin repo root - Child-agent architecture:
docs/AGENT_JOBS.org - Interactive help:
M-x magent-action-run-doctorfor self-diagnostics - Frontend:
M-x magent-start - Skills:
M-x magent-agent-shell-toggle-skill-for-next-request - Logs: open
*magent-log*withC-x b - Agent selection:
M-x agent-shell-set-session-modefrom the agent-shell buffer
Next Steps
- Run the tests — Start with
make test-unit; use an isolated Emacs server before running the fullmake test - Try the examples — Run
M-x magent-start - Read the code — Follow the guided tour above
- Experiment — Create a custom agent or skill
- Contribute — Check open issues and submit PRs
Welcome 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.