From 5e07811952f6f3f74da2eb761a60e235f8ed92c6 Mon Sep 17 00:00:00 2001
From: Nalla Prakash <81852531+prakashNalla@users.noreply.github.com>
Date: Mon, 2 Nov 2026 17:31:05 +0530
Subject: [PATCH] fix(widget): drop the whole language tag from a code block
---
.changeset/fence-language-tag.md | 5 +++++
packages/widget/src/markdown.ts | 2 +-
packages/widget/tests/markdown.test.ts | 17 +++++++++++++++++
3 files changed, 23 insertions(+), 1 deletion(-)
create mode 100644 .changeset/fence-language-tag.md
diff --git a/.changeset/fence-language-tag.md b/.changeset/fence-language-tag.md
new file mode 100644
index 00000000..59261cde
--- /dev/null
+++ b/.changeset/fence-language-tag.md
@@ -0,0 +1,5 @@
+---
+"@chatcops/widget": patch
+---
+
+A code block tagged `c++`, `c#` or `objective-c` no longer shows part of the tag as its first line, and a one-line code block keeps all of its text.
diff --git a/packages/widget/src/markdown.ts b/packages/widget/src/markdown.ts
index 71586fd4..18dfb0f9 100644
--- a/packages/widget/src/markdown.ts
+++ b/packages/widget/src/markdown.ts
@@ -42,7 +42,7 @@ export function renderMarkdown(input: string): string {
// Code blocks (``` ... ```) — stashed before any markdown transformation so
// their content stays literal and their newlines survive the
step.
- html = html.replace(/```(?:\w*)\n?([\s\S]*?)```/g, (_match, code: string) => {
+ html = html.replace(/```(?:[^`\n]*\n)?([\s\S]*?)```/g, (_match, code: string) => {
return stashHtml(`
${code.trim()}`);
});
diff --git a/packages/widget/tests/markdown.test.ts b/packages/widget/tests/markdown.test.ts
index 6ef853b1..28136119 100644
--- a/packages/widget/tests/markdown.test.ts
+++ b/packages/widget/tests/markdown.test.ts
@@ -21,6 +21,23 @@ describe('renderMarkdown', () => {
expect(result).toContain('const x = 1;');
});
+ it.each(['c++', 'c#', 'objective-c', 'ts'])('drops a %s language tag from a code block', (lang) => {
+ expect(renderMarkdown(`\`\`\`${lang}\nint x;\n\`\`\``)).toBe('int x;');
+ });
+
+ it('keeps all the text of a one-line code block', () => {
+ expect(renderMarkdown('```const x```')).toBe('const x');
+ });
+
+ it('drops a language tag with a space after it', () => {
+ expect(renderMarkdown('```ts \nconst x = 1;\n```')).toBe('const x = 1;');
+ });
+
+ it('leaves a code block that is still streaming as text', () => {
+ expect(renderMarkdown('```ts\nconst x = 1;')).toBe('```ts