Magent Onboarding Guide
Updated: 2026-08-27
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 or Git for project search
- 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 definitions, 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-mode-line.el— Optional active Action count and current-Step tooltipmagent-action-session-view.el— Isolated Action session listing and inspectionmagent-action-builtin-doctor.el— Trusted read-only probes and one sanitized tool-free analysis requestmagent-redaction.el— Fail-closed redaction for Magent-owned outbound valuesmagent-agent-job.el— Durable child-agent job records and JSON shapemagent-action.el— Workflow DSL, Step runtime, layered Action registry, and Invocation lifecyclemagent-action-project.el— Approved project Action discovery and loadingmagent-runtime.el— Static initialization plus retained project-local definition loadingmagent-runtime-api.el— UI/backend-facing runtime session and prompt APImagent-runtime-queue.el— Per-session FIFO runtime queues, concurrent sessions, and session-scoped cancellationmagent-audit.el— Live-buffer or JSONL-file audit recording 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 retains project-local definitions by canonical scope. Request execution resolves those definitions against the exact runtime session scope, so changing interactive context does not unload another session’s definitions. 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 uses one unified Action 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, and starts the Magent-owned loopmagent-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— Scope-aware hash-table registry and project definitionsmagent-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 19gptel-toolstructs: read_file, write_file, edit_file, grep, glob, bash, emacs_read, emacs_eval, emacs_eval_live, read_tool_output, spawn_agent, send_agent_message, wait_agent, list_agents, close_agent, update_plan, web_search, web_open, web_findmagent-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-sampling.el— Provider-neutral request/event protocolmagent-sampling-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-run-turn owns provider-native tool continuation, fails ordinary turns with empty final responses explicitly, and fails directly at an optional sampling limit. Reasoning is kept separate from assistant text. magent-sampling-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-project.el— Approved project Action discovery and loadingmagent-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.
ACP advertises every visible instruction skill as /$name in agent-shell;
submitting or selecting it explicitly applies the skill to one ordinary turn.
Skills never enter the Action registry. Elisp-native Actions are registered
separately through magent-action-register and are selected as /name from
agent-shell’s slash menu. /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, trusted blocks from
magent-context-provider-functions, 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. Context providers are trusted local Elisp, but supporting
data they embed cannot override current user instructions or live
Emacs/repository state. 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 built-in skills/, user ~/.agents/skills/ and ~/.emacs.d/magent/skills/, then project .agents/skills/ and .magent/skills/; later roots take precedence. The Codex-compatible minimum frontmatter is name plus description, and omitted type defaults to instruction. Known host-only fields such as license, metadata, and disable-model-invocation are accepted as passive metadata. magent-find-skill, magent-install-skill, and magent-delete-skill manage user-level skills only and never write to ~/.agents/skills/. A skill can also declare capability: true with resolver metadata such as modes, features, files, prompt-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 scoped project definition.
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-sampling-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-project.el— Approved project Action discovery and loadingmagent-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:
read_file— Requiressource=diskorsource=live-bufferand returns a revision used by writesemacs_read— Runs fixed, bounded queries against the live Emacsemacs_eval— Runs arbitrary Elisp in a fresh child Emacs with once-only approvalemacs_eval_live— Runs arbitrary Elisp in the live Emacs; dangerous, once-only, and unavailable to restricted built-insread_tool_output— Pages a spilled result by opaque id within the current sessionspawn_agent/send_agent_message/wait_agent/list_agents/close_agent— Coordinate durable child-agent jobsweb_search,web_open,web_find— configurable search (keyless Bing RSS by default), source snapshots and deterministic find; see README
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 — Package entry point, public autoloads, and lazy runtime bootstrap
- magent-log.el — UI-neutral logging sinks and headless fallback
- magent-prompt.el — Manifest-backed prompt loading and placeholder rendering
- magent-config.el — UI-neutral runtime and feature customization
- magent-json.el — JSON-safe serialization helpers
- magent-redaction.el — Fail-closed outbound redaction owned by Magent
- magent-project-instructions.el — Bounded, scoped
AGENTS.mddiscovery and prompt injection
Protocol, State & Persistence
- magent-protocol.el — Wire protocol types and normalized runtime events
- magent-lifecycle-events.el — Structured lifecycle event sinks and context helpers
- magent-ledger.el — Canonical thread/turn/item state machine, journal, and snapshot
- magent-session.el — Ledger projections, scoped JSON persistence, and spill storage
- magent-agent-job.el — Durable child-agent job state, runtime registry, and JSON shape
- magent-audit.el — Live-buffer or JSONL audit records for tool decisions
Sampling & Runtime
- magent-sampling.el — Provider-neutral request/event contract
- magent-sampling-gptel.el — One-request
gptel-requestadapter - magent-runtime.el — Static initialization and retained project-local definition loading
- magent-runtime-queue.el — Per-session FIFO queues, concurrent sessions, and session-scoped cancellation
- magent-runtime-api.el — Frontend-neutral runtime session and submission API
- magent-agent-loop.el — Normalized event loop, serial tool queue, abort, and continuation
Actions
- magent-action.el — Workflow DSL, managed Steps, layered registry, and Invocation lifecycle
- magent-action-project.el — Approved project Action discovery and loading
- magent-action-controls.el — Core current-session controls such as
/compact - magent-action-skills.el — Scope-aware
/skillsAction projection - magent-action-builtins.el — Prompt Action definitions and built-in registration
- magent-action-session.el — Isolated Action persistence, ledger, and cancellation
- magent-action-mode-line.el — Optional active Action count and current-Step tooltip
- magent-action-session-view.el — Isolated Action session listing and inspection
- magent-action-builtin-doctor.el — Trusted probes and one sanitized, tool-free analysis
Agent System
- magent-agent.el — Prompt assembly, request-local agent/tool resolution, and loop startup
- magent-agent-info.el — Agent metadata struct and helpers
- magent-agent-builtins.el — 7 built-in agent definitions
- magent-agent-registry.el — Scope-aware agent registry and project definitions
- magent-agent-file.el — Custom agent loader from
.magent/agent/*.md - magent-permission.el — Tool access control with glob patterns
Tools, Skills & Capabilities
- magent-web.el — Search provider registry, asynchronous HTTP and source snapshots
- magent-web-page.el — HTML/text/PDF extraction, pagination and find
- magent-tools.el — Canonical catalog of 19
gptel-toolimplementations - magent-tool-orchestrator.el — Permission, approval, audit, and tool-call orchestration
- magent-approval.el — User approval prompts for sensitive operations
- magent-file-loader.el — Shared file-backed frontmatter parser
- magent-skills.el — Scope-aware instruction-skill registry, descriptors, and inspection
- magent-skill-manager.el — Lazy, network-aware user skill discovery and installation
- magent-capability.el — Capability definitions, resolution, and file-backed loading
Supported Frontend
- magent-acp.el — In-process ACP adapter
- magent-agent-shell.el — Magent agent-shell configuration and isolated context compatibility
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. Keep this map aligned with every production file in
source-files.txt.
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-sampling-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: 19 tool implementations have different side effects, process lifecycles, revision contracts, spill retention, child-agent state, and error handling. emacs_read uses the captured origin buffer; emacs_eval uses a disposable child process; emacs_eval_live deliberately crosses into the main process.
Approach carefully: Keep child-eval cleanup and host-owned timeout handling robust. Preserve once-only approval for both arbitrary eval tools, session isolation for spilled output, revision validation for writes, and parent/child request-context inheritance.
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_readtool - 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 thinking: enabled permissions: read: allow write: ask bash: deny --- System prompt goes here.
Use exact permission group keys such as read, write, edit, and agent.
Unknown keys and non-mapping permission forms are rejected.
Adding a Skill
Create skills/my-skill/SKILL.md:
--- name: my-skill description: Brief description tools: [read_file, grep] --- Skill instructions for the agent.
type: instruction is optional; it is the only supported explicit type.
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: select
/$namefrom agent-shell’s slash menu - 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.