shellfie 0.1.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +56 -2
  3. data/README.md +248 -228
  4. data/lib/shellfie/animation_frame_builder.rb +202 -0
  5. data/lib/shellfie/animation_scroll_easing.rb +77 -0
  6. data/lib/shellfie/animation_timeline.rb +28 -0
  7. data/lib/shellfie/ansi_colors.rb +94 -0
  8. data/lib/shellfie/ansi_line_buffer.rb +103 -0
  9. data/lib/shellfie/ansi_normalizer.rb +61 -0
  10. data/lib/shellfie/ansi_parser.rb +162 -83
  11. data/lib/shellfie/cassette.rb +76 -0
  12. data/lib/shellfie/cli.rb +75 -163
  13. data/lib/shellfie/cli_authoring.rb +233 -0
  14. data/lib/shellfie/cli_generate.rb +401 -0
  15. data/lib/shellfie/cli_info.rb +239 -0
  16. data/lib/shellfie/cli_run.rb +167 -0
  17. data/lib/shellfie/config.rb +112 -25
  18. data/lib/shellfie/config_defaults.rb +83 -0
  19. data/lib/shellfie/config_validation.rb +289 -0
  20. data/lib/shellfie/dependency_checker.rb +147 -0
  21. data/lib/shellfie/errors.rb +12 -1
  22. data/lib/shellfie/ffmpeg_encoder.rb +46 -0
  23. data/lib/shellfie/font_resolver.rb +68 -0
  24. data/lib/shellfie/format_resolver.rb +15 -0
  25. data/lib/shellfie/gif_generator.rb +231 -89
  26. data/lib/shellfie/gif_palette.rb +105 -0
  27. data/lib/shellfie/headless_theme_registry.rb +42 -0
  28. data/lib/shellfie/html_renderer.rb +54 -0
  29. data/lib/shellfie/image_magick_command_builder.rb +75 -0
  30. data/lib/shellfie/line_layout.rb +146 -0
  31. data/lib/shellfie/output_writer.rb +46 -0
  32. data/lib/shellfie/parser.rb +183 -30
  33. data/lib/shellfie/parser_validation.rb +178 -0
  34. data/lib/shellfie/raster_painter.rb +157 -0
  35. data/lib/shellfie/render_chrome_cache.rb +40 -0
  36. data/lib/shellfie/render_geometry.rb +115 -0
  37. data/lib/shellfie/render_segment.rb +71 -0
  38. data/lib/shellfie/renderer.rb +96 -149
  39. data/lib/shellfie/rendering/shape_helpers.rb +42 -0
  40. data/lib/shellfie/rendering/text_painter.rb +195 -0
  41. data/lib/shellfie/rendering/window_chrome.rb +196 -0
  42. data/lib/shellfie/reproducibility_manifest.rb +41 -0
  43. data/lib/shellfie/session.rb +111 -0
  44. data/lib/shellfie/session_config.rb +562 -0
  45. data/lib/shellfie/session_runner.rb +689 -0
  46. data/lib/shellfie/svg_raster_wrapper.rb +35 -0
  47. data/lib/shellfie/svg_renderer.rb +222 -0
  48. data/lib/shellfie/terminal_screen.rb +389 -0
  49. data/lib/shellfie/text_metrics.rb +155 -0
  50. data/lib/shellfie/theme_data.rb +80 -0
  51. data/lib/shellfie/theme_registry.rb +131 -0
  52. data/lib/shellfie/themes/base.rb +10 -1
  53. data/lib/shellfie/themes/configured.rb +61 -0
  54. data/lib/shellfie/themes/macos.rb +3 -1
  55. data/lib/shellfie/themes/ubuntu.rb +2 -1
  56. data/lib/shellfie/themes/windows_terminal.rb +7 -1
  57. data/lib/shellfie/transcript_renderer.rb +92 -0
  58. data/lib/shellfie/version.rb +1 -1
  59. data/lib/shellfie/yaml_safety.rb +147 -0
  60. data/lib/shellfie.rb +44 -3
  61. data/schema/shellfie-v1.schema.json +153 -0
  62. data/schema/shellfie-v2.schema.json +262 -0
  63. metadata +58 -20
  64. data/.rspec +0 -3
  65. data/Rakefile +0 -8
  66. data/examples/animation.yml +0 -33
  67. data/examples/colored.yml +0 -20
  68. data/examples/demo.gif +0 -0
  69. data/examples/demo.png +0 -0
  70. data/examples/demo_animation.yml +0 -31
  71. data/examples/headless.png +0 -0
  72. data/examples/headless.yml +0 -16
  73. data/examples/scrolling.yml +0 -48
  74. data/examples/simple.yml +0 -21
  75. data/examples/theme_macos.png +0 -0
  76. data/examples/theme_ubuntu.png +0 -0
  77. data/examples/theme_windows.png +0 -0
  78. data/shellfie.gemspec +0 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2aa4926f71fb587dd2ec442e5257a849e8af9b7fbbb7fb62e0ef1a840cd8dac6
4
- data.tar.gz: 6dbfb90a504e732089a68548970c1ac17879338793612c50872b2cc762572b7f
3
+ metadata.gz: 0dbccd8edad54ded2bda6b8da245ab3f4ab3c9527ffd4bc75ef04cf7b6fc8713
4
+ data.tar.gz: 5fa83b5f80fae2d6281adc4ef685271af2b8c8f303d4116cbe26904ecf12c2a4
5
5
  SHA512:
6
- metadata.gz: 278e0eabca9c70c2284ca9ccbcba74933fe14e24e6c1050c0a2b635a058fb01d22d353f854083bc8edd4531c7565dbb4e47f84eebc286a33721c238bc025e568
7
- data.tar.gz: 2712539d09a9d2fe1e2149d6786f230ba68b230ea2f3fa3f885c081f52985d4437d0020a702fa9af2c2eed4fdb781dd0d4fa68d251fb1d11338ae090014eea1a
6
+ metadata.gz: 473c51c3384978e8bc493b0a27cc1b5e9949c99c9f14d2cd6516cae963648c07bd281650175713f4028c09be1ce5d0140c119a4ffd7336da92e8a80075c43f30
7
+ data.tar.gz: fc061b6f9bff4c8f5bf7f512891ed8c13b39bf3342a14a5b98b967b15ac68a7d0dafc582ac884ea402e9d4ba61a0e549ca19d1883575c3af69a4e7e556b1d063
data/CHANGELOG.md CHANGED
@@ -1,6 +1,60 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased
3
+ ## 1.1.0 - 2026-08-29
4
+
5
+ ### Added
6
+
7
+ - Add executable version 2 sessions with `run`, `record`, and `replay`; PTY sessions support command and key input, waits, assertions, hidden steps, redaction, named captures, editable recordings, and offline cassettes.
8
+ - Add native selectable-text SVG, accessible HTML, MP4, WebM, event-duration PNG sequences, plain and ANSI-preserving text, structured JSON, and asciinema v2 output. Legacy raster-backed SVG remains available as `svg-raster`.
9
+ - Add multiple configured outputs and capture-specific outputs from one session.
10
+ - Add JSON Schemas, file/line/column diagnostics, typo suggestions, and `new`, `format`, `compile`, `schema`, `completion`, and include-aware `watch` authoring commands.
11
+ - Add typed session variables, reusable and repeated step sets, and OS, shell, Ruby, and configured-environment step conditions.
12
+ - Add inferred output names, collision-checked output templates, common aspect presets, bounded parallel batch rendering with `--jobs`, and non-mutating output verification with `generate --check`.
13
+ - Add reproducibility manifests and JSON, SARIF, and JUnit validation reports for CI and editor integrations.
14
+ - Add a reusable GitHub Action for generating or checking outputs and Docker packaging for a consistent rendering environment.
15
+ - Add deterministic animation seeds, separate typing rate, frame timing, and playback speed controls, reverse and ping-pong playback, loop offsets, and format-specific GIF, WebP, and APNG controls.
16
+ - Add configurable East Asian Ambiguous width and report the active Unicode and width-table profile through inspection and manifests.
17
+ - Add broader terminal behavior for cursor movement, erase and insertion controls, alternate screens, scroll regions, colon-form colors, extended underline styles and colors, blink, conceal, and safe OSC 8 links.
18
+
19
+ ### Changed
20
+
21
+ - Treat every frame `delay` as a post-action delay; a `type` frame's delay now overrides the global command delay, and `lines` initialize the screen when `frames` are also present.
22
+ - Treat an explicit WebP format as static unless the input has frames or `--animate` is supplied.
23
+ - Deprecate `--fps` in favor of `--framerate`; use `--typing-rate` to control input speed independently.
24
+
25
+ ### Fixed
26
+
27
+ - Correct terminal tab stops, backspace behavior, wide-cell overwrites, grapheme-cluster typing, split Unicode input, line feeds, autowrap, and scroll-region editing.
28
+ - Correct animation duration rounding, duplicate-frame timing, APNG tail duration, playback-speed timing, and minimum video duration.
29
+ - Prevent output collisions before rendering, stream stdout without an output-sized memory copy, preserve existing outputs on failure, and remove partial animation files after errors or interruption.
30
+ - Improve live-session prompt and exit synchronization, preserve asynchronous output, honor PTY dimensions and working directories, and terminate leftover child processes.
31
+ - Improve `doctor` and dependency checks with real rendering, format delegates, fonts, security policy, and temporary-storage diagnostics.
32
+
33
+ ### Security and reliability
34
+
35
+ - Add include cycle and chain diagnostics, per-file and aggregate size limits, and an optional symlink-aware root policy for includes and session working directories.
36
+ - Add environment allowlists, total and per-step timeouts, bounded regular-expression evaluation, output and control-sequence limits, and rendering workload and temporary-disk budgets.
37
+ - Add opt-in rejection of unsupported terminal graphics and an explicit policy for preserving only bounded `http`, `https`, and `mailto` OSC 8 links.
38
+
39
+ ## 1.0.0 - 2026-05-20
40
+
41
+ ### Added
42
+
43
+ - Add static SVG and WebP output plus animated WebP and APNG output, with format selection by extension or `--format` and binary output through stdout.
44
+ - Add batch generation from multiple files and glob patterns, directory outputs, automatic output-directory creation, and `--quiet` and `--verbose` modes.
45
+ - Add `inspect` for resolved configuration and output dimensions, and `doctor` for Ruby, ImageMagick, output-directory, and encoding checks.
46
+ - Add custom themes, Dracula, One Dark, Solarized Dark, and Catppuccin Mocha color schemes, configurable colors and window decorations, background gradients, font fallbacks, and block, bar, or underline cursors.
47
+ - Add reusable YAML includes, line selection and semantic prompt, command, and output colors.
48
+ - Add clip, wrap, and scroll overflow modes, exact-size and trimmed canvases, maximum height and line controls, configurable tab width, and per-line or persistent ANSI state.
49
+ - Add animation typing jitter and chunking, output and final delays, frame limits, global, adaptive, or theme palettes, optional dithering, and configurable scroll easing.
50
+ - Add public Ruby APIs for parsing, validating, rendering, and inspecting configurations.
51
+
52
+ ### Changed
53
+
54
+ - Correct xterm 256-color values and malformed extended colors, and add dim, reverse, strikethrough, and overline styles plus carriage return, backspace, cursor movement, erase, and tab handling.
55
+ - Improve line measurement, clipping, wrapping, fixed-height scrolling, trailing-line preservation, stable animation dimensions, and Windows, Ubuntu, macOS, and headless window rendering.
56
+ - Refuse to replace an existing output unless `--force` is supplied, write outputs atomically, report errors on stderr, and distinguish filesystem failures with their own exit code.
57
+ - Reject unknown keys, invalid types, unsupported values, excessive lines, frames, characters, pixels, and rendered frames with clearer validation errors before rendering.
4
58
 
5
59
  ## 0.1.1 - 2026-01-12
6
60
 
@@ -8,4 +62,4 @@
8
62
 
9
63
  ## 0.1.0 - 2026-01-12
10
64
 
11
- - Initial release.
65
+ - Initial release.
data/README.md CHANGED
@@ -1,333 +1,353 @@
1
1
  <p align="center">
2
- <img src="assets/logo-header.svg" alt="shellfie header logo">
3
- <p align="center">
4
- <strong>Generate beautiful terminal screenshots from YAML</strong>
5
- </p>
6
- <p align="center">
7
- <a href="https://rubygems.org/gems/shellfie"><img src="https://img.shields.io/gem/v/shellfie.svg?colorB=319e8c" alt="Gem Version"></a>
8
- <a href="https://rubygems.org/gems/shellfie"><img src="https://img.shields.io/gem/dt/shellfie.svg" alt="Downloads"></a>
9
- <img src="https://img.shields.io/badge/ruby-%3E%3D%203.0-ruby.svg" alt="Ruby Version">
10
- <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License">
11
- </p>
2
+ <img src="assets/logo-header.svg" alt="Shellfie header logo">
12
3
  </p>
13
4
 
14
5
  <p align="center">
15
- <a href="#features">Features</a>
16
- <a href="#installation">Installation</a>
17
- <a href="#usage">Usage</a> •
18
- <a href="#configuration">Configuration</a> •
19
- <a href="#themes">Themes</a>
6
+ <strong>Deterministic terminal visuals and executable sessions from YAML</strong>
7
+ </p>
8
+
9
+ <p align="center">
10
+ <a href="https://rubygems.org/gems/shellfie"><img src="https://img.shields.io/gem/v/shellfie.svg?colorB=319e8c" alt="Gem Version"></a>
11
+ <a href="https://rubygems.org/gems/shellfie"><img src="https://img.shields.io/gem/dt/shellfie.svg" alt="Downloads"></a>
12
+ <img src="https://img.shields.io/badge/ruby-%3E%3D%203.0-ruby.svg" alt="Ruby Version">
13
+ <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License">
14
+ </p>
15
+
16
+ <p align="center">
17
+ <a href="#features">Features</a> ·
18
+ <a href="#installation">Installation</a> ·
19
+ <a href="#quick-start">Quick Start</a> ·
20
+ <a href="#terminal-sessions">Terminal Sessions</a> ·
21
+ <a href="#configuration">Configuration</a> ·
22
+ <a href="#automation">Automation</a>
20
23
  </p>
21
24
 
22
25
  ---
23
26
 
24
- **Shellfie** (Shell + Selfie) creates stunning terminal screenshot-style images from simple YAML configuration files. Perfect for documentation, README files, tutorials, and presentations without actually taking screenshots.
27
+ Shellfie compiles YAML into deterministic terminal images, animations, and semantic transcripts. When explicitly requested, it can also run real PTY sessions, assert their output, record cassettes, and replay them offline.
25
28
 
26
29
  <p align="center">
27
- <img src="examples/demo.gif" alt="Shellfie Demo" width="550">
30
+ <img src="examples/demo.gif" alt="Shellfie generating and validating an animated terminal demo" width="720">
31
+ <br>
32
+ <sub>Generated by Shellfie from <a href="examples/demo_animation.yml">examples/demo_animation.yml</a>.</sub>
28
33
  </p>
29
34
 
30
35
  ## Features
31
36
 
32
- ### Multiple Themes
33
-
34
- Generate images with different terminal styles:
37
+ - Deterministic compose mode that never executes configuration content
38
+ - Optional PTY execution with waits, assertions, captures, and redaction
39
+ - Editable recordings and offline cassette replay
40
+ - PNG, WebP, native SVG, HTML, GIF, APNG, MP4, WebM, and PNG sequence output
41
+ - Plain text, ANSI, JSON, and asciinema v2 semantic transcripts
42
+ - macOS, Ubuntu, Windows, and custom window styles, plus a headless mode
43
+ - ANSI colors and controls, Unicode grapheme handling, and configurable ambiguous width
44
+ - JSON Schemas, source-aware diagnostics, formatting, compilation, completion, and watch commands
45
+ - Resource limits, path policies, dependency preflight, and atomic output replacement
35
46
 
36
- <table>
37
- <tr>
38
- <th>macOS</th>
39
- <th>Ubuntu</th>
40
- <th>Windows</th>
41
- </tr>
42
- <tr>
43
- <td><img src="examples/theme_macos.png" width="280" alt="macOS theme"></td>
44
- <td><img src="examples/theme_ubuntu.png" width="280" alt="Ubuntu theme"></td>
45
- <td><img src="examples/theme_windows.png" width="280" alt="Windows theme"></td>
46
- </tr>
47
- </table>
48
-
49
- ### Animated GIFs
47
+ ## Installation
50
48
 
51
- Create typing animations with realistic effects:
49
+ Add Shellfie to your Gemfile:
52
50
 
53
- ```yaml
54
- animation:
55
- typing_speed: 50 # Milliseconds per character
56
- command_delay: 500 # Pause after command
57
- loop: true # Loop animation
51
+ ```ruby
52
+ gem "shellfie"
58
53
  ```
59
54
 
60
- ### Full ANSI Color Support
61
-
62
- - Standard 8 colors + bright variants
63
- - 256-color palette
64
- - True color (24-bit RGB)
65
- - Bold, italic, underline styles
55
+ Then install:
66
56
 
67
- ### Flexible Output Options
57
+ ```bash
58
+ bundle install
59
+ ```
68
60
 
69
- - **High DPI support** — Generate 2x or 3x scaled images for Retina displays
70
- - **Headless mode** — Output without window decorations
71
- - **Shadow effects** — Beautiful drop shadows
72
- - **Transparent backgrounds** — Perfect for overlays
73
- - **Fixed height with scrolling** — Consistent GIF dimensions
61
+ Or install it directly:
74
62
 
75
- ## Installation
63
+ ```bash
64
+ gem install shellfie
65
+ ```
76
66
 
77
67
  ### Requirements
78
68
 
79
69
  - Ruby 3.0+
80
- - ImageMagick 7.0+
70
+ - ImageMagick
71
+ - ffmpeg for MP4, WebM, and APNG output
81
72
 
82
- ```bash
83
- # Install ImageMagick first
84
- brew install imagemagick # macOS
85
- sudo apt install imagemagick # Ubuntu/Debian
86
- choco install imagemagick # Windows
87
- ```
88
-
89
- ### Install the gem
73
+ Install media dependencies on macOS:
90
74
 
91
75
  ```bash
92
- gem install shellfie
76
+ brew install imagemagick ffmpeg
93
77
  ```
94
78
 
95
- Or add to your Gemfile:
79
+ On Ubuntu or Debian:
96
80
 
97
- ```ruby
98
- gem 'shellfie'
81
+ ```bash
82
+ sudo apt install imagemagick ffmpeg
99
83
  ```
100
84
 
101
- ## Usage
85
+ Static and animated composition works on macOS, Linux, and Windows. Live PTY sessions are not supported on native Windows.
102
86
 
103
- ### Quick Start
87
+ ## Quick Start
104
88
 
105
- 1. Create a configuration file:
89
+ Create `terminal.yml`:
106
90
 
107
91
  ```yaml
108
- # terminal.yml
92
+ version: 1
109
93
  theme: macos
110
- title: "Terminal — zsh"
111
-
112
- window:
113
- width: 600
114
- padding: 20
94
+ title: "Terminal"
115
95
 
116
96
  lines:
117
97
  - prompt: "$ "
118
- command: "echo 'Hello, World!'"
119
- - output: "Hello, World!"
98
+ command: "echo hello"
99
+ - output: "hello"
120
100
  ```
121
101
 
122
- 2. Generate an image:
102
+ Generate an image:
123
103
 
124
104
  ```bash
125
- shellfie generate terminal.yml -o output.png
105
+ shellfie generate terminal.yml -o terminal.png
126
106
  ```
127
107
 
128
- ### Commands
108
+ Without `-o`, Shellfie writes `terminal.png` beside the input. `shf` is available as a short alias for `shellfie`.
129
109
 
130
- | Command | Description |
131
- |---------|-------------|
132
- | `shellfie generate <file> -o <output>` | Generate image from config |
133
- | `shellfie init` | Output sample configuration |
134
- | `shellfie themes` | List available themes |
135
- | `shellfie validate <file>` | Validate configuration |
136
- | `shellfie version` | Show version |
137
- | `shellfie help` | Show help |
110
+ ### Output Formats
138
111
 
139
- > [!TIP]
140
- > Use `shf` as a shorter alias for `shellfie`
112
+ | Kind | Formats |
113
+ | --- | --- |
114
+ | Static | PNG, WebP, native selectable-text SVG, accessible HTML |
115
+ | Animated | GIF, WebP, APNG, MP4, WebM, event-duration PNG sequence with `timeline.json` |
116
+ | Semantic | TXT, ANSI, JSON, asciinema v2 (`asciicast` or `cast`) |
141
117
 
142
- ### Generate Options
118
+ Use `svg-raster` only when the legacy PNG-backed SVG behavior is required.
143
119
 
144
- ```bash
145
- shellfie generate config.yml -o output.png [options]
146
- ```
120
+ ## CLI
147
121
 
148
- | Option | Description |
149
- |--------|-------------|
150
- | `-o, --output PATH` | Output file path (required) |
151
- | `-t, --theme NAME` | Override theme (`macos`, `ubuntu`, `windows`) |
152
- | `-a, --animate` | Generate animated GIF |
153
- | `-s, --scale FACTOR` | Output scale (1, 2, 3) for HiDPI |
154
- | `-w, --width PIXELS` | Override width |
155
- | `--no-shadow` | Disable shadow effect |
156
- | `--no-header` | Disable window header (headless mode) |
157
- | `--transparent` | Transparent background |
122
+ | Command | Purpose |
123
+ | --- | --- |
124
+ | `generate` | Render a version 1 compose configuration |
125
+ | `run` | Execute and render a version 2 terminal session |
126
+ | `record` | Execute a session and save a cassette or editable YAML |
127
+ | `replay` | Render a cassette without executing its commands |
128
+ | `new` / `init` | Create or print starter configuration |
129
+ | `format` | Normalize YAML formatting |
130
+ | `compile` | Print the resolved configuration or session IR |
131
+ | `validate` | Validate input as text, JSON, SARIF, or JUnit |
132
+ | `inspect` | Show resolved settings, dimensions, fonts, and resource estimates |
133
+ | `schema` | Print the version 1 or version 2 JSON Schema |
134
+ | `completion` | Print bash, zsh, fish, or PowerShell completion |
135
+ | `watch` | Regenerate when a configuration or include changes |
136
+ | `themes` | List available themes and color schemes |
137
+ | `doctor` | Check media tools, formats, fonts, policies, and storage |
138
+ | `version` | Show the installed Shellfie version |
158
139
 
159
- ### Examples
140
+ ## Terminal Sessions
160
141
 
161
- ```bash
162
- # Basic PNG
163
- shellfie generate config.yml -o terminal.png
142
+ Version 2 sessions execute commands only through `run` or `record`; review a session before running it. A minimal session looks like this:
164
143
 
165
- # Animated GIF
166
- shellfie generate config.yml -o demo.gif --animate
144
+ ```yaml
145
+ version: 2
146
+ mode: run
147
+ title: "Recorded shell"
148
+ theme: macos
167
149
 
168
- # Retina-ready (2x scale)
169
- shellfie generate config.yml -o terminal@2x.png --scale 2
150
+ terminal:
151
+ shell: /bin/sh
152
+ columns: 80
153
+ rows: 16
154
+ timeout: 10s
155
+
156
+ steps:
157
+ - type: printf 'hello from shellfie\n'
158
+ speed: 30cps
159
+ - key: enter
160
+ - expect:
161
+ screen_contains: hello from shellfie
162
+ exit_status: 0
163
+ - capture: complete
164
+
165
+ outputs:
166
+ - path: session.svg
167
+ format: svg
168
+ capture: complete
169
+ - path: session.txt
170
+ format: txt
171
+ ```
170
172
 
171
- # Headless (no window decorations)
172
- shellfie generate config.yml -o code.png --no-header
173
+ Run, record, or replay it:
173
174
 
174
- # Ubuntu theme with custom width
175
- shellfie generate config.yml -o ubuntu.png -t ubuntu -w 800
175
+ ```bash
176
+ shellfie run session.yml
177
+ shellfie record session.yml --cassette session.json
178
+ shellfie record session.yml --yaml editable-recording.yml
179
+ shellfie replay session.json -o session.gif --animate
176
180
  ```
177
181
 
178
- ## Configuration
182
+ ### Session Actions
179
183
 
180
- ### Basic Structure
184
+ | Action | Purpose |
185
+ | --- | --- |
186
+ | `run` | Execute a command directly, hidden by default |
187
+ | `type` | Type visible text at a configurable rate |
188
+ | `key` | Send Enter, arrows, modifiers, and other terminal keys |
189
+ | `sleep` | Add a deterministic presentation pause |
190
+ | `wait` | Wait for screen, line, prompt, exit, or stable-screen conditions |
191
+ | `expect` | Assert screen text, lines, exit status, cursor, elapsed time, or a text golden |
192
+ | `hide` / `show` | Control whether preparation and cleanup are recorded |
193
+ | `capture` | Name an intermediate screen for a specific output |
181
194
 
182
- ```yaml
183
- theme: macos # Theme: macos, ubuntu, windows
184
- title: "Terminal — zsh" # Window title
185
- headless: false # Hide window decorations
195
+ Sessions also support `requires`, step-level working directories, multiple outputs, reusable includes, environment allowlists, total and per-step timeouts, and redaction patterns. Set `terminal.cwd_policy: root` to confine working directories to the session root. Use `async: true` before interacting with a long-running or full-screen process, then synchronize with `wait`.
186
196
 
187
- window:
188
- width: 600 # Window width in pixels
189
- padding: 20 # Content padding
190
- visible_lines: 10 # Fixed line count (for scrolling GIFs)
197
+ Variables use `{{name}}` placeholders. Reusable `step_sets` expand through `use`, `repeat` repeats a step or set, and `if` can select steps by OS, shell, Ruby requirement, or explicitly configured environment values. Expansion is bounded and cycles are rejected.
191
198
 
192
- font:
193
- family: "Monaco" # Font family
194
- size: 14 # Font size
195
- line_height: 1.4 # Line height multiplier
199
+ ## Authoring
196
200
 
197
- lines: # Static content
198
- - prompt: "$ "
199
- command: "echo hello"
200
- - output: "hello"
201
+ Create and inspect configurations without rendering them:
202
+
203
+ ```bash
204
+ shellfie new terminal.yml --template static
205
+ shellfie new demo.yml --template animation
206
+ shellfie new session.yml --template run
207
+ shellfie format terminal.yml
208
+ shellfie compile terminal.yml --format json
209
+ shellfie validate terminal.yml --format sarif
210
+ shellfie inspect terminal.yml --json
211
+ shellfie watch terminal.yml -o terminal.png
201
212
  ```
202
213
 
203
- ### Static Images
214
+ Templates include `static`, `animation`, `run`, `tui`, `ci`, and `theme-gallery`. JSON Schemas live in [`schema/`](schema/); add the following directive for editor validation:
204
215
 
205
216
  ```yaml
206
- theme: macos
207
- title: "Terminal"
208
-
209
- lines:
210
- - prompt: "$ "
211
- command: "gem install shellfie"
212
-
213
- - output: |
214
- Fetching shellfie-0.1.0.gem
215
- Successfully installed shellfie-0.1.0
216
- 1 gem installed
217
-
218
- - prompt: "$ "
219
- command: ""
217
+ # yaml-language-server: $schema=../schema/shellfie-v1.schema.json
220
218
  ```
221
219
 
222
- ### Animated GIFs
220
+ Use schema version 2 for executable sessions. Run `shellfie schema 1` or `shellfie schema 2` to print either schema, and `shellfie completion zsh` to generate shell completion.
223
221
 
224
- ```yaml
225
- theme: macos
226
- title: "Demo"
222
+ ## Automation
227
223
 
228
- animation:
229
- typing_speed: 50 # ms per character
230
- command_delay: 500 # ms after command execution
231
- cursor_blink: true # Show blinking cursor
232
- loop: true # Loop the animation
233
-
234
- frames:
235
- - prompt: "$ "
236
- type: "echo 'Hello!'" # Text to type (animated)
237
- delay: 500 # Pause after this frame
224
+ Use the Docker-based GitHub Action to generate an output or fail when a committed output is stale:
238
225
 
239
- - output: "Hello!"
240
- delay: 1000
226
+ ```yaml
227
+ - uses: ydah/shellfie@main
228
+ with:
229
+ input: examples/simple.yml
230
+ output: docs/terminal.png
231
+ check: "true"
241
232
  ```
242
233
 
243
- ### ANSI Colors
234
+ Or build and run the included container locally:
244
235
 
245
- ```yaml
246
- lines:
247
- - prompt: "\e[32muser@host\e[0m:\e[34m~/project\e[0m$ "
248
- command: "ls"
249
-
250
- - output: "\e[34mdir1\e[0m \e[32mfile.txt\e[0m \e[31merror.log\e[0m"
236
+ ```bash
237
+ docker build -t shellfie .
238
+ docker run --rm -v "$PWD:/work" shellfie \
239
+ generate /work/examples/simple.yml -o /work/terminal.png --force
251
240
  ```
252
241
 
253
- **Supported escape codes:**
242
+ Use `--manifest manifest.json` during generation to record configuration and output hashes, Ruby, OS, ImageMagick, ffmpeg, and resolved font fingerprints.
254
243
 
255
- | Code | Effect |
256
- |------|--------|
257
- | `\e[0m` | Reset |
258
- | `\e[1m` | Bold |
259
- | `\e[3m` | Italic |
260
- | `\e[4m` | Underline |
261
- | `\e[30-37m` | Foreground colors |
262
- | `\e[40-47m` | Background colors |
263
- | `\e[90-97m` | Bright foreground |
264
- | `\e[38;5;Nm` | 256-color foreground |
265
- | `\e[38;2;R;G;Bm` | RGB foreground |
266
-
267
- ### Fixed Height with Scrolling
244
+ ## Configuration
268
245
 
269
- For GIFs with many lines, use `visible_lines` to maintain consistent dimensions:
246
+ ### Compose Configuration
247
+
248
+ | Key | Purpose |
249
+ | --- | --- |
250
+ | `theme` | `macos`, `ubuntu`, `windows`, or `custom` |
251
+ | `window_theme` | Window chrome to use with a custom theme |
252
+ | `color_scheme` | Built-in palette: `dracula`, `one_dark`, `solarized_dark`, or `catppuccin_mocha` |
253
+ | `colors` | Individual color overrides |
254
+ | `window` | Width, height, padding, wrapping, clipping, scrolling, and terminal policies |
255
+ | `font` | Family, fallback families, size, and line height |
256
+ | `animation` | Typing, timing, playback, loop, palette, and encoder controls |
257
+ | `cursor` | Cursor style and color |
258
+ | `headless` | Hide window chrome |
259
+ | `lines` | Initial or static terminal content |
260
+ | `frames` | Animated terminal events |
261
+ | `limits` | Source, output-frame, pixel, and temporary-storage ceilings |
262
+
263
+ Static content uses `lines`; animations add `frames`:
270
264
 
271
265
  ```yaml
266
+ version: 1
267
+ theme: macos
268
+ title: "Demo"
269
+
272
270
  window:
273
271
  width: 600
274
- visible_lines: 8 # Show only last 8 lines
272
+ padding: 20
273
+ visible_lines: 8
274
+ overflow: clip
275
+
276
+ animation:
277
+ typing_speed: 50
278
+ framerate: 30
279
+ playback_speed: 1.0
280
+ cursor_blink: true
281
+ loop: true
282
+ seed: 1
283
+
284
+ lines:
285
+ - output: "Ready"
275
286
 
276
287
  frames:
277
288
  - prompt: "$ "
278
- type: "for i in {1..20}; do echo $i; done"
279
- # Lines will scroll as content exceeds visible_lines
289
+ type: "echo hello"
290
+ delay: 500
291
+ - output: "hello"
292
+ delay: 1000
280
293
  ```
281
294
 
282
- ## Themes
283
-
284
- ### macOS (default)
285
-
286
- Classic macOS Terminal appearance with traffic light buttons (red, yellow, green) on the left side.
287
-
288
- ### Ubuntu
289
-
290
- GNOME Terminal style with window controls on the right side and Ubuntu's signature purple background.
291
-
292
- ### Windows Terminal
293
-
294
- Modern Windows Terminal design with flat styling and square corners.
295
-
296
- ### Headless Mode
295
+ A frame `delay` is applied after its action; on a `type` frame it overrides `animation.command_delay`. When both `lines` and `frames` are present, `lines` initialize the screen before animated events run.
297
296
 
298
- No window decorations — just the terminal content. Perfect for embedding in documentation.
299
-
300
- <p align="center">
301
- <img src="examples/headless.png" alt="Headless mode" width="500">
302
- </p>
303
-
304
- ```bash
305
- shellfie generate config.yml -o output.png --no-header
306
- ```
307
-
308
- Or in YAML:
297
+ ### Generate Options
309
298
 
310
- ```yaml
311
- headless: true
312
- ```
299
+ | Option | Description |
300
+ | --- | --- |
301
+ | `-o, --output PATH` | Output path or `{name}-{theme}-{scale}.{format}` template |
302
+ | `--preset NAME` | Exact `readme`, `ogp`, `widescreen`, `standard`, or `vertical` canvas |
303
+ | `-t, --theme NAME` | Override the theme |
304
+ | `-a, --animate` | Render animation |
305
+ | `-s, --scale FACTOR` | Output scale: `1`, `2`, or `3` |
306
+ | `-w, --width PIXELS` | Override width |
307
+ | `--format FORMAT` | Select an output format |
308
+ | `--check` | Fail if an existing output is stale without replacing it |
309
+ | `--jobs N` | Render up to 32 inputs in parallel after preflight |
310
+ | `--typing-rate CPS` | Override typing rate in characters per second |
311
+ | `--framerate FPS` | Set output timing precision |
312
+ | `--seed N` | Set the deterministic animation seed |
313
+ | `--playback-speed FACTOR` | Scale the final timeline |
314
+ | `--overflow MODE` | `clip`, `wrap`, or `scroll` |
315
+ | `--no-shadow` | Disable the window shadow |
316
+ | `--transparent` | Use a transparent background |
317
+ | `--no-header` | Hide window chrome |
318
+ | `--force` | Replace an existing output |
319
+
320
+ ### Advanced Controls
321
+
322
+ - Set `animation.direction` to `forward`, `reverse`, or `ping_pong`; `animation.loop_offset` selects a different initial frame.
323
+ - Tune GIF colors and optimization, WebP quality and lossless mode, APNG prediction and loop count, and scroll easing under `animation`.
324
+ - Set `window.ambiguous_width` to `1` or `2`; inspection and manifests report the active Unicode and width-table profile.
325
+ - Set `window.osc_policy: preserve` to keep bounded `http`, `https`, and `mailto` OSC 8 links in SVG and HTML.
326
+ - Set `window.graphics_policy: error` to reject SIXEL, Kitty, or iTerm2 graphics instead of discarding them.
327
+ - Use `include` for shared YAML. Set `include_policy: root` to reject paths outside the root configuration directory, including symlink escapes.
328
+ - Set resource ceilings under `limits`; Shellfie checks source size, pixels, frame work, and temporary storage before expensive rendering.
329
+
330
+ ## How It Works
331
+
332
+ 1. Configuration parsing resolves includes, validates input, and reports source locations.
333
+ 2. Compose, live PTY, or cassette input is normalized into terminal events.
334
+ 3. The terminal screen applies Unicode, ANSI, cursor, erase, alternate-screen, and scroll behavior.
335
+ 4. Raster, SVG, HTML, video, or semantic renderers produce the requested outputs.
336
+ 5. Output files are written atomically after dependency, collision, and resource preflight.
337
+
338
+ `generate` is deterministic and never runs configuration content. `run` and `record` opt into PTY execution. `replay` uses a cassette and does not execute the recorded commands.
313
339
 
314
340
  ## Development
315
341
 
316
342
  ```bash
317
- git clone https://github.com/yourusername/shellfie.git
318
- cd shellfie
319
-
320
343
  bundle install
321
- bundle exec rspec # Run tests
344
+ bundle exec rspec
345
+ gem build shellfie.gemspec
322
346
  ```
323
347
 
324
348
  ## Contributing
325
349
 
326
- 1. Fork it
327
- 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
328
- 3. Commit your changes (`git commit -am 'Add amazing feature'`)
329
- 4. Push to the branch (`git push origin feature/amazing-feature`)
330
- 5. Open a Pull Request
350
+ Bug reports and pull requests are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) and [SECURITY.md](SECURITY.md) before submitting changes or security reports.
331
351
 
332
352
  ## License
333
353