Skip to content

ogent

╭──────────────────────────────────────╮
│                  █                   │
│                 ███                  │
│                █████                 │
│               ╱  █  ╲                │
│              ╱   █   ╲               │
│             ┌┘   █   └┐              │
│             │  ╔═╩═╗  │              │
│             │  ║ ✦ ║  │              │
│             │  ╚═╦═╝  │              │
│             ┌┴───┴───┴┐              │
│            │ ◣█▏   ▕█◢ │             │
│            │  ▀▀   ▀▀  │             │
│            ├┐ ┌─────┐ ┌┤             │
│            │║ │▆▆▆▆▆│ ║│             │
│            │║ └─────┘ ║│             │
│             └╨───────╨┘              │
│                                      │
│    _____ _____  _____ _   _ _____    │
│   |  _  |  __ \|  ___| \ | |_   _|   │
│   | | | | |  \/| |__ |  \| | | |     │
│   | | | | | __ |  __|| . ` | | |     │
│   \ \_/ / |_\ \| |___| |\  | | |     │
│    \___/ \____/\____/\_| \_/ \_/     │
│                                      │
│         · agentic org-mode ·         │
╰──────────────────────────────────────╯

https://github.com/ryjm/ogent/actions/workflows/ci.yml/badge.svg

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.

Exoskeleton + Agent

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-c beats 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.

Features

  • Context as data: @handles resolve 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 with C-c C-k.
  • Commands: C-c . RET runs the current bullet as the prompt, with parent bullets passed as # Parent Bullets context. C-c . q asks a new minibuffer question about the current subtree. C-c . ? shows the ask menu. C-c . p opens full dispatch. C-c . E requests 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.

Requirements

  • 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

Install

  1. Clone the repository:
    git clone https://github.com/ryjm/ogent.git
    cd ogent
        
  2. Ensure dependencies compile cleanly:
    make lint
    make test
        
  3. Add lisp/ and lisp/ui/ to your load-path, then require ogent:
    (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)
        

Configuration

Quick Setup (Recommended)

Run M-x ogent-onboard to interactively configure your LLM provider. This wizard:

  1. Lets you choose between OpenAI Codex OAuth, Claude Code OAuth, or API key authentication
  2. Guides you through the login process
  3. Configures gptel backends automatically
  4. Run M-x ogent-doctor at any time to check Emacs/package versions, gptel/backend state, br availability, and local OAuth caches without making network calls.

OpenAI Codex / ChatGPT OAuth

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 sessions

After 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

Claude Code / Claude Max/Pro OAuth

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 code

This stores refresh tokens in ~/.emacs.d/ogent/anthropic-oauth/ and automatically refreshes them as needed, so there is no API key to manage.

Vanilla Emacs (API Key)

(add-hook 'org-mode-hook #'ogent-mode)
(setq ogent-default-model "gpt-5.6-sol")

Doom Emacs

(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))

Usage

  • Open any Org buffer and toggle ogent-mode (or rely on ogent-global-mode).
  • Write a normal Org bullet/heading, then press C-c . RET to run that subtree as the prompt; ogent inserts a compact Request: / Response transcript below it.
  • Parent bullets are sent explicitly under # Parent Bullets for 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 ideas makes that directory the request workspace. Explicit labels (Context:, Workspace:, Project:, Repo:) still work, but are optional. The payload shows a # Workspace section, 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 . RET appends a fresh run, C-c . ! (or C-c C-c on the transcript) replaces it. Earlier runs collapse automatically when a new run starts.
  • Press C-c . q to 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 . p to open the dispatcher, pick models, and send the current subtree.
  • Doom/Evil users get the same command surface under SPC o when ogent-setup-doom-bindings or evil bindings are active.
  • Use C-c . c for a context preview and C-c . m to inspect the codemap.
  • Press C-c . d to capture the last AI response to a Notes child heading.
  • To attach reusable prompt snippets, create Org nodes with an OGENT_ID (see docs/prompts.org).

Zen notebook presentation

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: / Response headings 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 with ogent-zen-result-headline-density (minimal, balanced, rich, or debug). Multi-model runs show model chips, selected/accepted responses, and sibling lineage such as latest or superseded 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 show 0 chars instead 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 legacy OGENT_REVIEW in 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 under C-c ,. Active requests animate only in visible buffers (ogent-zen-pretty-headings). Parent breadcrumb suffixes are opt-in via ogent-zen-show-breadcrumbs. Overlay-local RET / r / u / e action hints and bindings are opt-in via ogent-zen-heading-actions so Evil and other modal keymaps keep owning those keys by default. Use C-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, and C-c . C-a (ogent-zen-apply-last-edit) replays the latest structured edit into an inline diff preview. Accept or reject the preview with ogent-zen-accept-edit / ogent-zen-reject-edit (or inline-diff-mode’s C-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 with C-c . h (ogent-zen-show-tool-calls). Set ogent-zen-tool-calls-inline to 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, and superseded lineage when a new run starts (ogent-zen-collapse-previous-runs).
  • Set ogent-zen-center-column to 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.

Keybindings

KeyCommandDescription
C-c . pogent-prompt-dispatchOpen dispatcher to select models/presets
C-c . @ogent-model-pickerSwitch models, assign task roles, pin models
C-c . RETogent-run-subtreeRun current bullet/subtree as prompt
C-c . !ogent-zen-rerunRe-run transcript at point (or run bullet)
C-c . wogent-zen-copy-responseCopy only the Zen response body
C-c . uogent-zen-review-menuMark Zen request/response review state
C-c . C-rogent-zen-run-regionAsk about active region with Zen context
C-c . C-eogent-zen-edit-dwimRewrite region/paragraph/sentence
C-c . C-aogent-zen-apply-last-editRe-preview latest structured edit
C-c . rogent-requestSend request with current context
C-c . aogent-abort-requestAbort current request
C-c . Rogent-retry-requestRetry last request
C-c . cogent-context-previewPreview context before sending
C-c . mogent-codemap-bufferGenerate codemap for current buffer
C-c . Pogent-pin-dwimPin file/buffer/region to context
C-c . Uogent-unpin-interactiveUnpin item from context
C-c . logent-list-pinnedList all pinned context items
C-c . eogent-edit-menuEdit menu for inline code changes
C-c . Eogent-request-editRequest code edits for buffer
C-c . sogent-edit-goto-sourceGo to source from companion
C-c . Cogent-edit-goto-companionGo to companion from source
C-c . togent-debug-tools-menuTools debug menu
C-c . Togent-tool-rerunRe-run tool at point
C-c . hogent-zen-show-tool-callsList Zen tool calls under heading
C-c . bogent-show-backlinksShow backlinks to current heading
C-c . gogent-show-dependency-graphShow dependency graph
C-c . oogent-open-blockOpen source block with ogent-mode
C-c . iogent-issuesOpen issue tracker
C-c . Sogent-session-saveSave current session
C-c . Logent-session-loadLoad a saved session
C-c . Hogent-session-listList saved sessions
C-c . qogent-ask-hereAsk at point; insert Request/Response
C-c . ?ogent-ask-menuShow contextual ask menu
C-c . dogent-notes-captureCapture last response to Notes heading
C-c . Dogent-debug-modeToggle debug mode

Review Prefix

KeyCommandDescription
C-c , nogent-review-nextNext review item needing attention
C-c , pogent-review-previousPrevious review item needing attention
C-c , aogent-review-acceptAccept current completion/Zen item
C-c , xogent-review-rejectReject current completion/Zen item
C-c , uogent-review-usefulMark current Zen item useful
C-c , mogent-review-deferMark current Zen item needs review
C-c , sogent-review-staleMark current Zen item stale
C-c , dogent-review-dashboardOpen the Zen review queue/dashboard
C-c , .ogent-review-describeExplain current review target and state

Armory

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.

KeyCommandDescription
C-c . jogent-armory-homeArmory Home
C-c . Kogent-armory-statusArmory graph/status
C-c . yogent-armory-agentsArmory agents
C-c . Yogent-armory-agentArmory agent profile
C-c . Bogent-armory-org-chartArmory org chart
C-c . ;ogent-armory-dataArmory data browser
C-c . Iogent-armory-tasksArmory task board
C-c . Oogent-armory-conversationsArmory conversations
C-c . Nogent-armory-actionsArmory action approvals
C-c . Jogent-armory-scheduleDay/week/month schedule
C-c . Qogent-armory-agendaOrg agenda over Armory
C-c . :ogent-armory-git-statusArmory git status
C-c . /ogent-armory-command-paletteRanked command palette
C-c . ,ogent-armory-settingsArmory settings
C-c . .ogent-armory-helpArmory help
C-c . 'ogent-armory-onboardOnboard Armory
C-c . =ogent-armory-registry-importImport Armory template
C-c . _ogent-armory-backupBack up Armory
C-c . Vogent-armory-searchArmory-wide search
C-c . Wogent-armory-appsGenerated app artifacts
C-c . Xogent-armory-create-agentCreate Armory agent
C-c . Zogent-armory-create-jobCreate 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.

Prompt Templates

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.

Using Prompt Templates

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

Composing Multiple Templates

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")

Available Templates

TemplatePurpose
@code-reviewReview code for bugs, style, performance
@refactoringSuggest refactoring opportunities
@documentationGenerate docstrings and comments
@testingSuggest test cases and edge cases
@explain-codeExplain what code does step by step
@debug-stepsSystematic debugging approach
@security-auditAudit for security vulnerabilities
@performance-reviewReview for performance issues

See docs/prompts.org for the full list and detailed instructions.

Creating Custom Templates

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

Per-Project Customization

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...")))))))

Yasnippet Integration

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.

Updating

Pull the latest changes, then rerun make lint and make test to confirm your environment still passes before hacking.

Contributing

See CONTRIBUTING.md for setup, testing, and pull request guidelines.

License

ogent is licensed under GPL-3.0-or-later. See LICENSE for the full license text.

About

ogent brings language models into Org-mode the Emacs way: composable commands with text + org-mode as the universal interface.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages