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 3c3f2687d9e8 camel-tui: Add --record option and demo tape recordings
(#23364)
3c3f2687d9e8 is described below
commit 3c3f2687d9e8b5b4c8ccb6f2b160c1608dfdd83c
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed May 20 13:43:18 2026 +0200
camel-tui: Add --record option and demo tape recordings (#23364)
Add TamboUI-based demo recording support to Camel TUI monitor:
- New --record CLI option that activates TamboUI's headless RecordingBackend
for artifact-free terminal recordings via .tape interaction scripts
- Hello world demo tape with screenshots and animated gif
- record.sh wrapper script for easy recording
- Register .tape file extension with license-maven-plugin (SCRIPT_STYLE)
Co-authored-by: Claude Opus 4.6 <[email protected]>
---
.../docs/video/camel-tui-hello.cast | 59 +++++++++++++++++++++
.../docs/video/camel-tui-hello.gif | Bin 0 -> 685576 bytes
.../docs/video/camel-tui-hello.tape | 54 +++++++++++++++++++
.../camel-jbang-plugin-tui/docs/video/readme.md | 56 +++++++++++++++++++
.../camel-jbang-plugin-tui/docs/video/record.sh | 53 ++++++++++++++++++
.../video/screenshots/camel-tui-hello-diagram.png | 1 +
.../screenshots/camel-tui-hello-endpoints.png | 1 +
.../video/screenshots/camel-tui-hello-health.png | 1 +
.../docs/video/screenshots/camel-tui-hello-log.png | 1 +
.../video/screenshots/camel-tui-hello-overview.png | 1 +
.../video/screenshots/camel-tui-hello-routes.png | 1 +
.../dsl/jbang/core/commands/tui/CamelMonitor.java | 17 ++++++
pom.xml | 2 +
13 files changed, 247 insertions(+)
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/camel-tui-hello.cast
b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/camel-tui-hello.cast
new file mode 100644
index 000000000000..4031c45820de
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/camel-tui-hello.cast
@@ -0,0 +1,59 @@
+{"version": 2, "width": 200, "height": 50, "timestamp": 1779272014, "env":
{"TERM": "xterm-256color"}}
+[0.000000, "o", "\u001b[2J\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel
TUI\u001b[0m \u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1
integration(s)\u001b[0m
\u001b[2;1H
[...]
+[0.140000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[2;1H
[...]
+[0.406000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[2;1H
[...]
+[0.680000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[2;1H
[...]
+[1.602000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[2;1H
[...]
+[1.734000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[2;1H
[...]
+[2.270000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[2;1H
[...]
+[2.527000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[2;1H
[...]
+[2.662000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[2;1H
[...]
+[2.795000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[2;1H
[...]
+[3.330000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[2;1H
[...]
+[3.457000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[2;1H
[...]
+[3.717000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[2;1H
[...]
+[4.148000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[4.678000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[5.734000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[6.648000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[7.681000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[7.812000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[8.191000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[8.981000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[9.646000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[10.703000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[11.881000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[12.119000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[12.254000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[12.788000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[13.169000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[13.439000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[13.809000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[14.444000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[14.834000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[15.484000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[15.849000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[16.650000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[16.913000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[17.150000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[17.283000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[17.650000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[18.830000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[19.757000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[20.820000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[21.223000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[25.297000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[25.559000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[25.686000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[25.929000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[26.289000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[26.527000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[26.770000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[27.009000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[27.415000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[27.544000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[27.815000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[28.081000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[28.478000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[28.739000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
+[29.134000, "o", "\u001b[1;1H\u001b[0;38;2;246;145;35;1m Camel TUI\u001b[0m
\u001b[0;32mv4.21.0-SNAPSHOT\u001b[0m \u001b[0;36m1 integration(s)\u001b[0m
\u001b[0;33mselected: timer-log\u001b[0m
\u001b[2;1H
[...]
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/camel-tui-hello.gif
b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/camel-tui-hello.gif
new file mode 100644
index 000000000000..8026062396cf
Binary files /dev/null and
b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/camel-tui-hello.gif differ
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/camel-tui-hello.tape
b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/camel-tui-hello.tape
new file mode 100644
index 000000000000..a0de446c05fc
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/camel-tui-hello.tape
@@ -0,0 +1,54 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Overview tab shows running integrations
+Sleep 4s
+Screenshot screenshots/camel-tui-hello-overview.png
+
+# Routes tab - see the timer route
+Type "3"
+Sleep 4s
+Screenshot screenshots/camel-tui-hello-routes.png
+
+# Route diagram
+Type "D"
+Sleep 4s
+Screenshot screenshots/camel-tui-hello-diagram.png
+Type "D"
+Sleep 1s
+
+# Endpoints tab
+Type "5"
+Sleep 4s
+Screenshot screenshots/camel-tui-hello-endpoints.png
+
+# Log tab - see Hello World messages flowing
+Type "2"
+Sleep 4s
+Screenshot screenshots/camel-tui-hello-log.png
+
+# Health tab
+Type "7"
+Sleep 4s
+Screenshot screenshots/camel-tui-hello-health.png
+
+# Back to overview
+Type "1"
+Sleep 4s
+
+# Quit
+Type "q"
diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/readme.md
b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/readme.md
new file mode 100644
index 000000000000..e28f111a6871
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/readme.md
@@ -0,0 +1,56 @@
+# Camel TUI Demo Videos
+
+Terminal demo recordings using TamboUI's built-in recording system.
+This produces Asciinema `.cast` files with pixel-perfect rendering
+(no differential rendering artifacts).
+
+## Prerequisites
+
+- [Camel JBang](https://camel.apache.org/manual/camel-jbang.html) installed
+- [camel-jbang-examples](https://github.com/apache/camel-jbang-examples) cloned
+ (for the circuit-breaker, openapi, and routes demos)
+- Optional: [agg](https://github.com/asciinema/agg) to convert `.cast` to
`.gif`
+ (`brew install agg`)
+- Optional: [asciinema](https://asciinema.org/) to play `.cast` files in the
terminal
+ (`brew install asciinema`)
+
+## Recording
+
+Use the `record.sh` wrapper script:
+
+```bash
+# Basic hello world demo (uses built-in example)
+./record.sh camel-tui-hello --example=timer-log
+
+```
+
+The script starts a Camel integration in the background (`camel run
--background`),
+then launches `camel tui monitor --record=<tape>` which uses TamboUI's headless
+recording backend. Interactions from the `.tape` file are played back
automatically.
+After recording, the background integration is stopped with `camel stop`.
+
+## Playback
+
+```bash
+asciinema play camel-tui-hello.cast
+```
+
+## Convert to GIF
+
+```bash
+agg camel-tui-hello.cast camel-tui-hello.gif
+```
+
+## Tape files
+
+Tape files use the [VHS](https://github.com/charmbracelet/vhs) format to script
+terminal interactions (`Type`, `Sleep`, `Screenshot`, etc.).
+
+| File | Description |
+|------|-------------|
+| `camel-tui-hello.tape` | First impression — basic Hello World tour across
all main tabs |
+
+## Output
+
+Screenshots are saved to `screenshots/` and `.cast` files are written
+to the current directory.
diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/record.sh
b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/record.sh
new file mode 100755
index 000000000000..bc47a58776b9
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/record.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Records Camel TUI demos using TamboUI's built-in recording system.
+#
+# Usage:
+# ./record.sh <tape-name> <camel-run-args...>
+#
+# Examples:
+# ./record.sh camel-tui-hello --example=timer-log
+
+set -e
+
+TAPE_NAME="${1:?Usage: $0 <tape-name> <camel-run-args...>}"
+shift
+CAMEL_RUN_ARGS="$@"
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+TAPE_FILE="${SCRIPT_DIR}/${TAPE_NAME}.tape"
+
+if [ ! -f "$TAPE_FILE" ]; then
+ echo "Error: Tape file not found: $TAPE_FILE"
+ exit 1
+fi
+
+echo "Starting Camel integration in background..."
+camel run --background --background-wait=false $CAMEL_RUN_ARGS
+
+echo "Recording ${TAPE_NAME} ..."
+camel tui monitor --record="${TAPE_FILE}"
+
+# Stop the background integration
+echo "Stopping Camel integration..."
+camel stop "*"
+
+echo "Done. Output: ${TAPE_NAME}.cast"
+echo "Play with: asciinema play ${TAPE_NAME}.cast"
+echo "Convert to gif: agg ${TAPE_NAME}.cast ${TAPE_NAME}.gif"
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/screenshots/camel-tui-hello-diagram.png
b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/screenshots/camel-tui-hello-diagram.png
new file mode 100644
index 000000000000..cbf6e2c6d33f
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/screenshots/camel-tui-hello-diagram.png
@@ -0,0 +1 @@
+<svg class="rich-terminal" viewBox="0 0 2458 1270"
xmlns="http://www.w3.org/2000/svg"> <!-- Generated with TamboUI -->
<style> @font-face { font-family: "Fira Code"; src:
local("FiraCode-Regular"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2")
format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff")
format("woff"); font-style: normal; [...]
\ No newline at end of file
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/screenshots/camel-tui-hello-endpoints.png
b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/screenshots/camel-tui-hello-endpoints.png
new file mode 100644
index 000000000000..06d77b8b04de
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/screenshots/camel-tui-hello-endpoints.png
@@ -0,0 +1 @@
+<svg class="rich-terminal" viewBox="0 0 2458 1270"
xmlns="http://www.w3.org/2000/svg"> <!-- Generated with TamboUI -->
<style> @font-face { font-family: "Fira Code"; src:
local("FiraCode-Regular"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2")
format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff")
format("woff"); font-style: normal; [...]
\ No newline at end of file
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/screenshots/camel-tui-hello-health.png
b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/screenshots/camel-tui-hello-health.png
new file mode 100644
index 000000000000..c482d7f802d0
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/screenshots/camel-tui-hello-health.png
@@ -0,0 +1 @@
+<svg class="rich-terminal" viewBox="0 0 2458 1270"
xmlns="http://www.w3.org/2000/svg"> <!-- Generated with TamboUI -->
<style> @font-face { font-family: "Fira Code"; src:
local("FiraCode-Regular"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2")
format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff")
format("woff"); font-style: normal; [...]
\ No newline at end of file
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/screenshots/camel-tui-hello-log.png
b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/screenshots/camel-tui-hello-log.png
new file mode 100644
index 000000000000..8d26ea7c1c0d
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/screenshots/camel-tui-hello-log.png
@@ -0,0 +1 @@
+<svg class="rich-terminal" viewBox="0 0 2458 1270"
xmlns="http://www.w3.org/2000/svg"> <!-- Generated with TamboUI -->
<style> @font-face { font-family: "Fira Code"; src:
local("FiraCode-Regular"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2")
format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff")
format("woff"); font-style: normal; [...]
\ No newline at end of file
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/screenshots/camel-tui-hello-overview.png
b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/screenshots/camel-tui-hello-overview.png
new file mode 100644
index 000000000000..a4c4e63ba82b
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/screenshots/camel-tui-hello-overview.png
@@ -0,0 +1 @@
+<svg class="rich-terminal" viewBox="0 0 2458 1270"
xmlns="http://www.w3.org/2000/svg"> <!-- Generated with TamboUI -->
<style> @font-face { font-family: "Fira Code"; src:
local("FiraCode-Regular"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2")
format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff")
format("woff"); font-style: normal; [...]
\ No newline at end of file
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/screenshots/camel-tui-hello-routes.png
b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/screenshots/camel-tui-hello-routes.png
new file mode 100644
index 000000000000..c42cc6af06b3
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/docs/video/screenshots/camel-tui-hello-routes.png
@@ -0,0 +1 @@
+<svg class="rich-terminal" viewBox="0 0 2458 1270"
xmlns="http://www.w3.org/2000/svg"> <!-- Generated with TamboUI -->
<style> @font-face { font-family: "Fira Code"; src:
local("FiraCode-Regular"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2")
format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff")
format("woff"); font-style: normal; [...]
\ No newline at end of file
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 f0ff530e1bd6..805ee1327737 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
@@ -156,6 +156,11 @@ public class CamelMonitor extends CamelCommand {
defaultValue = "100")
long refreshInterval = DEFAULT_REFRESH_MS;
+ @CommandLine.Option(names = { "--record" },
+ description = "Record a demo to an Asciinema .cast
file using a TamboUI tape script",
+ arity = "0..1")
+ String record;
+
// State
private final AtomicReference<List<IntegrationInfo>> data = new
AtomicReference<>(Collections.emptyList());
private final Map<String, VanishingInfo> vanishing = new
ConcurrentHashMap<>();
@@ -367,6 +372,18 @@ public class CamelMonitor extends CamelCommand {
public Integer doCall() throws Exception {
System.setProperty("java.awt.headless", "true");
+ // Configure TamboUI recording if --record is specified
+ if (record != null) {
+ Path tapeFile = Path.of(record);
+ Path castFile = Path.of(record.replaceAll("\\.tape$", "") +
".cast");
+ System.setProperty("tamboui.record",
castFile.toAbsolutePath().toString());
+ System.setProperty("tamboui.record.config",
tapeFile.toAbsolutePath().toString());
+ System.setProperty("tamboui.record.width", "200");
+ System.setProperty("tamboui.record.height", "50");
+ System.setProperty("tamboui.record.duration", "120000");
+ System.setProperty("tamboui.record.fps", "10");
+ }
+
// to make ServiceLoader work with tamboui for downloaded JARs
Thread.currentThread().setContextClassLoader(classLoader);
TuiHelper.preloadClasses(classLoader);
diff --git a/pom.xml b/pom.xml
index bf02b125d302..d2fc977e2e55 100644
--- a/pom.xml
+++ b/pom.xml
@@ -391,6 +391,7 @@
<exclude>**/helm/etc/**</exclude>
<exclude>**/examples/*</exclude>
<exclude>**/*.wav</exclude>
+ <exclude>**/*.cast</exclude>
</excludes>
</licenseSet>
</licenseSets>
@@ -436,6 +437,7 @@
<spring.provides>CAMEL_PROPERTIES_STYLE</spring.provides>
<spring.schemas>CAMEL_PROPERTIES_STYLE</spring.schemas>
<sql>DOUBLEDASHES_STYLE</sql>
+ <tape>SCRIPT_STYLE</tape>
<thrift>JAVADOC_STYLE</thrift>
<toml>SCRIPT_STYLE</toml>
<unrealircd.conf>SLASHSTAR_STYLE</unrealircd.conf>