This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new b95eea2e3389 CAMEL-24759: camel-jbang - upgrade tamboui to 0.5.0 with 
window title and syntax highlighting (#26482)
b95eea2e3389 is described below

commit b95eea2e33896b3d1bfea3f0cd52137a52e79d41
Author: Adriano Machado <[email protected]>
AuthorDate: Wed Sep 16 15:18:48 2026 -0400

    CAMEL-24759: camel-jbang - upgrade tamboui to 0.5.0 with window title and 
syntax highlighting (#26482)
    
    Bump tamboui from 0.4.0 to 0.5.0. The TUI sets the terminal window title 
("Camel TUI", or "Camel TUI: <name>" for the selected process) through the new 
TuiRunner.setWindowTitle API, and a theme-aware SyntaxTheme is wired into the 
13 MarkdownView sites so fenced code blocks in docs, help overlays and the AI 
chat panel are syntax coloured (Monokai palette in dark mode, a GitHub-like one 
in light mode). The web frontend loads the xterm.js Unicode 11 addon so the 
browser uses the same cha [...]
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
    Co-Authored-By: Claude Opus 5 <[email protected]>
---
 .../camel/dsl/jbang/core/commands/tui/AiPanel.java |  3 +-
 .../dsl/jbang/core/commands/tui/CamelMonitor.java  | 15 ++++++++++
 .../dsl/jbang/core/commands/tui/CveAuditTab.java   |  1 +
 .../core/commands/tui/DiagramDetailSupport.java    |  3 ++
 .../jbang/core/commands/tui/DocViewerPopup.java    |  2 ++
 .../dsl/jbang/core/commands/tui/EndpointsTab.java  |  3 ++
 .../dsl/jbang/core/commands/tui/HelpOverlay.java   |  1 +
 .../dsl/jbang/core/commands/tui/SourceViewer.java  |  1 +
 .../camel/dsl/jbang/core/commands/tui/Theme.java   | 35 ++++++++++++++++++++++
 .../src/main/resources/tui/web/index.html          |  4 +++
 .../resources/tui/web/vendor/LICENSE-xterm.txt     | 11 +++++--
 .../tui/web/vendor/xterm-addon-unicode11.js        |  2 ++
 parent/pom.xml                                     |  2 +-
 13 files changed, 78 insertions(+), 5 deletions(-)

diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanel.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanel.java
index 9d5b1b6f831b..84696942d1dc 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanel.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanel.java
@@ -2193,7 +2193,8 @@ class AiPanel {
         // couple of lines hidden below the visible area.
         MarkdownView.Builder viewBuilder = MarkdownView.builder()
                 .source(source)
-                .styles(Theme.chatMarkdownStyles());
+                .styles(Theme.chatMarkdownStyles())
+                .syntaxTheme(Theme.syntaxTheme());
         MarkdownView measure = viewBuilder.build();
         int totalLines = measure.computeHeight(mdArea.width());
 
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
index 90225935f5f6..9454f5319860 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
@@ -202,6 +202,7 @@ public class CamelMonitor extends CamelCommand {
     // the AI panel overlays the editor, so it is hidden while an edit is 
replayed and shown again afterwards
     private boolean replayHidAiPanel;
     private TuiRunner runner;
+    private String lastWindowTitle;
     // Set by TuiWebServer for browser sessions; local terminal sessions leave 
this null
     // and let TuiBackendHelper auto-detect the active terminal instead.
     Backend webBackend;
@@ -1030,6 +1031,7 @@ public class CamelMonitor extends CamelCommand {
                 // session registers it.
                 Signal.handle(new Signal("INT"), sig -> tui.quit());
             }
+            updateWindowTitle();
             tui.run(
                     this::handleEvent,
                     this::render);
@@ -1851,6 +1853,7 @@ public class CamelMonitor extends CamelCommand {
             dataService.refresh(runner, this::refreshLogData, 
this::refreshConditionalData);
             tabRegistry.routesTab().refreshDiagramIfNeeded();
             tabRegistry.diagramTab().refreshDiagramIfNeeded();
+            updateWindowTitle();
             dataRefreshed = true;
         }
         // Redraw only when the periodic data refresh fired or an animation is 
in flight.
@@ -3064,6 +3067,18 @@ public class CamelMonitor extends CamelCommand {
         ctx.selectedPid = phantom.pid;
     }
 
+    private void updateWindowTitle() {
+        if (runner == null) {
+            return;
+        }
+        String name = ctx != null && ctx.selectedPid != null ? 
ctx.selectedName() : null;
+        String title = name != null ? "Camel TUI: " + name : "Camel TUI";
+        if (!title.equals(lastWindowTitle)) {
+            lastWindowTitle = title;
+            runner.setWindowTitle(title);
+        }
+    }
+
     void setRunnerForTesting(Runnable onQuit) {
         aiPanel.setExitCallbackForTestingOrRuntime(onQuit);
     }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CveAuditTab.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CveAuditTab.java
index a7fd1c8ee5f6..fb69a634eb07 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CveAuditTab.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CveAuditTab.java
@@ -337,6 +337,7 @@ class CveAuditTab extends AbstractTableTab {
                         .scroll(detailScroll)
                         
.block(Block.builder().borderType(BorderType.ROUNDED).borders(Borders.ALL).title(title).build())
                         .styles(Theme.markdownStyles())
+                        .syntaxTheme(Theme.syntaxTheme())
                         .build(),
                 area);
     }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramDetailSupport.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramDetailSupport.java
index 3565dd3771f3..cf8cc265aa01 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramDetailSupport.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramDetailSupport.java
@@ -487,6 +487,7 @@ final class DiagramDetailSupport {
                             
.block(Block.builder().borderType(BorderType.ROUNDED).borders(Borders.ALL)
                                     .title(" EIP Detail ").build())
                             .styles(Theme.markdownStyles())
+                            .syntaxTheme(Theme.syntaxTheme())
                             .build(),
                     area);
             return;
@@ -501,6 +502,7 @@ final class DiagramDetailSupport {
                             
.block(Block.builder().borderType(BorderType.ROUNDED).borders(Borders.ALL)
                                     .title(" EIP Detail ").build())
                             .styles(Theme.markdownStyles())
+                            .syntaxTheme(Theme.syntaxTheme())
                             .build(),
                     area);
             return;
@@ -551,6 +553,7 @@ final class DiagramDetailSupport {
                         
.block(Block.builder().borderType(BorderType.ROUNDED).borders(Borders.ALL)
                                 .title(title).build())
                         .styles(Theme.markdownStyles())
+                        .syntaxTheme(Theme.syntaxTheme())
                         .build(),
                 area);
     }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DocViewerPopup.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DocViewerPopup.java
index 797c861a9c1e..c3c79bce3a92 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DocViewerPopup.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DocViewerPopup.java
@@ -264,6 +264,7 @@ class DocViewerPopup {
         int offset = MarkdownView.builder()
                 .source(prefix)
                 .styles(Theme.markdownStyles())
+                .syntaxTheme(Theme.syntaxTheme())
                 .build()
                 .computeHeight(lastContentWidth);
         docScroll = offset;
@@ -618,6 +619,7 @@ class DocViewerPopup {
                     .source(docContent)
                     .scroll(docScroll)
                     .styles(Theme.markdownStyles())
+                    .syntaxTheme(Theme.syntaxTheme())
                     .build();
             frame.renderWidget(view, hChunks.get(0));
             int totalHeight = view.computeHeight(lastContentWidth);
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/EndpointsTab.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/EndpointsTab.java
index 997980952706..a51aa87b522d 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/EndpointsTab.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/EndpointsTab.java
@@ -566,6 +566,7 @@ class EndpointsTab extends AbstractTableTab {
                                     .borderStyle(detailBorderStyle)
                                     .title(Title.from(Line.from(Span.styled(" 
Endpoint Detail ", detailTitleStyle)))).build())
                             .styles(Theme.markdownStyles())
+                            .syntaxTheme(Theme.syntaxTheme())
                             .build(),
                     area);
             return;
@@ -582,6 +583,7 @@ class EndpointsTab extends AbstractTableTab {
                                     .borderStyle(detailBorderStyle)
                                     .title(Title.from(Line.from(Span.styled(" 
Endpoint Detail ", detailTitleStyle)))).build())
                             .styles(Theme.markdownStyles())
+                            .syntaxTheme(Theme.syntaxTheme())
                             .build(),
                     area);
             return;
@@ -683,6 +685,7 @@ class EndpointsTab extends AbstractTableTab {
                                 .borderStyle(detailBorderStyle)
                                 .title(Title.from(Line.from(Span.styled(title, 
detailTitleStyle)))).build())
                         .styles(Theme.markdownStyles())
+                        .syntaxTheme(Theme.syntaxTheme())
                         .build(),
                 area);
     }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HelpOverlay.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HelpOverlay.java
index ca2aa1a6b4c6..a73b1d81ac14 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HelpOverlay.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HelpOverlay.java
@@ -99,6 +99,7 @@ class HelpOverlay {
                 .scroll(scroll)
                 .block(block)
                 .styles(Theme.markdownStyles())
+                .syntaxTheme(Theme.syntaxTheme())
                 .build();
         frame.renderWidget(view, popup);
     }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java
index 38afe57018b6..b489a9666b04 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java
@@ -1560,6 +1560,7 @@ class SourceViewer {
                     .scroll(markdownScroll)
                     .block(block)
                     .styles(Theme.markdownStyles())
+                    .syntaxTheme(Theme.syntaxTheme())
                     .build();
             frame.renderWidget(view, area);
             return;
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/Theme.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/Theme.java
index 5ff339e2c612..6043ff456ad6 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/Theme.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/Theme.java
@@ -31,6 +31,8 @@ import dev.tamboui.css.Styleable;
 import dev.tamboui.css.engine.StyleEngine;
 import dev.tamboui.style.Color;
 import dev.tamboui.style.Style;
+import dev.tamboui.widgets.syntax.SyntaxTheme;
+import dev.tamboui.widgets.syntax.TokenType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -293,6 +295,39 @@ public final class Theme {
                 .link(Style.EMPTY.fg(accent()).underlined());
     }
 
+    /**
+     * Theme-aware syntax highlighting palette for fenced code blocks in 
MarkdownView. Reuses the Monokai (dark) and
+     * GitHub-inspired (light) palettes from {@link SyntaxHighlighter}.
+     */
+    public static SyntaxTheme syntaxTheme() {
+        if (isDark()) {
+            return SyntaxTheme.builder()
+                    .token(TokenType.COMMENT, 
Style.EMPTY.fg(SyntaxHighlighter.MONOKAI_COMMENT))
+                    .token(TokenType.KEYWORD, 
Style.EMPTY.fg(SyntaxHighlighter.MONOKAI_KEYWORD))
+                    .token(TokenType.TYPE, 
Style.EMPTY.fg(SyntaxHighlighter.MONOKAI_TYPE))
+                    .token(TokenType.STRING, 
Style.EMPTY.fg(SyntaxHighlighter.MONOKAI_STRING))
+                    .token(TokenType.NUMBER, 
Style.EMPTY.fg(SyntaxHighlighter.MONOKAI_CONSTANT))
+                    .token(TokenType.CONSTANT, 
Style.EMPTY.fg(SyntaxHighlighter.MONOKAI_CONSTANT))
+                    .token(TokenType.FUNCTION, 
Style.EMPTY.fg(SyntaxHighlighter.MONOKAI_FUNCTION))
+                    .token(TokenType.ANNOTATION, 
Style.EMPTY.fg(SyntaxHighlighter.MONOKAI_FUNCTION))
+                    .token(TokenType.TAG, 
Style.EMPTY.fg(SyntaxHighlighter.MONOKAI_KEYWORD))
+                    .token(TokenType.ATTRIBUTE, 
Style.EMPTY.fg(SyntaxHighlighter.MONOKAI_FUNCTION))
+                    .build();
+        }
+        return SyntaxTheme.builder()
+                .token(TokenType.COMMENT, Style.EMPTY.fg(Color.rgb(106, 115, 
125)))
+                .token(TokenType.KEYWORD, Style.EMPTY.fg(Color.rgb(215, 58, 
73)))
+                .token(TokenType.TYPE, Style.EMPTY.fg(Color.rgb(0, 92, 197)))
+                .token(TokenType.STRING, Style.EMPTY.fg(Color.rgb(3, 47, 98)))
+                .token(TokenType.NUMBER, Style.EMPTY.fg(Color.rgb(111, 66, 
193)))
+                .token(TokenType.CONSTANT, Style.EMPTY.fg(Color.rgb(111, 66, 
193)))
+                .token(TokenType.FUNCTION, Style.EMPTY.fg(Color.rgb(0, 92, 
197)))
+                .token(TokenType.ANNOTATION, Style.EMPTY.fg(Color.rgb(0, 92, 
197)))
+                .token(TokenType.TAG, Style.EMPTY.fg(Color.rgb(215, 58, 73)))
+                .token(TokenType.ATTRIBUTE, Style.EMPTY.fg(Color.rgb(0, 92, 
197)))
+                .build();
+    }
+
     /** Diagram box-drawing border color. */
     public static synchronized Color diagramBorder() {
         return color("diagram-border", FALLBACK_DIAGRAM_BORDER);
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/web/index.html 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/web/index.html
index 5ffe7b3cfd4f..4362ef184eaf 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/web/index.html
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/web/index.html
@@ -143,6 +143,7 @@
 
   <script src="/vendor/xterm.js"></script>
   <script src="/vendor/xterm-addon-fit.js"></script>
+  <script src="/vendor/xterm-addon-unicode11.js"></script>
   <script>
     (function () {
       'use strict';
@@ -198,6 +199,9 @@
 
           fitAddon = new FitAddon.FitAddon();
           term.loadAddon(fitAddon);
+          var unicode11Addon = new Unicode11Addon.Unicode11Addon();
+          term.loadAddon(unicode11Addon);
+          term.unicode.activeVersion = '11';
           term.open(document.getElementById('terminal-container'));
 
           function sendInit() {
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/web/vendor/LICENSE-xterm.txt
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/web/vendor/LICENSE-xterm.txt
index 234ea0e7c225..9cad528cd98c 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/web/vendor/LICENSE-xterm.txt
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/web/vendor/LICENSE-xterm.txt
@@ -1,6 +1,6 @@
 This directory bundles the following third-party components, vendored to
-avoid a runtime dependency on a CDN. Neither is modified from its upstream
-release.
+avoid a runtime dependency on a CDN. None are modified from their upstream
+releases.
 
 xterm.js 5.5.0 (xterm.js, xterm.css)
 https://github.com/xtermjs/xterm.js
@@ -14,7 +14,12 @@ 
https://github.com/xtermjs/xterm.js/tree/master/addons/addon-fit
 
 Copyright (c) 2019, The xterm.js authors (https://github.com/xtermjs/xterm.js)
 
-Both are released under the MIT License:
+xterm-addon-unicode11 0.9.0 (xterm-addon-unicode11.js)
+https://github.com/xtermjs/xterm.js/tree/master/addons/addon-unicode11
+
+Copyright (c) 2019, The xterm.js authors (https://github.com/xtermjs/xterm.js)
+
+All are released under the MIT License:
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/web/vendor/xterm-addon-unicode11.js
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/web/vendor/xterm-addon-unicode11.js
new file mode 100644
index 000000000000..941130afb3ad
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/web/vendor/xterm-addon-unicode11.js
@@ -0,0 +1,2 @@
+!function(e,t){"object"==typeof exports&&"object"==typeof 
module?module.exports=t():"function"==typeof 
define&&define.amd?define([],t):"object"==typeof 
exports?exports.Unicode11Addon=t():e.Unicode11Addon=t()}(globalThis,(()=>(()=>{"use
 strict";var 
e={384:(e,t,s)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.UnicodeV11=void
 0;const 
r=s(765),n=[[768,879],[1155,1161],[1425,1469],[1471,1471],[1473,1474],[1476,1477],[1479,1479],[1536,1541],[1552,1562],[1564,1564],[1611,1631],[1648,1648
 [...]
+//# sourceMappingURL=addon-unicode11.js.map
\ No newline at end of file
diff --git a/parent/pom.xml b/parent/pom.xml
index 72b5b21b60fc..0f6c5f179025 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -522,7 +522,7 @@
         <swagger-ui-version>5.32.14</swagger-ui-version>
         <stringtemplate-version>4.3.4</stringtemplate-version>
         <tahu-version>1.0.21</tahu-version>
-        <tamboui-version>0.4.0</tamboui-version>
+        <tamboui-version>0.5.0</tamboui-version>
         <testcontainers-version>2.0.5</testcontainers-version>
         <thymeleaf-version>3.1.5.RELEASE</thymeleaf-version>
         <tika-version>4.0.0</tika-version>

Reply via email to