agentic.nvim

agent
Guvenlik Denetimi
Gecti
Health Gecti
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Community trust — 504 GitHub stars
Code Gecti
  • Code scan — Scanned 8 files during light audit, no dangerous patterns found
Permissions Gecti
  • Permissions — No dangerous permissions requested

Bu listing icin henuz AI raporu yok.

SUMMARY

Agentic Chat Interface directly in Neovim with ACP providers from Claude-Code, Gemini, Codex, OpenCode, and Cursor-agent

README.md

Agentic.nvim

PR Checks

⚡ A Chat interface for AI agents in Neovim that works with any provider
supporting the Agent Client Protocol (ACP)
— including Claude, Gemini, Codex, OpenCode, Cursor Agent, Copilot, Auggie,
Mistral Vibe, Cline, Goose, Kiro, Pi, and more.

Agentic.nvim brings your AI assistant to Neovim through the implementation
of the Agent Client Protocol (ACP).

You'll get the same results and performance as you would when using the ACP
provider's official CLI directly from the terminal.

Agentic.nvim is the interface, your agent is the Brain. This plugin will use all
the same configurations and authentication methods you already have set up on
your terminal.

Including your MCP servers, commands, SKILLs, and sub-agents, you don't have to
recreate your configuration to use Agentic.nvim.

Sessions are interchangeable — start a conversation in Neovim and continue it in
the terminal, or pick up a terminal session right inside Neovim. Your ACP
provider manages sessions natively, so they're available everywhere.

There're no hidden prompts or magic happening behind the scenes. Just a Chat
interface, your colors, and your keymaps.

Supported providers

Works with any AI provider that implements the
Agent Client Protocol, including, but not
limited to:

Claude
Claude
Gemini
Gemini
Codex
Codex
OpenCode
OpenCode
Cursor
Cursor
Copilot
Copilot
Augment
Augment
Mistral Vibe
Mistral Vibe
Kiro
Kiro
Cline
Cline
Goose
Goose
Pi
Pi

...and any future ACP-compatible provider.

✨ Features

  • ⚡ Performance First - Optimized for minimal overhead and fast response
    times
  • 🔌 Any ACP Provider - Works with any AI provider that implements the Agent
    Client Protocol — Claude, Gemini, Codex, OpenCode, Cursor Agent, Copilot,
    Auggie, Mistral Vibe, Cline, Goose, Kiro, Pi, and any future ACP-compatible
    provider
  • 🔑 Zero Config Authentication - No API keys needed
    • Keep you secrets secret: run claude /login, or gemini auth login
      once and, if they're working on your Terminal, they will work automatically
      on Agentic.
  • 🧠 Model Switcher - Switch between available models mid-session
    (<localLeader>m in the chat widget)
  • 🔀 Switch Providers - Switch between ACP providers mid-conversation
    without losing chat history (<localLeader>s in the chat widget)
  • ♻️ Session Restore - Sessions are interchangeable between Neovim and
    terminal — continue any conversation anywhere
  • 📝 Context Control - Add files and text selections to conversation context
    with one keypress
  • 🏞️ Image Support - Drag-and-drop or paste images and screenshots directly
    into the chat
  • 🛡️ Permission System - Interactive approval workflow for AI tool calls,
    mimicking Claude-code's approach, with 1, 2, 3, ... one-key press for quick
    responses
  • 🤖 🤖 Multiple agents - Independent Chat sessions for each Neovim Tab let
    you have multiple agents working simultaneously on different tasks
  • 🎯 Clean UI - Sidebar interface with markdown rendering and syntax
    highlighting
  • ⌨️ Slash Commands - Native Neovim completion for ACP slash commands with
    fuzzy filtering
    • Every slash command your provider has access too will apear when you type
      / in the prompt as the first character
  • 📁 File Picker - Type @ to trigger autocomplete for workspace files
    • Reference multiple files: @file1.lua @file2.lua
  • 🔄 Agent Mode Switching - Switch between ACP-supported agent modes with
    Shift-Tab (Similar to Claude, Gemini, Cursor-agent, etc)
    • Default, Auto Accept, Plan mode, etc... (depends on the provider)
  • ℹ️ Smart Context - Automatically includes system and project information
    in the first message of each session, so the Agent don't spend time and tokens
    gathering basic info

🎥 Showcase

Simple replace with tool approval:

https://github.com/user-attachments/assets/4b33bb18-95f7-4fea-bc12-9a9208823911

Rich diff preview

When editing files, if your provider asks for permission, you can see a diff
preview side-by-side or inline, set your preference in your options:

Side-by-side Inline
Side-by-side diff Inline diff

Dynamic layout rotation: right - bottom - left

https://github.com/user-attachments/assets/000c5a9a-5469-44e3-b302-4074caa58fa9

Image and Screenshot support in the Chat

Drag-n-Drop or paste an image from the Clipboard directly to the chat context:

https://github.com/user-attachments/assets/6ae57136-9c08-4d71-bc8a-59babc49be4d

Session restoration

Start in the terminal, continue in Neovim — or the other way around!

Agentic-session-restore

🐣 NEW: Switch agent mode: Always ask, Accept Edits, Plan mode...

https://github.com/user-attachments/assets/96a11aae-3095-46e7-86f1-ccc02d21c04f

Add files to the context:

Add the current file to the Chat context or the selected text, let your agent
know where you want it to work.

https://github.com/user-attachments/assets/b6b43544-a91e-407f-834e-4b4de41259f8

Use @ to fuzzy find any file:

https://github.com/user-attachments/assets/c6653a8b-20ef-49c8-b644-db0df1b342f0

📋 Requirements

  • Neovim v0.11.0 or higher
  • ACP Provider CLI - Install the CLI for any ACP-compatible provider of your
    choice
    • For security reasons, this plugin doesn't install or manage binaries for
      you. You must install them manually.

We recommend using pnpm
pnpm uses a constant, static global path, that's resilient to updates.
While npm loses global packages every time you change Node versions using
tools like nvm, fnm, etc...

You are free to chose any installation method you prefer!

Provider Install
claude-agent-acp pnpm add -g @agentclientprotocol/claude-agent-acp
OR npm i -g @agentclientprotocol/claude-agent-acp
OR Download binary
gemini-cli pnpm add -g @google/gemini-cli
OR npm i -g @google/gemini-cli
OR brew install --cask gemini
codex-acp pnpm add -g @zed-industries/codex-acp
OR npm i -g @zed-industries/codex-acp
OR Download binary
opencode pnpm add -g opencode-ai
OR npm i -g opencode-ai
OR brew install opencode
OR curl -fsSL https://opencode.ai/install | bash
cursor-agent curl https://cursor.com/install -fsS | bash OR windows: irm 'https://cursor.com/install?win32=true' | iex
OR See Cursor docs
copilot-cli pnpm add -g @github/copilot
OR npm i -g @github/copilot
OR brew install copilot-cli
OR curl -fsSL https://gh.io/copilot-install | bash
auggie pnpm add -g @augmentcode/auggie
OR npm i -g @augmentcode/auggie
OR See Auggie docs
mistral-vibe curl -LsSf https://mistral.ai/vibe/install.sh | bash
OR uv tool install mistral-vibe
OR pip install mistral-vibe
OR Download binary
cline pnpm add -g cline
OR npm i -g cline
OR See Cline docs
goose brew install block-goose-cli
OR See Goose docs
kiro-cli curl -fsSL https://cli.kiro.dev/install | bash
OR See Kiro CLI docs
pi-acp Requires the pi CLI installed first: curl -fsSL https://pi.dev/install.sh | sh
OR pnpm add -g @earendil-works/pi-coding-agent
OR npm i -g @earendil-works/pi-coding-agent
Then the adapter: pnpm add -g pi-acp OR npm i -g pi-acp

[!WARNING]
These install commands are here for convenience, please always refer to the
official installation instructions from the respective ACP provider.

[!NOTE]
Why install ACP provider CLIs globally?
shai-hulud
should be reason enough. 📌 Pin your versions!
But frontend projects with strict package management policies will fail to
start when using npx ...

📦 Installation

lazy.nvim

{
  "carlos-algms/agentic.nvim",

  --- @type agentic.PartialUserConfig
  opts = {
    -- Any ACP-compatible provider works. Built-in: "claude-agent-acp" | "gemini-acp" | "codex-acp" | "opencode-acp" | "cursor-acp" | "copilot-acp" | "auggie-acp" | "mistral-vibe-acp" | "cline-acp" | "goose-acp" | "kiro-acp" | "pi-acp"
    provider = "claude-agent-acp", -- setting the name here is all you need to get started
  },

  -- these are just suggested keymaps; customize as desired
  keys = {
    {
      "<C-\\>",
      function() require("agentic").toggle() end,
      mode = { "n", "v", "i" },
      desc = "Toggle Agentic Chat"
    },
    {
      "<C-'>",
      function() require("agentic").add_selection_or_file_to_context() end,
      mode = { "n", "v" },
      desc = "Add file or selection to Agentic to Context"
    },
    {
      "<C-,>",
      function() require("agentic").new_session() end,
      mode = { "n", "v", "i" },
      desc = "New Agentic Session"
    },
    {
      "<A-i>r", -- ai Restore
      function()
          require("agentic").restore_session()
      end,
      desc = "Agentic Restore session",
      silent = true,
      mode = { "n", "v", "i" },
    },
    {
      "<leader>ad", -- ai Diagnostics
      function()
          require("agentic").add_current_line_diagnostics()
      end,
      desc = "Add current line diagnostic to Agentic",
      mode = { "n" },
    },
    {
      "<leader>aD", -- ai all Diagnostics
      function()
          require("agentic").add_buffer_diagnostics()
      end,
      desc = "Add all buffer diagnostics to Agentic",
      mode = { "n" },
    },
  },
}

⚙️ Configuration

You don't have to copy and paste anything from the default config, linking it
here for ease access and reference:
lua/agentic/config_default.lua.

Customizing ACP Providers

You can customize the built-in providers or add any new ACP-compatible provider
by configuring the acp_providers property:

[!NOTE]
You don't have to override anything or include these in your setup!
These are just examples of how you can customize the commands, env, etc.

{
  "carlos-algms/agentic.nvim",
  --- @type agentic.PartialUserConfig
  opts = {
    acp_providers = {
      -- Override existing provider (e.g., add API key)
      -- Agentic.nvim doesn't require API keys
      -- Only add it if that's how you prefer to authenticate
      ["claude-agent-acp"] = {
        env = {
          ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY"),
        },
      },

      -- Example of how override the ACP command to suit your installation, if needed
      ["codex-acp"] = {
        command = "~/.local/bin/codex-acp",
      },

      -- Add any new ACP-compatible provider — the name and command are up to you
      ["my-cool-acp"] = {
        name = "My Cool ACP",
        command = "cool-acp",
        args = { "--mode", "acp" },
        env = {
          COOL_API_KEY = os.getenv("COOL_API_KEY"),
        },
      },
    },
  },
}

Provider Configuration Fields:

  • command (string) - The CLI command to execute (must be in PATH or absolute
    path)
  • args (table, optional) - Array of command-line arguments
  • env (table, optional) - Environment variables to set for the process
  • default_mode (string, optional) - Default mode ID to set on session creation
    (e.g., "bypassPermissions", "plan")
  • initial_model (string, optional) - Default model ID to set on session
    creation (e.g., "haiku")
  • default_thought_level (string, optional) - Default thought effort level to
    apply on session creation (e.g., "high", "max" for Claude)

[!NOTE]
Customizing a provider only requires specifying the fields you want to
override, not the entire configuration.

Window Layout

Configure the widget layout position and sizing:

{
  "carlos-algms/agentic.nvim",
  --- @type agentic.PartialUserConfig
  opts = {
    windows = {
      position = "right",  -- "right", "left", or "bottom"
      width = "40%",       -- Sidebar width (position = "right" or "left")
      height = "30%",      -- Panel height (position = "bottom")
    },
  },
}
  • position - Widget layout: "right" or "left" (vertical sidebar) or
    "bottom" (horizontal panel)
  • width - Sidebar width when position is right or left (percentage, decimal,
    or absolute)
  • height - Panel height when position = "bottom" (percentage, decimal, or
    absolute)

Rotating Layouts dynamically at runtime

You can rotate between layouts, dynamically, without closing Neovim with
rotate_layout():

-- Rotates through all three layouts: right → bottom → left → right ...
require("agentic").rotate_layout()

-- Rotates between right and bottom only
require("agentic").rotate_layout({ "right", "bottom" })

-- Rotates between right and left only
require("agentic").rotate_layout({ "right", "left" })

Customizing Window Options

You can customize the behavior of individual chat widget windows by configuring
the win_opts property for each window. These options override the default
window settings.

Customizing Window Headers

You can customize the header text for each panel in the chat widget using either
a table configuration or a custom render function.

Table-Based Configuration

{
  "carlos-algms/agentic.nvim",
  --- @type agentic.PartialUserConfig
  opts = {
    headers = {
      chat = {
        title = "󰻞 My Custom Chat Title",
        suffix = "<S-Tab>: change mode",
      },
      -- ...
    },
  },
}

Function-Based Configuration

For complete control over header rendering, provide a function that receives the
header parts:

{
  "carlos-algms/agentic.nvim",
  --- @type agentic.PartialUserConfig
  opts = {
    headers = {
      chat = function(parts)
        local header = parts.title
        if parts.context then
          header = header .. " [" .. parts.context .. "]"
        end
        if parts.suffix then
          header = header .. " • " .. parts.suffix
        end
        return header
      end,
    },
  },
}

Folding

Completed tool call outputs are automatically folded to keep the chat buffer
readable. Failed tool calls stay open unless fold_on_error is enabled.

--- @type agentic.PartialUserConfig
opts = {
  folding = {
    tool_calls = {
      enabled = true,
      threshold = 10,
      fold_on_error = false,
    },
  },
}

Set threshold = 0 to always fold completed calls, and failed calls when
fold_on_error = true. Negative values are clamped to 0. Set enabled = false
to disable folding entirely.

The fold hides the body only - the tool call header and completion status remain
visible. Use standard Vim fold commands (za, zo, zc) to toggle individual
folds, or zR/zM to open/close all folds in the chat window.

Tool Call Titles

Long non-diff titles for configured tool call kinds are truncated in the header
and shown in full as the first body block.

--- @type agentic.PartialUserConfig
opts = {
  tool_calls = {
    title = {
      max_length = 50,
      truncate_title_kinds = {
        "execute",
        "think",
        "SubAgent",
        "fetch",
        "search",
      },
    },
  },
}

Only truncate_title_kinds are affected by max_length. Titles longer than
max_length are truncated to max_length bytes plus ...; the full title is
rendered in the folded body. Set max_length = 0 to disable title truncation.
Negative values are clamped to 0. Diff tool calls keep full header-only titles.

🚀 Usage (Public Lua API)

Commands

Function Description
:lua require("agentic").toggle() Toggle chat sidebar
:lua require("agentic").open() Open chat sidebar (keep open if already visible)
:lua require("agentic").close() Close chat sidebar
:lua require("agentic").add_selection() Add visual selection to context
:lua require("agentic").add_file() Add current file to context
:lua require("agentic").add_selection_or_file_to_context() Add selection (if any) or file to the context
:lua require("agentic").add_files_to_context(opts) Add a list of file paths or buffer numbers to context
:lua require("agentic").add_current_line_diagnostics() Add diagnostics at cursor line to context
:lua require("agentic").add_buffer_diagnostics() Add all diagnostics from current buffer to context
:lua require("agentic").new_session() Start new chat session, destroying and cleaning the current one
:lua require("agentic").stop_generation() Stop current generation or tool execution (session stays active)
:lua require("agentic").restore_session() Show provider's session picker to restore a previous session
:lua require("agentic").restore_session_by_id(session_id) Restore a session by its ID
:lua require("agentic").switch_provider() Switch ACP provider mid-session (shows picker, preserves history)
:lua require("agentic").rotate_layout() Rotate window position through layouts (right → bottom → left)

Optional Parameters

Open and Toggle supports optional parameter:

  • auto_add_to_context (boolean, default: true) - Whether to automatically
    add the current visual selection or file to context when opening the Chat
-- Open the chat without adding anything to context
require("agentic").open({ auto_add_to_context = false })

When adding files or selections to context, you can also specify whether to
focus the prompt input after opening the chat:

  • focus_prompt (boolean, default: true) - Whether to move cursor to prompt
    input after opening the chat

Available on: add_selection(opts), add_file(opts),
add_selection_or_file_to_context(opts), add_files_to_context(opts),
add_current_line_diagnostics(opts), add_buffer_diagnostics(opts)

-- Add selection without focusing the prompt
require("agentic").add_selection({ focus_prompt = false })

add_files_to_context(opts) accepts a files field with a list of file paths
(strings) or buffer numbers (integers). It can be used from anywhere, like your
file picker.

-- Add specific files by path
require("agentic").add_files_to_context({
  files = {
    "src/main.lua",
    "src/utils.lua",
  },
})

-- Add files by buffer number
require("agentic").add_files_to_context({
  files = { 1, 5 },
  focus_prompt = false,
})

restore_session_by_id(session_id) accepts a session_id argument with the
ID of the session you want to restore. Session IDs come from your provider's
session storage (e.g. provider logs, project metadata, or scripts that track
them). Unlike restore_session(), this does not require the provider to support
listing sessions.

-- Restore a session by ID
require("agentic").restore_session_by_id("58e5cf8a-1277-4e43-bc29-10c1246a2c66")

Built-in Keybindings

These keybindings are automatically set in Agentic buffers:

Keybinding Mode Description
<S-Tab> n/v/i Switch agent mode (only available if provider supports modes)
<CR> n Submit prompt
<C-s> n/v/i Submit prompt
<localLeader>p n Paste image from clipboard in the Prompt buffer
<C-v> i Paste image from clipboard (same as Claude-code)
<localLeader>s n Switch ACP provider (preserves chat history)
<localLeader>m n Switch model without (preserves chat history)
<localLeader>t n Select thought effort level (model-dependent on Claude)
q n Close chat widget
d n Remove file, code selection, or diagnostic at cursor
d v Remove multiple selected files, code selections, or diagnostics
]] n Navigate to next chat heading
[[ n Navigate to previous chat heading
]t n Navigate to next tool call
[t n Navigate to previous tool call
]c n Navigate to next diff hunk (when diff preview is active)
[c n Navigate to previous diff hunk (when diff preview is active)

Customizing Keybindings

You can customize the default keybindings by configuring the keymaps option in
your setup:

{
  "carlos-algms/agentic.nvim",
  --- @type agentic.PartialUserConfig
  opts = {
    keymaps = {
      -- Keybindings for ALL buffers in the widget (chat, prompt, code, files)
      widget = {
        close = "q",  -- String for a single keybinding
        change_mode = {
          {
            "<S-Tab>",
            mode = { "i", "n", "v" },  -- Specify modes for this keybinding
          },
        },
        switch_provider = "<localLeader>s",  -- Switch ACP provider
        switch_model = "<localLeader>m",     -- Switch model
        change_thought_level = "<localLeader>t",  -- Select thought effort level
      },

      -- Keybindings for the prompt buffer only
      prompt = {
        submit = {
          "<CR>",  -- Normal mode, just Enter
          {
            "<C-s>",
            mode = { "n", "v", "i" },
          },
        },

        paste_image = {
          {
            "<localLeader>p",
            mode = { "n" },
          },
          {
            "<C-v>", -- Same as Claude-code in insert mode
            mode = { "i" },
          }
        },
      },

      -- Keybindings for chat buffer navigation
      chat = {
        next_heading = "]]",
        prev_heading = "[[",
        next_tool_call = "]t",
        prev_tool_call = "[t",
      },

      -- Keybindings for diff preview navigation
      diff_preview = {
        next_hunk = "]c",
        prev_hunk = "[c",
      },

      -- Keybindings to cycle focus between pending permission blocks.
      -- Once a block is focused, per-block keys cycle the stacked button
      -- rows (one button per row, rendered between bottom_pad and the
      -- status row):
      --   h / <Left> / k / <Up>    : focus previous button
      --   l / <Right> / j / <Down> : focus next button
      --   <CR>                     : submit focused button
      --   1..4                     : submit option N directly
      -- Per-block keys only fire while a block is focused.
      permission = {
        cycle_next = "<C-n>",
        cycle_prev = "<C-p>",
      },
    },
  },
}

Keymap Configuration Format:

  • String: close = "q" - Simple keybinding (normal mode by default)
  • Array: submit = { "<CR>", "<C-s>" } - Multiple keybindings (normal mode
    only)
  • Table with mode: { "<C-s>", mode = { "i", "v" } } - Keybinding with
    specific modes

The header text in the chat and prompt buffers will automatically update to show
the appropriate keybinding for the current mode.

Diff Preview

When the agent makes file edits, agentic.nvim can show a preview of the changes
before you accept or reject them. You can configure the diff preview layout:

{
  "carlos-algms/agentic.nvim",
  --- @type agentic.PartialUserConfig
  opts = {
    diff_preview = {
      enabled = true,
      layout = "split",  -- "split" or "inline"
      center_on_navigate_hunks = true,
    },
  },
}

Layout Options:

  • "split" (default) - Side-by-side diff view
  • "inline" - Unified diff view in a single buffer

Navigation:

Use ]c and [c to navigate between diff hunks (configurable).

Note: Changing the layout requires restarting Neovim.

Slash Commands

Type / in the Prompt buffer to see available slash commands with
auto-completion.

The /new command is always available to start a new session, other commands
are provided by your ACP provider.

File Picker

You can reference and add files to the context by typing @ in the Prompt.
It will trigger the native Neovim completion menu with a list of all files in
the current workspace.

  • Automatic scanning: Uses rg, fd, git ls-files, or lua globs as
    fallback
  • Fuzzy filtering: uses Neovim's native completion to filter results as you
    type
  • Multiple files: You can reference multiple files in one prompt:
    @file1.lua @file2.lua

Image and Screenshots support

You can drag-and-drop images into the Prompt buffer or paste images and
screenshots directly from your clipboard.

The support still depends on the ACP provider capabilities, but most of them
support images in the conversation.

Drag-and-drop should work out of the box if your terminal supports it, no need
for extra configuration or plugins.
In SSH/headless sessions, image paste and drag-and-drop usually do not reach
remote Neovim, terminal and protocol limitations.
Agentic does not copy local files into the remote filesystem; upload the image
first with scp, SFTP, or your usual file-transfer workflow, then attach the
remote file path using the @... notation.

Pasting screenshots from your clipboard works out of the box on macOS, Windows,
and WSL when Windows interop and wslpath are available. On Linux, you need one
small CLI dependency:

  • macOS: no extra install. Uses the system osascript.
  • Windows: no extra install. Uses the bundled powershell.exe.
  • WSL: no extra install when Windows interop and wslpath are available.
  • Linux (Wayland): install wl-clipboard (provides wl-paste).
    • Debian/Ubuntu: sudo apt install wl-clipboard
    • Arch: sudo pacman -S wl-clipboard
    • Fedora: sudo dnf install wl-clipboard
  • Linux (X11): install xclip.
    • Debian/Ubuntu: sudo apt install xclip
    • Arch: sudo pacman -S xclip
    • Fedora: sudo dnf install xclip

Then just press <localleader>p in the Prompt buffer to paste the image from
your clipboard.

Session Restoration

Sessions are interchangeable between Neovim and the terminal. Start a
conversation in your terminal CLI, then load it in Neovim — or the other way
around. Your ACP provider manages sessions natively, so they're available
everywhere the provider runs.

Restoring sessions:

Call require("agentic").restore_session() to:

  1. See a list of previous sessions from your provider for the current project
    (including sessions started in the terminal)
  2. Select a session to restore the full conversation history

If you know the session ID, call
require("agentic").restore_session_by_id(session_id) to restore a specific
session directly. This skips listing sessions, so it also works with providers
that don't support session listing.

Conflict handling:

If you try to restore a session when the current tab already has an active
conversation, you'll be prompted to:

  • Cancel the restoration (keep current session)
  • Clear current session and restore the selected one

System Information

Agentic automatically includes environment and project information in the first
message of each session:

  • Platform information (OS, version, architecture)
  • Shell and Neovim version
  • Current date
  • Git repository status (if applicable):
    • Current branch
    • Changed files
    • Recent commits (last 3)
  • Project root path

This helps the AI Agent understand the context of the current project without
having to run additional commands or grep through files, the goals is to reduce
time for the first response.

Event Hooks

Agentic.nvim provides hooks that let you respond to specific events during the
chat lifecycle. These are useful for logging, notifications, analytics, or
integrating with other plugins.

{
  "carlos-algms/agentic.nvim",
  --- @type agentic.PartialUserConfig
  opts = {
    hooks = {
      -- Called when a new ACP session is created (or fails to create).
      -- Fires on both success and failure; check `data.err` first.
      on_create_session_response = function(data)
        -- data.session_id: string|nil - The ACP session ID (nil if err is set)
        -- data.tab_page_id: number - The Neovim tabpage ID
        -- data.response: table|nil - The ACP session creation response
        --   (nil if err is set)
        -- data.err: table|nil - Error details if session creation failed
        if data.err then
          vim.notify(
            "Session failed: " .. vim.inspect(data.err),
            vim.log.levels.ERROR
          )
          return
        end
        vim.notify("New session: " .. data.response.sessionId)

        -- Reset the agentic_usage tabpage var (set by the on_session_update
        -- example below) so a new session starts with a clean usage counter.
        if vim.api.nvim_tabpage_is_valid(data.tab_page_id) then
          vim.t[data.tab_page_id].agentic_usage = nil
        end
      end,

      -- Called when the user submits a prompt
      on_prompt_submit = function(data)
        -- data.prompt: string - The user's prompt text
        -- data.session_id: string - The ACP session ID
        -- data.tab_page_id: number - The Neovim tabpage ID
        vim.notify("Prompt submitted: " .. data.prompt:sub(1, 50))
      end,

      -- Called when the agent finishes responding
      on_response_complete = function(data)
        -- data.session_id: string - The ACP session ID
        -- data.tab_page_id: number - The Neovim tabpage ID
        -- data.success: boolean - Whether response completed without error
        -- data.error: table|nil - Error details if failed
        if data.success then
          vim.notify("Agent finished!", vim.log.levels.INFO)
        else
          vim.notify("Agent error: " .. vim.inspect(data.error), vim.log.levels.ERROR)
        end
      end,

      -- Called when the session is updated.
      on_session_update = function(data)
        -- data.session_id: string - The ACP session ID
        -- data.tab_page_id: number - The Neovim tabpage ID
        -- data.update: table -- The update

          if data.update.sessionUpdate == "usage_update" then
            -- Use this in your status line, scoped per tab/session.
            if vim.api.nvim_tabpage_is_valid(data.tab_page_id) then
              vim.t[data.tab_page_id].agentic_usage = {
                used = data.update.used,
                size = data.update.size,
              }
            end
          end
      end,

      -- Called after Agentic writes to a file (file-mutating tool call completed).
      -- Note: mutating the file here (e.g. formatters that save) can cause the
      -- agent to re-read or retry edits on its next action.
      on_file_edit = function(data)
        -- data.filepath: string - Absolute path to the edited file
        -- data.session_id: string - The ACP session ID
        -- data.tab_page_id: number - The Neovim tabpage ID
        -- data.bufnr: number|nil - Buffer number if the file is loaded
        if data.bufnr then
          vim.lsp.buf.format({ bufnr = data.bufnr, timeout_ms = 5000 })
        end
      end,

      -- Called when the agent needs permission to execute a tool (e.g. shell command).
      -- Fires for each pending permission request.
      on_request_permission = function(data)
        -- data.request: table - The ACP permission request object
        -- data.request.toolCall: table - contains .kind, .title, etc.
        -- data.session_id: string - The ACP session ID
        -- data.tab_page_id: number - The Neovim tabpage ID
        local tool = data.request.toolCall
        local label = tool.title or tool.kind or "action"
        vim.notify("Agent needs permission for: " .. label)
      end,
    }
  }
}

🍚 Customization (Ricing)

Agentic.nvim uses custom highlight groups that you can override to match your
colorscheme.

Available Highlight Groups

Highlight Group Purpose Default
AgenticDiffDelete Deleted lines in diff view Links to DiffDelete
AgenticDiffAdd Added lines in diff view Links to DiffAdd
AgenticDiffDeleteWord Word-level deletions in diff bg=#9a3c3c, bold=true
AgenticDiffAddWord Word-level additions in diff bg=#155729, bold=true
AgenticStatusPending Pending tool call status indicator bg=#5f4d8f
AgenticStatusCompleted Completed tool call status indicator bg=#2d5a3d
AgenticStatusFailed Failed tool call status indicator bg=#7a2d2d
AgenticPermissionButtonAllow Focused button (allow kind) bg=#2d5a3d, bold=true
AgenticPermissionButtonReject Focused button (reject kind) bg=#7a2d2d, bold=true
AgenticPermissionButtonInactive Non-focused permission button bg=#3a3a3a
AgenticCodeBlockFence The left border decoration on tool calls Links to Directory
AgenticTitle Window titles in sidebar bg=#2787b0, fg=#000000, bold=true
AgenticThinking Thinking block text in chat buffer Links to Comment

If any of these highlight exists, Agentic will use it instead of creating new
ones.

Customizing Diagnostic Icons

You can customize the icons used for diagnostics in the context panel:

{
  "carlos-algms/agentic.nvim",
  --- @type agentic.PartialUserConfig
  opts = {
    diagnostic_icons = {
      error = "❌",    -- Diagnostic severity: error
      warn = "⚠️",     -- Diagnostic severity: warning
      info = "ℹ️",      -- Diagnostic severity: information
      hint = "✨",     -- Diagnostic severity: hint
    },
  },
}

Default icons use emoji characters (❌, ⚠️, ℹ️, ✨) but you can use any string,
including Nerd Font icons or plain text.

Customizing Status Icons

You can customize the icons used to indicate tool call status in the chat:

{
  "carlos-algms/agentic.nvim",
  --- @type agentic.PartialUserConfig
  opts = {
    status_icons = {
      pending = "󰔛",      -- Tool call awaiting execution
      in_progress = "󰔛",  -- Tool currently executing
      completed = "✔",    -- Tool executed successfully
      failed = "",       -- Tool execution failed
    },
  },
}

Customizing Permission Icons

You can customize the icons used in the permission approval workflow:

{
  "carlos-algms/agentic.nvim",
  --- @type agentic.PartialUserConfig
  opts = {
    permission_icons = {
      allow_once = "",    -- Allow this execution only
      allow_always = "",  -- Allow all future executions
      reject_once = "",    -- Reject this execution only
      reject_always = "󰜺",  -- Reject all future executions
    },
  },
}

Customizing Chat Icons

You can customize the icons used to identify user and agent messages in the
chat:

{
  "carlos-algms/agentic.nvim",
  --- @type agentic.PartialUserConfig
  opts = {
    chat_icons = {
      user = " ",    -- Icon shown for user messages
      agent = "󱚠 ",  -- Icon shown for agent/AI messages
    },
  },
}

Customizing Message Icons

You can customize the icons used for messages and interaction states:

{
  "carlos-algms/agentic.nvim",
  --- @type agentic.PartialUserConfig
  opts = {
    message_icons = {
      thinking = "🧠",   -- Shown when the agent is thinking/reasoning
      finished = "🏁",   -- Shown when the interaction completes successfully
      stopped = "🛑",     -- Shown when the user cancels the generation
      error = "❌",      -- Shown when the interaction ends with an error
    },
  },
}

Integration with other Plugins

Prompt suggestions with Copilot

To get Copilot suggestions while you are typing your prompt, you need to tell
Copilot to attach to the AgenticInput filetype.

copilot.vim

{
  "github/copilot.vim",
   -- ....
  init = function()
      vim.g.copilot_filetypes = {
          AgenticInput = true,
      }
  end,
}

copilot.lua

{
  "zbirenbaum/copilot.lua",
  -- ....
  opts = {
    -- Override should_attach to allow copilot in AgenticInput buffers
    -- AgenticInput uses buftype = "nofile" which copilot.lua rejects by default
    should_attach = function(bufnr, bufname)
      local filetype = vim.bo[bufnr].filetype

      if filetype == "AgenticInput" then
          return true
      end

      -- Delegate to default behavior for all other buffers
      local default_should_attach =
          require("copilot.config.should_attach").default
      return default_should_attach(bufnr, bufname)
    end,
  },
}

Lualine

If you're using lualine.nvim or
similar statusline plugins, configure it to ignore Agentic windows to prevent
conflicts with custom window decorations:

require('lualine').setup({
  options = {
    disabled_filetypes = {
      statusline = { 'AgenticChat', 'AgenticInput', 'AgenticCode', 'AgenticFiles', 'AgenticDiagnostics' },
      winbar = { 'AgenticChat', 'AgenticInput', 'AgenticCode', 'AgenticFiles', 'AgenticDiagnostics' },
    }
  }
})

This ensures that Agentic's custom window titles and statuslines render
correctly without interference from your statusline plugin.

Markdown render plugins

Only the AgenticChat buffer is properly set as markdown and starts
Treesitter parser, you only need to mention it in your markdown render plugin
setup.

{
  "MeanderingProgrammer/render-markdown.nvim",
  -- ...
  opts = {
    file_types = { "markdown", "md", "AgenticChat" },
  }
}

Blink.cmp

You can disable blink.cmp from attaching to Agentic prompt buffers by adding
the following to your blink.cmp setup:

require('blink.cmp').setup({
  enabled = function()
    return not vim.tbl_contains({"AgenticInput"}, vim.bo.filetype)
  end,
})

Alternatively, you can disable Agentic's built-in autocomplete and let blink.cmp handle slash command and file picker completions in the prompt buffer:

{
  "carlos-algms/agentic.nvim",
  opts = {
    slash_commands = {
      auto_trigger = false,
    },
    file_picker = {
      auto_trigger = false,
    },
  },
}
{
  'saghen/blink.cmp',
  version = '1.*',
  opts = {
    -- ...
    completion = {
      menu = {
        draw = {
          components = {
            -- Increase the label description width to show more of the slash
            -- command descriptions
            label_description = {
              width = { max = 100 },
            },
          },
        },
      },
    },
    sources = {
      per_filetype = {
        -- You can also enable copilot here if you want copilot suggestions in the Prompt buffer
        AgenticInput = { 'agentic_slash', 'agentic_at' },
      },
      providers = {
        agentic_slash = {
          module = 'blink.cmp.sources.complete_func',
          name = 'AgenticSlash',
          -- Detect / at the start of the prompt input to trigger slash command completions
          enabled = function()
            local cursor = vim.api.nvim_win_get_cursor(0)
            if cursor[1] ~= 1 then return false end
            local before = vim.api.nvim_get_current_line():sub(1, cursor[2])
            return before:match('^/[^%s]*$') ~= nil
          end,
          opts = { complete_func = function() return "v:lua.require'agentic.acp.slash_commands'.complete_func" end },
          -- Fix output by removing / added in label details
          transform_items = function(_, items)
            for _, item in ipairs(items) do
              if item.labelDetails then
                item.labelDetails.detail = nil
              end
            end
            return items
          end,
        },
        agentic_at = {
          module = 'blink.cmp.sources.complete_func',
          -- Detect @ is before the cursor to trigger file picker completions
          name = 'AgenticAt',
          enabled = function()
            local col = vim.api.nvim_win_get_cursor(0)[2]
            local before = vim.api.nvim_get_current_line():sub(1, col)
            return (before:match('^@[^%s]*$') or before:match('[%s]@[^%s]*$')) ~= nil
          end,
          opts = { complete_func = function() return "v:lua.require'agentic.ui.file_picker'.complete_func" end },
          -- Fix output by removing @ added in label details
          transform_items = function(_, items)
            for _, item in ipairs(items) do
              if item.labelDetails then
                item.labelDetails.detail = nil
              end
            end
            return items
          end,
        },
      },
    },
  },
}

nvim-cmp

You can disable nvim-cmp from attaching to Agentic prompt buffers by using
filetype-specific setup or the enabled option:

-- Option 1: Filetype-specific setup (disable all sources)
require('cmp').setup.filetype('AgenticInput', {
  sources = {}
})

-- Option 2: Global enabled function
require('cmp').setup({
  enabled = function()
    return not vim.tbl_contains({"AgenticInput"}, vim.bo.filetype)
  end,
})

❤️ Sponsor

If agentic.nvim makes your day better, consider sponsoring development. Pick
whichever channel you prefer - all of them help equally.

GitHub Sponsors
Patreon
Buy Me a Coffee
Corporate Sponsor

🏢 For companies

Does your company have the budget to sponsor open source?

Sponsoring agentic.nvim gets your team:

  • Logo placement in this README
  • Direct line to the maintainer
  • Priority consideration on issues affecting your workflow

Reach out via GitHub Sponsors or
open an issue to
discuss custom terms.

🔧 Development

Health Check

Verify your installation and dependencies:

:checkhealth agentic

This will check:

  • Neovim version (≥ 0.11.0 required)
  • Current ACP provider installation (We don't install them for security reasons)
  • Optional ACP providers (so you know which ones are available and can use at
    any time)
  • Clipboard image paste tooling (powershell.exe, wslpath, wl-paste, or
    xclip)
  • Node.js and package managers (Most of the ACP CLIs require Node.js to install
    and run, some have native binaries too, we don't have control over that, it up
    to the Creators)

Debug Mode

Enable debug logging to troubleshoot issues:

{
   "carlos-algms/agentic.nvim",
    --- @type agentic.PartialUserConfig
    opts = {
      debug = true,
      -- ... rest of your options
    }
}

View debug logs with :messages (lost after restarting Neovim)

View messages exchanged with the ACP provider in the log file at:
(persistent until you delete it)

  • ~/.cache/nvim/agentic_debug.log

📚 Resources

📄 License

MIT License
Feel free to copy, modify, and distribute, just be a good samaritan and include
the the acknowledgments 😊.

🙏 Acknowledgments

Yorumlar (0)

Sonuc bulunamadi