From 4381b034122d151c10924f24e9b04e91f28d8332 Mon Sep 17 00:00:00 2001 From: Jake Date: Fri, 9 Jan 2026 21:56:45 +1300 Subject: [PATCH 1/2] Auto-Reply: relax regex for reply tags to allow whitespace --- src/auto-reply/reply/reply-tags.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/auto-reply/reply/reply-tags.ts b/src/auto-reply/reply/reply-tags.ts index d7f2e4fe3..86ca07956 100644 --- a/src/auto-reply/reply/reply-tags.ts +++ b/src/auto-reply/reply/reply-tags.ts @@ -11,18 +11,18 @@ export function extractReplyToTag( let replyToId: string | undefined; let hasTag = false; - const currentMatch = cleaned.match(/\[\[reply_to_current\]\]/i); + const currentMatch = cleaned.match(/\[\[\s*reply_to_current\s*\]\]/i); if (currentMatch) { - cleaned = cleaned.replace(/\[\[reply_to_current\]\]/gi, " "); + cleaned = cleaned.replace(/\[\[\s*reply_to_current\s*\]\]/gi, " "); hasTag = true; if (currentMessageId?.trim()) { replyToId = currentMessageId.trim(); } } - const idMatch = cleaned.match(/\[\[reply_to:([^\]\n]+)\]\]/i); + const idMatch = cleaned.match(/\[\[\s*reply_to\s*:\s*([^\]\n]+)\s*\]\]/i); if (idMatch?.[1]) { - cleaned = cleaned.replace(/\[\[reply_to:[^\]\n]+\]\]/gi, " "); + cleaned = cleaned.replace(/\[\[\s*reply_to\s*:[^\]\n]+\]\]/gi, " "); replyToId = idMatch[1].trim(); hasTag = true; } From 7d9300e0f598114c63d73b1df7e77fe05f4e5f52 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 9 Jan 2026 17:03:44 +0100 Subject: [PATCH 2/2] fix: allow whitespace in reply tags (#560) (thanks @mcinteerj) --- CHANGELOG.md | 1 + src/auto-reply/reply.directive.parse.test.ts | 12 ++++++++++++ src/auto-reply/reply/reply-tags.ts | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 783575b69..e401cbfa7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ - Auto-reply: block reply ordering fix (duplicate PR superseded by #503). (#483) — thanks @AbhisekBasu1 - Auto-reply: avoid splitting outbound chunks inside parentheses. (#499) — thanks @philipp-spiess - Auto-reply: preserve spacing when stripping inline directives. (#539) — thanks @joshp123 +- Auto-reply: relax reply tag parsing to allow whitespace. (#560) — thanks @mcinteerj - Auto-reply: fix /status usage summary filtering for the active provider. - Status: show provider prefix in /status model display. (#506) — thanks @mcinteerj - Status: compact /status with session token usage + estimated cost, add `/cost` per-response usage lines (tokens-only for OAuth). diff --git a/src/auto-reply/reply.directive.parse.test.ts b/src/auto-reply/reply.directive.parse.test.ts index e3a2fecfb..ad03d8fa6 100644 --- a/src/auto-reply/reply.directive.parse.test.ts +++ b/src/auto-reply/reply.directive.parse.test.ts @@ -162,12 +162,24 @@ describe("directive parsing", () => { expect(res.cleaned).toBe("ok"); }); + it("extracts reply_to_current tag with whitespace", () => { + const res = extractReplyToTag("ok [[ reply_to_current ]]", "msg-1"); + expect(res.replyToId).toBe("msg-1"); + expect(res.cleaned).toBe("ok"); + }); + it("extracts reply_to id tag", () => { const res = extractReplyToTag("see [[reply_to:12345]] now", "msg-1"); expect(res.replyToId).toBe("12345"); expect(res.cleaned).toBe("see now"); }); + it("extracts reply_to id tag with whitespace", () => { + const res = extractReplyToTag("see [[ reply_to : 12345 ]] now", "msg-1"); + expect(res.replyToId).toBe("12345"); + expect(res.cleaned).toBe("see now"); + }); + it("preserves newlines when stripping reply tags", () => { const res = extractReplyToTag( "line 1\nline 2 [[reply_to_current]]\n\nline 3", diff --git a/src/auto-reply/reply/reply-tags.ts b/src/auto-reply/reply/reply-tags.ts index 86ca07956..ef2de524a 100644 --- a/src/auto-reply/reply/reply-tags.ts +++ b/src/auto-reply/reply/reply-tags.ts @@ -22,7 +22,7 @@ export function extractReplyToTag( const idMatch = cleaned.match(/\[\[\s*reply_to\s*:\s*([^\]\n]+)\s*\]\]/i); if (idMatch?.[1]) { - cleaned = cleaned.replace(/\[\[\s*reply_to\s*:[^\]\n]+\]\]/gi, " "); + cleaned = cleaned.replace(/\[\[\s*reply_to\s*:\s*[^\]\n]+\s*\]\]/gi, " "); replyToId = idMatch[1].trim(); hasTag = true; }