feat(start-work): auto-select single incomplete plan and use system-reminder format
- Auto-select when only one incomplete plan exists among multiple - Wrap multiple plans message in <system-reminder> tag - Change prompt to 'ask user' style for agent guidance - Add 'All Plans Complete' state handling
This commit is contained in:
parent
57fb5e0c71
commit
64b9b4d36a
@ -151,5 +151,90 @@ describe("start-work hook", () => {
|
|||||||
expect(output.parts[0].text).not.toContain("$TIMESTAMP")
|
expect(output.parts[0].text).not.toContain("$TIMESTAMP")
|
||||||
expect(output.parts[0].text).toMatch(/\d{4}-\d{2}-\d{2}T/)
|
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("<system-reminder>")
|
||||||
|
expect(output.parts[0].text).toContain("</system-reminder>")
|
||||||
|
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?")
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -80,6 +80,7 @@ Looking for new plans...`
|
|||||||
|
|
||||||
if (!existingState || getPlanProgress(existingState.active_plan).isComplete) {
|
if (!existingState || getPlanProgress(existingState.active_plan).isComplete) {
|
||||||
const plans = findPrometheusPlans(ctx.directory)
|
const plans = findPrometheusPlans(ctx.directory)
|
||||||
|
const incompletePlans = plans.filter(p => !getPlanProgress(p).isComplete)
|
||||||
|
|
||||||
if (plans.length === 0) {
|
if (plans.length === 0) {
|
||||||
contextInfo += `
|
contextInfo += `
|
||||||
@ -88,8 +89,14 @@ Looking for new plans...`
|
|||||||
|
|
||||||
No Prometheus plan files found at .sisyphus/plans/
|
No Prometheus plan files found at .sisyphus/plans/
|
||||||
Use Prometheus to create a work plan first: /plan "your task"`
|
Use Prometheus to create a work plan first: /plan "your task"`
|
||||||
} else if (plans.length === 1) {
|
} else if (incompletePlans.length === 0) {
|
||||||
const planPath = plans[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 progress = getPlanProgress(planPath)
|
||||||
const newState = createBoulderState(planPath, sessionId)
|
const newState = createBoulderState(planPath, sessionId)
|
||||||
writeBoulderState(ctx.directory, newState)
|
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.`
|
boulder.json has been created. Read the plan and begin execution.`
|
||||||
} else {
|
} else {
|
||||||
const planList = plans.map((p, i) => {
|
const planList = incompletePlans.map((p, i) => {
|
||||||
const progress = getPlanProgress(p)
|
const progress = getPlanProgress(p)
|
||||||
const stat = require("node:fs").statSync(p)
|
const stat = require("node:fs").statSync(p)
|
||||||
const modified = new Date(stat.mtimeMs).toISOString()
|
const modified = new Date(stat.mtimeMs).toISOString()
|
||||||
@ -115,6 +122,7 @@ boulder.json has been created. Read the plan and begin execution.`
|
|||||||
|
|
||||||
contextInfo += `
|
contextInfo += `
|
||||||
|
|
||||||
|
<system-reminder>
|
||||||
## Multiple Plans Found
|
## Multiple Plans Found
|
||||||
|
|
||||||
Current Time: ${timestamp}
|
Current Time: ${timestamp}
|
||||||
@ -122,7 +130,8 @@ Session ID: ${sessionId}
|
|||||||
|
|
||||||
${planList}
|
${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.
|
||||||
|
</system-reminder>`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user