Skip to content

feat(chat): add syntax highlighting for code blocks#1109

Merged
benoitf merged 3 commits intokortex-hub:mainfrom
fbricon:chat-highlighting
Mar 19, 2026
Merged

feat(chat): add syntax highlighting for code blocks#1109
benoitf merged 3 commits intokortex-hub:mainfrom
fbricon:chat-highlighting

Conversation

@fbricon
Copy link
Contributor

@fbricon fbricon commented Mar 17, 2026

Integrates highlight.js to provide syntax highlighting for code snippets in
chat messages. Uses CSS variables for automatic light/dark theme switching.

Light theme:
Light Theme

Dark Theme:
Dark Theme

Fixes 2 related issues:

  • ensures the chat view respects the Dark theme on application restart
  • adds a margin below the code snippets, so text doesn't look cramped

@fbricon fbricon requested a review from a team as a code owner March 17, 2026 08:09
@fbricon fbricon requested review from bmahabirbu and gastoner and removed request for a team March 17, 2026 08:09
@coderabbitai
Copy link

coderabbitai bot commented Mar 17, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds syntax highlighting support to the markdown renderer by introducing highlight.js dependency, a new renderMarkdown function that handles anchor transformation, header ID generation, and code block highlighting, plus a GitHub-style CSS theme file. The chat component is updated to synchronize theme settings with the app's appearance.

Changes

Cohort / File(s) Summary
Syntax Highlighting Foundation
packages/renderer/package.json, packages/renderer/src/lib/markdown/syntax-highlighting.css
Added highlight.js (^11.11.1) runtime dependency and introduced new GitHub-style CSS theme with light/dark mode support for syntax highlighting.
Markdown Rendering Enhancement
packages/renderer/src/lib/markdown/Markdown.svelte
Introduced renderMarkdown function that processes markdown source through multiple transformations: converts # anchors to data-pd-jump-in-page attributes, adds generated IDs to headers, rewrites podman-desktop:// URLs, applies hljs syntax highlighting to code blocks, and returns transformed HTML string.
Theme Synchronization
packages/renderer/src/lib/chat/route/CustomChat.svelte
Added app appearance store integration with derived forcedTheme constant, updated ThemeProvider to pass theme prop synchronized with application dark mode setting.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding syntax highlighting for code blocks in the chat feature.
Description check ✅ Passed The description relates directly to the changeset, explaining the integration of highlight.js for syntax highlighting and the theme switching mechanism.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/renderer/src/lib/markdown/syntax-highlighting.css (1)

65-71: Resolve duplicate .hljs-name token mapping.

Line 66 maps .hljs-name to --hljs-keyword, then Line 124 remaps it to --hljs-tag. The first mapping is effectively dead and makes token intent harder to maintain.

♻️ Proposed cleanup
 .hljs-section,
-.hljs-name,
 .hljs-selector-tag,
 .hljs-deletion,
 .hljs-subst {
   color: var(--hljs-keyword);
 }

Also applies to: 123-126

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/renderer/src/lib/markdown/syntax-highlighting.css` around lines 65 -
71, The CSS maps .hljs-name twice (first in the selector group with
.hljs-section, .hljs-selector-tag, .hljs-deletion, .hljs-subst to
var(--hljs-keyword) and later to var(--hljs-tag)), leaving the first mapping
dead and confusing; remove .hljs-name from the first selector group (or move it
only into the later rule that sets var(--hljs-tag)) so .hljs-name has a single,
clear mapping, and ensure both conflicting rule blocks
(.hljs-section/.hljs-selector-tag/.hljs-deletion/.hljs-subst and the later
.hljs-name/.hljs-tag group) reflect the intended semantic color variables.
packages/renderer/src/lib/markdown/Markdown.svelte (1)

50-50: Consider importing highlight.js/lib/core and manually registering required languages to reduce renderer bundle size.

Line 50 imports the full package, which registers all languages. According to highlight.js documentation, importing from lib/core and registering only needed languages results in a smaller bundle. However, this requires identifying which languages are used in your markdown and updating the highlightElement() calls accordingly, or detecting language from code block class hints.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/renderer/src/lib/markdown/Markdown.svelte` at line 50, Replace the
blanket import of highlight.js with the core build and explicitly register only
the languages used by our markdown renderer: change the import in
Markdown.svelte from the full package to 'highlight.js/lib/core' and import +
register each needed language (e.g., javascript, typescript, bash, json, css,
html) via hljs.registerLanguage(...). Keep using the existing highlightElement()
call but ensure it detects the language from the code block class (e.g.,
"language-xyz") or falls back to auto-detection; update any code that calls
highlightElement() to pass the detected language if required. This reduces
bundle size while preserving the current highlighting behavior in
Markdown.svelte.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/renderer/src/lib/markdown/Markdown.svelte`:
- Around line 82-97: The reactive markdown update block (the $: if (markdown) {
... } sequence that calls micromark, decode, DOMParser, highlights via
hljs.highlightElement, and assigns html) currently omits the link/heading
transforms that are applied later in onMount (the handlers that generate header
ids, rewrite podman-desktop:// links, and add jump/hash behavior), causing
inconsistencies after mount; extract the link/heading transform logic from
onMount into a shared function (e.g., applyTransforms or transformDoc) that
accepts the parsed/tempDoc or html and performs header id generation,
podman-desktop:// rewriting, and jump handling, then call that shared function
from both the reactive block (before assigning html) and from onMount so both
mount-time and reactive updates apply the same transforms.

---

Nitpick comments:
In `@packages/renderer/src/lib/markdown/Markdown.svelte`:
- Line 50: Replace the blanket import of highlight.js with the core build and
explicitly register only the languages used by our markdown renderer: change the
import in Markdown.svelte from the full package to 'highlight.js/lib/core' and
import + register each needed language (e.g., javascript, typescript, bash,
json, css, html) via hljs.registerLanguage(...). Keep using the existing
highlightElement() call but ensure it detects the language from the code block
class (e.g., "language-xyz") or falls back to auto-detection; update any code
that calls highlightElement() to pass the detected language if required. This
reduces bundle size while preserving the current highlighting behavior in
Markdown.svelte.

In `@packages/renderer/src/lib/markdown/syntax-highlighting.css`:
- Around line 65-71: The CSS maps .hljs-name twice (first in the selector group
with .hljs-section, .hljs-selector-tag, .hljs-deletion, .hljs-subst to
var(--hljs-keyword) and later to var(--hljs-tag)), leaving the first mapping
dead and confusing; remove .hljs-name from the first selector group (or move it
only into the later rule that sets var(--hljs-tag)) so .hljs-name has a single,
clear mapping, and ensure both conflicting rule blocks
(.hljs-section/.hljs-selector-tag/.hljs-deletion/.hljs-subst and the later
.hljs-name/.hljs-tag group) reflect the intended semantic color variables.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1e1f569c-4f5c-419f-ae3a-b1fbd640aae4

📥 Commits

Reviewing files that changed from the base of the PR and between 5b6bbf8 and b17d752.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • packages/renderer/package.json
  • packages/renderer/src/lib/markdown/Markdown.svelte
  • packages/renderer/src/lib/markdown/syntax-highlighting.css

@codecov
Copy link

codecov bot commented Mar 17, 2026

Codecov Report

❌ Patch coverage is 81.81818% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ages/renderer/src/lib/chat/route/CustomChat.svelte 0.00% 1 Missing ⚠️
packages/renderer/src/lib/markdown/Markdown.svelte 90.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@fbricon
Copy link
Contributor Author

fbricon commented Mar 17, 2026

I still need to fix an issue with the theme not being applied correctly on application restart done

@fbricon fbricon marked this pull request as draft March 17, 2026 08:54
@fbricon fbricon force-pushed the chat-highlighting branch 2 times, most recently from 68465d3 to fc89405 Compare March 17, 2026 10:20
@fbricon fbricon marked this pull request as ready for review March 17, 2026 10:23
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/renderer/src/lib/markdown/Markdown.svelte`:
- Around line 85-87: The reactive update currently only runs when markdown is
truthy, leaving previous html when markdown becomes an empty string; change the
reactive blocks that reference markdown and html (the "$: if (markdown) { html =
renderMarkdown(markdown); }" and the similar block around the 134-141 region) so
they always assign html — e.g., set html to renderMarkdown(markdown) when
markdown has content and to an empty string when it does not (use a conditional
assignment based on markdown in the reactive statement).
- Line 129: The inline arrow callback passed to
doc.querySelectorAll(...).forEach currently uses an implicit return (block =>
hljs.highlightElement(...)); change it to an explicit block-bodied arrow (block
=> { hljs.highlightElement(...); }) so the callback is clearly a side-effecting
statement; update the occurrence where doc.querySelectorAll('pre code').forEach
is called and ensure the callback body contains the highlight call wrapped in
braces.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 42834d68-28da-4c39-86cc-11d90588458d

📥 Commits

Reviewing files that changed from the base of the PR and between b17d752 and fc89405.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (5)
  • packages/renderer/package.json
  • packages/renderer/src/lib/chat/route/CustomChat.svelte
  • packages/renderer/src/lib/chat/route/main-chat-layout.svelte
  • packages/renderer/src/lib/markdown/Markdown.svelte
  • packages/renderer/src/lib/markdown/syntax-highlighting.css
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/renderer/package.json
  • packages/renderer/src/lib/markdown/syntax-highlighting.css

@fbricon fbricon force-pushed the chat-highlighting branch from fc89405 to d0ba131 Compare March 17, 2026 10:31
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (2)
packages/renderer/src/lib/markdown/Markdown.svelte (2)

85-87: ⚠️ Potential issue | 🟠 Major

Reactive rendering still skips empty markdown and can leave stale content.

At Line 85, the truthy guard prevents clearing html when markdown becomes '', so old rendered output can remain visible.

Proposed fix
-$: if (markdown) {
-  html = renderMarkdown(markdown);
-}
+$: {
+  html = renderMarkdown(markdown ?? '');
+}
@@
 onMount(() => {
   if (markdown) {
     text = markdown;
   }
 
   // Render markdown with all transformations applied
-  html = renderMarkdown(text);
+  html = renderMarkdown(markdown ? markdown : (text ?? ''));
 });

Also applies to: 134-141

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/renderer/src/lib/markdown/Markdown.svelte` around lines 85 - 87, The
reactive guard currently only runs renderMarkdown when markdown is truthy, so
when markdown becomes an empty string it leaves stale html; change the reactive
statements that set html (the one using markdown and the other similar block
later around renderMarkdown) to always set html = markdown ?
renderMarkdown(markdown) : '' (i.e., explicitly clear html when markdown is
empty) and reference the renderMarkdown function and the markdown and html
variables to locate and update both reactive blocks.

129-129: ⚠️ Potential issue | 🟡 Minor

Biome lint error remains on forEach implicit return callback.

At Line 129, this still triggers lint/suspicious/useIterableCallbackReturn; use a block body for side-effect-only callbacks.

Proposed fix
-  doc.querySelectorAll('pre code').forEach(block => hljs.highlightElement(block as HTMLElement));
+  doc.querySelectorAll('pre code').forEach(block => {
+    hljs.highlightElement(block as HTMLElement);
+  });
#!/bin/bash
# Verify the pattern still exists in the current branch
rg -n "querySelectorAll\\('pre code'\\)\\.forEach\\(block => hljs\\.highlightElement" packages/renderer/src/lib/markdown/Markdown.svelte
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/renderer/src/lib/markdown/Markdown.svelte` at line 129, The lint
error is caused by the concise arrow callback used for side effects in the
forEach call; change the callback for doc.querySelectorAll('pre code').forEach
from a concise-body arrow to a block-body arrow (or a named function) so the
callback uses a statement body that calls hljs.highlightElement(block as
HTMLElement); update the callback at the forEach invocation in Markdown.svelte
(referencing doc.querySelectorAll, forEach and hljs.highlightElement) to use {
hljs.highlightElement(block as HTMLElement); } as the body.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/renderer/src/lib/markdown/Markdown.svelte`:
- Line 108: The code currently calls decode(rendered) before parsing, which can
re-enable escaped HTML and introduce XSS; update the DOM parsing in
Markdown.svelte to stop calling decode on the user-provided rendered string
(i.e., use rendered directly when creating doc via new
DOMParser().parseFromString) and ensure any HTML inserted with {`@html` html} is
sanitized (e.g., run through your sanitizer) or only used for trusted sources;
modify the usage around the DOMParser invocation and the html variable to remove
decode and add sanitization where appropriate.
- Around line 111-117: In the anchor-processing loop inside Markdown.svelte (the
doc.querySelectorAll('a').forEach callback), do not remove the href attribute —
keep the existing href so links remain focusable and keyboard-activatable;
instead set data-pd-jump-in-page to currentHref.substring(1) (and keep
link.classList.add('cursor-pointer')). Update the click/key activation handler
(the listener that performs smooth-scroll) to detect links with
data-pd-jump-in-page, call event.preventDefault() there, and perform the
smooth-scroll; this preserves native keyboard semantics while still enabling
in-page jump handling.

---

Duplicate comments:
In `@packages/renderer/src/lib/markdown/Markdown.svelte`:
- Around line 85-87: The reactive guard currently only runs renderMarkdown when
markdown is truthy, so when markdown becomes an empty string it leaves stale
html; change the reactive statements that set html (the one using markdown and
the other similar block later around renderMarkdown) to always set html =
markdown ? renderMarkdown(markdown) : '' (i.e., explicitly clear html when
markdown is empty) and reference the renderMarkdown function and the markdown
and html variables to locate and update both reactive blocks.
- Line 129: The lint error is caused by the concise arrow callback used for side
effects in the forEach call; change the callback for doc.querySelectorAll('pre
code').forEach from a concise-body arrow to a block-body arrow (or a named
function) so the callback uses a statement body that calls
hljs.highlightElement(block as HTMLElement); update the callback at the forEach
invocation in Markdown.svelte (referencing doc.querySelectorAll, forEach and
hljs.highlightElement) to use { hljs.highlightElement(block as HTMLElement); }
as the body.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 825f536b-bea0-4d6d-b553-00f1d91f3b74

📥 Commits

Reviewing files that changed from the base of the PR and between fc89405 and d0ba131.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (5)
  • packages/renderer/package.json
  • packages/renderer/src/lib/chat/route/CustomChat.svelte
  • packages/renderer/src/lib/chat/route/main-chat-layout.svelte
  • packages/renderer/src/lib/markdown/Markdown.svelte
  • packages/renderer/src/lib/markdown/syntax-highlighting.css
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/renderer/src/lib/chat/route/main-chat-layout.svelte
  • packages/renderer/src/lib/chat/route/CustomChat.svelte
  • packages/renderer/package.json

@fbricon fbricon force-pushed the chat-highlighting branch from d0ba131 to 5411230 Compare March 17, 2026 11:41
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
packages/renderer/src/lib/markdown/Markdown.svelte (1)

106-106: ⚠️ Potential issue | 🔴 Critical

XSS risk: decode() may re-enable escaped HTML.

The decode() function converts HTML entities back to raw characters before DOM parsing. If micromark escaped malicious input (e.g., &lt;script&gt;), decode() would convert it back to <script>, which then gets injected via {@html html}.

🔒 Proposed fix
-  const doc = new DOMParser().parseFromString(decode(rendered), 'text/html');
+  const doc = new DOMParser().parseFromString(rendered, 'text/html');
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/renderer/src/lib/markdown/Markdown.svelte` at line 106, The code
calls decode(rendered) before new DOMParser().parseFromString(...) which can
re-enable escaped HTML and allow XSS when the result is later injected via
{`@html` html}; remove the decode(...) step and instead sanitize the HTML produced
by micromark (the rendered variable) before parsing or injecting (e.g., run
rendered through a trusted sanitizer such as DOMPurify.sanitize or your existing
sanitizer) so DOMParser.parseFromString and the {`@html` html} binding only ever
receive sanitized HTML; update the code paths around rendered,
DOMParser.parseFromString and any use of {`@html` html} to use the sanitized
output.
🧹 Nitpick comments (1)
packages/renderer/src/lib/markdown/syntax-highlighting.css (1)

5-44: Unused CSS custom properties create maintenance overhead.

Several variables are defined but never used in the selectors:

  • --hljs-variable (lines 15, 36) — .hljs-variable uses --hljs-number instead (line 92)
  • --hljs-attribute (lines 16, 37) — .hljs-attribute uses --hljs-string instead (line 79)
  • --hljs-type (lines 14, 35) — .hljs-type uses --hljs-number instead (line 87)

If this grouping is intentional for visual consistency, consider removing the unused variables to avoid confusion. Otherwise, update the selectors to reference the intended variables.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/renderer/src/lib/markdown/syntax-highlighting.css` around lines 5 -
44, The CSS file defines custom properties (--hljs-variable, --hljs-attribute,
--hljs-type) that are not actually used by the selectors; update either the
selectors or the variables so names match: either remove the unused properties
(--hljs-variable, --hljs-attribute, --hljs-type) to reduce clutter, or change
the selectors (.hljs-variable, .hljs-attribute, .hljs-type) to reference the
intended properties instead of using --hljs-number or --hljs-string; locate
these names in syntax-highlighting.css and make the variables/selectors
consistent across the :root/.dark blocks and the .hljs-* rules.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/renderer/src/lib/markdown/Markdown.svelte`:
- Around line 121-124: The header ID generation in the doc.querySelectorAll('h1,
h2, h3, h4, h5, h6') loop is too naive; replace the current id =
header.textContent?.toLowerCase().replace(/\s/g, '-') logic in the header
processing to a proper slugify routine that (1) trims whitespace, lowercases,
removes/normalizes diacritics, replaces any sequence of non-alphanumeric
characters with a single hyphen, collapses multiple hyphens, and strips
leading/trailing hyphens to produce valid HTML IDs, and (2) ensures uniqueness
by tracking generated slugs (e.g., a Map or object keyed by slug) and appending
a counter suffix like -1, -2 when duplicates occur before calling
header.setAttribute('id', id); this change should be applied where header is
handled inside that forEach.

---

Duplicate comments:
In `@packages/renderer/src/lib/markdown/Markdown.svelte`:
- Line 106: The code calls decode(rendered) before new
DOMParser().parseFromString(...) which can re-enable escaped HTML and allow XSS
when the result is later injected via {`@html` html}; remove the decode(...) step
and instead sanitize the HTML produced by micromark (the rendered variable)
before parsing or injecting (e.g., run rendered through a trusted sanitizer such
as DOMPurify.sanitize or your existing sanitizer) so DOMParser.parseFromString
and the {`@html` html} binding only ever receive sanitized HTML; update the code
paths around rendered, DOMParser.parseFromString and any use of {`@html` html} to
use the sanitized output.

---

Nitpick comments:
In `@packages/renderer/src/lib/markdown/syntax-highlighting.css`:
- Around line 5-44: The CSS file defines custom properties (--hljs-variable,
--hljs-attribute, --hljs-type) that are not actually used by the selectors;
update either the selectors or the variables so names match: either remove the
unused properties (--hljs-variable, --hljs-attribute, --hljs-type) to reduce
clutter, or change the selectors (.hljs-variable, .hljs-attribute, .hljs-type)
to reference the intended properties instead of using --hljs-number or
--hljs-string; locate these names in syntax-highlighting.css and make the
variables/selectors consistent across the :root/.dark blocks and the .hljs-*
rules.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: be5f4b29-b5dd-44a8-b3e5-dde2a0d6d352

📥 Commits

Reviewing files that changed from the base of the PR and between d0ba131 and 5411230.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • packages/renderer/package.json
  • packages/renderer/src/lib/markdown/Markdown.svelte
  • packages/renderer/src/lib/markdown/syntax-highlighting.css
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/renderer/package.json

Copy link
Contributor

@gastoner gastoner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that not every change is really related to the feature

Otherwise tried on Linux, is working fine

const doc = parser.parseFromString(decode(html), 'text/html');
const links = doc.querySelectorAll('a');
links.forEach(link => {
const doc = new DOMParser().parseFromString(decode(rendered), 'text/html');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we can really just replace the html -> rendered

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure what you mean here

@fbricon fbricon force-pushed the chat-highlighting branch from 5411230 to a52a0bb Compare March 18, 2026 10:38
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/renderer/src/lib/markdown/Markdown.svelte (1)

134-140: Consider avoiding redundant rendering when markdown prop is provided.

When the markdown prop is truthy, renderMarkdown is called twice on mount:

  1. Via the reactive binding at line 85
  2. Via onMount at line 140

This is functionally correct but performs redundant work.

💡 Optional optimization
 onMount(() => {
-  if (markdown) {
-    text = markdown;
+  // Only render here if using slot content (markdown prop is empty)
+  // When markdown prop exists, the reactive binding already handles rendering
+  if (!markdown && text) {
+    html = renderMarkdown(text);
   }
-
-  // Render markdown with all transformations applied
-  html = text ? renderMarkdown(text) : '';

   // We create a click listener in order to execute any internal micromark commands
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/renderer/src/lib/markdown/Markdown.svelte` around lines 134 - 140,
The onMount handler redundantly calls renderMarkdown when the reactive binding
already rendered HTML from the markdown prop; update the onMount in
Markdown.svelte so it only assigns text = markdown (or otherwise sets the prop)
and does not call renderMarkdown again — i.e., remove the html = text ?
renderMarkdown(text) : '' line from onMount (or guard it to run only if html is
empty) and let the existing reactive block (which uses renderMarkdown) perform
rendering for consistency with the markdown/text/reactive flow.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/renderer/src/lib/markdown/Markdown.svelte`:
- Around line 134-140: The onMount handler redundantly calls renderMarkdown when
the reactive binding already rendered HTML from the markdown prop; update the
onMount in Markdown.svelte so it only assigns text = markdown (or otherwise sets
the prop) and does not call renderMarkdown again — i.e., remove the html = text
? renderMarkdown(text) : '' line from onMount (or guard it to run only if html
is empty) and let the existing reactive block (which uses renderMarkdown)
perform rendering for consistency with the markdown/text/reactive flow.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a57719cf-2b32-44f0-bb19-46cfe7007a12

📥 Commits

Reviewing files that changed from the base of the PR and between 5411230 and a52a0bb.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • packages/renderer/package.json
  • packages/renderer/src/lib/chat/route/CustomChat.svelte
  • packages/renderer/src/lib/markdown/Markdown.svelte
  • packages/renderer/src/lib/markdown/syntax-highlighting.css
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/renderer/src/lib/chat/route/CustomChat.svelte
  • packages/renderer/src/lib/markdown/syntax-highlighting.css

@fbricon fbricon force-pushed the chat-highlighting branch 2 times, most recently from 26952a0 to 6412eb4 Compare March 18, 2026 11:29
@benoitf
Copy link
Contributor

benoitf commented Mar 18, 2026

there is now a conflict as I merged another PR related to Markdown file

probably #1115 will also conflict, I don't know which one you want to merge first ?

fbricon and others added 2 commits March 18, 2026 15:23
The chat views use @sejohnson/svelte-themes ThemeProvider with
attribute="class" to control dark mode via Tailwind's dark: variant.
This is the only part of the app that uses ThemeProvider — the rest
uses Appearance.svelte with the isDark store and --pd-* CSS variables.

On restart with appearance set to "Dark", the ThemeProvider would read
its own localStorage value and apply "light" before the app's config
loaded, causing mixed light/dark colors in the chat UI.

Fix: use forcedTheme prop bound to the app's isDark store so the
ThemeProvider always syncs with the app's appearance setting.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Signed-off-by: Fred Bricon <fbricon@gmail.com>
Add spacing between code blocks and following content to prevent
text from appearing cramped against the code block.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Signed-off-by: Fred Bricon <fbricon@gmail.com>
@fbricon fbricon force-pushed the chat-highlighting branch from 6412eb4 to 58089db Compare March 18, 2026 14:33
@fbricon
Copy link
Contributor Author

fbricon commented Mar 18, 2026

I fixed the conflict here. Once you merge it I'll move on to the other one

Integrates highlight.js to provide syntax highlighting for code snippets in
chat messages. Uses CSS variables for automatic light/dark theme switching.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Signed-off-by: Fred Bricon <fbricon@gmail.com>
@fbricon fbricon force-pushed the chat-highlighting branch from 58089db to 5be7b52 Compare March 18, 2026 15:01
@benoitf benoitf merged commit 7651253 into kortex-hub:main Mar 19, 2026
15 checks passed
@fbricon fbricon self-assigned this Mar 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants