Apache License 2.0

项目介绍

tninja/ai-code-interface.el 是一个托管在 GitHub 上的开源项目,主要使用 Emacs Lisp 编写,采用 Apache License 2.0 许可证,目前获得 241 个 Star、27 次 Fork。

仓库全名
tninja/ai-code-interface.el
开源许可证
Apache License 2.0
Star 数
241
Fork 数
27
未关闭 Issue
9

README 摘要

[[file:./ai-code-interface.png]] AI Code Interface AI Code Interface is a backend-agnostic Emacs workflow layer for AI-assisted software development. Use Codex, Claude Code, Gemini CLI, Pi, agent-shell/ACP, and other coding agents while keeping the same Emacs workflow for context, prompting, code changes, review, TDD, Git, tasks, and session management. Why AI Code Interface? AI coding agents change quickly. AI Code…

完整内容见 GitHub 原始 README 或本页 。

常见问题

ai-code-interface.el 用什么语言开发?

主要使用 Emacs Lisp 编写,采用 Apache License 2.0 许可证,目前有 241 个 Star。

ai-code-interface.el 可以免费商用吗?

仓库采用 Apache License 2.0 许可证,可免费使用与修改,商业使用请遵守许可证条款(例如保留版权声明与许可声明)。

如何获取 ai-code-interface.el 的源码?

可以直接克隆仓库:git clone https://github.com/tninja/ai-code-interface.el.git;安装与运行步骤见仓库 README。

ai-code-interface.el 最近还在维护吗?

仓库最近一次更新为 6月24日,当前有 9 个未关闭 Issue;Star 数为 241,可作为社区活跃度的参考。

关于

GitHub 原始描述(英文)

Unified Emacs interface supporting OpenAI Codex, Antigravity CLI, Claude Code, GitHub Copilot CLI, Opencode, and more

描述取自 GitHub 官方 API,保持仓库作者书写的原文。

语言占比

Emacs Lisp
Shell
YASnippet

Release

README

[[file:./ai-code-interface.png]]

  • AI Code Interface

[[https://melpa.org/#/ai-code][https://melpa.org/packages/ai-code-badge.svg]] [[https://stable.melpa.org/#/ai-code][https://stable.melpa.org/packages/ai-code-badge.svg]] [[https://github.com/tninja/ai-code-interface.el/graphs/contributors][https://img.shields.io/github/contributors/tninja/ai-code-interface.el.svg]] [[https://github.com/RoggeOhta/awesome-codex-cli][https://awesome.re/mentioned-badge.svg]]

AI Code Interface is a backend-agnostic Emacs workflow layer for AI-assisted software development.

Use Codex, Claude Code, Gemini CLI, Pi, agent-shell/ACP, and other coding agents while keeping the same Emacs workflow for context, prompting, code changes, review, TDD, Git, tasks, and session management.

** Why AI Code Interface?

AI coding agents change quickly. AI Code Interface keeps your developer workflow stable while allowing the agent underneath to change: the backend can change; your Emacs workflow does not have to.

If you want the deepest possible integration with one specific agent runtime, a dedicated client may be a better fit. If you use or evaluate multiple coding agents and want one consistent Emacs workflow, AI Code Interface is built for that.

Workflow portability is the core idea:

  • Keep the same context and prompt workflow.
  • Keep the same code-change, review, refactoring, and TDD workflow.
  • Keep the same task, Git, MCP, and session workflow.
  • Switch the AI backend without rebuilding your Emacs setup.

** Design Philosophy

AI Code Interface unifies developer workflows, not agent runtimes.

Native coding CLIs keep ownership of their own interaction model, tool execution, retries, queueing or steering, permissions, and other runtime behavior. AI Code Interface integrates with those capabilities rather than reimplementing them.

Structured external backends such as agent-shell/ACP can provide deeper lifecycle and UI integration when available, without making those semantics a requirement for every backend. This keeps the common workflow portable while allowing each backend to use its native strengths.

Supported AI coding CLIs: Claude Code, OpenAI Codex, Gemini CLI, GitHub Copilot CLI, Cursor CLI, Opencode, Aider, Grok CLI, Kiro CLI, Kilo, Pi, Antigravity CLI, Muse Code, CodeBuddy Code, and Open Interpreter, plus external backends such as agent-shell (ACP), ECA, claude-code-ide.el, and claude-code.el.

See [[https://github.com/tninja/ai-code-interface.el/tree/main#ai-coding-cli-backend][AI coding CLI backend]] for the full backend list and configuration details.

  • Screenshot

[[./transient_menu.png]]

** New User Quick Start

If you are new to this package, follow this order:

  1. Read this section
  2. Run the setup in Installation
  3. Try one workflow in Typical Workflows Example
  4. Configure backend details in AI coding CLI backend

Minimal setup:

#+begin_src emacs-lisp (use-package ai-code :config (ai-code-set-backend 'codex) ;; Optional: use a narrower transient menu on smaller frames ;; (setq ai-code-menu-layout 'two-columns) (global-set-key (kbd “C-c a”) #'ai-code-menu)) #+end_src

First 60 seconds:

  • C-c a a: Start the currently selected AI CLI session
  • C-c a c: Ask AI to change current function/region
  • C-c a q: Ask question only (no code change)
  • C-c a z: Jump back to AI session buffer

The first time you open C-c a, AI Code also shows a small quickstart buffer with these core actions. You can reopen it later from C-c a h (Help / Quick Start).

** Installation

Enable installation of packages from MELPA by adding an entry to package-archives after (require 'package) and before the call to package-initialize in your init.el or .emacs file:

#+begin_src emacs-lisp (require 'package) (add-to-list 'package-archives '(“melpa” . “https://melpa.org/packages/”) t) (package-initialize) #+end_src

  • Use =M-x package-refresh-contents= or =M-x package-list-packages= to ensure that Emacs has fetched the MELPA package list
  • Use =M-x package-install= to install =ai-code= package
  • Import and configure =ai-code= in your init.el or .emacs file:

#+begin_src emacs-lisp (use-package ai-code ;; :straight (:host github :repo “tninja/ai-code-interface.el”) ;; if you want to use straight to install, no need to have MELPA setting above :config ;; use codex as backend, other options are 'pi, 'claude-code, 'gemini, 'github-copilot-cli, 'open-interpreter, 'opencode, 'kilo, 'grok, 'cursor, 'kiro, 'codebuddy, 'aider, 'eca, 'agent-shell, 'claude-code-ide, 'claude-code-el (ai-code-set-backend 'codex) ;; Optional: default menu stays unchanged; use a narrower 2-column layout on smaller frames ;; (setq ai-code-menu-layout 'two-columns) ;; Enable global keybinding for the main menu (global-set-key (kbd “C-c a”) #'ai-code-menu) ;; Optional: Use eat if you prefer, by default it is vterm ;; (setq ai-code-backends-infra-terminal-backend 'eat) ;; config for native CLI backends. for external backends such as agent-shell, claude-code-ide.el and claude-code.el, please check their own config ;; Optional: Try ghostel as an backend infra ;; (setq ai-code-backends-infra-terminal-backend 'ghostel) ;; Optional: Badge tab-bar tabs that show AI sessions with their state (○ idle, ◐ working, ✓ done unseen, ? needs input) ;; (ai-code-session-attention-mode 1) ;; Optional: Disable @ file completion in comments and AI sessions ;; (ai-code-prompt-filepath-completion-mode -1) ;; Optional: Ask AI to run test after code changes, for a tighter build-test loop (setq ai-code-auto-test-type 'ask-me) ;; Optional: Disable numbered next steps for discussion prompts at send time ;; (enabled by default) ;; (setq ai-code-discussion-auto-follow-up-enabled nil) ;; Optional: Show candidates as you type in task file, using company ;; (add-hook 'ai-code-prompt-mode-hook #'ai-code-prompt-completion-setup) ;; Optional: Turn on auto-revert buffer, so that the AI code change automatically appears in the buffer (global-auto-revert-mode 1) (setq auto-revert-interval 1) ;; set to 1 second for faster update ;; Optional: Set up Magit integration for AI commands in Magit popups (with-eval-after-load 'magit (ai-code-magit-setup-transients))) #+end_src

** Windows

Native Windows Emacs is supported. Ghostel is the recommended terminal backend because it uses ConPTY and provides pre-built Windows native modules. If the default vterm backend cannot start on native Windows, AI Code automatically falls back to Ghostel. See [[./docs/windows.org][Native Windows Support]] for setup and troubleshooting.

** Dependencies

*** Required Dependencies

  • Emacs 29.1 or later
  • org: Org-mode support
  • magit: Git integration
  • transient: For the menu system
  • One of vterm (default), eat, or [[https://github.com/dakra/ghostel][ghostel]] needs to be installed to support native AI coding CLI backends, depending on ai-code-backends-infra-terminal-backend.
  • [[https://github.com/dakra/ghostel][ghostel]] is a newly supported native backend infra option.
    • Ghostel is an Emacs terminal emulator powered by libghostty-vt, the VT engine from Ghostty.
    • AI Code enables Ghostel image support for AI sessions:
      • terminal programs can use Ghostel’s Kitty graphics protocol;
      • local image paths printed by an AI CLI (for example =screenshot.png=) are previewed inline in the session buffer while the source path remains visible and clickable.
      • tall local previews can use the optional =ultra-scroll= integration described below.
      • while a local preview is visible, line scrolling (=scroll-up-line=, =scroll-down-line=, evil’s =C-e= / =C-y=) and the plain mouse wheel move by pixels, one line height per step, instead of jumping a whole image.
    • [[https://github.com/dakra/ghostel][ghostel]] is under active development, please install the latest version.
    • To try it:

#+begin_src emacs-lisp (setq ai-code-backends-infra-terminal-backend 'ghostel) #+end_src

*** Optional Dependencies

  • [[https://github.com/jdtsmith/ultra-scroll][ultra-scroll]]: Recommended for partial-pixel scrolling past tall local image previews in Ghostel. AI Code loads and dispatches it only while such a preview is visible, without enabling its global mode. Set =ai-code-ghostel-image-preview-prefer-ultra-scroll= to =nil= to opt out.
  • helm: For an enhanced auto-completion experience (ai-code-input.el).
  • whisper: For speech-to-text input via ai-code-speech-to-text-input. Record audio, press RET to stop, then choose whether to insert the transcription into the current buffer, send it to the active AI coding session with editable initial input, or copy it to the clipboard.
  • gptel: For intelligent, AI-generated content headlines in the prompt file.
    • ai-code-task-use-gptel-filename: When non-nil, file name created by ai-code-create-or-open-task-file or ai-code-create-file-or-dir will have auto-generated filenames created by GPTel
    • ai-code-use-gptel-headline: When non-nil, prompts sent to the AI will have auto-generated headlines created by GPTel, providing better organization and readability in the prompt file
    • ai-code-use-gptel-classify-prompt: When non-nil, and ai-code-auto-test-type or ai-code-discussion-auto-follow-up-enabled is non-nil, classify whether the current prompt is about code changes so test prompts or discussion follow-up suggestions are only added when relevant
  • flycheck: To enable the =Fix Flycheck errors in scope= action under =C-c a b= and the ai-code-flycheck-fix-errors-in-scope command.
  • yasnippet: For snippet support in the prompt file. A library of snippets is included.
    • (emacs built-in) abbrev + skeleton is also a good way to expand prompt. [[./etc/prompt_expand_with_abbrev_skeleton.el][example abbrev to solve / iterate leetcode problem with tdd (need to set ai-code-auto-test-type with tdd)]], [[./examples/leetcode][example problem resolved]]
  • cape / company: For inline completion of prompts you have written before, described under [[*Reusing Prompts You Already Wrote][Reusing Prompts You Already Wrote]]. Prompt completion itself needs neither package. cape, when installed, adds English dictionary words to the same candidate list with no configuration; company shows the candidates as you type once you opt in. Neither is a dependency, and neither is loaded when it is not installed.
  • projectile: For project root initialization.
  • helm-gtags: For tags creation and symbol navigation fallback from clickable session symbols.

*** Optional Screenshot Capture

The Insert submenu’s =Screenshot= commands rely on an external program to capture an image. Install or configure the option for your platform:

| Platform | Screenshot capture | Setup | |-----------------±----------------------------------±-------------------------------------------| | macOS | =screencapture= | Preinstalled; used by default with =-i=. | | Linux (Wayland) | =grim= | Install =grim=; selected when =WAYLAND_DISPLAY= is set. | | Linux (X11) | =import= from ImageMagick | Install the ImageMagick package. | | Windows | No compatible tool is bundled | Configure a capture program as shown below. |

Customize =ai-code-send-screenshot-command= when the default is unavailable. The command is a list containing the program followed by its arguments; AI Code appends the destination PNG path when invoking it:

#+begin_src emacs-lisp (setopt ai-code-send-screenshot-command '(“my-screenshot-program” “–interactive”)) #+end_src

** Key Features

  • Transient-Driven Hub (C-c a): One keystroke opens a contextual transient menu that groups every capability (CLI control, code actions, agile workflows, utilities) so you never need to memorize scattered keybindings.
    • If the default wide layout does not fit your frame well, set ai-code-menu-layout to two-columns for a narrower menu with the same commands.
  • AI CLI Session Management: Start (a), resume (R), or jump back into (z) the active AI CLI buffer, instantly swap backends (s), upgrade them (u), install backend skills (S), edit backend configs (g), open backend agent file (G), and run prompts against the current file (|). It supports multiple sessions per project. The S entry is especially useful for installing shared skill packs such as [[https://github.com/obra/superpowers][obra/superpowers]].
    • A task associated with a worktree uses that checkout for backend selection, behavior settings, and project session lookup, even when the task file is shared from the main repository. Shared task storage stays in the main repository.

    • Z toggles the AI session dashboard in a window across the bottom of the frame, where you can inspect active sessions, refresh the list, visit a session buffer, kill a session, or open the repository’s Magit status. Press Z again, or q in the dashboard, to close it. Besides repository, task file, backend and branch, each row shows the session’s Status, how long it has been in that state (Since), its uncommitted changes (for example =2 files +3 −2=), and a one-line summary of the last prompt sent to it from Emacs; hover over the summary to see the prompt.

      With =tab-bar-mode= enabled, =RET= returns to the tab showing the session and focuses its window, preserving existing tab layouts. If no tab shows it, a new tab opens for the session.

      [[file:./session_dashboard.png]]

    • H sends a session checkpoint prompt when run from an AI session buffer, asking the AI to summarize the goal, files changed, current hypothesis, tests/build result, blockers, and next action.

    • When resuming, selecting a UUID in the region appends that UUID automatically so you can continue a specific session.

    • In AI session side windows, C-. grows and C-, shrinks the panel immediately. On left/right side windows it adjusts width; on top/bottom side windows it adjusts height.

  • AI CLI Editor Viewport: Managed terminal TUI sessions support editing in a native Emacs viewport.
    • Within managed AI CLI sessions, general EDITOR / VISUAL requests auto-submit by default (ai-code-editor-viewport-auto-submit is t). Set it to nil to make those requests save-only, including kubectl edit or crontab -e launched inside the session; Git editor requests are always save-only.
  • Clickable Session Links: In AI session buffers, supported in-repo file references, nearby code symbols, and http / https URLs are underlined and clickable. File links such as src/foo.el:42, src/foo.el:42:7, src/foo.el:L42-L60, or src/foo.el#L42-L60 jump directly to the right location, nearby symbols such as setq-local, ai-code-session-link-enabled, or UserService.processRequest() trigger code navigation in the associated file, and web links open in your browser. Symbol navigation first tries xref, then helm-gtags when available, and finally falls back to searching in the opened file buffer. Set ai-code-session-link-enabled to nil if you want to disable this link rendering. [[./clickable_link_ai_session.png]]
  • Context-Aware Code Actions: The menu exposes dedicated entries for changing code (c), implementing TODOs (i), asking questions (q), explaining code (x), sending free-form commands (<SPC>), and managing AI context (@). The context menu can copy scoped references with repository-relative or full paths, including the current function or selected line range. Each command automatically captures the surrounding function, region, or clipboard contents (via C-u) to keep prompts precise.
    • In Dired, changing, asking, explaining, refactoring, copying, and adding context use all marked files/directories in buffer order, falling back to the file at point when nothing is marked. Insert follows the same rule unless an active Dired region selects its files explicitly.
  • Address code annotation (m under AI code actions with context): Manage source-file and Magit hunk annotations and ask AI for suggestions about them. Requires the optional, ordinary [[https://github.com/bastibe/annotate.el][annotate.el]] package, version 2.5.0 or newer (annotation IDs); no modified annotate fork is needed. If annotate.el is missing or no annotations exist, the command explains this instead of sending an empty request.
    • The command offers six ordered choices: 1. Add / Edit annotation at point, 2. Browse worktree annotations, 3. Ask AI about annotation at point, 4. Ask AI about worktree annotations, 5. Delete annotation at point, 6. Clear worktree annotations. Outside Git, “worktree” is replaced by “current file”. The prompt displays the scope, annotation count (including replies), and whether the at-point annotation mode is enabled. In Magit buffers the at-point actions use hunk notes; elsewhere they use =annotate-mode= (enabled automatically when adding). Clearing asks for confirmation and preserves annotations outside the selected scope.
    • Browse opens the read-only =AI Code Annotations= list with type, file, matched line number, status and text summary. =RET= jumps to an exact current match, or previews the snapshot if the note is stale; =v= previews the complete note, replies and snapshot. =e= edits note text and =d= deletes a note and its replies after confirmation. Both work on unmatched saved notes without changing source files or guessing new locations. In the note editor, =C-c C-c= saves and =C-c C-k= cancels.
    • In the list, =m= toggles a mark, =s= asks AI about marked notes (or the current row when none are marked), =f= asks about every source and hunk note for the row’s file, =w= asks about the entire scope, and =g= refreshes the list. Source replies are included with their selected root note. Outside the list, =M-x ai-code-annotation-send-file= asks about the current source file or Magit file section. These narrower scopes avoid sending unrelated notes and oversized worktree context.
    • Use =annotate-mode= to annotate source files. For Magit status/diff buffers, use =M-x ai-code-annotate-magit-mode= instead (do not enable =annotate-mode= there). =C-c # a= edits a hunk/selected-line note, =C-c C-c= saves it, =C-c C-k= cancels, =C-c # d= deletes, =C-c # s= previews all saved worktree notes, and =C-c # w= copies them.
    • Magit notes retain the original diff, file/old-file names, source line ranges, branch and HEAD. They survive refresh and reopening, and reattach only to exact, unambiguous hunk/context matches; branch and HEAD are metadata, so unrelated commits or branch switches do not detach staged/unstaged notes. Unmatched snapshots remain available for review, and notes exported without a Magit view of the worktree are marked =NOT CHECKED= rather than unmatched. =ai-code-annotate-magit-file= configures the separate database (default =~/.emacs.d/annotate-magit-reviews=, compatible with the earlier optional integration).
    • The action collects source annotations from the active =annotate-file= database and databases associated with live annotated buffers in the current worktree. Live root notes override saved records, including unsaved edits/deletions, while retaining saved reply chains to surviving roots. Legacy records are read completely and migrated without truncation when written. Closed files using an unrelated, undiscovered local database are not scanned. Outside Git, only the current source file is included. Stale/missing source text is marked unmatched, with no guessed current line numbers. At-point requests distinguish a disabled annotation mode from an absence of notes; browsing saved notes does not require enabling their display mode.
    • Before anything is sent, the assembled prompt always opens in the =AI Compose= buffer for review, with its character count in the header: edit it freely, then =C-c C-c= sends it or =C-c C-k= cancels without sending.
    • AI focuses on each annotation and its replies; the associated source excerpts or original diff snapshots provide supporting context. It interprets the concern/question, checks whether replies already resolve it, and explains a focused response with reasons, risks and directly related proposed patches/tests. It does not perform a general code review or suggest unrelated changes, and waits for your decision. It must not modify files or resolve notes. Generic prompt suffixes and Org summary-write instructions are suppressed for this action. This is a suggestions-only prompt, not a backend filesystem sandbox: select a read-only backend permission mode if you need enforced write prevention. After reviewing, separately ask AI to implement only the suggestions you approve. Existing notes are not automatically deleted or resolved.
    • When a visible AI session buffer already exists, prompts can be routed to that session directly instead of opening a new one.
  • Insert into AI Sessions: Open the configurable ai-code-menu prefix (C-c a in the configuration examples), then press I to open the Insert submenu for files, Dired selections, regions, diagnostics-aware DWIM, screenshots, and clipboard images. The I entry always remains available. If no session is running, pressing it reports that state; if only sessions for other projects are running, it opens the submenu with just the to... entries for choosing one explicitly. An editor viewport associated with the destination session receives the insertion when present; otherwise AI Code inserts into that session’s TUI input without submitting it. Screenshot capture may require the [[*Optional Screenshot Capture][platform-specific utility described above]].
    • Inserted TUI content is always preceded and followed by two newline characters.[fn:insert-tui-spacing] In a viewport, AI Code omits the leading two newlines when the viewport is empty, keeps them when it already contains content, and always appends two newlines. Viewport attachments follow the same spacing rule.
  • Agile Development Workflows: Use the refactoring navigator (r), the guided TDD cycle (t), and the pull/review diff helper (v) to keep AI-assisted work aligned with agile best practices. Prompt authoring is first-class through quick access to the prompt file (p), build/test helper (b), and AI-assisted shell/file execution (!). In prompt files, send the current block with C-c C-c.
  • Acceptance Tests: Press =C-c a t= and select =7. Acceptance tests=. Optionally provide an original requirement or issue URL; leave it blank to let the agent follow human-authored references from the current Org task or AI session. The request is editable in Compose. Prefer stable E2E coverage when practical, otherwise integration/unit tests; explain the choice and comment on the linked acceptance criteria. Only tests and necessary test fixtures may be changed; implementation defects must be reported, not silently fixed. This is an agent instruction, not a filesystem permission boundary.
  • Productivity & Debugging Utilities: Initialize project navigation assets (.), investigate exceptions (e), debug Emacs runtime issues (d), auto-fix Flycheck issues in scope (f), create or open task files (k), open prompt history (p), capture session notes straight into Org (n), search notes with AI (/), and dictate prompts with speech-to-text (:).
  • Architecture Document Generation: Derive practical architecture documents for the current repository with C-c a A (ai-code-derive-architecture-document). The command can generate architecture guardrails, a C4 PlantUML overview, a lightweight DDD context, or a test context document under .ai.code.files/architecture/ so future AI coding sessions can reuse module boundaries, dependency rules, runtime flows, and validation expectations. See [[./docs/architecture/c4-overview.org][the C4 architecture overview for this repository]] for an example C4 diagram guide.
  • Seamless Prompt Management: Open the prompt file via ai-code-open-prompt-file (stored under .ai.code.files/.ai.code.prompt.org inside a Git repository), send regions with ai-code-prompt-send-block, and reuse prompt snippets via yasnippet to keep conversations organized. If the preferred prompt-history location is not writable, AI Code falls back to ~/.ai.code.files/.ai.code.prompt.org; customize ai-code-prompt-fallback-directory to change that location or set it to nil to disable fallback. Prompt sending still proceeds with a warning when prompt history cannot be written.
    • Prompts you typed by hand can be completed back inline with ai-code-prompt-completion-capf, indexed across every repository. See [[*Reusing Prompts You Already Wrote][Reusing Prompts You Already Wrote]].
  • Interactive Chat & Context Tools: Dedicated buffers hold long-running chats, automatically enriched with file paths, diffs, and history from Magit or Git commands for richer AI responses.
  • AI-Assisted Bash Commands: From Dired, shell, eshell, or vterm, run C-c a ! and type natural-language commands prefixed with : (e.g., :count lines of python code recursively); the tool generates the shell command for review and executes it in a compile buffer.

[fn:insert-tui-spacing] Managed TUI sessions expose rendered terminal contents, not a backend-independent logical input value. AI Code therefore cannot reliably determine whether a TUI input is empty and conservatively keeps the leading separator.

*** Typical Workflows Example

  • Changing Code: Position the cursor on a function or select a region of code. Press C-c a, then c (ai-code-code-change). Describe the change you want to make in the prompt. The AI will receive the context of the function or region and your instruction.
  • Implementing a TODO: Write a comment in your code, like ;; TODO: Implement caching for this function. Place your cursor on that line and press C-c a, then i (ai-code-implement-todo). The AI will generate the implementation based on the comment.
  • Verify a Branch or PR Against Requirements (discussion-first): Press =C-c a K= (=ai-code-task-file-action=), select =Verify branch / PR vs requirements= (=ai-code-verify-current-work=), choose =Current branch= or =GitHub PR=, and provide the original problem, issue, acceptance criteria, or design intent. This is not a TODO-state workflow or a generic code-quality review. It asks whether the actual changes address the intended problem, including important missing behavior, regressions, and unnecessary complexity.
    • Problem context is automatic: If text is selected, =V= uses that exact selection as its starting context (with source location). Otherwise, when the cursor is inside a task file’s Org headline, it uses the selected enclosing section/subtree (including =DONE=). It does not ask you to type the same problem again. Only when neither source is available does it prompt for a problem statement; for PRs this prompt may be left empty so the agent can investigate the original issue/discussion. For current branches, some problem context is required. You may clarify or extend the requirements naturally during the subsequent AI conversation.
    • Original references are the source of truth: The selected text or Org section may contain Slack threads, Radar tickets, GitHub issues/PR discussions, meeting notes, and Splunk logs. Verify should follow these references when accessible and compare actual code changes against original human-provided requirements and decisions, not AI-generated resume summaries, intermediate designs, implementation plans, or an unverified PR description. Splunk logs are raw observations, not automatically human requirements. Cite original source links or precise locations when explaining requirement coverage. When original sources are missing, inaccessible, contradictory, or superseded by later human decisions, surface the uncertainty and ask instead of claiming the code matches the requirements. The Org task section is an entry point, not necessarily authoritative by itself.
    • Edit before sending: Verify opens the existing =AI Compose= buffer with the complete generated prompt (including selected text or Org section context, change scope, evidence-first review instructions and safety boundaries). Adjust the focus, questions or acceptance criteria before sending; press =C-c C-c= to accept and send, or =C-c C-k= to cancel without sending. This compose step is always used for Verify, independently of =ai-code-use-compose-buffer=. Mandatory read-only and original-reference rules are appended after acceptance, even if you edit away their original paragraphs; they are prompt instructions, not a filesystem permission restriction.
    • Choose change scope: =Current branch= asks the agent to identify the proper comparison base, review the complete committed branch delta and separately inspect staged/unstaged changes; it must clarify an ambiguous base and avoid unrelated work. =GitHub PR= asks for a PR URL and instructs the agent to inspect its actual head/base, diff, surrounding implementation, linked issues, review discussion, and available CI using GitHub MCP or =gh= when available. The PR need not be checked out locally.
    • Discussion, not a PASS/FAIL gate: The agent begins with a few evidence-backed findings and open questions, distinguishes demonstrated behavior from guesses, and asks one important question at a time when your domain knowledge, missing requirements, or a design tradeoff matter. You can challenge a finding, clarify a criterion, or ask it to run another safe check. Continue in the same AI session until you decide the evidence is sufficient; a final assessment is optional.
    • Optional result notes in the task file: After accepting the Verify Compose buffer, if the command originated in an Org task, the existing =Append result summary to current section?= question is offered (just like =C-c a spec=). Answer =y= to allow one append-only Verification Notes sub-heading in the chosen task section after you explicitly finish the verification discussion. The notes should capture original human source links, evidence-backed findings, unmet requirements and open questions, clearly distinguishing AI interpretations from original requirements. Answer =n= to keep the task file untouched; cancelling Compose sends nothing and does not ask. A selected ancestor headline is used as the summary destination, not an unrelated child.
    • Strict code read-only boundary: Verify must never modify code (including tests, fixtures, snapshots), configuration, documentation, Git state, task status, existing task contents, or PR metadata. It must not apply proposed fixes. The only permitted write is the explicitly opted-in, append-only Org verification note after the discussion ends; no implementation/auto-commit/follow-up suffixes are added. Read-only checks and existing CI evidence are allowed; destructive checks must be done separately. These are agent instructions, not filesystem or backend permission enforcement.
    • Which code was examined? Local Verify includes the checkout, HEAD, full staged/unstaged diff fingerprints, Git status and unsaved-buffer notices. It observes again after Compose, so edits made while composing do not silently reuse the earlier identity. =M-x ai-code-verify-check-code-state= in the invoking buffer reports whether that observation has changed; it runs no tests and is available only while the buffer/Emacs remains open. The fingerprints cover Git-visible tracked patches, including binary changes; untracked contents, ignored files, unsaved buffer contents and submodule contents are excluded. An unchanged observation is not a verification verdict. The agent must recheck its actual examined state before concluding and preserve the identifiers, comparison base and coverage in optional Verification Notes. For remote PRs, the agent must obtain and re-fetch the actual base/head metadata; local HEAD is never a substitute. Missing identity or access remains unverified. Observations are not atomic snapshots and do not enforce a freeze on concurrent changes.
    • Code-state design inspiration: Rachel Laycock, [[https://martinfowler.com/rachels-ramblings/good-devs-wary.html][Why are good developers so wary of agentic development?]] (2026-10-29), and Annie Vella, [[https://annievella.com/posts/supervisory-engineering-work/][Supervisory Engineering Work]] (2026-10-23), the latter highlighted in Martin Fowler’s [[https://martinfowler.com/fragments/2026-10-28.html][October 28 Fragment]]. These motivate trustworthy feedback and observable state for human supervision. The Git fingerprints, Compose reobservation and freshness command are this project’s design extension, not mechanisms prescribed or validated by those articles.
    • Background: Adapted from Cindy Sridharan, [[https://copyconstruct.medium.com/how-to-effectively-debug-when-you-no-longer-understand-the-code-bd3dcb2c5f7b][How to effectively debug when you no longer understand the code]] (2026), as recommended in Martin Fowler’s [[https://martinfowler.com/fragments/2026-10-21.html][October 21, 2026 Fragment]]. The emphasis is independent evidence and falsifiable hypotheses, applied here to requirement-fit discussions rather than mandatory production debugging.
  • Asking a Question: Place your cursor within a function, press C-c a, then q (ai-code-ask-question), type your question, and press Enter. The question, along with context, will be sent to the AI.
  • Discussion follow-up suggestions: ai-code-discussion-auto-follow-up-enabled is enabled by default. Set (setq ai-code-discussion-auto-follow-up-enabled nil) to turn it off. Then ask a question with C-c a q or use C-c a <SPC> for a design discussion. When enabled, AI Code asks at send time whether to append 2-3 numbered next-step suggestions, and the transient toggle on C-c a F lets you turn the feature on or off from the menu.
  • Refactoring a Function: With the cursor in a function, press C-c a, then r (ai-code-refactor-book-method). Select a refactoring technique from the list, provide any required input (e.g., a new method name), and the prompt will be generated. Source: Martin Fowler’s [[https://martinfowler.com/books/refactoring.html][Refactoring]] and [[https://refactoring.com/catalog/][refactoring catalog]]; the Emacs navigation and agent prompts are package adaptations.
  • Grow Next Step: In an Org task headline, use =C-c a K= and choose =Grow next step= to discuss one independently useful, verifiable increment before optionally writing a child TODO. Inspiration: Steve Freeman and Nat Pryce, [[https://growing-object-oriented-software.com/][Growing Object-Oriented Software, Guided by Tests]]. The one-step discussion and value-first task workflow are this project’s adaptation, not a reproduction of the book’s full process.
  • Value-driven Simplification: Press C-c a r and choose the second entry to discuss either the current branch (relative to a selected base, with an explicit choice about uncommitted changes) or a repository topic. The AI investigates code and asks one question at a time; you decide what to keep and how to simplify. This entry starts a discussion and does not edit code.
    • Grow Next Step, Value-driven Simplification, Verify, task resume, handoff, and checkpoint omit automatic suffixes (including custom, test, commit, and follow-up instructions). Verify retains its optional Org notes question; the others use only their own writeback instructions. Ordinary prompts keep their configured suffixes.
  • Automatically run tests after change: When ai-code-auto-test-type is non-nil, AI will automatically run tests after code changes and follow up on results.
  • Optional agent commits: Toggle =ai-code-auto-commit-enabled= (default =nil=) with =C-c a C=. When on (and =Use prompt suffix= is on), prompts ask the agent to commit only the code it changed, after checks pass, with an =[ai]= message prefix. This is prompt guidance only: Emacs does not run Git. Review the commits with Magit.
  • One-prompt TDD with refactoring: Press C-c a, then t (ai-code-tdd-cycle) and choose 5. Red + Green + Blue (One prompt) to generate tests, implement code, run tests, and then refactor the changed code in one flow.
  • Reviewing a Pull Request: Press C-c a, then v (ai-code-pull-or-review-diff-file). Choose to generate a diff between two branches. The diff will be created in a new buffer, and you’ll be prompted to start a review. Set ai-code-default-review-source to github-mcp or gh-cli to skip the review source prompt and always use that backend; leave it nil (the default) to be prompted each time.
  • Reviewing the Current Branch with Difftastic: Press C-c a, then v, and choose Review current branch with difftastic to run difftastic-magit-diff for a structural review of the current branch. If the =difftastic= package is not installed, AI Code will tell you to install it from MELPA or from [[https://github.com/pkryger/difftastic.el][pkryger/difftastic.el]].
  • Multiple Sessions Support: Start more AI coding session with C-c a a after launching one. Select active session with C-c a z. Prompt with above command will be sent to the selected session.
  • Speech to Text Input: Press C-c a, then : (ai-code-speech-to-text-input). Speak your prompt, press RET to stop recording, then choose whether to insert the transcription into the current buffer, send it to the active AI coding session after editing it in ai-code-read-string, or copy it to the clipboard.
  • Agent Handoff: When switching AI backends or pausing work, press C-c a H to have the AI write a neutral handoff log into the task file. Later, in a new backend session, run C-u C-c a H to feed the entire handoff history back to the new agent.

*** Reusing Prompts You Already Wrote

Most of what you retype into a prompt is wording, not structure: “explain the current code”, the handoff instructions you send at every backend switch. This completes those from the prompt history files AI Code already keeps, across every repository it knows about – projectile’s known projects, ai-code-prompt-completion-roots, the current directory and the fallback location, with remote (Tramp) roots skipped so completion never opens a connection. Point ai-code-prompt-completion-files (nil by default) at files of your own – a prompt library you keep by hand, a diary, any Org file whose wording you reuse. Setting ai-code-prompt-completion-use-org-roam adds the notes org-roam tracks the same way – off by default, since a whole zettelkasten contributes note sections rather than prompts. In both, every headline offers two prompts however deep it sits, its own text and the text written under it, and whatever stands before the first headline – the whole of a file written without any – is split on blank lines. Datetree headlines, tags, statistics cookies and link wrappers are markup rather than wording and drop out, as does a heading of a word or two, quicker typed than picked from a popup. Neither history filter below applies there: you wrote those files, so they are offered as written. A large diary is worth measuring before you point at it – 10MB of Org indexes in about a second and contributes on the order of 10^5 candidates.

It needs no configuration: opening a prompt file installs the capf, so completion-at-point (=M-TAB=) offers your earlier prompts right away, and if =cape= is installed its cape-dict words join the same candidate list. Only the popup front-end is left to you:

#+begin_src emacs-lisp ;; Show candidates as you type, using company (add-hook 'ai-code-prompt-mode-hook #'ai-code-prompt-completion-setup) #+end_src

Both =cape= and =company= are optional: neither is a dependency, and neither is loaded when it is not installed. Set ai-code-prompt-completion-enable-company to nil when a front-end such as corfu shows the candidates instead, or (remove-hook 'ai-code-prompt-mode-hook #'ai-code-prompt-completion--enable) to opt out completely. If your own config already merges capfs with cape, add ai-code-prompt-completion-capf to that list rather than relying on the default: the first capf at a given hook depth answers, and yours is added first.

Candidates are the prompts you wrote by hand, ranked by how often you wrote them, shown as a truncated first line and inserted whole. A prompt is recalled from any word of three characters or more in its first line, not only the opening one, and choosing it rewrites the line from the start when what you already typed there opens that same prompt – so a half-finished - Go ahead with the suggested refac completes in place, while a TODO: of your own stays put. Matching still begins at a word: Emacs only offers a non-exclusive capf once plain prefix completion could succeed, so factor reaches refactoring only if your own completion-styles include flex. Prompts AI Code generated itself are left out by prefix (ai-code-prompt-completion-template-prefixes), and anything longer than ai-code-prompt-completion-max-lines is dropped as a one-off paste. The index is cached for the session; ai-code-prompt-completion-refresh rebuilds it.

One caveat on the dictionary half: cape-dict reads /usr/share/dict/words, which on macOS is Webster’s 1934 edition. For a modern list, generate one and point cape-dict-file at it:

#+begin_src sh aspell -d en dump master | aspell -l en expand | tr ’ ’ ‘\n’ | sort -u \

~/.emacs.d/dict-en.txt #+end_src

*** Context Engineering

Context engineering is the deliberate practice of selecting, structuring, and delivering the right information to an AI model so the output is specific, accurate, and actionable. For AI-assisted programming, the model cannot read your whole codebase by default, so the quality of the result depends heavily on the clarity and relevance of the provided context (file paths, functions, regions, related files, and repo-level notes). Good context engineering reduces ambiguity, prevents irrelevant suggestions, and keeps changes aligned with the current code.

This package makes context engineering easy by automatically assembling precise context blocks and letting you curate additional context on demand:

  • Automatic file and window context: prompts can include the current file and other visible files (ai-code--get-context-files-string), so the AI sees related code without manual copying.

  • Function or region scoping: most actions capture the current function or active region, keeping requests focused (e.g., ai-code-code-change, ai-code-implement-todo, ai-code-ask-question).

  • Tree-sitter semantic scope: when the current buffer has an active Tree-sitter parser, prompts carry structural context derived from the real syntax tree instead of just a function name. A prompt for a method now includes its enclosing type, both declaration headers, and the function’s line range:

    #+begin_example Enclosing class: UserService Class definition: class UserService(BaseService): Function: find_user Function definition: def find_user(self, user_id: int) -> str: Function range: lines 2-4 #+end_example

  • Imenu @# symbol completion: after picking a file with @ (e.g., @src/service.py), type # to pick a symbol from that file. The major mode’s Imenu index supplies candidates in file-definition order, with declaration headers and line numbers when positions are available. Imenu container hierarchy and optional Tree-sitter scope information preserve qualified names (Bar, Bar.baz); Tree-sitter is not required. Coverage follows the mode’s index, so symbols it omits (for example, constructors in java-ts-mode) are not offered. Works in comments, *.prompt.org buffers, and AI session buffers.

Screenshot:

[[file:./symbol-completion-example-screenshot.png]]

Example (focused refactor with curated context):

  1. In a buffer, run C-c a @ to add the current function or selected region to stored repo context.
  2. Open another related file in a window so it is picked up by ai-code--get-context-files-string.
  3. Place the cursor in the target function and run C-c a c to request a change. The generated prompt will include the function/region scope, visible file list, and stored repo context entries, giving the AI exactly the surrounding information it needs.

**** Agent actions on Magit hunks

Place point on a textual hunk in Magit status, diff, or revision buffers, then use the existing AI commands:

| Key | Action on selected hunks | |-----±-------------------------| | =C-c a x= | Explain behavior changes, assumptions, and risks (read-only) | | =C-c a q= | Ask a question about the patch (read-only) | | =C-c a c= | Apply requested feedback to current working-tree source | | =C-c a t= | Add useful missing regression tests for the existing change | | =C-c a @= | Add or copy a patch snapshot through the context menu |

Use Magit’s section selection to select multiple sibling hunk headings. A text selection inside one hunk includes the complete hunk and marks the selected excerpt as the focus. Invalid selections, binary diffs, combined merge hunks, and file headings are rejected by the hunk actions. The copy command still copies the branch name elsewhere in a Magit status buffer.

Context includes the repository, file paths, displayed diff provenance, HEAD at capture, and capture time. Stored hunks are snapshots: refresh Magit and capture again to update them. Staged hunks describe the index; edit and test requests tell the agent to re-read current source, preserve unrelated changes, and avoid staging or committing. Historical diffs support explain, question, and context capture; switch to a current status hunk before asking for edits or tests.

In Magit, =C-c a t= checks existing coverage and adds tests only where useful. The agent runs verification and reports commands and results. It does not claim a test-first Red/Green cycle for code already written, and it reports production failures without changing production code. This action and the read-only actions suppress automatic implementation TDD suffixes for that send. File-buffer TDD behavior is unchanged. =C-u= adds clipboard context to hunk questions and change requests, as it does in file buffers.

**** Built-in Emacs MCP Tools

AI Code includes an Emacs MCP server with these built-in tools:

  • =project_info=: summarize the current project, active buffer, and file count
  • =editor_state=: inspect the currently selected buffer, point, mode, region, and buffer flags
  • =visible_buffers=: list the buffers visible in the selected frame windows
  • =buffer_query=: read buffer contents, optionally by line range
  • =get_diagnostics=: return Flycheck or Flymake diagnostics for one file or open project buffers
  • =get_project_files=: list regular files in the current project
  • =get_project_buffers=: list open buffers that belong to the current project
  • =imenu_list_symbols=: list useful symbols from a file via imenu
  • =xref_find_references=: find references to an identifier in project context
  • =xref_find_definitions_at_point=: find definitions at a file location
  • =treesit_info=: inspect tree-sitter node information for a file location

Additional debugging tools come from =ai-code-mcp-debug-tools.el= and are enabled by default:

This make emacs runtime debugging possible. With emacs debugging mcp enabled, you can simply ask AI to trouble shooting your emacs lisp related problem (could deep inside some installed package), AI can automatically figure out the problem and suggest how to fix / perform the fix

#+begin_src emacs-lisp (setq ai-code-mcp-debug-tools-enabled t) ;; default ;; (setq ai-code-mcp-debug-tools-enabled nil) ;; disable them #+end_src

These tools add:

  • =get_variable_value=: return the printed value of an Emacs variable by name
  • =get_variable_binding_info=: inspect current and default bindings for an Emacs variable
  • =get_function_info=: inspect function metadata such as kind, aliasing, and advice state
  • =get_feature_load_state=: inspect whether an Emacs feature is loaded and where it comes from
  • =get_recent_messages=: return the latest lines from =Messages=
  • =get_last_error_backtrace=: return the most recently recorded Emacs command error snapshot
  • =eval_elisp=: evaluate arbitrary Emacs Lisp with possible side effects in a chosen buffer context when explicitly enabled (no restrictions once enabled)

The old =ai-code-mcp-editor-tools.el= module has been removed. Its live-editor read tools are now built in, while =eval_elisp= remains an explicit opt-in.

To register =eval_elisp=:

#+begin_src emacs-lisp (setq ai-code-mcp-debug-tools-enable-eval-elisp t) #+end_src

Once enabled, =eval_elisp= can evaluate any Emacs Lisp form without restrictions. It takes =code= (a single top-level form), optional =buffer_name= or =file_path= for evaluation context, optional =capture_messages= to collect new =Messages= output, optional =include_backtrace= to include a backtrace on failure, and optional =timeout_ms=. This is useful for letting the AI apply fixes by evaluating modified function definitions directly.

screenshot inside Codex cli:

[[file:./emacs_mcp_tools.png]]

  • Emacs mcp use cases
    • [[./docs/emacs-package-cleanup-with-ai-agent.org][Unused package clean up]]

***** Use It with an AI CLI

Set the backend to =claude-code=, =codex=, =github-copilot-cli=, or =antigravity= and start a session with =C-c a a=. AI Code will:

  • start a local Emacs MCP HTTP server
  • register the current project/buffer as the MCP session context
  • inject a session-scoped MCP config into that agent session automatically

Auto-wiring is currently enabled for =claude-code=, =codex=, =github-copilot-cli=, =open-interpreter=, and =antigravity=.

Antigravity does not expand environment variables in MCP headers, so AI Code temporarily writes the session token to =.agents/mcp_config.json= with private permissions. Existing JSON configuration is merged and restored byte for byte when the last Antigravity session exits. If the file changes outside AI Code while a session is active, cleanup leaves the edited file untouched rather than overwriting it.

If you disabled it before, enable it again with:

#+begin_src emacs-lisp (setq ai-code-mcp-agent-enabled-backends '(claude-code codex github-copilot-cli open-interpreter antigravity)) #+end_src

***** Make Sure It Works

  1. Start =claude-code=, =codex=, =github-copilot-cli=, =open-interpreter=, or =antigravity= with =C-c a a= from the file or project you want to work on.
  2. Switch to the agent buffer and run =M-x ai-code-mcp-agent-show-buffer-status=.

If it shows =:backend=, =:session-id=, and a local =:server-url=, then Emacs has attached MCP to this session.

  1. Then ask the agent to use one of the Emacs tools, for example:
  • use =project_info= and tell me the current project info
  • use =imenu_list_symbols= for the current file
  • use =get_diagnostics= and summarize the current file diagnostics

The status command only proves the Emacs side is wired. The real proof is that the agent returns your current project path, buffer context, or current-file symbols from those tools.

***** Add a New MCP Tool

  1. Define an Emacs Lisp function.

#+begin_src emacs-lisp (defun ai-code-mcp-current-buffer-name () “Return the current buffer name for the active MCP session.” (buffer-name (current-buffer))) #+end_src

  1. Register it as an MCP tool before you start the AI agent session:

#+begin_src emacs-lisp (require 'ai-code-mcp-server)

(ai-code-mcp-make-tool :function #'ai-code-mcp-current-buffer-name :name “current_buffer_name” :description “Return the current Emacs buffer name.” :args nil) #+end_src

  1. Start =claude-code=, =codex=, or =github-copilot-cli= with =C-c a a=. If the agent session is already running, restart it after registering the new tool.

  2. Ask the agent to use the tool, for example:

  • use =current_buffer_name= and tell me the current Emacs buffer name
  1. If you want to verify from Emacs first, run:

#+begin_src emacs-lisp (ai-code-mcp-dispatch “tools/list”) #+end_src

If =current_buffer_name= appears in the tool list, Emacs has registered it. If the agent can call it and returns the expected buffer name, the tool is available inside the AI coding session.

***** Use the MCP Core Directly from Elisp

If you want to use the MCP core without an AI CLI, you can still call it directly:

#+begin_src emacs-lisp (require 'ai-code-mcp-server) (ai-code-mcp-builtins-setup) (ai-code-mcp-dispatch “tools/list”) #+end_src

To expose your own Emacs function as a tool, use =ai-code-mcp-make-tool=.

*** Harness Engineering Practice

Harness engineering is about building a reliable loop around the model, so the AI does not stop at /make a change/ but continues into /verify the change and react to the result/. In this package, the clearest examples are the auto test loop for code changes and the optional next-step loop for discussion prompts.

Instead of manually telling the AI what to do after every code change or discussion turn, you can make follow-up part of the workflow:

  • ai-code-auto-test-type: choose how code-change prompts should continue after the edit. You can ask the AI to run tests after the change, use TDD Red+Green, use Red+Green+Blue with refactoring, turn it off, or decide case by case with ask-me. The =ask-me= choices also include Uncle Bob’s coding agent harness and harness+; the original keeps the evidence-first gauntlet, while harness+ adds maintainability sensors and semantic modularity checks. Source: bundled adaptations of [[https://github.com/AmazingAng/old-coder][AmazingAng/old-coder]], as recorded in [[https://github.com/tninja/ai-code-interface.el/pull/469][PR #469]]; subsequent hardening and harness+ extensions are maintained in this project.
  • Evidence-First coding harness (also in =ask-me=): constrains outcomes and reproducible evidence while allowing implementation strategies beyond strict TDD. Design sources, documented in [[https://github.com/tninja/ai-code-interface.el/pull/497][PR #497]]: Birgitta Böckeler, [[https://martinfowler.com/articles/exploring-gen-ai/tdd-in-the-agent-loop.html][TDD inside the agent loop - theater or actual value?]]; Giles Edwards-Alexander, [[https://martinfowler.com/articles/exploring-gen-ai/refactoring-economic-benefit.html][The Economic Benefit of Refactoring]]; Rahul Garg, [[https://martinfowler.com/articles/orchestrator-tax.html][The Orchestrator’s Tax]]; Unmesh Joshi, [[https://martinfowler.com/articles/llm-and-dsls.html][DSLs Enable Reliable Use of LLMs]]. The bundled loop combines those influences with this project’s prior harness work; it is not an author-supplied or experimentally validated workflow.
  • ai-code-discussion-auto-follow-up-enabled: when non-nil, discussion-style prompts can offer a send-time choice to append 2-3 numbered candidate next steps. You can customize this variable directly or toggle it from the transient menu with C-c a F.
  • ai-code-next-step-suggestion-suffix: customize the exact instruction appended for those numbered next-step suggestions.
  • ai-code-use-gptel-classify-prompt: when paired with the settings above, GPTel can classify prompts so code-change prompts skip discussion follow-up suggestions and discussion prompts skip test follow-up.
  • ai-code-tdd-cycle: run a guided TDD flow from the menu, including separate Red, Green, Blue stages or the combined one-prompt flows. Source: Kent Beck’s [[https://newsletter.kentbeck.com/p/canon-tdd][Canon TDD]] and the Red-Green-Refactor cycle; the staged agent commands and Blue label are this package’s presentation.
  • ai-code-build-or-test-project: run build, test, lint, or scoped Flycheck fixes from C-c a b when you want a direct verification or diagnostics step in the middle of the loop.
  • ai-code-prompt-suffix: add persistent project rules when needed, so repeated instructions such as response language, coding constraints, or test expectations do not have to be retyped in every prompt.
  • ai-code-grill-me-enabled: when non-nil, offer a one-shot clarification step (/“Grill me before acting?”/) immediately before the completed prompt is sent for ai-code-code-change, ai-code-ask-question, ai-code-implement-todo, and ai-code-send-command. When accepted, the AI reads the bundled =prompt/grilling.v1.md= harness and asks targeted clarifying questions before acting, reducing ambiguity in the request. The harness is adapted from [[https://github.com/mattpocock/skills/blob/main/skills/productivity/grilling/SKILL.md][mattpocock/skills – grilling]]. Disabled by default; enable it with: #+begin_src emacs-lisp (setq ai-code-grill-me-enabled t) #+end_src
  • ai-code-use-compose-buffer: when non-nil, edit complete generated prompts longer than two lines, including their context, in =AI Compose= before sending. This also covers Code Change, Ask Question, Implement TODO, Checkpoint, and Apply Prompt on File; already-confirmed prompts open only once. Accept with =C-c C-c= or cancel with =C-c C-k= before history, suffixes, or sending. Verify always uses compose. Disabled by default; enable it with: #+begin_src emacs-lisp (setq ai-code-use-compose-buffer t) #+end_src Apply Prompt on File keeps its CLI pipe, using the shared suffix providers and prompt history. Multiline prompts are streamed with =printf= and =cat=; =ai-code-sed-command= is obsolete.
  • [[https://github.com/obra/superpowers][obra/superpowers]] pair well with these features.

With the built-in =get_diagnostics= MCP tool, the loop can move further left:

  • record a diagnostics baseline before editing so the AI knows which warnings or errors already existed
  • re-run =get_diagnostics= after each edit on the touched files before moving on to slower test commands
  • treat completion as /no new diagnostics/ on the touched files relative to the baseline, instead of requiring the entire project to be clean
  • use tests as the next sensor in the loop, not the first one

Screenshot:

[[file:./emacs_mcp_tool_diagnosis.png]]

The benefit is practical:

  • faster feedback after each AI code change
  • less context switching between prompting, testing, and follow-up fixes
  • more consistent AI behavior because verification is part of the workflow
  • easier to let the AI continue with the next step after a failed or passing test

This is why features such as ai-code-auto-test-type, ai-code-discussion-auto-follow-up-enabled, ai-code-grill-me-enabled, and ai-code-tdd-cycle fit the idea of harness engineering: they turn testing, clarification, and follow-up into part of the system, not an afterthought in each prompt.

Nit: During using auto test feature, I prefer to turn off the approval request from AI, it will make the whole process more smooth. Eg. for Codex CLI, it is

#+begin_src emacs-lisp (setq ai-code-codex-cli-program-switches '(“-a” “never”)) #+end_src

  • Design background: Birgitta Böckeler, [[https://martinfowler.com/articles/harness-engineering.html][Harness engineering for coding agent users]] (2026-04-02): feedback, deterministic checks and human steering. The package’s diagnostics baseline and suffix routing are local implementations of those ideas.

*** Desktop Notifications (Experimental)

When working with multiple AI sessions, it can be useful to receive desktop notifications when AI responses are complete. This is especially helpful when you prompt an AI and then switch to other tasks while waiting for the response.

**** Enabling Notifications

  • Notifications are disabled by default.
  • Press C-c a then N to toggle notifications on/off.
  • Alternatively, use M-x ai-code-notifications-toggle.
  • To enable notifications in your config: #+begin_src emacs-lisp (setq ai-code-notifications-enabled t) #+end_src

**** How It Works

  • The package monitors terminal activity in AI session buffers.
  • When the terminal has been idle for ~5 seconds (configurable via ai-code-backends-infra-idle-delay), it’s considered a completed response.
  • If the AI session buffer is not currently visible/focused, a desktop notification is sent.
  • Notifications are throttled to avoid spam (minimum 2 seconds between notifications).

**** Platform Support

  • On Linux with D-Bus, native desktop notifications are used.
  • On other platforms, notifications appear in the Emacs minibuffer.

*** Sessions Needing Attention

When several AI sessions run in parallel, ai-code-session-attention-mode badges every tab-bar tab that shows an AI session, for every AI coding CLI backend, so you can tell AI tabs apart and see their state at a glance:

#+begin_src emacs-lisp (ai-code-session-attention-mode 1) #+end_src

| Badge | State | Meaning | |-------±------±--------| | =○= | idle | An AI session is here; nothing is happening | | =◐= | working | The session is producing output | | =✓= | done unseen | The session finished while you were not looking at it | | =?= | needs input | The session waits for you, for example a permission prompt |

[[file:./tab_bar_session_badges.png]]

  • Circles are ambient status; =✓= and =?= mean it is your turn. A tab with several sessions shows the most important badge: =?=, then =✓=, then =◐=, then =○=.
  • Showing a session in a window clears =✓= and =?=. Other tabs get no badge.
  • The session dashboard (C-c a Z) shows the same states in its Status column, plus =stopped= when the process has exited.
  • “Working” and “done” use the terminal output and idle check (ai-code-backends-infra-idle-delay), so typing in a session briefly shows =◐=. “Needs input” needs a terminal that reports program status, currently the Ghostel backend.

*** Portable Agent Handoff via Task Files

To transfer development work between different AI coding backends (e.g., from Codex to Antigravity CLI) without relying on backend-specific session histories, ai-code-interface.el supports portable agent handoffs using Org-mode task files.

  • Create or Open Task Files (k / ai-code-create-or-open-task-file): Quickly initialize a new task file (by default under .ai.code.files/) with date, branch, selected backend, and structured Org headings (Task Description, Investigation, Code Change).
  • Generate Portable Handoff (K → Handoff / checkpoint / ai-code-agent-handoff-or-checkpoint): C-c a K then Handoff / checkpoint picks its behavior from the current buffer.
    • In an Org buffer, run C-c a H (without a prefix) outside any handoff section to ask the current AI agent to append a structured handoff section (* Agent Handoff YYYY-MM-DD HH:MM) summarizing the task objective, current progress, files modified, design decisions, failed approaches, test results, and a startup prompt for the next agent.
    • Run C-c a H with a prefix argument (e.g. C-u C-c a H) to load the whole task file as neutral handoff context in a new AI session.
    • Run C-c a H anywhere inside a handoff section, or with the cursor on any Org heading, to load only that subtree as prompt context for the active session. The cursor does not have to sit on the handoff headline itself.
    • In an AI session buffer, C-c a H sends the session checkpoint prompt (ai-code-session-checkpoint) instead.
    • In any other buffer, C-c a H asks which of the two actions to run.
    • New handoffs also record the observed Git state and a machine-readable HEAD baseline, source links/dates, validation commands, task-related uncommitted work, and one concrete first action for the next session.

*** Pick Up an Interrupted Task

Use =C-c a K= and select =Resume task briefing= (=ai-code-task-resume=) in an Org task file, or select a task from another buffer. Review the prompt; the agent appends a =Task Resume= subtree with progress, relevant Git changes, open questions and a next action. The prompt references the whole saved task file with =@file= and asks the agent to read every section, regardless of the selected region or narrowed Org view.

  • Preserve original context sources (Radar, Slack threads, PRs, GitHub links, meeting notes and Splunk logs) first, with raw excerpts/signals, brief descriptions and next-use hints. Prior AI summaries/handoffs are pointers to originals, not evidence; do not recursively summarize them. Keep Splunk queries and time ranges.
  • Resume works without a prior handoff. Missing information and unread sources stay

README 内容过长,已截取前 64 KB。完整内容请前往 GitHub 仓库查看。

评论

暂无评论