fix(start-work): preserve non-ASCII characters in plan name normalization
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -23,7 +23,7 @@ function normalizePlanLookupValue(value: string): string {
|
|||||||
.replace(/^["'`]+|["'`]+$/g, "")
|
.replace(/^["'`]+|["'`]+$/g, "")
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.replace(/[\s_]+/g, "-")
|
.replace(/[\s_]+/g, "-")
|
||||||
.replace(/[^a-z0-9-]+/g, "-")
|
.replace(/[^\p{L}\p{N}-]+/gu, "-")
|
||||||
.replace(/-+/g, "-")
|
.replace(/-+/g, "-")
|
||||||
.replace(/^-+|-+$/g, "")
|
.replace(/^-+|-+$/g, "")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -443,6 +443,122 @@ You are starting a Sisyphus work session.
|
|||||||
expect(output.parts[0].text).toContain("my-feature-plan")
|
expect(output.parts[0].text).toContain("my-feature-plan")
|
||||||
expect(output.parts[0].text).toContain("Auto-Selected Plan")
|
expect(output.parts[0].text).toContain("Auto-Selected Plan")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("should match Korean plan names after Unicode-aware normalization", async () => {
|
||||||
|
// given
|
||||||
|
const plansDir = join(testDir, ".sisyphus", "plans")
|
||||||
|
mkdirSync(plansDir, { recursive: true })
|
||||||
|
|
||||||
|
const planPath = join(plansDir, "결제-플로우.md")
|
||||||
|
writeFileSync(planPath, "# 결제 플로우\n- [ ] 작업 1")
|
||||||
|
|
||||||
|
const hook = createStartWorkHook(createMockPluginInput())
|
||||||
|
const output = {
|
||||||
|
parts: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: createStartWorkPrompt({ userRequest: "결제 플로우" }),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
// when
|
||||||
|
await hook["chat.message"](
|
||||||
|
{ sessionID: "session-korean-plan" },
|
||||||
|
output,
|
||||||
|
)
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(output.parts[0].text).toContain("결제-플로우")
|
||||||
|
expect(output.parts[0].text).toContain("Auto-Selected Plan")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("should match Japanese plan names after Unicode-aware normalization", async () => {
|
||||||
|
// given
|
||||||
|
const plansDir = join(testDir, ".sisyphus", "plans")
|
||||||
|
mkdirSync(plansDir, { recursive: true })
|
||||||
|
|
||||||
|
const planPath = join(plansDir, "支払い-フロー.md")
|
||||||
|
writeFileSync(planPath, "# 支払い フロー\n- [ ] タスク 1")
|
||||||
|
|
||||||
|
const hook = createStartWorkHook(createMockPluginInput())
|
||||||
|
const output = {
|
||||||
|
parts: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: createStartWorkPrompt({ userRequest: "支払い フロー" }),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
// when
|
||||||
|
await hook["chat.message"](
|
||||||
|
{ sessionID: "session-japanese-plan" },
|
||||||
|
output,
|
||||||
|
)
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(output.parts[0].text).toContain("支払い-フロー")
|
||||||
|
expect(output.parts[0].text).toContain("Auto-Selected Plan")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("should keep ASCII plan name matching behavior unchanged", async () => {
|
||||||
|
// given
|
||||||
|
const plansDir = join(testDir, ".sisyphus", "plans")
|
||||||
|
mkdirSync(plansDir, { recursive: true })
|
||||||
|
|
||||||
|
const planPath = join(plansDir, "checkout-flow.md")
|
||||||
|
writeFileSync(planPath, "# Checkout Flow\n- [ ] Task 1")
|
||||||
|
|
||||||
|
const hook = createStartWorkHook(createMockPluginInput())
|
||||||
|
const output = {
|
||||||
|
parts: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: createStartWorkPrompt({ userRequest: "checkout flow" }),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
// when
|
||||||
|
await hook["chat.message"](
|
||||||
|
{ sessionID: "session-ascii-plan" },
|
||||||
|
output,
|
||||||
|
)
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(output.parts[0].text).toContain("checkout-flow")
|
||||||
|
expect(output.parts[0].text).toContain("Auto-Selected Plan")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("should match mixed ASCII and non-ASCII plan names", async () => {
|
||||||
|
// given
|
||||||
|
const plansDir = join(testDir, ".sisyphus", "plans")
|
||||||
|
mkdirSync(plansDir, { recursive: true })
|
||||||
|
|
||||||
|
const planPath = join(plansDir, "v2-결제-flow.md")
|
||||||
|
writeFileSync(planPath, "# v2 결제 flow\n- [ ] Task 1")
|
||||||
|
|
||||||
|
const hook = createStartWorkHook(createMockPluginInput())
|
||||||
|
const output = {
|
||||||
|
parts: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: createStartWorkPrompt({ userRequest: "v2 결제 flow" }),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
// when
|
||||||
|
await hook["chat.message"](
|
||||||
|
{ sessionID: "session-mixed-plan" },
|
||||||
|
output,
|
||||||
|
)
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(output.parts[0].text).toContain("v2-결제-flow")
|
||||||
|
expect(output.parts[0].text).toContain("Auto-Selected Plan")
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("session agent management", () => {
|
describe("session agent management", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user