summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortheprimeagain <the.primeagen@gmail.com>2026-02-18 08:28:21 -0700
committertheprimeagain <the.primeagen@gmail.com>2026-02-18 08:28:21 -0700
commit045e6056508a2a5c7bdeebae46875b7bba3a6f21 (patch)
tree41f85b83c44c1c8580c1f056641dcbd3fa65aa78
parent406f4438e7728b57f9ebcad8a214aba0e7be8f0e (diff)
downloada4-045e6056508a2a5c7bdeebae46875b7bba3a6f21.tar.xz
a4-045e6056508a2a5c7bdeebae46875b7bba3a6f21.zip
worker extension
-rw-r--r--lua/99/extensions/work/worker.lua75
-rw-r--r--lua/99/init.lua40
-rw-r--r--lua/99/ops/search.lua14
-rw-r--r--lua/99/window/init.lua8
4 files changed, 107 insertions, 30 deletions
diff --git a/lua/99/extensions/work/worker.lua b/lua/99/extensions/work/worker.lua
new file mode 100644
index 0000000..dbcf9b3
--- /dev/null
+++ b/lua/99/extensions/work/worker.lua
@@ -0,0 +1,75 @@
+local Window = require("99.window")
+
+--- @class _99.Extension.Worker
+local M = {}
+
+--- @class _99.WorkOpts
+--- @field description string | nil
+
+--- @param opts _99.WorkOpts | nil
+function M.set_work(opts)
+ opts = opts or {}
+ local description = opts.description
+ if description then
+ M.current_work_item = description
+ else
+ Window.capture_input(" Work ", {
+ cb = function(success, result)
+ if not success then
+ return
+ end
+ M.current_work_item = result
+ end,
+
+ content = { "Put in the description of the work you want to complete" },
+ })
+ end
+
+ -- i think this makes sense. last work search should be cleared
+ M.last_work_search = nil
+end
+
+--- craft_prompt can be overridden so you can create your own prompt
+--- @param worker _99.Extension.Worker
+--- @return string
+function M.craft_prompt(worker)
+ return string.format(
+ [[
+<YourGoal>
+You are to take the current git diff and git diff --staged and figure out what is left to change to complete the work item.
+The work item is described in <Description>
+
+Carefully review everything in git diff and git diff --staged and <Description> before you respond.
+respond with proper Search Format described in <Rule> and an example in <Output>
+
+If you see bugs, also report those
+</YourGoal>
+<Description>
+%s
+</Description>
+]],
+ worker.current_work_item
+ )
+end
+
+function M.work()
+ assert(
+ M.current_work_item,
+ 'you must call "set_work" and set your current work item before calling this'
+ )
+ local _99 = require("99")
+ M.last_work_search = _99.search({
+ additional_prompt = M.craft_prompt(M),
+ })
+end
+
+function M.last_search_results()
+ if M.last_work_search == nil then
+ print("no previous search results")
+ return
+ end
+
+ require("99").qfix_search_results(M.last_work_search)
+end
+
+return M
diff --git a/lua/99/init.lua b/lua/99/init.lua
index f8755dd..a51cc51 100644
--- a/lua/99/init.lua
+++ b/lua/99/init.lua
@@ -45,6 +45,7 @@ end
--- @class _99.RequestEntry.Data.Search
--- @field type "search"
+--- @field qfix_items _99.Search.Result[]
--- @class _99.RequestEntry.Data.Visual
--- @field type "visual"
@@ -397,15 +398,16 @@ function _99:rule_from_path(path)
end
--- @param opts? _99.ops.SearchOpts
+--- @return number
function _99.search(opts)
local o = process_opts(opts) --[[ @as _99.ops.SearchOpts ]]
local context = get_context("search")
if o.additional_prompt then
ops.search(context, o)
- return
else
capture_prompt(ops.search, "Search", context, o)
end
+ return context.xid
end
--- @param opts _99.ops.Opts
@@ -473,21 +475,6 @@ end
--- @field col number
--- @field text string
---- @param entry _99.RequestEntry
---- @return _99.QFixEntry
-local function request_entry_to_qfix_item(entry)
- local context = entry.context
- local point = entry.point
- local text = string.format("[%s] %s", entry.status, entry.context.operation)
-
- return {
- filename = context and context.full_path or "",
- lnum = point and point.row or 0,
- col = point and point.col or 0,
- text = text,
- }
-end
-
function _99.stop_all_requests()
for _, request in pairs(_99_state.__request_by_id) do
if request.status == "requesting" then
@@ -503,12 +490,18 @@ function _99.clear_all_marks()
_99_state.__active_marks = {}
end
-function _99.previous_requests_to_qfix()
- local items = {}
- for _, entry in ipairs(_99_state.__request_history) do
- table.insert(items, request_entry_to_qfix_item(entry))
- end
- vim.fn.setqflist({}, "r", { title = "99 Requests", items = items })
+--- @param xid number | nil
+function _99.qfix_search_results(xid)
+ --- @type _99.RequestEntry
+ local entry = _99_state.__request_by_id[xid]
+ assert(entry, "qfix_search_results could not find id: " .. xid)
+
+ local data = entry.operation_data
+ assert(data, "there must be data associated with request entry")
+ assert(data.type == "search", "the operation_data must be type search")
+
+ local items = data.qfix_items
+ vim.fn.setqflist({}, "r", { title = "99 Search Results", items = items })
vim.cmd("copen")
end
@@ -673,4 +666,7 @@ function _99.__debug()
end
_99.Providers = Providers
+_99.Extensions = {
+ Worker = require("99.extensions.work.worker"),
+}
return _99
diff --git a/lua/99/ops/search.lua b/lua/99/ops/search.lua
index f819e4b..d6e5428 100644
--- a/lua/99/ops/search.lua
+++ b/lua/99/ops/search.lua
@@ -36,10 +36,9 @@ local function parse_line(line)
}
end
---- @param _99 _99.State
+--- @param context _99.RequestContext
--- @param response string
-local function create_search_locations(_99, response)
- _ = _99
+local function create_search_locations(context, response)
local lines = vim.split(response, "\n")
local qf_list = {}
@@ -49,10 +48,13 @@ local function create_search_locations(_99, response)
table.insert(qf_list, res)
end
end
+ context._99:add_data(context, {
+ type = "search",
+ qfix_items = qf_list,
+ })
if #qf_list > 0 then
- vim.fn.setqflist(qf_list, "r")
- vim.cmd("copen")
+ require("99").qfix_search_results(context.xid)
else
vim.notify("No search results found", vim.log.levels.INFO)
end
@@ -89,7 +91,7 @@ local function search(context, opts)
response or "no response provided"
)
elseif status == "success" then
- create_search_locations(context._99, response)
+ create_search_locations(context, response)
end
end))
end
diff --git a/lua/99/window/init.lua b/lua/99/window/init.lua
index d7018c8..8db5b2f 100644
--- a/lua/99/window/init.lua
+++ b/lua/99/window/init.lua
@@ -283,9 +283,13 @@ local function set_defaul_win_options(win, name)
end
--- @param win _99.window.Window
---- @param rules _99.Agents.Rules
+--- @param rules _99.Agents.Rules?
--- @param group any
local function highlight_rules_found(win, rules, group)
+ if rules == nil then
+ return
+ end
+
local rule_nsid = vim.api.nvim_create_namespace("99.window.rules")
local function check_and_highlight_rules()
if not nvim_win_is_valid(win.win_id) then
@@ -352,7 +356,7 @@ end
--- @field cb fun(success: boolean, result: string): nil
--- @field on_load? fun(): nil
--- @field content? string[]
---- @field rules _99.Agents.Rules
+--- @field rules? _99.Agents.Rules
--- @param name string
--- @param opts _99.window.CaptureInputOpts