From c0d2326e34c59c4fdba9ba49edca64328e96e215 Mon Sep 17 00:00:00 2001 From: zias Date: Thu, 26 Feb 2026 11:55:48 +0100 Subject: [PATCH] feat: add ThePrimeagen/99 AI agent plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Configured with OpenCodeProvider (default, matches opencode environment) - blink.cmp as completion source for # rules and @ file references - tmp_dir = ./tmp (per-project, keeps opencode permission happy) - Auto-injects AGENT.md files from file location up to project root - Keymaps under 9 group: 9v (visual) replace selection with AI result 9s search project → quickfix list 9x stop all in-flight requests 9c clear previous results 9l view debug logs 9m telescope model picker 9p telescope provider picker - Added AI [9]9 group to which-key --- lua/plugins/extras/ai.lua | 56 +++++++++++++++++++++++++++++++++++++++ lua/plugins/which-key.lua | 1 + 2 files changed, 57 insertions(+) create mode 100644 lua/plugins/extras/ai.lua diff --git a/lua/plugins/extras/ai.lua b/lua/plugins/extras/ai.lua new file mode 100644 index 0000000..6664d35 --- /dev/null +++ b/lua/plugins/extras/ai.lua @@ -0,0 +1,56 @@ +-- lua/plugins/extras/ai.lua +-- ThePrimeagen/99 — AI agent for Neovim +-- Augments coding via opencode (default provider) with two core workflows: +-- search → AI project-wide search, results in quickfix list +-- visual → replace visual selection with AI-generated result +-- https://github.com/ThePrimeagen/99 + +return { + 'ThePrimeagen/99', + config = function() + local _99 = require '99' + local basename = vim.fs.basename(vim.uv.cwd()) + + _99.setup { + -- OpenCodeProvider is the default; matches the opencode environment + logger = { + level = _99.DEBUG, + path = '/tmp/' .. basename .. '.99.debug', + print_on_error = true, + }, + -- tmp_dir must be inside CWD so opencode has write permission + tmp_dir = './tmp', + -- Auto-inject AGENT.md files found between the open file and project root + md_files = { 'AGENT.md' }, + completion = { + source = 'blink', -- blink.cmp is your completion engine + }, + } + + -- Visual selection → AI replacement + -- Intentionally v-mode only: avoids accidentally using a stale selection + vim.keymap.set('v', '9v', _99.visual, { desc = 'AI: replace visual selection' }) + + -- Project-wide AI search → quickfix list + vim.keymap.set('n', '9s', _99.search, { desc = 'AI: search project' }) + + -- Cancel all in-flight requests + vim.keymap.set('n', '9x', _99.stop_all_requests, { desc = 'AI: stop all requests' }) + + -- Clear previous search/visual results + vim.keymap.set('n', '9c', _99.clear_previous_requests, { desc = 'AI: clear previous requests' }) + + -- View debug logs for the last run + vim.keymap.set('n', '9l', _99.view_logs, { desc = 'AI: view logs' }) + + -- Telescope: switch model on the fly (persists for the session) + vim.keymap.set('n', '9m', function() + require('99.extensions.telescope').select_model() + end, { desc = 'AI: select model' }) + + -- Telescope: switch provider (OpenCode / Claude / Cursor / Gemini) + vim.keymap.set('n', '9p', function() + require('99.extensions.telescope').select_provider() + end, { desc = 'AI: select provider' }) + end, +} diff --git a/lua/plugins/which-key.lua b/lua/plugins/which-key.lua index 7ef5247..d14be1e 100644 --- a/lua/plugins/which-key.lua +++ b/lua/plugins/which-key.lua @@ -24,6 +24,7 @@ return { { 't', group = '[T]oggle' }, { 'h', group = 'Git [H]unk', mode = { 'n', 'v' } }, { 'd', group = '[D]ebug' }, + { '9', group = 'AI [9]9' }, }, }, }