From 44443795b5d80ec3bedd98007ba25fb2394b389e Mon Sep 17 00:00:00 2001 From: wassname <1103714+wassname@users.noreply.github.com> Date: Sat, 12 Sep 2026 21:40:10 +0800 Subject: [PATCH] Prioritize unfinished goals in widget --- src/index.ts | 6 +++++- test/goals.test.ts | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/index.ts b/src/index.ts index a165362..720fbcb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -121,7 +121,11 @@ export default function mainSupervisor(pi: ExtensionAPI) { const accepted = items.filter((g) => g.status === "done" && state.signoffs[key(g.subject)]).length; ctx.ui.setStatus("goals", `👀 ${accepted}/${items.length} goals`); const mark = (status: GoalStatus) => status === "done" ? "✔" : status === "active" ? "◼" : status === "cancelled" ? "✗" : "◻"; - const lines = items.slice(0, WIDGET_GOAL_LIMIT).map((g, index) => `${mark(g.status)} G${index + 1}: ${g.subject}`); + const priority: Record = { active: 0, open: 1, done: 2, cancelled: 3 }; + const visible = [...items].sort((a, b) => priority[a.status] - priority[b.status]).slice(0, WIDGET_GOAL_LIMIT); + const lines = visible.map((g) => `${mark(g.status)} G${items.indexOf(g) + 1}: ${g.subject}`); + const hidden = items.length - visible.length; + if (hidden) lines.push(`… ${hidden} more goal${hidden === 1 ? "" : "s"}`); ctx.ui.setWidget("goals", lines); } function watchPlan(ctx: ExtensionContext) { diff --git a/test/goals.test.ts b/test/goals.test.ts index 4be6220..6f07880 100644 --- a/test/goals.test.ts +++ b/test/goals.test.ts @@ -585,11 +585,11 @@ it("lineage-only child attaches its plan without a widget, retains task context, expect(completion.content[0].text).toContain("only to the active parent"); }); -it("shows only the first three goals in the widget", async () => { +it("prioritizes unfinished goals and says when the widget list is truncated", async () => { const f = fixture(); await f.draft(); - writeFileSync(f.path, "- [ ] goal: one\n- [ ] goal: two\n- [ ] goal: three\n- [ ] goal: four\n"); + writeFileSync(f.path, "- [x] goal: completed one\n- [x] goal: completed two\n- [/] goal: active work\n- [ ] goal: open one\n- [ ] goal: open two\n"); await f.command("ready"); - expect(f.ctx.ui.setWidget.mock.lastCall?.[1]).toEqual(["◻ G1: one", "◻ G2: two", "◻ G3: three"]); + expect(f.ctx.ui.setWidget.mock.lastCall?.[1]).toEqual(["◼ G3: active work", "◻ G4: open one", "◻ G5: open two", "… 2 more goals"]); f.shutdown(); });