diff --git a/src/hooks/start-work/index.test.ts b/src/hooks/start-work/index.test.ts index 3a12ca2c8..31f73fdfb 100644 --- a/src/hooks/start-work/index.test.ts +++ b/src/hooks/start-work/index.test.ts @@ -151,5 +151,90 @@ describe("start-work hook", () => { expect(output.parts[0].text).not.toContain("$TIMESTAMP") expect(output.parts[0].text).toMatch(/\d{4}-\d{2}-\d{2}T/) }) + + test("should auto-select when only one incomplete plan among multiple plans", async () => { + // #given - multiple plans but only one incomplete + const plansDir = join(TEST_DIR, ".sisyphus", "plans") + mkdirSync(plansDir, { recursive: true }) + + // Plan 1: complete (all checked) + const plan1Path = join(plansDir, "plan-complete.md") + writeFileSync(plan1Path, "# Plan Complete\n- [x] Task 1\n- [x] Task 2") + + // Plan 2: incomplete (has unchecked) + const plan2Path = join(plansDir, "plan-incomplete.md") + writeFileSync(plan2Path, "# Plan Incomplete\n- [ ] Task 1\n- [x] Task 2") + + const hook = createStartWorkHook(createMockPluginInput()) + const output = { + parts: [{ type: "text", text: "Start Sisyphus work session" }], + } + + // #when + await hook["chat.message"]( + { sessionID: "session-123" }, + output + ) + + // #then - should auto-select the incomplete plan, not ask user + expect(output.parts[0].text).toContain("Auto-Selected Plan") + expect(output.parts[0].text).toContain("plan-incomplete") + expect(output.parts[0].text).not.toContain("Multiple Plans Found") + }) + + test("should wrap multiple plans message in system-reminder tag", async () => { + // #given - multiple incomplete plans + const plansDir = join(TEST_DIR, ".sisyphus", "plans") + mkdirSync(plansDir, { recursive: true }) + + const plan1Path = join(plansDir, "plan-a.md") + writeFileSync(plan1Path, "# Plan A\n- [ ] Task 1") + + const plan2Path = join(plansDir, "plan-b.md") + writeFileSync(plan2Path, "# Plan B\n- [ ] Task 2") + + const hook = createStartWorkHook(createMockPluginInput()) + const output = { + parts: [{ type: "text", text: "Start Sisyphus work session" }], + } + + // #when + await hook["chat.message"]( + { sessionID: "session-123" }, + output + ) + + // #then - should use system-reminder tag format + expect(output.parts[0].text).toContain("") + expect(output.parts[0].text).toContain("") + expect(output.parts[0].text).toContain("Multiple Plans Found") + }) + + test("should use 'ask user' prompt style for multiple plans", async () => { + // #given - multiple incomplete plans + const plansDir = join(TEST_DIR, ".sisyphus", "plans") + mkdirSync(plansDir, { recursive: true }) + + const plan1Path = join(plansDir, "plan-x.md") + writeFileSync(plan1Path, "# Plan X\n- [ ] Task 1") + + const plan2Path = join(plansDir, "plan-y.md") + writeFileSync(plan2Path, "# Plan Y\n- [ ] Task 2") + + const hook = createStartWorkHook(createMockPluginInput()) + const output = { + parts: [{ type: "text", text: "Start Sisyphus work session" }], + } + + // #when + await hook["chat.message"]( + { sessionID: "session-123" }, + output + ) + + // #then - should prompt agent to ask user, not ask directly + expect(output.parts[0].text).toContain("Ask the user") + expect(output.parts[0].text).not.toContain("Which plan would you like to work on?") + }) }) }) diff --git a/src/hooks/start-work/index.ts b/src/hooks/start-work/index.ts index d58c2455d..d7a8c6922 100644 --- a/src/hooks/start-work/index.ts +++ b/src/hooks/start-work/index.ts @@ -80,6 +80,7 @@ Looking for new plans...` if (!existingState || getPlanProgress(existingState.active_plan).isComplete) { const plans = findPrometheusPlans(ctx.directory) + const incompletePlans = plans.filter(p => !getPlanProgress(p).isComplete) if (plans.length === 0) { contextInfo += ` @@ -88,8 +89,14 @@ Looking for new plans...` No Prometheus plan files found at .sisyphus/plans/ Use Prometheus to create a work plan first: /plan "your task"` - } else if (plans.length === 1) { - const planPath = plans[0] + } else if (incompletePlans.length === 0) { + contextInfo += ` + +## All Plans Complete + +All ${plans.length} plan(s) are complete. Create a new plan with: /plan "your task"` + } else if (incompletePlans.length === 1) { + const planPath = incompletePlans[0] const progress = getPlanProgress(planPath) const newState = createBoulderState(planPath, sessionId) writeBoulderState(ctx.directory, newState) @@ -106,7 +113,7 @@ Use Prometheus to create a work plan first: /plan "your task"` boulder.json has been created. Read the plan and begin execution.` } else { - const planList = plans.map((p, i) => { + const planList = incompletePlans.map((p, i) => { const progress = getPlanProgress(p) const stat = require("node:fs").statSync(p) const modified = new Date(stat.mtimeMs).toISOString() @@ -115,6 +122,7 @@ boulder.json has been created. Read the plan and begin execution.` contextInfo += ` + ## Multiple Plans Found Current Time: ${timestamp} @@ -122,7 +130,8 @@ Session ID: ${sessionId} ${planList} -Which plan would you like to work on? Reply with the number or plan name.` +Ask the user which plan to work on. Present the options above and wait for their response. +` } }