╭──────────────────────────────────────╮ │ █ │ │ ███ │ │ █████ │ │ ╱ █ ╲ │ │ ╱ █ ╲ │ │ ┌┘ █ └┐ │ │ │ ╔═╩═╗ │ │ │ │ ║ ✦ ║ │ │ │ │ ╚═╦═╝ │ │ │ ┌┴───┴───┴┐ │ │ │ ◣█▏ ▕█◢ │ │ │ │ ▀▀ ▀▀ │ │ │ ├┐ ┌─────┐ ┌┤ │ │ │║ │▆▆▆▆▆│ ║│ │ │ │║ └─────┘ ║│ │ │ └╨───────╨┘ │ │ │ │ _____ _____ _____ _ _ _____ │ │ | _ | __ \| ___| \ | |_ _| │ │ | | | | | \/| |__ | \| | | | │ │ | | | | | __ | __|| . ` | | | │ │ \ \_/ / |_\ \| |___| |\ | | | │ │ \___/ \____/\____/\_| \_/ \_/ │ │ │ │ · agentic org-mode · │ ╰──────────────────────────────────────╯
Use LLMs in structured Org workflows
ogent brings language models into Org-mode the Emacs way: composable commands with text + org-mode as the universal interface.
ogent is designed around this constraint:
- Make review fast: Responses land in Org blocks you can fold, diff, and navigate with standard keybindings. Tree based navigation beats scrolling and
C-c C-cbeats ad-hoc copy pasting for context management. - Make context explicit: You declare what goes in via
@handles, pins, and codemap. Obviously just giving it the whole project works too.
- Context as data:
@handlesresolve to Org nodes, files, or org-roam entries. Codemap indexes your project. Pins persist across requests. - Responses as structure: Output lands in src blocks with metadata (
:model,:status,:latency). Fold them, edit them, version them. It’s just Org. - Edits as diffs: Code changes render as smerge conflicts. Accept with
C-c C-c, reject withC-c C-k. - Commands:
C-c . RETruns the current bullet as the prompt, with parent bullets passed as# Parent Bulletscontext.C-c . qasks a new minibuffer question about the current subtree.C-c . ?shows the ask menu.C-c . popens full dispatch.C-c . Erequests code edits. - Armory: A local agent workspace built from plain Org files. Armory gives you persistent agents, jobs, conversations, approvals, schedules, task boards, data views, git state, and generated app artifacts without leaving Emacs.
- Emacs 29.1 or newer
- Org 9.8.7 or newer
- gptel 0.9.9.5 or newer for transport and model selection
- transient 0.13.5 or newer for command menus
- Optional: org-roam for cross-file handle resolution
- An LLM provider:
- **OpenAI Codex / ChatGPT**: Reuse Codex CLI OAuth credentials
- **Claude Code / Claude Max/Pro**: Use OAuth authentication (recommended, no API key needed)
- **API Key**: Traditional API key for Anthropic or OpenAI
- Clone the repository:
git clone https://github.com/ryjm/ogent.git cd ogent - Ensure dependencies compile cleanly:
make lint make test - Add
lisp/andlisp/ui/to yourload-path, then requireogent:(add-to-list 'load-path (expand-file-name "lisp" "/path/to/ogent")) (add-to-list 'load-path (expand-file-name "lisp/ui" "/path/to/ogent")) (require 'ogent)
Run M-x ogent-onboard to interactively configure your LLM provider. This wizard:
- Lets you choose between OpenAI Codex OAuth, Claude Code OAuth, or API key authentication
- Guides you through the login process
- Configures gptel backends automatically
- Run
M-x ogent-doctorat any time to check Emacs/package versions, gptel/backend state, br availability, and local OAuth caches without making network calls.
If you already use the Codex CLI with ChatGPT login, ogent can reuse the API key
cached in $CODEX_HOME/auth.json or ~/.codex/auth.json:
(require 'ogent)
(ogent-codex-login) ; Opens Codex browser login
(ogent-codex-login-device) ; Device-code fallback for headless sessionsAfter login, choose OpenAI Codex / ChatGPT (OAuth - Recommended) in
M-x ogent-onboard.
To check status: M-x ogent-codex-status
To logout: M-x ogent-codex-logout
If you have a Claude Pro, Max, Team, Enterprise, or Console account, you can authenticate via the Claude Code-compatible OAuth flow:
(require 'ogent)
(ogent-claude-code-login) ; Opens browser, paste the codeThis stores refresh tokens in ~/.emacs.d/ogent/anthropic-oauth/ and automatically
refreshes them as needed, so there is no API key to manage.
(add-hook 'org-mode-hook #'ogent-mode)
(setq ogent-default-model "gpt-5.6-sol")(package! ogent :recipe (:local-repo "/path/to/ogent/lisp" :files ("*.el" "ui/*.el")))
(use-package! ogent
:after org
:init
(setq ogent-enable-doom-bindings t
ogent-doom-prefix "o")
:config
(ogent-setup-doom-bindings)
(ogent-global-mode 1))- Open any Org buffer and toggle
ogent-mode(or rely onogent-global-mode). - Write a normal Org bullet/heading, then press
C-c . RETto run that subtree as the prompt; ogent inserts a compactRequest:/Responsetranscript below it. - Parent bullets are sent explicitly under
# Parent Bulletsfor Zen runs: each parent contributes its own body text, never its children, so nothing is duplicated and prior transcripts never leak into the payload. - Workspace selection is prose-first: a bullet like
look in ~/vault/projects/ogent for ideasmakes that directory the request workspace. Explicit labels (Context:,Workspace:,Project:,Repo:) still work, but are optional. The payload shows a# Workspacesection, relative ogent tool paths resolve from that root, and code-grounded wording asks gptel to use read-only tools before answering. - Re-run a bullet from anywhere inside its transcript:
C-c . RETappends a fresh run,C-c . !(orC-c C-con the transcript) replaces it. Earlier runs collapse automatically when a new run starts. - Press
C-c . qto ask a new minibuffer question about the subtree at point. - Press
C-c . ?when you are unsure: the ask menu names the active scope and offers run-current-bullet, re-run, inline ask, popup ask, malleable region ask/rewrite, edit application, context preview, and the full dispatcher. - Press
C-c . pto open the dispatcher, pick models, and send the current subtree. - Doom/Evil users get the same command surface under
SPC owhenogent-setup-doom-bindingsor evil bindings are active. - Use
C-c . cfor a context preview andC-c . mto inspect the codemap. - Press
C-c . dto capture the last AI response to a Notes child heading. - To attach reusable prompt snippets, create Org nodes with an
OGENT_ID(seedocs/prompts.org).
ogent-zen-mode (enabled with ogent-mode in Org buffers; see
ogent-zen-enable-in-org) keeps the page quiet without touching the
stored text. To turn it on for every Org buffer independently of
ogent-mode, enable global-ogent-zen-mode (it activates in Org
buffers only and skips internal scratch buffers):
- Heading stars compose into a uniform bullet (
ogent-zen-bullet, default•; skipped automatically when org-modern, org-bullets, or org-superstar is active). - Generated
Request:/Responseheadings render as compact run cards: expanded requests stay prompt-first, while folded completed requests become result-first indexes such as✓ 10 grounded ideas · from “Better headline display”. Folded results can add a muted virtual preview line (ogent-zen-folded-result-preview) without changing the stored Org. Request metadata is split into outcome badges and lower-priority right-aligned metadata when the window can support it; density is customizable withogent-zen-result-headline-density(minimal,balanced,rich, ordebug). Multi-model runs show model chips, selected/accepted responses, and sibling lineage such aslatestorsuperseded by newer run. Active tool work is promoted into the main title (reading lisp/ogent-zen.el · Headline idea) rather than buried in a suffix. Tool-call failures stay as inline diagnostics instead of failing the run card; only request-level model/network/abort failures turn the headline red. Empty runs show0 charsinstead of a vague warning. Response headings are quieter secondary rows and, when folded, carry response-local result previews plus review badges. Zen review now persists a structured decision model (OGENT_DECISION,OGENT_REVIEW_STATUS,OGENT_USEFULNESS,OGENT_LINEAGE,OGENT_OUTCOME, timestamps, reviewer, and a visible:REVIEW:drawer) while keeping legacyOGENT_REVIEWin sync for older transcripts. Review can explicitly target the run or one response, can accept a response as the selected model, and exposes a queue/dashboard workflow underC-c ,. Active requests animate only in visible buffers (ogent-zen-pretty-headings). Parent breadcrumb suffixes are opt-in viaogent-zen-show-breadcrumbs. Overlay-localRET/r/u/eaction hints and bindings are opt-in viaogent-zen-heading-actionsso Evil and other modal keymaps keep owning those keys by default. UseC-c . w(ogent-zen-copy-response) anywhere in a Zen transcript to copy only the response body, without request metadata or headings. Malleable editing uses the same tree-context machinery at smaller scope:C-c . C-r(ogent-zen-run-region) asks about the active region,C-c . C-e(ogent-zen-edit-dwim) rewrites the active region / paragraph / sentence with a SEARCH/REPLACE response, andC-c . C-a(ogent-zen-apply-last-edit) replays the latest structured edit into an inline diff preview. Accept or reject the preview withogent-zen-accept-edit/ogent-zen-reject-edit(orinline-diff-mode’sC-c C-c/C-c C-k). Tool calls no longer inline into the notebook: Zen records them out of band so repeated prompt submissions stay responsive, keeps a compact count on the request headline, and opens the full list (arguments, results, status) in a separate buffer withC-c . h(ogent-zen-show-tool-calls). Setogent-zen-tool-calls-inlineto restore the legacy inline:TOOL:drawers. Transcript property drawers and prompt blocks fold away immediately (ogent-zen-fold-noise), and earlier runs collapse with status, model, result titles, andsupersededlineage when a new run starts (ogent-zen-collapse-previous-runs). - Set
ogent-zen-center-columnto an integer (e.g.80) to center the notebook in wide windows.
Disabling the mode restores plain Org; the underlying transcript is
always standard Request: / Response text, so history replay and
older tooling keep working.
| Key | Command | Description |
|---|---|---|
C-c . p | ogent-prompt-dispatch | Open dispatcher to select models/presets |
C-c . @ | ogent-model-picker | Switch models, assign task roles, pin models |
C-c . RET | ogent-run-subtree | Run current bullet/subtree as prompt |
C-c . ! | ogent-zen-rerun | Re-run transcript at point (or run bullet) |
C-c . w | ogent-zen-copy-response | Copy only the Zen response body |
C-c . u | ogent-zen-review-menu | Mark Zen request/response review state |
C-c . C-r | ogent-zen-run-region | Ask about active region with Zen context |
C-c . C-e | ogent-zen-edit-dwim | Rewrite region/paragraph/sentence |
C-c . C-a | ogent-zen-apply-last-edit | Re-preview latest structured edit |
C-c . r | ogent-request | Send request with current context |
C-c . a | ogent-abort-request | Abort current request |
C-c . R | ogent-retry-request | Retry last request |
C-c . c | ogent-context-preview | Preview context before sending |
C-c . m | ogent-codemap-buffer | Generate codemap for current buffer |
C-c . P | ogent-pin-dwim | Pin file/buffer/region to context |
C-c . U | ogent-unpin-interactive | Unpin item from context |
C-c . l | ogent-list-pinned | List all pinned context items |
C-c . e | ogent-edit-menu | Edit menu for inline code changes |
C-c . E | ogent-request-edit | Request code edits for buffer |
C-c . s | ogent-edit-goto-source | Go to source from companion |
C-c . C | ogent-edit-goto-companion | Go to companion from source |
C-c . t | ogent-debug-tools-menu | Tools debug menu |
C-c . T | ogent-tool-rerun | Re-run tool at point |
C-c . h | ogent-zen-show-tool-calls | List Zen tool calls under heading |
C-c . b | ogent-show-backlinks | Show backlinks to current heading |
C-c . g | ogent-show-dependency-graph | Show dependency graph |
C-c . o | ogent-open-block | Open source block with ogent-mode |
C-c . i | ogent-issues | Open issue tracker |
C-c . S | ogent-session-save | Save current session |
C-c . L | ogent-session-load | Load a saved session |
C-c . H | ogent-session-list | List saved sessions |
C-c . q | ogent-ask-here | Ask at point; insert Request/Response |
C-c . ? | ogent-ask-menu | Show contextual ask menu |
C-c . d | ogent-notes-capture | Capture last response to Notes heading |
C-c . D | ogent-debug-mode | Toggle debug mode |
| Key | Command | Description |
|---|---|---|
C-c , n | ogent-review-next | Next review item needing attention |
C-c , p | ogent-review-previous | Previous review item needing attention |
C-c , a | ogent-review-accept | Accept current completion/Zen item |
C-c , x | ogent-review-reject | Reject current completion/Zen item |
C-c , u | ogent-review-useful | Mark current Zen item useful |
C-c , m | ogent-review-defer | Mark current Zen item needs review |
C-c , s | ogent-review-stale | Mark current Zen item stale |
C-c , d | ogent-review-dashboard | Open the Zen review queue/dashboard |
C-c , . | ogent-review-describe | Explain current review target and state |
Armory turns a directory of Org files into a local agent workspace. Open
M-x ogent-armory-home or press C-c . j. The Armory surface includes
agents, jobs, conversations, lead action approvals, data browsing, ranked
palette search, git state, settings, backup, registry import, help, app
artifacts, and a schedule calendar. In M-x ogent-armory-tasks, press c or
C-c c to capture a manual Inbox task with a short TODO-style prompt path.
| Key | Command | Description |
|---|---|---|
C-c . j | ogent-armory-home | Armory Home |
C-c . K | ogent-armory-status | Armory graph/status |
C-c . y | ogent-armory-agents | Armory agents |
C-c . Y | ogent-armory-agent | Armory agent profile |
C-c . B | ogent-armory-org-chart | Armory org chart |
C-c . ; | ogent-armory-data | Armory data browser |
C-c . I | ogent-armory-tasks | Armory task board |
C-c . O | ogent-armory-conversations | Armory conversations |
C-c . N | ogent-armory-actions | Armory action approvals |
C-c . J | ogent-armory-schedule | Day/week/month schedule |
C-c . Q | ogent-armory-agenda | Org agenda over Armory |
C-c . : | ogent-armory-git-status | Armory git status |
C-c . / | ogent-armory-command-palette | Ranked command palette |
C-c . , | ogent-armory-settings | Armory settings |
C-c . . | ogent-armory-help | Armory help |
C-c . ' | ogent-armory-onboard | Onboard Armory |
C-c . = | ogent-armory-registry-import | Import Armory template |
C-c . _ | ogent-armory-backup | Back up Armory |
C-c . V | ogent-armory-search | Armory-wide search |
C-c . W | ogent-armory-apps | Generated app artifacts |
C-c . X | ogent-armory-create-agent | Create Armory agent |
C-c . Z | ogent-armory-create-job | Create Armory job |
Schedule events come from OGENT_CRON jobs, agent heartbeat cron fields,
one-shot OGENT_RUN_AFTER tasks, and conversations with
OGENT_SCHEDULED_KEY. Missed past slots can be run directly from the schedule
buffer.
ogent includes a library of reusable prompt templates for common workflows.
Templates are defined in docs/prompts.org and can be referenced using @handle syntax.
Apply a template from the prompt dispatcher’s Templates infix (T in
M-x ogent-prompt-dispatch), or with M-x ogent-prompt-insert, which inserts
the composed template text at point. With the optional yasnippet integration
(see below), type a template’s handle and press TAB to expand it inline:
@code-review
Select more than one template from the Templates infix or ogent-prompt-insert;
ogent concatenates them, ordered by each template’s compose-order. The
@handle+@handle shorthand is accepted by the compose API
(ogent-prompt-compose-from-string):
(ogent-prompt-compose-from-string "@code-review+@security-audit")| Template | Purpose |
|---|---|
@code-review | Review code for bugs, style, performance |
@refactoring | Suggest refactoring opportunities |
@documentation | Generate docstrings and comments |
@testing | Suggest test cases and edge cases |
@explain-code | Explain what code does step by step |
@debug-steps | Systematic debugging approach |
@security-audit | Audit for security vulnerabilities |
@performance-review | Review for performance issues |
See docs/prompts.org for the full list and detailed instructions.
Create Org headlines with an OGENT_ID property:
** My Custom Review
:PROPERTIES:
:OGENT_ID: my-review
:END:
Review this code with special attention to:
- Our team's coding standards
- Integration with the legacy API
Set ogent-project-prompts-file in .dir-locals.el to load project-specific templates:
((nil . ((ogent-project-prompts-file . "prompts.org"))))Override existing templates with ogent-prompt-overrides:
((nil . ((ogent-prompt-overrides
. (("code-review" . (:content "Review with our team standards...")))))))Enable yasnippet integration for quick template insertion:
(add-hook 'org-mode-hook #'ogent-prompts-yasnippet-mode)Then type @code-review and press TAB to expand the template.
Pull the latest changes, then rerun make lint and make test to confirm your environment still passes before hacking.
See CONTRIBUTING.md for setup, testing, and pull request guidelines.
ogent is licensed under GPL-3.0-or-later. See LICENSE for the full license text.