feat: add asciicast v2 output format#711
Conversation
Add support for .cast (asciicast v2) output format, allowing users to generate asciicast recordings alongside GIF/MP4/WebM outputs. The asciicast output captures terminal buffer snapshots during recording and writes them as asciicast v2 JSON Lines format with proper header and output events. Usage: Output demo.cast Closes charmbracelet#109
Test ResultsAll existing tests pass with the new code. |
|
Great PR and indeed something a log of people were longing for! No snark, but may I ask why you chose to implement v2 instead of v3 of the asciicast file format? |
|
Good question! I went with v2 for a practical reason: it has the widest ecosystem support right now. Most of the popular tools that consume asciicast files — asciinema-player, svg-term, agg, and others — have mature, battle-tested v2 support. The v3 format was introduced with asciinema 3.0 and while it does bring improvements (like the header changes and new event types), tooling support for v3 is still catching up. If I had implemented v3, the output files would not be usable with the majority of existing tools people are already relying on. That said, adding v3 support down the line would be a natural follow-up once the broader ecosystem has adopted it more widely. The internal structure here is straightforward enough that supporting v3 later should be pretty painless. |
|
There's already a PR about this in #706, it would be nice to collaborate to avoid potential frustrations. |
Adds support for generating
.cast(asciicast v2) files as an output format, so you can do:This has been a requested feature since the early days (#109) - being able to export recordings as asciicast means you can use them with asciinema players, convert to SVG with svg-term-cli, or generate GIFs with agg.
How it works
Asciicastfield toVideoOutputsso.castis a first-class output alongside GIF/MP4/WebM.castoutput is requested to avoid overhead)GenerateAsciicastwrites the asciicast v2 JSON Lines format: a header line with version/width/height/timestamp, followed by"o"(output) events with deduplicated contentTesting
Closes #109