1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
local Window = require("99.window")
local utils = require("99.utils")
--- @class _99.Extensions.Worker
--- A persistent way to keep track of work.
---
--- this will likely be where the most change and focus goes into. I would like
--- to take this into worktree territory and be able to swap between stuff super
--- slick.
---
--- Until then, it is going to be a single bit of work that you can provide
--- the description and then use search to find what is left that needs to be done.
--- @docs base
--- @field set_work fun(opts?: _99.WorkOpts): nil
--- will set the work for the project. If opts provide a description then no
--- input capture of work description will be required
--- @field search fun(): nil
--- will use _99.search to find what is left to be done for this work item to be
--- considered done
local M = {}
local DEFAULT_WORK_DESCRIPTION =
"Put in the description of the work you want to complete"
--- @class _99.WorkOpts
--- @docs included
--- @field description string | nil
--- @return string
local function get_work_item_file()
local _99 = require("99")
local state = _99.__get_state()
local tmp = state:tmp_dir()
return utils.named_tmp_file(tmp, "work-item")
end
--- @return string | nil
local function read_work_item()
local ok, file = pcall(io.open, get_work_item_file(), "r")
if not ok or not file then
return nil
end
--- @type string
local contents
ok, contents = pcall(file.read, file, "*a")
pcall(file.close, file)
if not ok then
return nil
end
return contents
end
--- @return string | nil
local function hydrate_current_work_item()
if M.current_work_item == nil then
M.current_work_item = read_work_item()
end
return M.current_work_item or DEFAULT_WORK_DESCRIPTION
end
--- @param success boolean
---@param result string
local function set_work_item_cb(success, result)
if not success then
return
end
M.current_work_item = result
local file = io.open(get_work_item_file(), "w")
if file then
file:write(result)
file:close()
else
error("unable to save work item")
end
end
function M.update_work()
local work = hydrate_current_work_item()
Window.capture_input(" Work ", {
cb = set_work_item_cb,
content = vim.split(work, "\n"),
})
end
--- @param opts _99.WorkOpts | nil
function M.set_work(opts)
opts = opts or {}
local description = opts.description
if description then
set_work_item_cb(true, description)
else
local work = hydrate_current_work_item()
Window.capture_input(" Work ", {
cb = set_work_item_cb,
content = { work },
})
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.Extensions.Worker
--- @return string
function M.craft_prompt(worker)
return string.format(
[[
## You must complete the checklist
[ ] - Inspect and understand all changed code
[ ] - git diff
[ ] - git diff --staged
[ ] - commits that have not been pushed to remote
[ ] - Take the current pending and commited changes and figure out what is left
to change to complete the work item. The work item is described in <Description>
[ ] - Carefully review all the changes 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
[ ] - if there are tests, run the tests
<Description>
%s
</Description>
]],
worker.current_work_item
)
end
function M.search()
local _99 = require("99")
hydrate_current_work_item()
assert(
M.current_work_item,
'you must call "set_work" and set your current work item before calling this'
)
M.last_work_search = _99.search({
additional_prompt = M.craft_prompt(M),
})
end
function M.vibe()
local _99 = require("99")
hydrate_current_work_item()
assert(
M.current_work_item,
'you must call "set_work" and set your current work item before calling this'
)
M.last_work_search = _99.vibe({
additional_prompt = M.craft_prompt(M),
})
end
return M
|