{"id":50065245,"url":"https://github.com/ray-x/copilot-agent.nvim","last_synced_at":"2026-07-07T12:01:54.770Z","repository":{"id":353897936,"uuid":"1221339736","full_name":"ray-x/copilot-agent.nvim","owner":"ray-x","description":"An autonomous orchestrator for the Copilot Go SDK in Neovim, delivering a native, agentic coding experience.","archived":false,"fork":false,"pushed_at":"2026-06-03T05:58:16.000Z","size":3375,"stargazers_count":14,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-27T16:41:41.371Z","etag":null,"topics":["agent","agentic-coding","agentic-workflow","ai-agent","ai-coding","copilot","copilot-cli","copilot-sdk","github-copilot","neovim","nvim"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ray-x.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-26T04:17:10.000Z","updated_at":"2026-06-03T05:57:38.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ray-x/copilot-agent.nvim","commit_stats":null,"previous_names":["ray-x/copilot-agent.nvim"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/ray-x/copilot-agent.nvim","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ray-x%2Fcopilot-agent.nvim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ray-x%2Fcopilot-agent.nvim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ray-x%2Fcopilot-agent.nvim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ray-x%2Fcopilot-agent.nvim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ray-x","download_url":"https://codeload.github.com/ray-x/copilot-agent.nvim/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ray-x%2Fcopilot-agent.nvim/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35226918,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-07T02:00:07.222Z","response_time":90,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent","agentic-coding","agentic-workflow","ai-agent","ai-coding","copilot","copilot-cli","copilot-sdk","github-copilot","neovim","nvim"],"created_at":"2026-05-21T23:00:21.360Z","updated_at":"2026-07-07T12:01:54.752Z","avatar_url":"https://github.com/ray-x.png","language":"Lua","funding_links":[],"categories":["AI"],"sub_categories":["Diagnostics"],"readme":"# copilot-agent.nvim\n\nGitHub Copilot's agentic runtime, natively in Neovim. A lightweight Go bridge to the [official SDK](https://github.com/github/copilot-sdk) with native tool execution, four chat modes, session-aware permissions, persistent sessions, repository-local agent/skill discovery, and LSP code actions.\n\n## Demo video\n\nOne minute video to create a terminal version of flappy bird:\n\u003cvideo src=\"https://gist.github.com/user-attachments/assets/5091ddcb-84f8-4c1a-b8a7-ea4bef6393f4\" controls width=\"70%\"\u003e\u003c/video\u003e\n\n## Key Capabilities\n\n| Feature                       | Technical Highlight                                                         |\n| :---------------------------- | :-------------------------------------------------------------------------- |\n| **Autonomous SDK Loop**       | Native file I/O, terminal execution, and web search via official Go SDK.    |\n| **State Rewind**              | Undo/Restore codebase and session to any previous conversation point.       |\n| **Session Continuity**        | Resume sessions across Neovim, VS Code, and CLI with shared metadata.       |\n| **LSP-Native**                | AI-driven 'Fix', 'Test', and 'Explain' via standard `code_action` triggers. |\n| **Autopilot Modes**           | Four levels of oversight, from per-step approval to full autonomy.          |\n| **Project Intelligence**      | Automatic discovery of `.github/agents` and `.github/skills` configs.       |\n| **Integrate to nvim plugins** | review changes in Diffview; commit with fugitive and more                   |\n| **Live Observability**        | Async statusline and streaming UI for sub-agent tracking and token usage.   |\n\n---\n\n### Agent Tool Loop\n\nThe agentic loop is what makes this plugin different from simple chat wrappers. The assistant doesn't just answer; it acts: reading files, fetching web pages, running commands, writing code, and iterating until the task is done.\n\n## Architecture\n\n```mermaid\nflowchart TD\n    subgraph Neovim[\"Neovim (Lua plugin)\"]\n        UI[\"Chat buffer / input window\"]\n        LSPClient[\"vim.lsp (code actions)\"]\n        Cmds[\"CopilotAgent* commands\"]\n    end\n\n    subgraph GoService[\"Go HTTP service  :8088\"]\n        HTTP[\"HTTP router\\n/sessions  /models  /healthz\"]\n        SSE[\"SSE fan-out\\nsession.event  host.*\"]\n        Sessions[\"Session manager\\npermissions · tools · models\"]\n    end\n\n    subgraph LSPProcess[\"LSP-only process\"]\n        LSPServer[\"LSP server (stdio)\\ntextDocument/codeAction\\nworkspace/executeCommand\"]\n    end\n\n    subgraph SDK[\"GitHub Copilot SDK\"]\n        CopilotSDK[\"copilot-sdk/go\\nCopilot CLI / API\"]\n        Tools[\"Built-in tools\\nread_file · write_file · terminal\\nweb_search · ask_user · …\"]\n    end\n\n    UI --\u003e|\"curl POST /sessions/{id}/messages\"| HTTP\n    UI --\u003e|\"curl -N SSE stream\"| SSE\n    Cmds --\u003e|\"curl POST/DELETE\"| HTTP\n    LSPClient \u003c--\u003e|\"JSON-RPC stdio\"| LSPServer\n    LSPServer --\u003e|\"HTTP to existing service\"| HTTP\n    HTTP --\u003e Sessions\n    SSE --\u003e Sessions\n    Sessions \u003c--\u003e|\"copilot.Session\"| CopilotSDK\n    CopilotSDK --\u003e Tools\n```\n\nThe HTTP bridge and the LSP helper are separate processes. The HTTP service owns session state; `vim.lsp.start()` launches an LSP-only helper that talks to the already-running HTTP service. The Lua plugin communicates via `curl` shell-outs for all HTTP and SSE traffic.\n\n---\n\n## Comparison with Alternatives\n\n### vs CopilotChat.nvim\n\n[CopilotChat.nvim](https://github.com/CopilotC-Nvim/CopilotChat.nvim) calls the Copilot (or other) LLM REST APIs directly from Lua. It supports multiple providers but has no agent runtime of its own — tool execution and the agentic loop are implemented in Lua above the client.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e📂 Feature-by-feature comparison with CopilotChat.nvim\u003c/strong\u003e\u003c/summary\u003e\n\n| Feature                   | **copilot-agent.nvim**                                                | CopilotChat.nvim          |\n| ------------------------- | --------------------------------------------------------------------- | ------------------------- |\n| Backend                   | Official Copilot SDK (Go)                                             | Direct LLM REST API (Lua) |\n| Agent / tool-use mode     | ✅ full agentic (file edits, terminal, web search, …)                 | ❌ chat only              |\n| Chat modes                | ask · plan · **agent** · autopilot                                    | ask only                  |\n| Permission management     | ✅ interactive / approve-reads / approve-all / autopilot / reject-all | ❌                        |\n| Config discovery          | ✅ SDK-native (`.github/copilot-instructions.md`, etc.)               | ❌ manual                 |\n| Custom agents / skills    | ✅ SDK-native, same as VS Code                                        | ❌                        |\n| File \u0026 folder attachments | ✅ (buffer, selection, file, folder, image, clipboard paste)          | ✅ (buffer context❓ )    |\n| Session persistence       | ✅ per working directory                                              | ❌                        |\n| Model switching (live)    | ✅ mid-session switching                                              | ❓                        |\n| LSP code actions          | ✅ (explain / fix / add tests / add docs)                             | ❌                        |\n| MCP support               | ✅                                                                    | ❓                        |\n| Multi-provider            | ❌ (Copilot only, or Bring your own key)                              | ✅ (provider_resolver)    |\n| Dependencies              | codepilot-cli + go server                                             | Pure Lua                  |\n\nThe model picker shows each model's billing multiplier when the SDK provides one.\n\n\u003c/details\u003e\n\n**When to choose CopilotChat.nvim**: zero-binary Lua setup, just want Copilot chat with buffer context, happy with a Lua-managed tool loop.\n\n**When to choose copilot-agent.nvim**: you want the Copilot SDK owning the agent loop with native tools, permission control, and session persistence.\n\n---\n\n### vs ACP plugins (codecompanion.nvim, avante.nvim in ACP mode)\n\n[**ACP (Agent Client Protocol)**](https://agentclientprotocol.com) lets a Neovim plugin act as a client to any external CLI agent. The plugin sends prompts and streams back results; the CLI agent owns the tool execution and agentic loop. Both codecompanion.nvim and avante.nvim support ACP.\n\n`copilot-agent.nvim` is narrower in scope but deeper in Copilot integration: the Go service embeds the Copilot SDK directly, so it gets SDK-native features (config discovery, custom agents, skill directories, sub-agent streaming) that no ACP bridge can expose.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e📂 Feature-by-feature comparison with ACP-based plugins\u003c/strong\u003e\u003c/summary\u003e\n\n| Feature                       | **copilot-agent.nvim**                           | codecompanion.nvim                        | avante.nvim                            |\n| ----------------------------- | ------------------------------------------------ | ----------------------------------------- | -------------------------------------- |\n| Agent backend                 | Copilot SDK (Go, embedded)                       | ACP CLI agents or direct LLM adapters     | ACP CLI agents or direct LLM adapters  |\n| ACP support                   | ❌ (no plan)                                     | ✅ (Claude Code, Codex, Copilot CLI, …)   | ✅ (Zen Mode)                          |\n| Multi-provider / BYO API key  | ❌ (Copilot only)                                | ✅ (Anthropic, OpenAI, Gemini, Ollama, …) | ✅ (Claude, OpenAI, Gemini, Ollama, …) |\n| Tool-call execution           | SDK built-ins (file, terminal, web, ask_user …)  | Lua tools + ACP agent tools               | Rust tools + ACP agent tools           |\n| Sub-agent / streaming events  | ✅ SDK-native                                    | ❌                                        | ❌                                     |\n| MCP, agents \u0026 skill discovery | ✅                                               | ❌                                        | ❌                                     |\n| Permission management         | ✅ 4 modes, 5 permissions (e.g. plan+allow_read) | ❌                                        | ❌                                     |\n| Session Persistence           | ✅ Deep session \u0026 checkpoint resume              | ❌                                        | ❌                                     |\n| LSP code actions              | ✅ (explain / fix / add tests / add docs)        | ✅ (via prompt library)                   | ❌                                     |\n\n\u003c/details\u003e\n\n**When to choose copilot-agent.nvim**: you're committed to GitHub Copilot and want the deepest possible SDK integration: native tools, permission management, session persistence, sub-agent events, and LSP code actions, without routing through an intermediate CLI.\n\n---\n\n## Prerequisites\n\n- Go 1.24+ (only for building from source; pre-built binary skips this)\n- `curl` on `PATH`\n- GitHub Copilot CLI runtime (`@github/copilot/index.js`) or access via `-cli-url`\n- Neovim 0.12+ (with native autocomplete and LSP setup)\n\n**Optional:**\n\n- [`delta`](https://github.com/dandavison/delta) — rich diff viewer for permission \"Show diff\" (auto side-by-side for wide windows; falls back to builtin if not installed)\n- `pngpaste` / `wl-paste` / `xclip` — clipboard image paste\n- snacks.picker / telescope / fzf-lua / mini.pick — fuzzy file picker\n\nRun `:checkhealth copilot_agent` after installation to verify all requirements.\n\n\u003e [!NOTE]\n\u003e Seeing `service.command is empty — auto_start will not work` in `:checkhealth` can be a false warning when `service.command = nil` (runtime auto-detection). The plugin can still auto-detect `\u003cplugin_root\u003e/bin/copilot-agent` or fall back to `go run .` at runtime.\n\n---\n\n## Installation\n\n### Step 1 — Download the pre-built binary (recommended)\n\nRun this command inside Neovim after installing the plugin:\n\n```\n:CopilotAgentInstall\n```\n\nThis downloads the correct binary for your platform from the\n[latest GitHub release](https://github.com/ray-x/copilot-agent.nvim/releases/tag/latest)\nand saves it to `\u003cplugin_root\u003e/bin/copilot-agent` (or `copilot-agent.exe` on Windows).\nNo Go toolchain required.\n\nSupported platforms:\n\n| Platform            | Binary                            |\n| ------------------- | --------------------------------- |\n| Linux x86_64        | `copilot-agent-linux-amd64`       |\n| Linux aarch64       | `copilot-agent-linux-arm64`       |\n| Windows x86_64      | `copilot-agent-windows-amd64.exe` |\n| Windows aarch64     | `copilot-agent-windows-arm64.exe` |\n| macOS Apple Silicon | `copilot-agent-darwin-arm64`      |\n\nYou can also download manually from the\n[releases page](https://github.com/ray-x/copilot-agent.nvim/releases/tag/latest)\nand place it anywhere; then set `service.command = { \"/path/to/copilot-agent\" }`.\n\nOn Windows, the plugin automatically switches its local control channel from a Unix socket to a loopback TCP listener, so you do not need MSYS2 just to make the service start.\n\n### Step 2 — Plugin setup with lazy.nvim\n\nFor most users, this minimal setup is enough:\n\n```lua\n{\n  \"ray-x/copilot-agent.nvim\",\n  build = \":CopilotAgentInstall\",\n  opts = function()\n    require(\"copilot_agent\").setup({\n      -- lsp = { enabled = true }, -- auto-starts the helper LSP from setup(); call start_lsp() only for explicit/delayed startup\n    })\n  end,\n}\n```\n\n`service.auto_start` defaults to `true`. For backward compatibility, a top-level `auto_start = ...` in `setup()` is still accepted and mapped to `service.auto_start` unless you explicitly set `service.auto_start`.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e📂 Full setup example with common options\u003c/strong\u003e\u003c/summary\u003e\n\n```lua\n{\n  \"ray-x/copilot-agent.nvim\",\n  build = \":CopilotAgentInstall\",\n  config = function()\n    require(\"copilot_agent\").setup({\n      -- When auto_start=true the plugin connects to the shared Go service if\n      -- one already exists, otherwise it starts exactly one and reads its\n      -- port from stderr automatically. No manual base_url needed.\n      base_url = \"http://127.0.0.1:8088\",  -- only for externally-started services\n      client_name = \"nvim-copilot\",\n      default_provider = \"copilot\", -- or \"claude\"; Claude/LiteLLM uses ANTHROPIC_* from Neovim (or service.env) on session create/resume\n      permission_mode = \"approve-all\",  -- \"interactive\" | \"approve-all\" | \"autopilot\" | \"reject-all\"\n      auto_create_session = true,\n      lsp = {\n        enabled = true, -- auto-start the helper LSP from setup()\n      },\n      session = {\n        working_directory = function() return vim.fn.getcwd() end,\n        model = nil,    -- nil = Copilot picks a default\n        agent = nil,    -- nil = \"default\"; or \"coding\", \"gpt-4.1\", a custom agent name\n        streaming = true,\n        enable_config_discovery = true,  -- respects .github/copilot-instructions.md etc.\n        replay_permission_history = false,  -- false (default) skips permission replay on resume for faster session loads\n        history_turn_limit = 256,       -- only replay the most recent N turns when opening a large session\n        history_activity_turn_limit = 64, -- keep detailed activity only for the most recent N turns (\u003c= history_turn_limit)\n        history_preview_chars = 120,    -- truncation length for summarized historical activity/tool outputs\n        auto_resume = \"prompt\",  -- \"prompt\" (default) | \"auto\" — when multiple sessions exist\n      },\n      service = {\n        auto_start = true,\n        -- command = nil means auto: uses \u003cplugin_root\u003e/bin/copilot-agent if present,\n        -- otherwise falls back to { \"go\", \"run\", \".\" } (requires Go toolchain).\n        command = nil,\n        cwd = nil,                         -- defaults to \u003cplugin_root\u003e/server\n        detach = true,                     -- default: reuse one detached background service across Neovim instances\n        port_range = nil,                  -- e.g. \"18000-19000\" for fixed range\n        log = {\n          enabled = false,                 -- set true to enable Go service file logging\n          path = nil,                     -- nil = stdpath(\"state\") .. \"/copilot-agent-service.log\"\n        },\n        startup_timeout_ms = 15000,\n        startup_poll_interval_ms = 250,\n      },\n      chat = {\n        title = \"Copilot Chat\",\n        system_notify_timeout = 3000,    -- ms before auto-clearing transient notices\n        render_markdown = true,          -- set false to disable render-markdown.nvim (faster on long playbacks)\n        protect_markdown_buffer = true,  -- upstream Neovim Treesitter workaround for the prompt buffer; set false to disable\n        diff_cmd = { 'delta' },          -- external diff viewer; false = builtin float\n        diff_review = true,              -- offer vimdiff after agent modifies a git-tracked file; clean buffers auto-reload, conflicting modified buffers prompt before reload\n        activity_view = 'hover',         -- 'hover' (default) opens a read-only preview via K (or CursorHold when enabled); 'diff' opens editable file diffs on \u003cCR\u003e; 'raw' keeps the patch-text viewer\n        activity_diff_tool = 'native',   -- 'native', 'diffview', 'fugitive', or a custom Vim command name\n        -- Hover \u0026 preview controls:\n        -- activity_hover_key: string (default: 'K') - key to toggle the read-only hover preview when activity_view='hover' while keeping focus in chat.\n        -- activity_hover_focus_key: string (default: 'gK') - key to move focus into the current hover preview (opens it first if needed).\n        -- activity_hover_cursor_hold: boolean (default: false) - when true, show hover on CursorHold/CursorHoldI instead of the hover key.\n        -- activity_hover_timeout_ms: number (default: 2500) - auto-close timeout for hover preview in milliseconds (\u003c=0 disables auto-close).\n      },\n      prompt = {\n        style = \"cold\",                  -- \"cold\" (default) = red-violet/violet/blue, \"warm\" = red/yellow/green\n      },\n      compose = {\n        width = 0.4,                     -- left split width; fraction of chat width, or absolute columns\n        min_width = 40,\n        max_width = 100,\n        promote_keymap = \"\u003cleader\u003ecc\",   -- set false to disable the prompt-buffer promotion mapping\n      },\n      statusline = {\n        enabled = false,                 -- default: keep plugin-owned chat/input local statuslines disabled\n        components = {                   -- default: all true\n          mode = true,\n          permission = true,\n          busy = true,\n          session = true,\n          model = true,\n          tool = true,\n          intent = true,\n          context = true,\n          config = true,\n          attachments = true,\n          help = true,\n        },\n      },\n      notify = true,  -- set false to silence all [copilot-agent] vim.notify calls\n      file_log_level = \"WARN\",  -- TRACE | DEBUG | INFO | WARN | ERROR; TRACE logs raw host/session payloads, DEBUG logs plugin actions and HTTP details to stdpath(\"log\") .. \"/copilot_agent.log\"\n      file_log_batch = {\n        enabled = true,            -- queue file-log writes and flush in batches\n        flush_interval_ms = 2000,  -- flush pending log lines at least every 2 seconds\n        max_entries = 20,          -- flush immediately when queue reaches this size\n      },\n    })\n    -- Start the combined HTTP + LSP service.\n    -- lsp.enabled = true already starts the helper automatically from setup().\n    -- Call explicitly here only if you want immediate or delayed startup control:\n    require(\"copilot_agent\").start_lsp()\n  end,\n}\n```\n\n`file_log_batch` controls buffered file logging behavior. Set `enabled = false` to restore immediate per-line writes.\n\n`service.log.enabled` defaults to `false`. When enabled, `service.log.path` overrides the log file location; when `path` is `nil`, the default is `stdpath(\"state\") .. \"/copilot-agent-service.log\"`.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e📂 Advanced service command and isolation examples\u003c/strong\u003e\u003c/summary\u003e\n\nIf you want to point at a binary in a custom location:\n\n```lua\n-- Dynamic port (recommended for multiple nvim instances)\nservice = { auto_start = true, command = { \"/path/to/copilot-agent\" } }\n\n-- Fixed port\nservice = { auto_start = true, command = { \"/path/to/copilot-agent\", \"--addr\", \"127.0.0.1:8088\" } }\n\n-- Port range (first free port in 18000–19000)\nservice = { auto_start = true, command = { \"/path/to/copilot-agent\" }, port_range = \"18000-19000\" }\n```\n\nWhen the plugin starts the service on Windows, it appends a localhost control address automatically (`--control-addr 127.0.0.1:0`) unless you already provided `--control-addr` or `--control-socket` yourself. Keep `service.command` as a list/table so those flags can be added.\n\n**Global service vs isolated instances**\n\nBy default, `auto_start = true` connects to the shared service if it is already running, otherwise it starts a single detached background service for your user account. In managed mode, the plugin first discovers the live HTTP address via the local control endpoint (`copilot-agent.sock` / `--control-addr`), then falls back to `stdpath(\"state\") .. \"/copilot-agent.addr\"` only when that saved address still belongs to a live shared service. Session resume is still matched by `session.working_directory`, but the service process and persisted session catalog are global by default. On quit, the last Neovim instance now requests detached-service shutdown in the background so exit does not wait on a slow control socket.\n\nThe helper LSP reuses that same shared service; it does not spawn a separate Copilot backend.\n\nIf you want **per-project isolation**, pin a project-specific address and disable detaching:\n\n```lua\nrequire(\"copilot_agent\").setup({\n  base_url = \"http://127.0.0.1:18121\",\n  session = {\n    working_directory = function() return vim.fn.getcwd() end,\n  },\n  service = {\n    auto_start = true,\n    detach = false,\n    port_range = \"18121-18121\",\n  },\n})\n```\n\nReuse the same stable port when reopening the same project later. If you open multiple isolated projects at the same time, each one needs its own port.\n\n\u003c/details\u003e\n\n---\n\n## Running the Service Manually\n\nSee [server/README.md](server/README.md#running-the-service-manually) for manual startup, build flags, and service runtime details.\n\n### Startup troubleshooting\n\n- A `copilot-agent` binary alone is not enough: the GitHub Copilot CLI runtime must also be resolvable (`-cli-path`, environment, or `PATH`).\n- GUI Neovim launches (Finder/Spotlight/app launchers) often have a different `PATH` than terminal shells. If startup fails there but works in terminal Neovim, set explicit paths in your config (`service.command`, service env vars, or CLI path env) and re-run `:checkhealth copilot_agent`.\n\n---\n\n## Commands\n\nUse `:CopilotAgentDashboard` or `:CopilotAgentChat` to get started.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e📂 Full command reference\u003c/strong\u003e\u003c/summary\u003e\n\n| Command                              | Description                                                                                                                    |\n| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |\n| `:CopilotAgentInstall`               | Download pre-built binary for the current platform                                                                             |\n| `:CopilotAgentDashboard`             | Open the Copilot Agent startup dashboard                                                                                       |\n| `:CopilotAgentChat [fullscreen]`     | Open the chat buffer; `fullscreen` opens in a new tab                                                                          |\n| `:CopilotAgentChatToggle`            | Hide/show chat + input UI windows without reconnect/replay                                                                     |\n| `:CopilotAgentChatFocus`             | Focus or switch to an open chat buffer                                                                                         |\n| `:CopilotAgentAsk [prompt]`          | Send a prompt; no argument opens the input buffer                                                                              |\n| `:CopilotAgentMode [mode]`           | Set the input mode (`ask`, `plan`, `agent`, `test`, `autopilot`)                                                                |\n| `:CopilotAgentCompose [tab]`         | Open the compose scratch buffer; `tab` opens it in a new tab                                                                   |\n| `:CopilotAgentPromoteToCompose`      | Move current prompt-buffer text into compose                                                                                   |\n| `:CopilotAgentSendBuffer`            | Send the active compose buffer                                                                                                 |\n| `:CopilotAgentNewSession`            | Disconnect current session and start a fresh one                                                                               |\n| `:CopilotAgentSwitchSession`         | Pick from all persisted sessions and switch                                                                                    |\n| `:CopilotAgentProvider [name]`       | Switch provider; reuse a matching session or create a new one                                                                  |\n| `:CopilotAgentDeleteSession`         | Pick a session by summary + exact ID and delete it                                                                             |\n| `:CopilotAgentModel [id]`            | Pick or set a model; tab-completes from service model list                                                                     |\n| `:CopilotAgentStart`                 | Start the Go service with the current config                                                                                   |\n| `:CopilotAgentServerStart`           | Start the Copilot Agent server with the current config                                                                         |\n| `:CopilotAgentStop`                  | Disconnect the active session                                                                                                  |\n| `:CopilotAgentStop!`                 | Delete the active session; checkpoint cleanup waits 7 days                                                                     |\n| `:CopilotAgentCancel`                | Cancel the current agent turn                                                                                                  |\n| `:CopilotAgentDiff`                  | Pick two checkpoints and open vimdiff for a changed file                                                                       |\n| `:CopilotAgentFugitiveCommit [last]` | Generate a commit message and open fugitive commit; waits for final post-tool output; `last` reuses the latest assistant reply |\n| `:CopilotAgentStatus`                | Show service URL, session id, stream status                                                                                    |\n| `:CopilotAgentLsp`                   | Start (or reuse) the LSP client for code actions                                                                               |\n| `:CopilotAgentPasteImage`            | Paste clipboard image as attachment                                                                                            |\n| `:CopilotAgentRetryInput`            | Re-show the last dismissed ask_user prompt                                                                                     |\n\n\u003c/details\u003e\n\n---\n\n## Input Buffer\n\nOpen with `:CopilotAgentChat`, then press `i` or `\u003cEnter\u003e` in the chat buffer.\n\n### Keybindings\n\n| Key                               | Action                                                                                                  |\n| --------------------------------- | ------------------------------------------------------------------------------------------------------- |\n| `\u003cCR\u003e` / `\u003cC-s\u003e`                  | Send message                                                                                            |\n| `q` / `\u003cEsc\u003e`                     | Close input (normal mode)                                                                               |\n| `\u003cC-t\u003e`                           | Cycle chat mode: **💬 ask → 📋 plan → 🤖 agent → 🚀 autopilot**                                         |\n| `\u003cM-m\u003e`                           | Open model picker                                                                                       |\n| `\u003cM-P\u003e`                           | Switch provider                                                                                         |\n| `\u003cM-a\u003e`                           | Cycle permission mode: **🔐 interactive → 📂 approve-reads → ✅ approve-all → 🤖 autopilot**            |\n| `\u003cC-a\u003e`                           | Attach resource — opens picker menu (see below)                                                         |\n| `\u003cM-v\u003e`                           | Paste image from clipboard as attachment                                                                |\n| `\u003cC-x\u003e`                           | Toggle session tools (enable/disable individual tools)                                                  |\n| `\u003cTab\u003e`                           | Trigger completion (`@file` or `/command`)                                                              |\n| `\u003cC-e\u003e`                           | Dismiss the active completion popup                                                                     |\n| `@\u003cpath\u003e` / `@\"path with spaces\"` | Attach a file by path or open buffer (autocomplete from working directory and named open buffers)       |\n| `/\u003ccmd\u003e`                          | Run a built-in slash command (autocomplete with `\u003cTab\u003e`)                                                |\n| `\u003cC-w\u003e` (insert)                  | Delete previous word in the prompt while keeping the mode prefix (`ask❯❯❯`/`plan❯❯❯`/`agent❯❯❯`) intact |\n| `\u003cC-u\u003e` (insert)                  | Delete from prompt start to cursor while keeping the mode prefix (`ask❯❯❯`/`plan❯❯❯`/`agent❯❯❯`) intact |\n| `\u003cC-p\u003e` / `\u003cM-p\u003e`                 | Previous prompt from history                                                                            |\n| `\u003cC-n\u003e` / `\u003cM-n\u003e`                 | Next prompt from history                                                                                |\n| `\u003cC-c\u003e` (output)                  | Cancel current turn                                                                                     |\n| `zA` (output)                     | Toggle collapsed `Activity:` transcript blocks                                                          |\n| `\u003cCR\u003e` (output)                   | On Activity lines, open the editable diff split; otherwise open input                                   |\n| `K` (output)                      | Toggle the read-only Activity hover preview while keeping focus in chat                                 |\n| `gK` (output)                     | Move focus into the current Activity hover preview (opens it first if needed)                           |\n| `\u003cC-w\u003ej` (output)                 | Move into Activity hover preview when available; otherwise fallback to normal window-down (`\u003cC-w\u003ej`)    |\n| `CursorHold` / `CursorHoldI`      | When `activity_hover_cursor_hold=true`, show the concise read-only hover preview on Activity lines      |\n| `[[` / `]]` (output)              | Jump to previous/next conversation (`Prompt:` block)                                                    |\n| `[a` / `]a` (output)              | Jump to previous/next `Response:` or `Activity:` block                                                  |\n| `gT` (normal)                     | Open TODO float for the current turn                                                                    |\n| `g?` (normal)                     | Show help float with keybindings, session commands, and recovery tips                                   |\n\n### Slash Commands\n\nThe input buffer supports built-in slash commands handled by the plugin before the text is sent as a normal Copilot prompt. Type `/` and press `\u003cTab\u003e` to browse and complete the available commands. Press `\u003cC-e\u003e` while the popup is open to dismiss it without accepting a candidate. Some of the commands are still experimental.\n\n`/agent` completion is optimized for inline prompting: selecting an agent suggestion inserts the agent name without the `/agent` prefix, so `/agent Git Commit Agent` completion becomes `Git Commit Agent`.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e📂 Supported slash commands\u003c/strong\u003e\u003c/summary\u003e\n\n| Command                | Arguments                                                              | What it does                                                                                                                                                                                                                                                                                 |\n| ---------------------- | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `/add-dir`             | `[path]`                                                               | Add a directory to the session's allowed-directory list; prompts if omitted                                                                                                                                                                                                                  |\n| `/agent`               | `[name\\|default\\|clear]`                                               | Pick a discovered custom agent, or reset back to the default agent                                                                                                                                                                                                                           |\n| `/allow-all`           | —                                                                      | Switch permission mode to `approve-all`                                                                                                                                                                                                                                                      |\n| `/ask`                 | `[question]` or `@visual-selection [question]`                         | Ask a side question in a temporary read-only session; `@visual-selection` attaches the current selection to the prompt                                                                                                                                                                   |\n| `/clear`               | —                                                                      | Clear the current conversation and start a fresh session                                                                                                                                                                                                                                     |\n| `/compact`             | —                                                                      | Compact session history and refresh context usage                                                                                                                                                                                                                                            |\n| `/context`             | —                                                                      | Show current context-window token usage plus the latest quota and usage snapshot                                                                                                                                                                                                             |\n| `/cwd`                 | `[path]`                                                               | Show or change the working directory used for future session actions                                                                                                                                                                                                                         |\n| `/diff`                | `[vNNN\\|from to\\|from..to] [--difftool [name]]`                        | Show a checkpoint diff summary (default shows latest checkpoint changes), or open a visual diff via `--difftool` (`CodeDiff`, `Fugitive`, or native vim diff when no name is provided)                                                                                                       |\n| `/env`                 | —                                                                      | Show the current environment, service, session, model, and mode snapshot                                                                                                                                                                                                                     |\n| `/fleet`               | `[prompt]`                                                             | Start fleet mode for the active session                                                                                                                                                                                                                                                      |\n| `/init`                | `[args]`                                                               | Run the project initialization helper                                                                                                                                                                                                                                                        |\n| `/instructions`        | `[name]`                                                               | Open a discovered instructions file from the repository                                                                                                                                                                                                                                      |\n| `/list-dir`            | —                                                                      | List allowed directories for the current session                                                                                                                                                                                                                                             |\n| `/list-dirs`           | —                                                                      | Alias for `/list-dir`                                                                                                                                                                                                                                                                        |\n| `/list-tools`          | —                                                                      | List remembered tool approvals for the current session; if empty, explain that the backend does not expose a full available-tools inventory                                                                                                                                                  |\n| `/lsp`                 | `[create\\|status\\|show\\|test\\|help]`                                   | Bootstrap or inspect project LSP config for Copilot CLI                                                                                                                                                                                                                                      |\n| `/mcp`                 | `[add\\|show\\|edit\\|delete\\|disable\\|enable\\|reload] ...`               | Manage MCP servers in `.mcp.json`, `.vscode/mcp.json`, and `~/.copilot/mcp-config.json` (global): add/show/edit/delete entries, toggle disabled state, and reconnect the active session to reload discovery                                                                                  |\n| `/model`               | `[id]`                                                                 | Pick or switch the active model                                                                                                                                                                                                                                                              |\n| `/new`                 | —                                                                      | Start a fresh session                                                                                                                                                                                                                                                                        |\n| `/plan`                | `[draft text]`                                                         | Switch the input buffer to plan mode and optionally prefill the prompt                                                                                                                                                                                                                       |\n| `/rename`              | `[name]`                                                               | Rename the active session                                                                                                                                                                                                                                                                    |\n| `/research`            | `[topic]`                                                              | Send a research-oriented prompt that can use GitHub and web sources                                                                                                                                                                                                                          |\n| `/reset-allowed-tools` | —                                                                      | Clear remembered tool approvals for the current session                                                                                                                                                                                                                                      |\n| `/resume`              | `[session-id]`                                                         | Resume or switch to another saved session; prompts if omitted                                                                                                                                                                                                                                |\n| `/review`              | `[focus]`                                                              | Ask Copilot to review the current changes, optionally with extra focus text                                                                                                                                                                                                                  |\n| `/rewind`              | `[checkpoint]`                                                         | Rewind the session to a checkpoint such as `v003`, then queue the target git hash and reverted checkpoint summaries into the next Copilot prompt                                                                                                                                             |\n| `/search`              | `[text]`                                                               | Search the current transcript and jump to a matching entry                                                                                                                                                                                                                                   |\n| `/session`             | `[info\\|checkpoints\\|files\\|plan\\|rename\\|cleanup\\|prune\\|delete] ...` | Inspect and manage sessions; bare `/session` still opens the switch picker. `/session prune --older-than \u003cdays\u003e [--dry-run] [--include-named]` prunes old saved sessions, and `/session prune --keep-last \u003ccount\u003e [--session \u003cid\u003e] [--dry-run]` trims old checkpoint snapshots for a session |\n| `/share`               | `[markdown\\|html] [path]`                                              | Export the current transcript as Markdown or HTML                                                                                                                                                                                                                                            |\n| `/skills`              | `[name]`                                                               | Open a discovered skill from the repository                                                                                                                                                                                                                                                  |\n| `/tasks`               | `[filter]`                                                             | Show background task and sub-agent activity                                                                                                                                                                                                                                                  |\n| `/undo`                | —                                                                      | Restore the latest checkpoint for the current session, then queue the restore git hash/context into the next Copilot prompt                                                                                                                                                                  |\n| `/usage`               | —                                                                      | Show detailed session usage, quota snapshot, discovery counts, and context-window stats                                                                                                                                                                                                      |\n\n\u003c/details\u003e\n\n## Compose Buffer\n\nOpen with `:CopilotAgentCompose` to open it as a left-side split next to chat output, or `:CopilotAgentCompose tab` to edit in a new tab.\n\nThe compose buffer is a separate markdown scratch buffer for long prompts. It keeps the same `@` attachment and slash-command completion as the normal input buffer. From the prompt buffer, press `\u003cleader\u003ecc` or run `:CopilotAgentPromoteToCompose` to promote the current prompt into compose and continue editing there. Customize or disable the mapping with `compose.promote_keymap`.\n\n| Key / Command                   | Action                           |\n| ------------------------------- | -------------------------------- |\n| `\u003cleader\u003ecc` (prompt buffer)    | Move current prompt into compose |\n| `:CopilotAgentPromoteToCompose` | Move current prompt into compose |\n| `\u003cleader\u003ecs` / `\u003cC-s\u003e`          | Send compose buffer              |\n| `:w` / `:wq`                    | Send compose buffer              |\n| `:CopilotAgentSendBuffer`       | Send compose buffer              |\n| `q` / `\u003cEsc\u003e`                   | Close compose buffer             |\n\n### Attaching Files and Images\n\nPress `\u003cC-a\u003e` in the input buffer to open the resource picker:\n\n| Choice                     | What it does                                                   |\n| -------------------------- | -------------------------------------------------------------- |\n| Current buffer             | Attaches the previously focused file buffer                    |\n| Visual selection           | Attaches the current visual selection with file path + line range |\n| File                       | Opens fuzzy picker → select one or more files (multi-select)   |\n| Folder                     | Opens fuzzy picker / `vim.ui.input` to pick a directory        |\n| Instructions file          | Same as File but marked as an instructions context file (📋)   |\n| Image file                 | Opens fuzzy picker to select an image (png/jpg/gif/…)          |\n| Paste image from clipboard | Saves clipboard image to a temp PNG and attaches it (🖼️)       |\n\n`\u003cM-v\u003e` is a direct shortcut for **Paste image from clipboard** without opening the menu.\n`:CopilotAgentPasteImage` is the equivalent command.\n\nPending attachments appear in the input statusline as `📎 N`. Each attachment is also shown below the prompt text in the chat buffer once sent.\n\n#### Fuzzy Picker Integration\n\nThe File / Folder / Image / Instructions choices auto-detect and use the best available picker — no extra configuration needed:\n\n| Priority | Picker            | Notes                                                  |\n| -------- | ----------------- | ------------------------------------------------------ |\n| 1        | **snacks.picker** | `snacks.picker.files` / `snacks.picker.directories`    |\n| 2        | **telescope**     | `find_files`; `telescope-file-browser` for directories |\n| 3        | **fzf-lua**       | `fzf.files`; `fzf_exec fd --type d` for directories    |\n| 4        | **mini.pick**     | `mp.builtin.files` (files only)                        |\n| 5        | **vim.ui.input**  | Fallback — type the path with completion               |\n\nOverride the picker or force the native fallback via config:\n\n```lua\nchat = { file_picker = 'auto' }       -- default: detect best available\nchat = { file_picker = 'telescope' }  -- always use telescope\nchat = { file_picker = 'fzf-lua' }    -- always use fzf-lua\nchat = { file_picker = 'native' }     -- always use vim.ui.input\n```\n\n#### Clipboard Image Requirements\n\n| Platform      | Tool required     | Install                         |\n| ------------- | ----------------- | ------------------------------- |\n| macOS         | `pngpaste`        | `brew install pngpaste`         |\n| Linux/Wayland | `wl-paste`        | `sudo apt install wl-clipboard` |\n| Linux/X11     | `xclip` or `xsel` | `sudo apt install xclip`        |\n\n### Chat Modes\n\nCycled with `\u003cC-t\u003e` in the chat/input buffer. The mode is shown in the statusline.\n\n| Mode          | Icon | SDK session mode | Description                                                                                                                                                                                                                             |\n| ------------- | ---- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **ask**       | 💬   | `interactive`    | Single-turn Q\u0026A. The model answers once and stops. Tools are available but each call requires approval. Use for questions, explanations, and code reviews.                                                                              |\n| **plan**      | 📋   | `plan`           | Like ask, but the model is guided to produce a structured implementation plan before taking any action. Good for scoping a task before committing to it.                                                                                |\n| **agent**     | 🤖   | `autopilot`      | Multi-step agentic loop. The model calls tools (read files, run commands, write code) repeatedly and iterates until the task is done. Pauses to prompt you before writes/shell commands. Read access to the workspace is auto-approved. |\n| **autopilot** | 🚀   | `autopilot`      | Same agentic loop as agent, but with `approve-all` permission — every tool call (reads _and_ writes) is silently approved. Fully autonomous.                                                                                            |\n\n**SDK note:** The Copilot SDK has three session modes — `interactive`, `plan`, and `autopilot`. VS Code's four-label model maps exactly onto these: ask → `interactive`, plan → `plan`, agent and autopilot both → `autopilot` (the difference is the permission mode, not the SDK mode).\n\n### Performance Tips\n\n- **render-markdown.nvim** integrates automatically when installed. On very long responses it can cause visible lag. Disable with `chat = { render_markdown = false }` to use treesitter highlighting only (much faster).\n- **Streaming** is enabled by default (`session.streaming = true`). The chat buffer updates incrementally as tokens arrive.\n- **Permission history replay** is filtered by default (`session.replay_permission_history = false`) so large sessions resume faster. Set it to `true` if you want to review historical permission requests/completions in the restored chat transcript.\n- **Large-session replay window** defaults to the latest 256 turns (`session.history_turn_limit`) and keeps full activity detail only for the latest 64 turns (`session.history_activity_turn_limit`). Older replayed turns keep full assistant messages, while activity/tool outputs are summarized with previews capped by `session.history_preview_chars` (default 120).\n- **Usage telemetry** (`assistant.usage`) updates statusline/context snapshots silently instead of adding extra `Activity:` transcript blocks. Use `/context` or `/usage` for full usage details.\n- **Session resume**: with 1 matching session it resumes silently; with multiple sessions `auto_resume = \"prompt\"` (default) shows a picker titled with the current project name and path so you can choose which session to continue.\n\n### Permission Modes\n\nCycled with `\u003cM-a\u003e` in the input buffer, or set via config / `POST /sessions/{id}/permission-mode`.\nEach chat mode sets a sensible default permission automatically; `\u003cM-a\u003e` overrides it for the current mode.\n\n| Icon | Mode              | Behaviour                                                                                                           |\n| ---- | ----------------- | ------------------------------------------------------------------------------------------------------------------- |\n| 🔐   | **interactive**   | Neovim prompts `Allow / Deny` for every tool call                                                                   |\n| 📂   | **approve-reads** | Workspace read-file requests are auto-approved; writes and shell commands still prompt. Default for **agent** mode. |\n| ✅   | **approve-all**   | All tool calls silently approved. Default for **autopilot** mode.                                                   |\n| 🤖   | **autopilot**     | Approve all + auto-answer any `ask_user` questions (fully autonomous)                                               |\n| 🚫   | **reject-all**    | Reject all tool calls (safe read-only mode)                                                                         |\n\n#### `ask_user` requests — when will Copilot ask you a question?\n\nThere are **two separate interruption points** in an agentic loop:\n\n1. **Tool-call approval** — before the SDK executes a tool (read file, run shell, write code, etc.).\n   Controlled entirely by the permission mode above.\n\n2. **`ask_user` requests** — the _model itself_ decides to pause and ask you a clarifying question\n   mid-task (e.g. \"Which branch should I target?\" or \"There are two test files — which one?\").\n   This is independent of tool approval and happens at the model's discretion.\n\n| Permission mode   | Tool calls          | `ask_user` questions                       |\n| ----------------- | ------------------- | ------------------------------------------ |\n| **interactive**   | prompt every call   | shown via `vim.ui.input/select`            |\n| **approve-reads** | prompt writes/shell | shown via `vim.ui.input/select`            |\n| **approve-all**   | silent              | shown via `vim.ui.input/select`            |\n| **autopilot**     | silent              | **auto-answered** (first choice, silently) |\n| **reject-all**    | all rejected        | shown via `vim.ui.input/select`            |\n\n\u003e **Practical rule:** use **agent** mode (`approve-reads`) for day-to-day tasks — Copilot will still\n\u003e ask you clarifying questions but won't prompt for every file read. Switch to **autopilot** permission\n\u003e only when you are confident in the task scope and want zero interruptions.\n\n---\n\n## LSP Code Actions\n\nThe Go binary runs an LSP server on stdio. Setting `lsp.enabled = true` starts the helper automatically from `setup()`. `:CopilotAgentLsp` or `require(\"copilot_agent\").start_lsp()` is only needed when you want explicit or delayed startup, and the helper reuses the existing HTTP service instead of spawning a fresh backend session.\n\nThis helper server is separate from the project language servers used by Copilot CLI for code intelligence. Use `/lsp create` to bootstrap `.github/lsp.json` from active Neovim project LSP clients, then restart the Copilot service so config discovery reloads it.\n\nAvailable code actions (triggered on any selection via `vim.lsp.buf.code_action()`):\n\n- **Explain selection** — Ask Copilot to explain the selected code\n- **Fix selection** — Ask Copilot to suggest a fix\n- **Add tests for selection** — Generate unit tests\n- **Add docs for selection** — Generate documentation\n\nThe action builds a prompt from the selected text, file path, and line range, then POSTs it to the active HTTP session.\n\n---\n\n## Statusline\n\nExpose Copilot state in your statusline. Each function returns a short string.\n\nBy default, plugin-managed chat/input local statuslines are disabled (`statusline.enabled = false`), so you can keep your own statusline setup unchanged.\n\nIf you want plugin-managed local statuslines in Copilot windows, enable them explicitly:\n\n```lua\nrequire(\"copilot_agent\").setup({\n  statusline = {\n    enabled = true,\n  },\n})\n```\n\nYou can choose which components are rendered with `statusline.components` (default: all enabled). Supported component keys are: `mode`, `permission`, `busy`, `session`, `model`, `tool`, `intent`, `context`, `config`, `attachments`, `help`.\n\n```lua\nrequire(\"copilot_agent\").setup({\n  statusline = {\n    enabled = true,\n    components = {\n      mode = true,\n      busy = true,\n      session = true,\n      permission = false,\n      model = false,\n      tool = false,\n      intent = false,\n      context = false,\n      config = false,\n      attachments = false,\n      help = false,\n    },\n  },\n})\n```\n\nWhen enabled, default examples:\n\n```text\ninput window\n🤖agent (loop·approve-all)  ✅approve-all  ✅ready  default  󱃕 Instruction: 0  󱜙 Agent: 0 󱨚 Skill: 0  MCP: 0  (g? for help)\n\nchat window\n🤖agent (loop·approve-all)  ✅approve-all  ✅ready  default  󱃕 Instruction: 0 󱜙 Agent: 0 󱨚 Skill: 0  MCP: 0  session: [#project name 20260501 0905]\n```\n\nAs the session becomes active, the statusline updates live with readiness (`⏳working`, `📝sync`, `🧩2 tasks`, `❓input`, `✅ready`), the current tool/intent, context tokens, quota remaining from `assistant.usage` events, pending attachments, and the active session label.\n\n### Use statusline API\n\n```lua\n-- lualine\nrequire(\"lualine\").setup {\n  sections = {\n    lualine_x = {\n      require(\"copilot_agent\").statusline_mode,        -- [ask] / [plan] / [agent] / [autopilot]\n      require(\"copilot_agent\").statusline_model,       -- claude-sonnet-4.6 / default\n      require(\"copilot_agent\").statusline_busy,        -- ✅ready / ⏳working / 📝sync / 🧩2 tasks / ❓input\n      require(\"copilot_agent\").statusline_permission,  -- 🔐interactive / ✅approve-all / 🤖autopilot\n      require(\"copilot_agent\").statusline_attachments, -- 📎3 (when attachments pending)\n      require(\"copilot_agent\").statusline_tool,        -- 🔧 read_file (active tool)\n      require(\"copilot_agent\").statusline_intent,      -- current agent intent\n      require(\"copilot_agent\").statusline_context,     -- 12k/200k plus quota remaining when available\n    }\n  }\n}\n\n-- heirline / \u0026statusline\n-- %{v:lua.require'copilot_agent'.statusline()}\n```\n\n---\n\n## Session Persistence\n\nSession resume is scoped per project by `working_directory`: `pick_or_create_session` filters persisted sessions by working directory, so opening a different project starts a fresh session. The auto-started service itself is still global by default, which is why the startup picker now shows the current project name and path explicitly. Use `:CopilotAgentNewSession` to force a new one in the same directory, `:CopilotAgentSwitchSession` to pick from all persisted sessions across projects, or `:CopilotAgentDeleteSession` to remove one from a newest-first picker that includes the exact session ID and marks the active session with `●`.\n\nSessions are auto-named by the SDK after the first conversation turn. You can rename a session by typing `/rename My Session Name` in the input buffer.\n\nWhen a session is deleted, its checkpoint git worktree is soft-deleted instead of being removed immediately. This applies both to `:CopilotAgentDeleteSession` and `:CopilotAgentStop!`. The checkpoint metadata records the deletion time and the worktree is pruned automatically after 7 days on the next plugin startup or checkpoint/session lifecycle operation.\n\nWhen plugin-managed statuslines are enabled, the chat/output statusline shows the active session summary together with its short session ID, and transcript separators between turns render the completed-turn checkpoint label (`v001`, `v002`, ...) as a virtual rule so you can copy it for rewind/recovery workflows without opening the input buffer.\n\n**Session selection behaviour:**\n\n| Matching sessions for project          | Behaviour                                                         |\n| -------------------------------------- | ----------------------------------------------------------------- |\n| 0                                      | Creates a new session automatically                               |\n| 1                                      | Resumes it silently — no prompt                                   |\n| 2+ (`auto_resume = 'prompt'`, default) | Shows `vim.ui.select` picker; most recent session is listed first |\n| 2+ (`auto_resume = 'auto'`)            | Silently resumes the most recent session                          |\n\nTo always skip the picker, set in your config:\n\n```lua\nsession = { auto_resume = 'auto' }\n```\n\n---\n\n## HTTP API Reference\n\nSee [server/README.md](server/README.md#http-api-reference) for the full endpoint list, session permission modes, and SSE event reference.\n\n---\n\n## Tutorial\n\n1. 📖 **[Build a To-Do App with Copilot Agent](doc/tutorial-flask.md)** — Full-stack to-do list app with a REST API and responsive UI.\n2. 🌤️ **[Build a Weather Dashboard with Copilot Agent](doc/tutorial-weather-dashboard.md)** — Glassmorphism weather app with wttr.in data, animated UI, and backend tests.\n3. 🧩 **[Build a Weather Dashboard with Preset Copilot Agents](doc/tutorial-custom-agent-weather.md)** — Copy a ready-made `.github/agents/` pack and use separate UI, Python, and QA specialists.\n4. 🐦 **[Build a Terminal Flappy Bird with Custom Agents and Skills](doc/tutorial-flappy-bird-go.md)** — Bootstrap a repo with script-copied prompts/agents/skills, implement a Go terminal game, and run `go vet`/`go test` before launching from Neovim terminal.\n\n---\n\n## Included repo-local custom agents\n\n- **Go Quality Engineer** — runs the repository's existing Go quality checks\n- **Selene Lua Quality Engineer** — runs Selene against the Lua sources\n- **Code Review Engineer** — reviews Lua and Go changes for correctness, code quality, performance, and security\n- **Git Commit Agent** — inspects git status, runs repo-appropriate pre-commit checks, and prepares commit messages from the staged diff\n- **Document Update Agent** — reviews user-facing docs against recent plugin changes and updates commands, keymaps, changelog notes, and gotchas\n\nCustomize the commit agent's default checks and feedback rules in `.github/commit-agent.md`.\n\n---\n\n## Development\n\n### Formatting\n\nThe project uses `make` targets for formatting. Run from the repo root:\n\n```bash\nmake fmt        # format everything (Lua + Go)\nmake fmt-lua    # Lua only  — stylua lua/ plugin/  (config: stylua.toml)\nmake fmt-go     # Go only   — gofmt -w ./server\n```\n\nRequirements: [`stylua`](https://github.com/JohnnyMorganz/StyLua) and `gofmt` (bundled with Go).\n\nCI enforces both formatters on every push — PRs with unformatted code will fail the **Lint** workflow.\n\n## Testing\n\n```bash\n# Lua unit tests (no Neovim required)\nbusted --lpath='lua/?.lua;lua/?/init.lua' tests/unit/\n\n# Neovim integration tests (requires nvim on PATH)\nnvim --headless -u tests/minimal_init.lua \\\n  -c \"PlenaryBustedFile tests/integration/setup_spec.lua\"\n```\n\nCI runs all of the above automatically on push and PR via GitHub Actions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fray-x%2Fcopilot-agent.nvim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fray-x%2Fcopilot-agent.nvim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fray-x%2Fcopilot-agent.nvim/lists"}