|
| 1 | +# EdgarTools demo recordings (VHS) |
| 2 | + |
| 3 | +Reproducible terminal demo clips for the README, docs, and social — real |
| 4 | +terminal, real Rich output, scripted with [VHS](https://github.com/charmbracelet/vhs). |
| 5 | + |
| 6 | +Each clip is defined by a `.tape` file and renders to **both a GIF and an MP4** |
| 7 | +from one source, so the same recording serves all three venues: |
| 8 | + |
| 9 | +- **GIF** → README + social autoplay |
| 10 | +- **MP4** → docs-page embeds + social with captions/voiceover added in post |
| 11 | + |
| 12 | +No Homebrew required. Everything runs in a Docker image that bundles |
| 13 | +`vhs` + `ttyd` + `ffmpeg` and a venv with `edgartools`. |
| 14 | + |
| 15 | +## One-time setup |
| 16 | + |
| 17 | +```bash |
| 18 | +# Build the recording image (installs edgartools inside the vhs image). |
| 19 | +docker build -t edgartools-vhs scripts/vhs |
| 20 | +``` |
| 21 | + |
| 22 | +Rebuild only when `Dockerfile` / `pystartup.py` change or to pick up a newer |
| 23 | +edgartools release. |
| 24 | + |
| 25 | +## Render a clip |
| 26 | + |
| 27 | +From the repo root (uses your `EDGAR_IDENTITY` for SEC access): |
| 28 | + |
| 29 | +```bash |
| 30 | +docker run --rm \ |
| 31 | + -e EDGAR_IDENTITY="$EDGAR_IDENTITY" \ |
| 32 | + -v "$PWD:/vhs" -w /vhs \ |
| 33 | + edgartools-vhs scripts/vhs/hero-income-statement.tape |
| 34 | +``` |
| 35 | + |
| 36 | +Outputs land in `scripts/vhs/out/`. Promote a final clip to the published |
| 37 | +location when happy (the README hero lives at `docs/images/`): |
| 38 | + |
| 39 | +```bash |
| 40 | +cp scripts/vhs/out/hero-income-statement.gif docs/images/ |
| 41 | +``` |
| 42 | + |
| 43 | +## How it's wired |
| 44 | + |
| 45 | +| File | Role | |
| 46 | +|------|------| |
| 47 | +| `Dockerfile` | `FROM` Charm's vhs image; adds a venv with `edgartools` + the prelude. | |
| 48 | +| `pystartup.py` | Off-camera REPL prelude: `set_identity`, pre-imports, and a Rich display hook so a bare expression renders the formatted table in colour at a fixed width (`VHS_CONSOLE_WIDTH`, default 100). | |
| 49 | +| `theme.tape` | Shared "set design" (font, size, theme, typing speed). `Source`d by every tape — edit once to restyle the series. | |
| 50 | +| `*.tape` | One clip each. | |
| 51 | +| `out/` | Rendered GIFs/MP4s (working dir; not the published location). | |
| 52 | + |
| 53 | +The tape pattern: launch `python -q` **hidden** (identity + imports load from |
| 54 | +`PYTHONSTARTUP`), `Ctrl+L` to a clean prompt, `Show`, then type the single |
| 55 | +on-camera expression. Viewers never see boilerplate. |
| 56 | + |
| 57 | +## Clips |
| 58 | + |
| 59 | +| Tape | Clip | Status | |
| 60 | +|------|------|--------| |
| 61 | +| `hero-reel.tape` | 🌟 Hero reel — 30s tour: Company → filings → 10-K (TOC) → financials | ✅ done | |
| 62 | +| `hero-income-statement.tape` | Focused hero — Apple income statement in three lines | ✅ done | |
| 63 | +| _(planned)_ | Insider trades (Form 4) — `Company("TSLA")…transactions` | todo | |
| 64 | +| _(planned)_ | 13F holdings — `get_filings("13F-HR")[0].obj().holdings` | todo | |
| 65 | +| _(planned)_ | Universal `find()` — ticker / CIK / accession | todo | |
| 66 | +| _(planned)_ | Live filings feed — `get_current_filings().filter(form="8-K")` | todo | |
| 67 | + |
| 68 | +### Adding a clip |
| 69 | + |
| 70 | +1. Copy `hero-income-statement.tape`. |
| 71 | +2. Change the two `Output` paths and the on-camera `Type` line. |
| 72 | +3. Adjust `Set Height` if the output is taller/shorter than the default 720 |
| 73 | + (the hero uses 860 because the income statement is a tall table). |
| 74 | +4. Tune the post-`Enter` `Sleep` to cover the live SEC fetch (≈8–10s cold). |
| 75 | + |
| 76 | +## Tips |
| 77 | + |
| 78 | +- **Frame height = fit the output, no scroll.** If a table scrolls, its header |
| 79 | + is gone from the final hold frame. Raise `Set Height` until the whole result |
| 80 | + fits (≈21.6px per line at FontSize 18, plus padding). |
| 81 | +- **Determinism.** `pystartup.py` pins the Rich console width so layout is |
| 82 | + identical run to run regardless of PTY size. SEC values change over time — |
| 83 | + re-render to refresh numbers. |
| 84 | +- **Inspect a frame** without opening the video: |
| 85 | + `docker run --rm -v "$PWD:/vhs" -w /vhs --entrypoint ffmpeg edgartools-vhs \ |
| 86 | + -sseof -2.5 -i scripts/vhs/out/<clip>.mp4 -frames:v 1 -update 1 -y /tmp/f.png` |
0 commit comments