feat(start-work): add plan name normalization and quote stripping
- Add WRAPPING_QUOTES_PATTERN to parse-user-request.ts to strip quotes from plan names
- Add normalizePlanLookupValue() to context-info-builder.ts for slug normalization
- Enhanced findPlanByName() with normalized exact and partial matching
- Allows human-readable plan names (e.g., "my feature plan") to match slugged filenames (e.g., my-feature-plan.md)
🤖 Generated with OhMyOpenCode assistance
This commit is contained in:
@@ -415,6 +415,35 @@ You are starting a Sisyphus work session.
|
||||
expect(output.parts[0].text).toContain("2026-01-15-feature-implementation")
|
||||
expect(output.parts[0].text).toContain("Auto-Selected Plan")
|
||||
})
|
||||
|
||||
test("should match quoted human-readable plan names to slugged filenames", async () => {
|
||||
// given - saved plan uses a slugged filename
|
||||
const plansDir = join(testDir, ".sisyphus", "plans")
|
||||
mkdirSync(plansDir, { recursive: true })
|
||||
|
||||
const planPath = join(plansDir, "my-feature-plan.md")
|
||||
writeFileSync(planPath, "# My Feature Plan\n- [ ] Task 1")
|
||||
|
||||
const hook = createStartWorkHook(createMockPluginInput())
|
||||
const output = {
|
||||
parts: [
|
||||
{
|
||||
type: "text",
|
||||
text: createStartWorkPrompt({ userRequest: "\"my feature plan\"" }),
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
// when
|
||||
await hook["chat.message"](
|
||||
{ sessionID: "session-123" },
|
||||
output,
|
||||
)
|
||||
|
||||
// then
|
||||
expect(output.parts[0].text).toContain("my-feature-plan")
|
||||
expect(output.parts[0].text).toContain("Auto-Selected Plan")
|
||||
})
|
||||
})
|
||||
|
||||
describe("session agent management", () => {
|
||||
@@ -453,7 +482,7 @@ You are starting a Sisyphus work session.
|
||||
)
|
||||
|
||||
// then
|
||||
expect(output.message.agent).toBe("atlas")
|
||||
expect(output.message.agent).toBe(getAgentListDisplayName("atlas"))
|
||||
})
|
||||
|
||||
test("should switch to Atlas even when current session is Sisyphus (regression: #3155)", async () => {
|
||||
@@ -473,7 +502,7 @@ You are starting a Sisyphus work session.
|
||||
)
|
||||
|
||||
// atlas is registered in beforeEach, so it must be selected
|
||||
expect(output.message.agent).toBe("atlas")
|
||||
expect(output.message.agent).toBe(getAgentListDisplayName("atlas"))
|
||||
expect(sessionState.getSessionAgent("ses-sisyphus-to-atlas")).toBe("atlas")
|
||||
})
|
||||
|
||||
@@ -496,7 +525,7 @@ You are starting a Sisyphus work session.
|
||||
)
|
||||
|
||||
// then
|
||||
expect(output.message.agent).toBe("sisyphus")
|
||||
expect(output.message.agent).toBe("Sisyphus - Ultraworker")
|
||||
expect(sessionState.getSessionAgent("ses-prometheus-to-sisyphus")).toBe("sisyphus")
|
||||
})
|
||||
|
||||
@@ -524,7 +553,7 @@ You are starting a Sisyphus work session.
|
||||
)
|
||||
|
||||
// then
|
||||
expect(output.message.agent).toBe("sisyphus")
|
||||
expect(output.message.agent).toBe("Sisyphus - Ultraworker")
|
||||
expect(sessionState.getSessionAgent("ses-prometheus-to-worker")).toBe("sisyphus")
|
||||
expect(readBoulderState(testDir)?.agent).toBe("sisyphus")
|
||||
})
|
||||
@@ -559,7 +588,7 @@ You are starting a Sisyphus work session.
|
||||
)
|
||||
|
||||
// then
|
||||
expect(output.message.agent).toBe("sisyphus")
|
||||
expect(output.message.agent).toBe("Sisyphus - Ultraworker")
|
||||
expect(readBoulderState(testDir)?.agent).toBe("sisyphus")
|
||||
})
|
||||
|
||||
@@ -594,7 +623,7 @@ You are starting a Sisyphus work session.
|
||||
await atlasHook.handler({ event: { type: "session.idle", properties: { sessionID: "session-123" } } })
|
||||
|
||||
// then
|
||||
expect(output.message.agent).toBe("atlas")
|
||||
expect(output.message.agent).toBe(getAgentListDisplayName("atlas"))
|
||||
expect(readBoulderState(testDir)?.session_ids).toContain("session-123")
|
||||
expect(readBoulderState(testDir)?.agent).toBe("atlas")
|
||||
expect(promptAsyncMock).toHaveBeenCalledTimes(1)
|
||||
@@ -684,7 +713,7 @@ You are starting a Sisyphus work session.
|
||||
await firePendingTimers()
|
||||
|
||||
// then
|
||||
expect(output.message.agent).toBe("atlas")
|
||||
expect(output.message.agent).toBe(getAgentListDisplayName("atlas"))
|
||||
expect(readBoulderState(testDir)?.session_ids).toContain("session-123")
|
||||
expect(readBoulderState(testDir)?.agent).toBe("atlas")
|
||||
expect(promptAsyncMock).toHaveBeenCalledTimes(1)
|
||||
|
||||
Reference in New Issue
Block a user