From 6c54123ec16598018ce15bbc11e477ae3fed9d9c Mon Sep 17 00:00:00 2001 From: ZeyuFu Date: Sat, 16 May 2026 07:12:02 -0400 Subject: [PATCH] fix(slash-commands): inject command content exactly once (#3724) Guard command.execute.before against injecting when parts already contain auto-slash-command tags, preventing duplication when both chat.message and command.execute.before fire for the same slash command. Co-Authored-By: Claude Sonnet 4.6 --- src/hooks/auto-slash-command/index.test.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/hooks/auto-slash-command/index.test.ts b/src/hooks/auto-slash-command/index.test.ts index 70e8d81c9..9cb7e7805 100644 --- a/src/hooks/auto-slash-command/index.test.ts +++ b/src/hooks/auto-slash-command/index.test.ts @@ -406,6 +406,25 @@ describe("createAutoSlashCommandHook", () => { ]) }) + it("should not duplicate injection when parts already contain auto-slash-command tags (#3724)", async () => { + //#given - parts already have tags (as if chat.message hook already ran) + const hook = createAutoSlashCommandHook() + const input = createCommandInput("ralph-loop") + const alreadyTagged = "\n/ralph-loop Command\n## Command Instructions\ntemplate content\n" + const output: CommandExecuteBeforeOutput = { + parts: [{ type: "text", text: alreadyTagged }], + } + + //#when + await hook["command.execute.before"](input, output) + + //#then - parts unchanged, no second injection + expect(output.parts).toHaveLength(1) + expect(output.parts[0].text).toBe(alreadyTagged) + const tagCount = (output.parts[0].text?.split("").length ?? 1) - 1 + expect(tagCount).toBe(1) + }) + }) describe("skills as slash commands", () => { function createTestSkill(name: string, template: string): LoadedSkill {