Skip to content

Commit 4d87631

Browse files
committed
Merge pull request '✨ Toggle agent done / not done (undone)' (#6) from undone-toggle into main
Reviewed-on: https://git.greil.fr/mat/agent-fleet.nvim/pulls/6
2 parents 62aa40c + f5a2bb8 commit 4d87631

11 files changed

Lines changed: 72 additions & 32 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ fields to override. See [Configuration](#configuration).
116116
:AgentResume " reopen a past agent of this directory (focus if live, else resume)
117117
:Agents " list & switch agents of this directory (focus if live, else resume)
118118
:AgentsBoard " open the live board buffer (sections, colors, per-row keymaps)
119-
:AgentDone " mark an agent done (✓)
119+
:AgentDone " toggle an agent done / not done (✓)
120120
:AgentArchive " archive / unarchive an agent (hidden from :Agents by default)
121121
:AgentRename foo " rename the current agent (or pick one) to "foo"
122122
:AgentRename " rename via a prompt (current agent, or pick one)
@@ -150,7 +150,7 @@ keys (`j`/`k`/`/`/`gg`); the per-row actions are:
150150
| Key | Action |
151151
| --- | ------ |
152152
| `<CR>` | switch to the agent under the cursor (focus its terminal if live, else resume it via its CLI) |
153-
| `d` | mark done (✓) |
153+
| `d` | toggle done (✓) |
154154
| `x` | archive / unarchive |
155155
| `r` | rename (prompt) |
156156
| `s` | stop — kill the live terminal without marking it done (still resumable) |

ROADMAP.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ ships and what's planned. For the user-facing docs, see [README.md](README.md).
1717
- **[x] List & switch**`:Agents` lists the agents of the **current directory**
1818
(live ones in this nvim merged with this cwd's pi sessions on disk, deduped by
1919
session id) and switches to the chosen one — focus if live, else resume.
20-
`:AgentDone` marks an agent done (✓); `:AgentArchive` toggles archive (hidden
20+
`:AgentDone` toggles an agent done / not done (✓); `:AgentArchive` toggles archive (hidden
2121
by default). Soft archive only — never deletes a session file. `:AgentRename`
2222
renames an agent (the current agent's buffer, or a picked one). `:AgentDone` /
2323
`:AgentArchive` also act on the current agent's buffer, closing (killing) its

lua/agent-fleet/actions.lua

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,13 @@ end
2626

2727
function M.done(row)
2828
local roster = require("agent-fleet.roster")
29+
local now = not row.done
2930
roster.ensure({ id = row.id, type = row.type or "pi", name = row.name, cwd = row.cwd })
30-
roster.mark_done(row.id)
31-
M.close_live(row)
31+
roster.set_done(row.id, now)
32+
if now then
33+
M.close_live(row)
34+
end
35+
return now
3236
end
3337

3438
function M.archive(row)

lua/agent-fleet/board.lua

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -298,14 +298,7 @@ function M.render(rows, opts)
298298
end
299299

300300
function M.done_candidates(cwd)
301-
local rows = M.rows({ cwd = cwd or vim.fn.getcwd() })
302-
local result = {}
303-
for _, row in ipairs(rows) do
304-
if not row.done then
305-
result[#result + 1] = row
306-
end
307-
end
308-
return result
301+
return M.rows({ cwd = cwd or vim.fn.getcwd() })
309302
end
310303

311304
function M.archive_candidates(cwd)

lua/agent-fleet/roster.lua

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,16 @@ function M.set_name(id, name)
102102
end)
103103
end
104104

105-
function M.mark_done(id)
105+
function M.set_done(id, done)
106106
return update(id, function(entry)
107-
entry.done = true
107+
entry.done = done
108108
end)
109109
end
110110

111+
function M.mark_done(id)
112+
return M.set_done(id, true)
113+
end
114+
111115
function M.set_archived(id, archived)
112116
return update(id, function(entry)
113117
entry.archived = archived

lua/agent-fleet/ui.lua

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -198,32 +198,44 @@ local function handle_enter()
198198
require("agent-fleet.agent").resume_session({ id = row.id, cwd = row.cwd, type = row.type })
199199
end
200200

201-
local function mark_rows_done(rows)
201+
local function toggle_done_rows(rows)
202202
if #rows == 0 then
203203
return
204204
end
205205
local actions = require("agent-fleet.actions")
206+
local done, undone = 0, 0
206207
for _, row in ipairs(rows) do
207-
actions.done(row)
208+
if actions.done(row) then
209+
done = done + 1
210+
else
211+
undone = undone + 1
212+
end
208213
end
209214
M.refresh()
210215
if #rows == 1 then
211-
notify("marked done \u{2014} " .. rows[1].name)
212-
else
213-
notify("marked done \u{2014} " .. #rows .. " agents")
216+
notify((done == 1 and "marked done" or "marked not done") .. " \u{2014} " .. rows[1].name)
217+
return
214218
end
219+
local parts = {}
220+
if done > 0 then
221+
parts[#parts + 1] = "done " .. done
222+
end
223+
if undone > 0 then
224+
parts[#parts + 1] = "not done " .. undone
225+
end
226+
notify(table.concat(parts, ", "))
215227
end
216228

217229
function M.done_range(line1, line2)
218-
mark_rows_done(M.rows_in_range(line1, line2))
230+
toggle_done_rows(M.rows_in_range(line1, line2))
219231
end
220232

221233
local function handle_done()
222234
local row = M.row_under_cursor()
223235
if not row then
224236
return
225237
end
226-
mark_rows_done({ row })
238+
toggle_done_rows({ row })
227239
end
228240

229241
local function visual_line_range()

plugin/agent-fleet.lua

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,11 @@ vim.api.nvim_create_user_command("AgentDone", function()
7474
local actions = require("agent-fleet.actions")
7575
local row = actions.current_row()
7676
if row then
77-
actions.done(row)
78-
vim.notify("agent-fleet: marked done \u{2014} " .. row.name, vim.log.levels.INFO)
77+
local now = actions.done(row)
78+
vim.notify(
79+
("agent-fleet: %s \u{2014} %s"):format(now and "marked done" or "marked not done", row.name),
80+
vim.log.levels.INFO
81+
)
7982
return
8083
end
8184
local cands = require("agent-fleet.board").done_candidates(vim.fn.getcwd())
@@ -85,17 +88,20 @@ vim.api.nvim_create_user_command("AgentDone", function()
8588
end
8689
local now = os.time() * 1000
8790
vim.ui.select(cands, {
88-
prompt = "Mark done",
91+
prompt = "Mark done / not done",
8992
format_item = function(row)
9093
return require("agent-fleet.board").format_row(row, now)
9194
end,
9295
}, function(chosen)
9396
if chosen then
94-
actions.done(chosen)
95-
vim.notify("agent-fleet: marked done \u{2014} " .. chosen.name, vim.log.levels.INFO)
97+
local now = actions.done(chosen)
98+
vim.notify(
99+
("agent-fleet: %s \u{2014} %s"):format(now and "marked done" or "marked not done", chosen.name),
100+
vim.log.levels.INFO
101+
)
96102
end
97103
end)
98-
end, { desc = "agent-fleet: mark a past agent done (current directory)" })
104+
end, { desc = "agent-fleet: toggle an agent done / not done (current directory)" })
99105

100106
vim.api.nvim_create_user_command("AgentArchive", function()
101107
local actions = require("agent-fleet.actions")

tests/actions_spec.lua

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,15 @@ local id_done2 = "dddddddd-dddd-dddd-dddd-dddddddddd02"
6262
actions.done({ id = id_done2, name = "doner2", cwd = "/proj/d", live = false })
6363
check("done non-live marks done", roster.get(id_done2) ~= nil and roster.get(id_done2).done == true)
6464

65+
-- done: un-doing a live row -> returns false, not done, buffer kept
66+
local id_undone = "dddddddd-dddd-dddd-dddd-dddddddddd03"
67+
local buf_undone = make_term()
68+
local res_undone =
69+
actions.done({ id = id_undone, name = "undoner", cwd = "/proj/d", live = true, bufnr = buf_undone, done = true })
70+
check("done returns false when un-doing", res_undone == false)
71+
check("undone clears done", roster.get(id_undone) ~= nil and roster.get(id_undone).done == false)
72+
check("undone keeps buffer", vim.api.nvim_buf_is_valid(buf_undone) == true)
73+
6574
-- archive: live unarchived row -> returns true, archived, buffer wiped
6675
local id_arch = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa01"
6776
local buf_arch = make_term()

tests/lifecycle_spec.lua

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ local function write_session(cwd, id, ts)
4747
return file
4848
end
4949

50-
-- Case 1: done_candidates includes a live agent and a disk-only (non-roster)
51-
-- session; excludes a done one and an archived one.
50+
-- Case 1: done_candidates includes a live agent, a disk-only (non-roster)
51+
-- session, and an already-done one (so it can be un-done); excludes an
52+
-- archived one.
5253
local C1 = "/proj/c1"
5354
local id_plain = "11111111-1111-1111-1111-111111111111"
5455
local id_done = "11111111-1111-1111-1111-111111111112"
@@ -69,7 +70,7 @@ local dc = board.done_candidates(C1)
6970
check("case1 plain present", has_id(dc, id_plain))
7071
check("case1 live included", has_id(dc, id_live))
7172
check("case1 disk-only included", has_id(dc, id_disk))
72-
check("case1 done excluded", not has_id(dc, id_done))
73+
check("case1 done included", has_id(dc, id_done))
7374
check("case1 archived excluded", not has_id(dc, id_arch))
7475
check("case1 row shape", find_id(dc, id_live).live == true)
7576

@@ -107,7 +108,9 @@ roster.ensure({ id = row3.id, type = "pi", name = row3.name, cwd = row3.cwd })
107108
roster.mark_done(row3.id)
108109
check("case3 entry materialized", roster.get(id3) ~= nil)
109110
check("case3 marked done", roster.get(id3).done == true)
110-
check("case3 drops out of done_candidates", not has_id(board.done_candidates(C3), id3))
111+
check("case3 stays in done_candidates so it can be un-done", has_id(board.done_candidates(C3), id3))
112+
roster.set_done(row3.id, false)
113+
check("case3 toggling again via set_done reverts done to false", roster.get(id3).done == false)
111114

112115
-- Case 4: materialize-then-flag archive toggling a previously-untracked row.
113116
local C4 = "/proj/c4"

tests/roster_spec.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ check(
3636

3737
r.mark_done("aaa")
3838
check("mark_done", r.get("aaa").done == true)
39+
r.set_done("aaa", true)
40+
r.set_done("aaa", false)
41+
check("set_done toggles off", r.get("aaa").done == false)
3942
r.set_name("aaa", "x")
4043
check("set_name", r.get("aaa").name == "x")
4144

0 commit comments

Comments
 (0)