{"id":15616736,"url":"https://github.com/ofek/terminal-demo","last_synced_at":"2025-04-28T17:01:36.801Z","repository":{"id":236840848,"uuid":"793256440","full_name":"ofek/terminal-demo","owner":"ofek","description":"Produce GIFs from shell commands","archived":false,"fork":false,"pushed_at":"2025-01-22T02:19:44.000Z","size":40,"stargazers_count":12,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-18T18:33:15.576Z","etag":null,"topics":["demo","gif","presentation","terminal"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ofek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["ofek"],"custom":["https://ofek.dev/donate/"]}},"created_at":"2024-04-28T21:01:15.000Z","updated_at":"2025-03-21T09:00:54.000Z","dependencies_parsed_at":"2025-04-18T06:46:48.508Z","dependency_job_id":null,"html_url":"https://github.com/ofek/terminal-demo","commit_stats":null,"previous_names":["ofek/terminal-demo"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ofek%2Fterminal-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ofek%2Fterminal-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ofek%2Fterminal-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ofek%2Fterminal-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ofek","download_url":"https://codeload.github.com/ofek/terminal-demo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251352230,"owners_count":21575858,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["demo","gif","presentation","terminal"],"created_at":"2024-10-03T07:21:42.771Z","updated_at":"2025-04-28T17:01:36.190Z","avatar_url":"https://github.com/ofek.png","language":"Python","funding_links":["https://github.com/sponsors/ofek","https://ofek.dev/donate/"],"categories":[],"sub_categories":[],"readme":"# terminal-demo\n\nProduce GIFs from shell commands using [asciinema](https://github.com/asciinema/asciinema) and [agg](https://github.com/asciinema/agg).\n\n***Table of contents:***\n\n- [Image creation](#image-creation)\n- [Usage](#usage)\n- [Extra arguments](#extra-arguments)\n- [Configuration](#configuration)\n  - [Commands](#commands)\n  - [Prompt](#prompt)\n- [Fonts](#fonts)\n- [Troubleshooting](#troubleshooting)\n\n## Image creation\n\nCreate your own Dockerfile, for example:\n\n```dockerfile\n# Preferably set up your environment in a separate layer\nFROM ubuntu as setup\n\nRUN \u003c\u003cEOL\ncat \u003c\u003c'EOF' \u003e /script.sh\n#!/bin/bash\nawk 'BEGIN{\n  s=\"/\\\\/\\\\/\\\\/\\\\/\\\\\"; s=s s s s s s s s;\n  for (colnum = 0; colnum\u003c77; colnum++) {\n    r = 255-(colnum*255/76);\n    g = (colnum*510/76);\n    b = (colnum*255/76);\n    if (g\u003e255) g = 510-g;\n    printf \"\\033[48;2;%d;%d;%dm\", r,g,b;\n    printf \"\\033[38;2;%d;%d;%dm\", 255-r,255-g,255-b;\n    printf \"%s\\033[0m\", substr(s,colnum+1,1);\n  }\n  printf \"\\n\";\n}'\nEOF\nEOL\nRUN chmod +x /script.sh\n\nFROM ofekmeister/terminal-demo\n\n# Then copy what is necessary from previous layers\nCOPY --from=setup /script.sh /script.sh\n```\n\nThen build the image:\n\n```console\n$ docker build . -t demo\n```\n\n\u003e [!TIP]\n\u003e Although it's recommended to use `ofekmeister/terminal-demo` as the final layer, the image is based on [buildpack-deps](https://hub.docker.com/_/buildpack-deps) so if you want to use it directly as the base layer it should already contain most of the necessary tools and development headers.\n\n## Usage\n\nYou'll need to mount a directory to `/record` in the container that contains a TOML file named `config.toml` with the commands you want to run. For example:\n\n```toml\ncommands = \"\"\"\n# We are about to test for truecolor support\n. /script.sh\n\"\"\"\n```\n\nThe serialized recording and output GIF will be saved in this directory as well.\n\n```console\n$ docker run --rm -v $PWD:/record demo\n```\n\n\u003cimg src=\"https://raw.githubusercontent.com/ofek/terminal-demo/master/example.gif\" alt=\"Example recording\" role=\"img\"\u003e\n\n## Extra arguments\n\nThe image entrypoint is a script that will forward all arguments to [agg](https://github.com/asciinema/agg). For example, to see the available options run:\n\n```console\n$ docker run --rm -v $PWD:/record demo --help\n```\n\n## Configuration\n\n### Commands\n\nYou can specify the commands to run as a multi-line string in the `commands` field of the TOML file. For example:\n\n```toml\ncommands = \"\"\"\necho \"Hello, world!\"\necho \"Goodbye, world!\"\n\"\"\"\n```\n\nIf any commands must span multiple lines or you want extra control, you can use an array of command tables with a required `text` field. For example:\n\n```toml\n[[command]]\ntext = \"echo 'Hello, world!'\"\n[[command]]\ntext = '''\necho How \\\n    are \\\n    you, world?\n'''\n[[command]]\ntext = \"echo 'Goodbye, world!'\"\n```\n\nCommands have the following optional fields:\n\nField | Default | Description\n--- | --- | ---\n`delay` | `0.03` | Seconds between each keypress; set to `0` to disable.\n`wait` | `0.1` | Seconds to wait before running the next command. If there is no delay, then the default will instead be `0.25`.\n\n### Prompt\n\nYou can change the shell prompt by setting the top-level `prompt` field. The following is the default:\n\n```toml\nprompt = \"\\u001b[0;32m❯ \\u001b[0m\"\n```\n\nIf the prompt uses characters that represent placeholders, like the hostname, the session will hang looking for the prompt in order to know when to proceed with the next command. In this case, you can set the `prompt-pattern` field to a regular expression that matches the prompt.\n\nFor more information about ANSI escape codes, see [this guide](https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797).\n\n## Fonts\n\nThe image provides the following fonts that you can use in the `--font-family` [agg](https://github.com/asciinema/agg) option:\n\n- `Cascadia Mono NF` from Cascadia Code [v2404.23](https://github.com/microsoft/cascadia-code/releases/tag/v2404.23)\n- `FiraCode Nerd Font Mono` from Nerd Fonts [v3.2.1](https://github.com/ryanoasis/nerd-fonts/releases/tag/v3.2.1)\n- `FiraMono Nerd Font` from Nerd Fonts [v3.2.1](https://github.com/ryanoasis/nerd-fonts/releases/tag/v3.2.1)\n- `JetBrainsMono NF` from Nerd Fonts [v3.2.1](https://github.com/ryanoasis/nerd-fonts/releases/tag/v3.2.1)\n\n[Monochrome-only](https://github.com/asciinema/agg/tree/89c957608f44d3450335120f89222ac138929f91#emoji) emoji support comes from Google's Noto Emoji [v15.1](https://github.com/googlefonts/noto-emoji/releases/tag/v2.042).\n\n## Troubleshooting\n\nIf you encounter unexpected or lack of output for the first command prompt, try re-running. This is a known issue but rare enough that I've been unable to reproduce it for debugging.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fofek%2Fterminal-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fofek%2Fterminal-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fofek%2Fterminal-demo/lists"}