☰ GDG /
Docstrings (001–005)
#001 gdtest_minimal #002 gdtest_google #003 gdtest_sphinx #004 gdtest_nodocs #005 gdtest_mixed_docs
Layouts (006–013)
#006 gdtest_src_layout #007 gdtest_python_layout #008 gdtest_lib_layout #009 gdtest_hatch #010 gdtest_setuptools_find #011 gdtest_setup_cfg #012 gdtest_setup_py #013 gdtest_auto_discover
Exports (014–017)
#014 gdtest_no_all #015 gdtest_all_concat #016 gdtest_config_exclude #017 gdtest_auto_exclude
Object Types (018–027)
#018 gdtest_small_class #019 gdtest_big_class #020 gdtest_dataclasses #021 gdtest_enums #022 gdtest_typed_containers #023 gdtest_protocols #024 gdtest_descriptors #025 gdtest_dunders #026 gdtest_nested_class #027 gdtest_constants
Directives (028–032)
#028 gdtest_seealso #029 gdtest_nodoc #030 gdtest_user_guide_auto #031 gdtest_user_guide_sections #032 gdtest_user_guide_subdirs
User Guide (033–038)
#033 gdtest_user_guide_explicit #034 gdtest_user_guide_custom_dir #035 gdtest_user_guide_hyphen #036 gdtest_readme_rst #037 gdtest_index_qmd #038 gdtest_index_md
Landing Pages (039–043)
#039 gdtest_no_readme #040 gdtest_index_wins #041 gdtest_full_extras #042 gdtest_github_contrib #043 gdtest_cli_click
Extras & Config (044–050)
#044 gdtest_cli_nested #045 gdtest_explicit_ref #046 gdtest_kitchen_sink #047 gdtest_name_mismatch #048 gdtest_src_big_class #049 gdtest_google_big_class #050 gdtest_user_guide_cli
Cross-Dimension (051–065)
#051 gdtest_explicit_big_class #052 gdtest_src_no_all #053 gdtest_extras_guide #054 gdtest_google_seealso #055 gdtest_setup_cfg_src #056 gdtest_exclude_cli #057 gdtest_src_explicit_ref #058 gdtest_async_funcs #059 gdtest_generators #060 gdtest_overloads #061 gdtest_abstract_props #062 gdtest_multi_inherit #063 gdtest_slots_class #064 gdtest_frozen_dc #065 gdtest_generics
API Patterns (066–077)
#066 gdtest_context_mgr #067 gdtest_decorators #068 gdtest_exceptions #069 gdtest_reexports #070 gdtest_many_exports #071 gdtest_deep_nesting #072 gdtest_long_docs #073 gdtest_many_guides #074 gdtest_many_big_classes #075 gdtest_flit #076 gdtest_pdm #077 gdtest_namespace
Scale & Stress (078–082)
#078 gdtest_monorepo #079 gdtest_multi_module #080 gdtest_src_legacy #081 gdtest_empty_module #082 gdtest_all_private
Build Systems (083–088)
#083 gdtest_duplicate_all #084 gdtest_badge_readme #085 gdtest_math_docs #086 gdtest_mixed_guide_ext #087 gdtest_unicode_docs #088 gdtest_config_all_on
Edge Cases (089–095)
#089 gdtest_config_display #090 gdtest_config_minimal #091 gdtest_config_parser #092 gdtest_config_extra_keys #093 gdtest_github_icon #094 gdtest_source_branch #095 gdtest_source_path
Config Matrix (096–100)
#096 gdtest_source_title #097 gdtest_source_disabled #098 gdtest_sidebar_disabled #099 gdtest_sidebar_min_items #100 gdtest_sidebar_float
Config Options (101–125)
#101 gdtest_cli_name #102 gdtest_dynamic_false #103 gdtest_parser_google #104 gdtest_parser_sphinx #105 gdtest_display_name #106 gdtest_funding #107 gdtest_authors_multi #108 gdtest_no_darkmode #109 gdtest_exclude_list #110 gdtest_jupyter_kernel #111 gdtest_config_sections #112 gdtest_config_ug_string #113 gdtest_config_ug_list #114 gdtest_config_changelog #115 gdtest_config_reference #116 gdtest_config_combo_a #117 gdtest_config_combo_b #118 gdtest_config_combo_c #119 gdtest_config_combo_d #120 gdtest_config_combo_e #121 gdtest_config_combo_f #122 gdtest_attribution_on #123 gdtest_attribution_off #124 gdtest_rst_versionadded #125 gdtest_rst_deprecated
Docstring Richness (126–150)
#126 gdtest_rst_note #127 gdtest_rst_warning #128 gdtest_rst_tip #129 gdtest_rst_caution #130 gdtest_rst_danger #131 gdtest_rst_important #132 gdtest_rst_mixed_dirs #133 gdtest_sphinx_func_role #134 gdtest_sphinx_class_role #135 gdtest_sphinx_exc_role #136 gdtest_sphinx_meth_role #137 gdtest_sphinx_mixed_roles #138 gdtest_numpy_rich #139 gdtest_google_rich #140 gdtest_sphinx_rich #141 gdtest_docstring_examples #142 gdtest_docstring_notes #143 gdtest_docstring_warnings #144 gdtest_docstring_references #145 gdtest_docstring_seealso #146 gdtest_docstring_math #147 gdtest_docstring_tables #148 gdtest_docstring_combo #149 gdtest_ug_auto #150 gdtest_ug_numbered
UG Variations (151–165)
#151 gdtest_ug_sections_fm #152 gdtest_ug_subdirs #153 gdtest_ug_custom_dir #154 gdtest_ug_deep_nest #155 gdtest_ug_mixed_ext #156 gdtest_ug_many_pages #157 gdtest_ug_explicit_order #158 gdtest_ug_single_page #159 gdtest_ug_no_frontmatter #160 gdtest_ug_with_code #161 gdtest_ug_with_images #162 gdtest_ug_hyphen_dir #163 gdtest_ug_combo #164 gdtest_sec_examples #165 gdtest_sec_tutorials
Custom Sections (166–175)
#166 gdtest_sec_recipes #167 gdtest_sec_blog #168 gdtest_sec_faq #169 gdtest_sec_multi #170 gdtest_sec_navbar_after #171 gdtest_sec_with_ug #172 gdtest_sec_with_ref #173 gdtest_sec_deep #174 gdtest_sec_index_opt #175 gdtest_sec_index_hero
Reference Config (176–185)
#176 gdtest_sec_sidebar_single #177 gdtest_custom_passthrough_navbar #178 gdtest_custom_raw_navbar_after #179 gdtest_custom_mixed_modes #180 gdtest_custom_nested_combo #181 gdtest_custom_basename_output #182 gdtest_custom_nested_output #183 gdtest_custom_missing_dir_combo #184 gdtest_ref_explicit #185 gdtest_ref_members_false
Site Theming (186–195)
#186 gdtest_ref_mixed #187 gdtest_ref_reorder #188 gdtest_ref_sectioned #189 gdtest_ref_single_section #190 gdtest_ref_module_expand #191 gdtest_ref_big_class #192 gdtest_ref_multi_big #193 gdtest_ref_title #194 gdtest_theme_cosmo #195 gdtest_theme_lumen
Stress Tests (196–200)
#196 gdtest_theme_cerulean #197 gdtest_toc_disabled #198 gdtest_toc_depth #199 gdtest_toc_title #200 gdtest_site_combo #201 gdtest_display_badges #202 gdtest_display_authors #203 gdtest_display_funding #204 gdtest_stress_all_config #205 gdtest_stress_all_docstr #206 gdtest_stress_all_ug #207 gdtest_stress_all_sections #208 gdtest_stress_everything #209 gdtest_src_google_seealso #210 gdtest_hatch_nodoc #211 gdtest_pdm_big_class #212 gdtest_flit_enums #213 gdtest_namespace_ug #214 gdtest_ug_subdir_numbered #215 gdtest_homepage_ug #216 gdtest_long_names #217 gdtest_logo #218 gdtest_hero_basic #219 gdtest_hero_readme_badges #220 gdtest_hero_disabled #221 gdtest_hero_custom #222 gdtest_hero_wordmark #223 gdtest_hero_no_logo #224 gdtest_hero_explicit_badges #225 gdtest_hero_index_qmd #226 gdtest_hero_auto_logo #227 gdtest_md_disabled #228 gdtest_md_no_widget #229 gdtest_announce_simple #230 gdtest_announce_dict #231 gdtest_announce_disabled #232 gdtest_gradient_sky #233 gdtest_gradient_peach #234 gdtest_gradient_prism #235 gdtest_gradient_lilac #236 gdtest_gradient_slate #237 gdtest_gradient_honey #238 gdtest_gradient_dusk #239 gdtest_gradient_mint #240 gdtest_gradient_navbar #241 gdtest_gradient_both #242 gdtest_gradient_mixed #243 gdtest_gradient_no_dismiss #244 gdtest_header_text #245 gdtest_header_list #246 gdtest_header_file #247 gdtest_navbar_color #248 gdtest_navbar_color_light #249 gdtest_navbar_color_dark #250 gdtest_navbar_color_same #251 gdtest_navbar_color_split #252 gdtest_kitchen_sink_q #253 gdtest_stress_everything_q #254 gdtest_seealso_desc #255 gdtest_numpy_seealso_desc #256 gdtest_interlinks_prose #257 gdtest_autolink #258 gdtest_skill_default #259 gdtest_skill_curated #260 gdtest_skill_config #261 gdtest_skill_disabled #262 gdtest_skill_rich #263 gdtest_skill_combo #264 gdtest_skill_complex #265 gdtest_i18n_french #266 gdtest_i18n_japanese #267 gdtest_i18n_arabic #268 gdtest_code_cells #269 gdtest_nav_icons #270 gdtest_page_tags #271 gdtest_page_status #272 gdtest_tag_location #273 gdtest_icon_shortcode #274 gdtest_homepage_ug_subdirs #275 gdtest_gt_tables #276 gdtest_scale_to_fit #277 gdtest_scale_min_scale #278 gdtest_homepage_wide #279 gdtest_interlinks_userguide #280 gdtest_code_span_headings #281 gdtest_sec_blog_user_index #282 gdtest_sec_dir_titles #283 gdtest_namespace_src #284 gdtest_auto_include #285 gdtest_no_auto_exclude #286 gdtest_tbl_preview #287 gdtest_tbl_shortcode #288 gdtest_tbl_explorer #289 gdtest_hr_shortcode #290 gdtest_accent_color #291 gdtest_keys_shortcode #292 gdtest_inline_methods #293 gdtest_inline_always #294 gdtest_inline_never #295 gdtest_inline_threshold #296 gdtest_ref_inherited_explicit #297 gdtest_ref_include_inherited #298 gdtest_mock_code #299 gdtest_details_shortcode #300 gdtest_termshow
300/300 built ⏱ 13.5s 🧪 8/24

gdtest-termshow

A demo package showing the termshow terminal recording feature

Installation

pip install gdtest-termshow

Get Started

Source files
📁 demos/
📄 getting-started.termshow
{"version": 1, "format": "termshow", "term": {"cols": 80, "rows": 20, "type": "xterm-256color"}, "title": "Getting Started"}
[0.5, "o", "\u001b[32m\u001b[1m$\u001b[0m "]
[0.08, "o", "p"]
[0.06, "o", "i"]
[0.07, "o", "p"]
[0.1, "o", " "]
[0.07, "o", "i"]
[0.06, "o", "n"]
[0.08, "o", "s"]
[0.06, "o", "t"]
[0.07, "o", "a"]
[0.06, "o", "l"]
[0.08, "o", "l"]
[0.1, "o", " "]
[0.07, "o", "m"]
[0.06, "o", "y"]
[0.08, "o", "-"]
[0.06, "o", "t"]
[0.07, "o", "o"]
[0.06, "o", "o"]
[0.08, "o", "l"]
[0.6, "o", "\r\n"]
[0.3, "o", "\u001b[2K\u001b[33mCollecting my-tool...\u001b[0m\r\n"]
[0.8, "o", "\u001b[2K\u001b[33mDownloading my_tool-1.0.0-py3-none-any.whl (12 kB)\u001b[0m\r\n"]
[0.5, "o", "\u001b[2K\u001b[32mSuccessfully installed my-tool-1.0.0\u001b[0m\r\n"]
[1.0, "m", "Installation complete"]
[0.8, "o", "\u001b[32m\u001b[1m$\u001b[0m "]
[0.08, "o", "m"]
[0.06, "o", "y"]
[0.08, "o", "-"]
[0.06, "o", "t"]
[0.07, "o", "o"]
[0.06, "o", "o"]
[0.08, "o", "l"]
[0.1, "o", " "]
[0.07, "o", "i"]
[0.06, "o", "n"]
[0.08, "o", "i"]
[0.06, "o", "t"]
[0.6, "o", "\r\n"]
[0.2, "o", "\u001b[36m\u001b[1m\u2728 Initializing new project...\u001b[0m\r\n"]
[0.5, "o", "\r\n"]
[0.1, "o", "  \u001b[1mProject name:\u001b[0m my-awesome-project\r\n"]
[0.1, "o", "  \u001b[1mTemplate:\u001b[0m     default\r\n"]
[0.1, "o", "  \u001b[1mDirectory:\u001b[0m    ./my-awesome-project/\r\n"]
[0.3, "o", "\r\n"]
[0.2, "o", "\u001b[32m\u2714 Project created successfully!\u001b[0m\r\n"]
[1.0, "m", "Project initialized"]
[0.8, "o", "\u001b[32m\u001b[1m$\u001b[0m "]
[0.08, "o", "m"]
[0.06, "o", "y"]
[0.08, "o", "-"]
[0.06, "o", "t"]
[0.07, "o", "o"]
[0.06, "o", "o"]
[0.08, "o", "l"]
[0.1, "o", " "]
[0.07, "o", "r"]
[0.06, "o", "u"]
[0.08, "o", "n"]
[0.1, "o", " "]
[0.06, "o", "-"]
[0.08, "o", "-"]
[0.06, "o", "v"]
[0.07, "o", "e"]
[0.06, "o", "r"]
[0.08, "o", "b"]
[0.06, "o", "o"]
[0.07, "o", "s"]
[0.06, "o", "e"]
[0.6, "o", "\r\n"]
[0.2, "o", "\u001b[36m\u2699\ufe0f  Running task: build\u001b[0m\r\n"]
[0.4, "o", "  \u001b[90m[1/4]\u001b[0m Collecting sources...\r\n"]
[0.5, "o", "  \u001b[90m[2/4]\u001b[0m Compiling...\r\n"]
[0.6, "o", "  \u001b[90m[3/4]\u001b[0m Running tests...\r\n"]
[0.4, "o", "  \u001b[90m[4/4]\u001b[0m Packaging...\r\n"]
[0.3, "o", "\r\n\u001b[32m\u2714 Build complete (1.2s)\u001b[0m\r\n"]
[1.0, "m", "Build finished"]
[0.5, "o", "\u001b[32m\u001b[1m$\u001b[0m "]
📄 getting-started.termshow.yml
source: demos/getting-started.termshow

settings:
  idle_time_limit: 1.5
  window_chrome: colorful

chapters:
  - at: 0.0
    label: "Install"
  - at: 4.5
    label: "Initialize"
  - at: 10.0
    label: "Build"

annotations:
  - at: 0.5
    duration: 3.0
    text: "Install from PyPI with pip"
    position: top-right
    style: callout
  - at: 5.0
    duration: 3.5
    text: "Creates project structure with sensible defaults"
    position: bottom-right
    style: subtle
  - at: 11.0
    duration: 3.0
    text: "Verbose mode shows each build step"
    position: top-right
    style: callout
📄 great-docs-cli.termshow
{"version": 1, "format": "termshow", "term": {"cols": 80, "rows": 24, "type": "xterm-256color"}, "title": "Great Docs CLI"}
[0.5, "o", "\u001b[32m\u001b[1m$\u001b[0m "]
[0.08, "o", "g"]
[0.06, "o", "r"]
[0.07, "o", "e"]
[0.06, "o", "a"]
[0.08, "o", "t"]
[0.06, "o", "-"]
[0.07, "o", "d"]
[0.06, "o", "o"]
[0.08, "o", "c"]
[0.06, "o", "s"]
[0.1, "o", " "]
[0.07, "o", "-"]
[0.06, "o", "-"]
[0.06, "o", "v"]
[0.07, "o", "e"]
[0.06, "o", "r"]
[0.08, "o", "s"]
[0.06, "o", "i"]
[0.07, "o", "o"]
[0.06, "o", "n"]
[0.5, "o", "\r\n"]
[0.2, "o", "great-docs, version 0.10.0\r\n"]
[1.0, "m", "version"]
[0.6, "o", "\u001b[32m\u001b[1m$\u001b[0m "]
[0.08, "o", "g"]
[0.06, "o", "r"]
[0.07, "o", "e"]
[0.06, "o", "a"]
[0.08, "o", "t"]
[0.06, "o", "-"]
[0.07, "o", "d"]
[0.06, "o", "o"]
[0.08, "o", "c"]
[0.06, "o", "s"]
[0.1, "o", " "]
[0.07, "o", "s"]
[0.06, "o", "c"]
[0.08, "o", "a"]
[0.06, "o", "n"]
[0.5, "o", "\r\n"]
[0.3, "o", "\r\n"]
[0.1, "o", "\u001b[36m\u001b[1mPackage:\u001b[0m gdtest_termshow\r\n"]
[0.1, "o", "\u001b[36m\u001b[1mVersion:\u001b[0m 1.0.0\r\n"]
[0.1, "o", "\r\n"]
[0.1, "o", "\u001b[1mDiscovered Exports (3):\u001b[0m\r\n"]
[0.05, "o", "\r\n"]
[0.05, "o", "  \u001b[33mFunctions:\u001b[0m\r\n"]
[0.05, "o", "    \u001b[32m\u2022\u001b[0m greet(name)\r\n"]
[0.05, "o", "    \u001b[32m\u2022\u001b[0m init_project(path, *, template)\r\n"]
[0.05, "o", "    \u001b[32m\u2022\u001b[0m run_task(task_name, *, verbose)\r\n"]
[0.1, "o", "\r\n"]
[0.1, "o", "\u001b[90m\u2139 All 3 exports have docstrings.\u001b[0m\r\n"]
[1.2, "m", "scan complete"]
[0.6, "o", "\u001b[32m\u001b[1m$\u001b[0m "]
[0.08, "o", "g"]
[0.06, "o", "r"]
[0.07, "o", "e"]
[0.06, "o", "a"]
[0.08, "o", "t"]
[0.06, "o", "-"]
[0.07, "o", "d"]
[0.06, "o", "o"]
[0.08, "o", "c"]
[0.06, "o", "s"]
[0.1, "o", " "]
[0.07, "o", "l"]
[0.06, "o", "i"]
[0.08, "o", "n"]
[0.06, "o", "t"]
[0.5, "o", "\r\n"]
[0.3, "o", "\r\n"]
[0.1, "o", "\u001b[36m\u001b[1mLinting:\u001b[0m gdtest_termshow\r\n"]
[0.2, "o", "\r\n"]
[0.15, "o", "  \u001b[32m\u2714\u001b[0m docstrings \u001b[90m........\u001b[0m 3/3 documented\r\n"]
[0.15, "o", "  \u001b[32m\u2714\u001b[0m cross-refs \u001b[90m........\u001b[0m no broken references\r\n"]
[0.15, "o", "  \u001b[32m\u2714\u001b[0m style \u001b[90m.............\u001b[0m consistent (numpy)\r\n"]
[0.15, "o", "  \u001b[32m\u2714\u001b[0m directives \u001b[90m........\u001b[0m all valid\r\n"]
[0.15, "o", "  \u001b[32m\u2714\u001b[0m stale-versions \u001b[90m....\u001b[0m none found\r\n"]
[0.2, "o", "\r\n"]
[0.1, "o", "\u001b[32m\u001b[1m\u2728 All checks passed!\u001b[0m No issues found.\r\n"]
[1.2, "m", "lint complete"]
[0.6, "o", "\u001b[32m\u001b[1m$\u001b[0m "]
[0.08, "o", "g"]
[0.06, "o", "r"]
[0.07, "o", "e"]
[0.06, "o", "a"]
[0.08, "o", "t"]
[0.06, "o", "-"]
[0.07, "o", "d"]
[0.06, "o", "o"]
[0.08, "o", "c"]
[0.06, "o", "s"]
[0.1, "o", " "]
[0.07, "o", "t"]
[0.06, "o", "e"]
[0.08, "o", "r"]
[0.06, "o", "m"]
[0.1, "o", " "]
[0.07, "o", "r"]
[0.06, "o", "e"]
[0.08, "o", "n"]
[0.06, "o", "d"]
[0.07, "o", "e"]
[0.06, "o", "r"]
[0.1, "o", " "]
[0.06, "o", "d"]
[0.07, "o", "e"]
[0.06, "o", "m"]
[0.08, "o", "o"]
[0.06, "o", "s"]
[0.07, "o", "/"]
[0.06, "o", "g"]
[0.07, "o", "e"]
[0.06, "o", "t"]
[0.08, "o", "t"]
[0.06, "o", "i"]
[0.07, "o", "n"]
[0.06, "o", "g"]
[0.08, "o", "-"]
[0.06, "o", "s"]
[0.07, "o", "t"]
[0.06, "o", "a"]
[0.07, "o", "r"]
[0.06, "o", "t"]
[0.08, "o", "e"]
[0.06, "o", "d"]
[0.6, "o", "\r\n"]
[0.3, "o", "\r\n"]
[0.1, "o", "\u001b[36m\u001b[1mRendering:\u001b[0m demos/getting-started.termshow\r\n"]
[0.2, "o", "  \u001b[90mScript:\u001b[0m  demos/getting-started.termshow.yml\r\n"]
[0.1, "o", "  \u001b[90mChrome:\u001b[0m  colorful\r\n"]
[0.1, "o", "  \u001b[90mSize:\u001b[0m    80\u00d720\r\n"]
[0.2, "o", "\r\n"]
[0.4, "o", "  \u001b[33m\u25cf\u001b[0m Parsing recording (24 events)...\r\n"]
[0.3, "o", "  \u001b[33m\u25cf\u001b[0m Applying idle_time_limit: 1.5s\r\n"]
[0.5, "o", "  \u001b[33m\u25cf\u001b[0m Rendering keyframes...\r\n"]
[0.2, "o", "    \u001b[90mframe-000.svg\u001b[0m (0.00s)\r\n"]
[0.15, "o", "    \u001b[90mframe-001.svg\u001b[0m (0.50s)\r\n"]
[0.15, "o", "    \u001b[90mframe-002.svg\u001b[0m (2.08s)\r\n"]
[0.15, "o", "    \u001b[90mframe-003.svg\u001b[0m (3.28s)\r\n"]
[0.15, "o", "    \u001b[90mframe-004.svg\u001b[0m (4.50s)\r\n"]
[0.15, "o", "    \u001b[90mframe-005.svg\u001b[0m (5.10s)\r\n"]
[0.15, "o", "    \u001b[90mframe-006.svg\u001b[0m (7.60s)\r\n"]
[0.15, "o", "    \u001b[90mframe-007.svg\u001b[0m (10.00s)\r\n"]
[0.15, "o", "    \u001b[90mframe-008.svg\u001b[0m (10.60s)\r\n"]
[0.15, "o", "    \u001b[90mframe-009.svg\u001b[0m (14.20s)\r\n"]
[0.2, "o", "  \u001b[33m\u25cf\u001b[0m Writing manifest.json\r\n"]
[0.1, "o", "\r\n"]
[0.1, "o", "\u001b[32m\u001b[1m\u2714 Done!\u001b[0m 10 frames, 3 chapters, 16.6s duration\r\n"]
[0.1, "o", "  \u001b[90mOutput: termshow/getting-started/\u001b[0m\r\n"]
[1.0, "m", "render complete"]
[0.5, "o", "\u001b[32m\u001b[1m$\u001b[0m "]
📄 great-docs-cli.termshow.yml
source: demos/great-docs-cli.termshow

settings:
  idle_time_limit: 1.5
  window_chrome: colorful

chapters:
  - at: 0.0
    label: "Version"
  - at: 3.5
    label: "Scan Exports"
  - at: 9.0
    label: "Lint Docs"
  - at: 14.5
    label: "Render Recording"

annotations:
  - at: 0.5
    duration: 2.5
    text: "Check your installed version"
    position: top-right
    style: subtle
  - at: 4.0
    duration: 4.0
    text: "Discovers all public exports with docstring coverage"
    position: top-right
    style: callout
  - at: 9.5
    duration: 4.0
    text: "Checks docs quality: docstrings, cross-refs, style, and more"
    position: top-right
    style: callout
  - at: 15.5
    duration: 4.0
    text: "Renders .termshow recordings into SVG keyframes for embedding"
    position: top-right
    style: highlight
📄 tui-demo.termshow
{"version": 1, "format": "termshow", "term": {"cols": 60, "rows": 18, "type": "xterm-256color"}, "title": "TUI Interface"}
[0.3, "o", "\u001b[2J\u001b[H"]
[0.2, "o", "\u001b[34m\u001b[1m\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\u001b[0m\r\n"]
[0.02, "o", "\u001b[34m\u001b[1m\u2502\u001b[0m                                                \u001b[34m\u001b[1m\u2502\u001b[0m\r\n"]
[0.02, "o", "\u001b[34m\u001b[1m\u2502\u001b[0m   \u001b[36m\u001b[1m\u2728 my-tool v1.0\u001b[0m                               \u001b[34m\u001b[1m\u2502\u001b[0m\r\n"]
[0.02, "o", "\u001b[34m\u001b[1m\u2502\u001b[0m                                                \u001b[34m\u001b[1m\u2502\u001b[0m\r\n"]
[0.02, "o", "\u001b[34m\u001b[1m\u2502\u001b[0m   \u001b[33m\u276f\u001b[0m \u001b[1mNew Project\u001b[0m                              \u001b[34m\u001b[1m\u2502\u001b[0m\r\n"]
[0.02, "o", "\u001b[34m\u001b[1m\u2502\u001b[0m     Open Existing                            \u001b[34m\u001b[1m\u2502\u001b[0m\r\n"]
[0.02, "o", "\u001b[34m\u001b[1m\u2502\u001b[0m     Recent Files                             \u001b[34m\u001b[1m\u2502\u001b[0m\r\n"]
[0.02, "o", "\u001b[34m\u001b[1m\u2502\u001b[0m     Settings                                 \u001b[34m\u001b[1m\u2502\u001b[0m\r\n"]
[0.02, "o", "\u001b[34m\u001b[1m\u2502\u001b[0m     \u001b[90mQuit\u001b[0m                                     \u001b[34m\u001b[1m\u2502\u001b[0m\r\n"]
[0.02, "o", "\u001b[34m\u001b[1m\u2502\u001b[0m                                                \u001b[34m\u001b[1m\u2502\u001b[0m\r\n"]
[0.02, "o", "\u001b[34m\u001b[1m\u2502\u001b[0m   \u001b[90m\u2191/\u2193 navigate  \u23ce enter  q quit\u001b[0m             \u001b[34m\u001b[1m\u2502\u001b[0m\r\n"]
[0.02, "o", "\u001b[34m\u001b[1m\u2502\u001b[0m                                                \u001b[34m\u001b[1m\u2502\u001b[0m\r\n"]
[0.02, "o", "\u001b[34m\u001b[1m\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\u001b[0m\r\n"]
[2.0, "m", "Main menu"]
[0.8, "o", "\u001b[9;1H"]
[0.05, "o", "\u001b[34m\u001b[1m\u2502\u001b[0m     New Project                              \u001b[34m\u001b[1m\u2502\u001b[0m"]
[0.05, "o", "\u001b[10;1H"]
[0.05, "o", "\u001b[34m\u001b[1m\u2502\u001b[0m   \u001b[33m\u276f\u001b[0m \u001b[1mOpen Existing\u001b[0m                            \u001b[34m\u001b[1m\u2502\u001b[0m"]
[1.5, "m", "Navigate to Open"]
[0.5, "o", "\u001b[2J\u001b[H"]
[0.2, "o", "\u001b[36m\u001b[1m\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u001b[0m\r\n"]
[0.05, "o", "  \u001b[1mOpen Project\u001b[0m\r\n"]
[0.05, "o", "\u001b[36m\u001b[1m\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u001b[0m\r\n"]
[0.1, "o", "\r\n"]
[0.1, "o", "  \u001b[90mPath:\u001b[0m ~/projects/\u001b[4mmy-app\u001b[0m\r\n"]
[0.3, "o", "\r\n"]
[0.2, "o", "  \u001b[32m\u2714\u001b[0m Loaded \u001b[1m3 files\u001b[0m, \u001b[1m2 configs\u001b[0m\r\n"]
[0.5, "o", "  \u001b[32m\u2714\u001b[0m Project ready\r\n"]
[1.5, "m", "Project loaded"]
📄 tui-demo.termshow.yml
source: demos/tui-demo.termshow

settings:
  idle_time_limit: 2.0
  window_chrome: colorful

chapters:
  - at: 0.0
    label: "Main Menu"
  - at: 3.0
    label: "Navigation"
  - at: 5.5
    label: "Open Project"

annotations:
  - at: 0.5
    duration: 2.5
    text: "Full-screen TUI with keyboard navigation"
    position: top-right
    style: callout
  - at: 3.2
    duration: 2.0
    text: "Arrow keys move the selection cursor"
    position: bottom-right
    style: subtle
  - at: 6.0
    duration: 2.5
    text: "Enter confirms and opens the sub-view"
    position: top-left
    style: callout
📁 gdtest_termshow/
📄 __init__.py
"""A sample CLI/TUI tool for demonstrating termshow recordings."""

__version__ = "1.0.0"
__all__ = ["greet", "init_project", "run_task"]


def greet(name: str) -> str:
    """Greet a user by name.

    Parameters
    ----------
    name
        The name to greet.

    Returns
    -------
    str
        A greeting string.
    """
    return f"Hello, {name}!"


def init_project(path: str, *, template: str = 'default') -> dict:
    """Initialize a new project at the given path.

    Parameters
    ----------
    path
        Directory to create the project in.
    template
        Project template to use.

    Returns
    -------
    dict
        Project metadata.
    """
    return {'path': path, 'template': template}


def run_task(task_name: str, *, verbose: bool = False) -> int:
    """Run a named task.

    Parameters
    ----------
    task_name
        Name of the task to execute.
    verbose
        Enable verbose output.

    Returns
    -------
    int
        Exit code (0 for success).
    """
    return 0
📁 user_guide/
📄 01-quick-start.qmd
---
title: Quick Start
---

## Installation & First Run

Watch this quick demo to see `my-tool` in action — from installation
through your first build:

{{< termshow file="demos/getting-started" pause_on_chapters="true" >}}

### What just happened?

The recording above shows three steps:

1. **Install** — `pip install my-tool` fetches the package from PyPI
2. **Initialize** — `my-tool init` scaffolds a new project
3. **Build** — `my-tool run --verbose` executes the build pipeline

You can click any chapter marker in the timeline to jump directly
to that step, or use keyboard shortcuts:

| Key | Action |
|-----|--------|
| Space | Play/Pause |
| ← / → | Seek 5 seconds |
| . | Next chapter |
| , | Previous chapter |

## Next Steps

Now that you have `my-tool` installed, check out the
[TUI Interface](02-tui-interface.qmd) guide for the interactive mode.
📄 02-tui-interface.qmd
---
title: TUI Interface
---

## Interactive Mode

`my-tool` includes a full-screen terminal interface for visual
project management. Launch it with:

```bash
my-tool --interactive
```

Here's how it looks:

{{< termshow file="demos/tui-demo" pause_on_chapters="true" >}}

### Navigation

The TUI uses standard terminal navigation:

- **↑/↓** arrows to move between items
- **Enter** to select/confirm
- **q** to quit
- **Esc** to go back one level

### Features

The interactive mode provides:

- Project creation wizard
- File browser with preview
- Live build output
- Configuration editor
📄 03-recording-tips.qmd
---
title: Recording Tips
---

## Creating Your Own Recordings

Great Docs makes it easy to record, edit, and embed terminal
sessions in your documentation.

### Recording

```bash
# Start recording
great-docs termshow record demos/my-demo.termshow

# Perform your CLI actions...
# Press Ctrl+D or type 'exit' to stop
```

### Editing with Scripts

Create a `.termshow.yml` file alongside your recording to add
chapters, annotations, and timing adjustments:

```yaml
source: demos/my-demo.termshow

settings:
  idle_time_limit: 2.0
  window_chrome: colorful

chapters:
  - at: 0.0
    label: Introduction
  - at: 10.0
    label: Main Feature

annotations:
  - at: 2.0
    duration: 3.0
    text: This step installs dependencies
    position: top-right
    style: callout

cuts:
  - from: 5.0
    to: 8.0
    type: ellipsis
```

### Rendering

```bash
# Render SVG frames
great-docs termshow render demos/my-demo.termshow
```

### Embedding

Use the `termshow` shortcode in your `.qmd` files:

```markdown
{{< termshow file="demos/my-demo" pause_on_chapters="true" >}}
```

### Importing Existing Recordings

Already have recordings from asciinema or VHS?

```bash
# Import from asciinema
great-docs termshow import-cast recording.cast demos/my-demo

# Import from VHS tape
great-docs termshow import-tape demo.tape demos/my-demo
```
📄 04-termshow-guide.qmd
---
title: Termshow Guide
---

## Overview

The **termshow** is Great Docs' built-in terminal recording player.
It renders pre-recorded terminal sessions as interactive, frame-accurate
SVG animations directly in your documentation pages — no JavaScript
framework dependencies, no external services.

Key capabilities:

- Frame-accurate SVG rendering of terminal output
- Chapter-based navigation with labeled markers
- Contextual annotations that appear at specific timestamps
- Keyboard shortcuts for power users
- Adjustable playback speed (0.5× to 3×)
- Works offline and with `file://` protocol (all data embedded inline)
- Responsive layout that scales to any viewport width
- Light/dark theme support (follows the site theme)

### Live Demo

Here's a recording of real Great Docs CLI commands — `scan`, `lint`,
and `term render` — running against this very package:

{{< termshow file="demos/great-docs-cli" pause_on_chapters="true" >}}

## The Recording Format

Termshow uses a two-file system for each recording:

### The `.termshow` File

This is the raw terminal recording in NDJSON format. Each line is
a JSON array with `[delay, event_type, data]`:

```json
{"version": 1, "format": "termshow", "term": {"cols": 80, "rows": 20}}
[0.5, "o", "$ "]
[0.1, "o", "echo hello"]
[0.6, "o", "\r\nhello\r\n"]
[1.0, "m", "Command executed"]
```

Event types:

| Type | Meaning |
|------|---------|
| `"o"` | Output — terminal data written to stdout |
| `"i"` | Input — user keystrokes (for display purposes) |
| `"m"` | Marker — internal marker used for chapter sync |

The header line sets terminal dimensions and metadata.

### The `.termshow.yml` Script File

This companion file defines chapters, annotations, timing adjustments,
and visual settings:

```yaml
source: demos/my-recording.termshow

settings:
  idle_time_limit: 2.0      # Cap any idle gap to 2 seconds
  window_chrome: colorful   # Window decoration style
  theme: monokai            # Terminal color scheme
  font_size: 14             # Font size in pixels

chapters:
  - at: 0.0
    label: Introduction
  - at: 5.0
    label: Configuration
  - at: 12.0
    label: Running Tests

annotations:
  - at: 1.0
    duration: 3.0
    text: This installs all required dependencies
    position: top-right
    style: callout
  - at: 6.0
    duration: 2.5
    text: Configuration is auto-detected
    position: bottom-right
    style: subtle

cuts:
  - from: 8.0
    to: 11.0
    type: ellipsis   # Shows '…' for the cut section
```

## Settings Reference

| Setting | Default | Description |
|---------|---------|-------------|
| `idle_time_limit` | `3.0` | Maximum seconds for any idle gap |
| `window_chrome` | `colorful` | Window decoration: `colorful`, `plain`, `none` |
| `theme` | (auto) | Terminal color scheme |
| `font_size` | `14` | Font size in rendered SVG (px) |
| `line_height` | `1.2` | Line height multiplier |
| `padding` | `12` | Inner padding of the terminal area (px) |

## Annotation Styles

Annotations appear as overlays on the terminal at specified times.
Three styles are available:

| Style | Appearance |
|-------|------------|
| `callout` | Semi-opaque dark card with accent border |
| `subtle` | Lighter, smaller text — less intrusive |
| `highlight` | Amber-tinted with warm border — draws attention |

Positions: `top-left`, `top-right`, `bottom-left`, `bottom-right`.

## Embedding in Pages

Use the `termshow` Quarto shortcode in any `.qmd` file:

````markdown
## Basic usage

{{< termshow file="demos/getting-started" >}}

## With chapter pausing

{{< termshow file="demos/workflow" pause_on_chapters="true" >}}

## Autoplay with custom speed

{{< termshow file="demos/quick" autoplay="true" speed="1.5" >}}
````

### Shortcode Options

| Option | Default | Description |
|--------|---------|-------------|
| `file` | (required) | Path to `.termshow` file (without extension) |
| `autoplay` | `false` | Start playing automatically on page load |
| `loop` | `false` | Loop playback when reaching the end |
| `speed` | `1` | Initial playback speed multiplier |
| `pause_on_chapters` | `false` | Auto-pause at each chapter boundary |
| `controls` | `true` | Show the control bar |
| `theme` | `auto` | Player theme: `auto`, `dark`, or `light` |

## Player Controls

The player provides a full set of interactive controls:

### Control Bar

From left to right:

1. **Play/Pause button** — Toggles playback. Shows ↺ (replay) at the end.
2. **Current time** — Elapsed time counter.
3. **Timeline scrub bar** — Click anywhere to seek. Chapter markers
   appear as gold ticks with wider hit targets for easy clicking.
4. **Remaining time** — Counts down to zero during playback.
5. **Speed button** — Cycles through 0.5×, 1×, 1.5×, 2×, 3×.

### Chapter Bar

A thin overlay at the top of the player shows the name of the
current chapter, updating as playback progresses.

### Center Overlay

A semi-transparent button in the center of the viewport:

- **Before playback** — Shows ▶ as a call-to-action.
- **After playback ends** — Shows ↺ to indicate replay. Clicking
  returns the player to its initial state (frame 0, ready to play).
- **During chapter pauses** — Hidden, so the terminal content
  remains fully visible.

### Keyboard Shortcuts

Click the player viewport first to give it focus, then use:

| Key | Action |
|-----|--------|
| `Space` | Play / Pause (or reset from ended state) |
| `→` | Seek forward 5 seconds |
| `←` | Seek backward 5 seconds |
| `.` | Jump to next chapter |
| `,` | Jump to previous chapter |

## Workflow

The full termshow workflow from recording to rendered page:

```text
1. Record          great-docs termshow record demos/my-demo.termshow
2. Edit script     Create/edit demos/my-demo.termshow.yml
3. Preview         great-docs termshow play demos/my-demo.termshow
4. Embed           Add {{< termshow ... >}} to your .qmd
5. Build           great-docs build (renders SVG frames automatically)
```

### Step 1: Record

```bash
great-docs termshow record demos/install-guide.termshow
```

This launches a recording session. Everything you type and see in
the terminal is captured with precise timing. Press `Ctrl+D` or
type `exit` to end the recording.

### Step 2: Create the Script

Create `demos/install-guide.termshow.yml` alongside the recording.
Define chapters at logical breakpoints in your workflow, and add
annotations to explain what's happening:

```yaml
source: demos/install-guide.termshow

settings:
  idle_time_limit: 1.5
  window_chrome: colorful

chapters:
  - at: 0.0
    label: Setup
  - at: 8.0
    label: Install
  - at: 15.0
    label: Verify

annotations:
  - at: 1.0
    duration: 3.0
    text: Start by activating the virtual environment
    position: top-right
    style: callout
```

### Step 3: Preview

```bash
great-docs termshow play demos/install-guide.termshow
```

This plays the recording in your terminal so you can verify
timing and check that chapter boundaries feel natural.

### Step 4: Embed

Add the shortcode to any user guide or documentation page:

```markdown
{{< termshow file="demos/install-guide" pause_on_chapters="true" >}}
```

### Step 5: Build

```bash
great-docs build
```

During the build, Great Docs:

1. Finds all `.termshow` files in your project
2. Renders each recording into a series of SVG keyframes
3. Generates a `manifest.json` with timing, chapters, and annotations
4. The Lua shortcode filter embeds the manifest and all SVG frames
   inline in the HTML — no runtime fetches needed

## Importing Existing Recordings

Already have terminal recordings from other tools? Import them:

```bash
# From asciinema (.cast files)
great-docs termshow import-cast recording.cast demos/my-demo

# From VHS (.tape files)
great-docs termshow import-tape demo.tape demos/my-demo
```

The import preserves timing and terminal dimensions. You'll still
want to create a `.termshow.yml` script to add chapters and
annotations.

## Tips & Best Practices

- **Keep recordings short** — 15–30 seconds is ideal. Split longer
  workflows into multiple recordings.
- **Use `idle_time_limit`** — Caps long pauses so viewers aren't
  waiting through your thinking time.
- **Place chapters at logical transitions** — Each chapter should
  represent one distinct step in the workflow.
- **Use `pause_on_chapters`** for tutorials — Gives readers time
  to absorb each step before the next one plays.
- **Annotations are brief** — One sentence max. They complement
  the terminal output, not replace it.
- **Test at different speeds** — Make sure annotations are still
  readable at 1.5× and 2× speed.
- **80 columns, 20 rows** works well for most CLI recordings.
  Use 60 columns for narrower TUI demos.

## Architecture

Under the hood, termshow works in two phases:

**Build time** (Python + Lua):

1. `core.py` discovers `.termshow` files and calls the renderer
2. The renderer parses the NDJSON recording + YAML script
3. It produces SVG keyframes at each visual change point
4. A `manifest.json` captures timing, chapters, and annotation data
5. The Lua shortcode embeds everything inline as `<script>` JSON blocks

**Page load** (JavaScript):

1. `termshow.js` finds `.gd-termshow` containers
2. Reads inline manifest and SVG frame data from `<script>` elements
3. Builds the player UI (viewport, controls, chapter bar, overlays)
4. On play: advances time via `requestAnimationFrame`, swaps SVG
   frames at the correct timestamps

This architecture means:

- Zero network requests at runtime
- Works with `file://` protocol (offline docs)
- No CORS or fetch issues
- SVGs scale perfectly at any zoom level
📄 great-docs.yml
package_name: gdtest_termshow
display_name: My Tool
description: A demo showing terminal recordings in documentation
user_guide: true