From 52d015e615dfef97e0b64d8a97aba1910c6d55f4 Mon Sep 17 00:00:00 2001 From: galuis116 Date: Thu, 25 Jun 2026 05:27:25 -0400 Subject: [PATCH] fix(github): require a handle boundary after @gittensory in mention parsing (#1344) --- src/github/commands.ts | 5 ++++- test/unit/github-commands.test.ts | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/github/commands.ts b/src/github/commands.ts index 092349bec7..975565f31b 100644 --- a/src/github/commands.ts +++ b/src/github/commands.ts @@ -162,7 +162,10 @@ export type MaintainerQueueDigest = { export function parseGittensoryMentionCommand(body: string | null | undefined): GittensoryMentionCommand | null { if (!body) return null; - const match = body.match(/(?:^|\s)@gittensory(?:\s+([a-z-]+))?([^\n\r]*)/i); + // `(?![\w-])` keeps the handle from matching as a PREFIX of a longer GitHub username: a comment that + // mentions a different account like `@gittensory-bot` / `@gittensory2` must NOT be parsed as a bare + // `@gittensory help`. GitHub usernames are word chars + hyphen, so the boundary excludes both. + const match = body.match(/(?:^|\s)@gittensory(?![\w-])(?:\s+([a-z-]+))?([^\n\r]*)/i); if (!match) return null; const requested = (match[1]?.toLowerCase() || "help") as GittensoryMentionCommandName | GittensoryActionCommandName; if (ACTION_COMMANDS.has(requested as GittensoryActionCommandName)) { diff --git a/test/unit/github-commands.test.ts b/test/unit/github-commands.test.ts index 2a807faf6a..da761d0ab3 100644 --- a/test/unit/github-commands.test.ts +++ b/test/unit/github-commands.test.ts @@ -39,6 +39,13 @@ describe("GitHub mention commands", () => { reason: "known false positive, shipping", }); expect(parseGittensoryMentionCommand("gittensory preflight")).toBeNull(); + // A mention of a DIFFERENT account whose handle merely starts with "gittensory" must not be parsed as a + // bare @gittensory command (GitHub never resolves @gittensory-bot to @gittensory). + expect(parseGittensoryMentionCommand("@gittensory-bot please take a look")).toBeNull(); + expect(parseGittensoryMentionCommand("@gittensory2 ping")).toBeNull(); + expect(parseGittensoryMentionCommand("@gittensorybot ask q")).toBeNull(); + // ...but real punctuation/whitespace boundaries after the handle still parse. + expect(parseGittensoryMentionCommand("@gittensory, preflight please")?.name).toBe("help"); expect(isMaintainerOnlyCommand("queue-summary")).toBe(true); expect(isMaintainerOnlyCommand("preflight")).toBe(false); });