This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch worktree-camel-tui-demo in repository https://gitbox.apache.org/repos/asf/camel.git
commit 5032bc8f0b546b336ac4d9b0c85f10346b2532fc Author: Claus Ibsen <[email protected]> AuthorDate: Wed May 20 12:23:53 2026 +0200 camel-tui: Add --record option and demo tape recordings 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 9090fbc6be38..d632bceae948 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 @@ -154,6 +154,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<>(); @@ -359,6 +364,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>
