Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 31 additions & 17 deletions .claude/skills/record-tui-gif/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: record-tui-gif
description: Record the actop TUI as an animated GIF with vhs, optionally under a real GPU workload so the gauges move (for the README hero / launch demos). Covers the vhs tape (sizing, off-camera warm-up so the first frame is already live, on-camera glyph/layout/process toggles), the llama.cpp / ollama GPU driver that lights up GPU/ANE/bandwidth/power, and the record.sh orchestrator that starts the workload, records, and always stops it. Use when refreshing the hero GIF after a TUI/layout change or producing a launch capture. For a *still* ASCII diagram in the docs use capture-tui-diagram instead.
description: Record the actop TUI as an animated GIF with vhs, optionally under a real GPU workload so the gauges move (for the README hero / launch demos). Covers the vhs tape (sizing, off-camera warm-up so the first frame is already live, on-camera glyph/per-core/process-table/theme toggles), the llama.cpp / ollama GPU driver that lights up GPU/ANE/bandwidth/power, and the record.sh orchestrator that starts the workload, records, and always stops it. Use when refreshing the hero GIF after a TUI/layout change or producing a launch capture. For a *still* ASCII diagram in the docs use capture-tui-diagram instead.
---

# record-tui-gif
Expand Down Expand Up @@ -97,27 +97,41 @@ Notes:

`actop-demo.tape` (bundled) is the hero recipe. Key techniques:

- **Warm up off-camera** with `Hide` … `Sleep 6s` … `Show` so the **first visible
- **Warm up off-camera** with `Hide` … `Sleep` … `Show` so the **first visible
frame already shows non-zero gauges** (the acceptance check — an idle first
frame reads as broken). Quit (`Type "q"`) also goes under a trailing `Hide`.
- **Width 1400 @ FontSize 16 ≈ 165 cols** — well above the ~96-col floor where
the `grid` preset auto-degrades to `stack` (see run-actop).
- **Height sizes to the layout.** `stack` is tall (~47 rows); `Set Height 1050`
fits the stacked column + process table with **no bottom gap**. A `grid`-only
tape uses ~`Height 900`.
- **Gapless layout switch**: do the `l` (grid→stack) switch *off-camera* — `grid`
at stack's height leaves a large empty gap. `g` (glyph) and `t` (processes)
toggles are safe *on-camera* because `stack` already fills the height.
- Choreography: `l` (stack, hidden) → show dots → `g` (blocks) → `t` (processes).
The final frame — stack + block charts + per-process **watt attribution**
(workload procs top the PWR column) — is the strongest hero frame.
frame reads as broken). The sleep must cover the whole **chart span**, not just
"a few seconds": the sparklines are right-aligned across the full chart width,
so a short warm-up shows a thin trace clinging to the right edge and still
reads as a dashboard that just booted. At the 1s default interval the window is
~328 samples (`span 5m28s`), so the tape sleeps **330s** — 7s fills 2% of the
chart and 40s only 12%. Quit (`Type "q"`) also goes under a trailing `Hide`.
- **Width 1800 @ FontSize 16 ≈ 212 cols.** Width is load-bearing because `p`
splits the dashboard against the process table: at 1400px (~165 cols) the
dashboard drops to ~80 cols and **silently degrades to stack mid-take**. 1800px
leaves it ~122 cols, so `grid` survives the whole recording. Do not lower it.
- **Height sizes to the layout, and the layout is fixed for the take.**
`Set Height 930` fits the tallest on-camera grid state (grid + per-core panels
+ process table ≈ 42 dashboard rows + chrome). `stack` at this width would need
~`Height 1240`.
- **Do NOT press `l` on camera.** The hero take stays in `grid` start to finish —
grid is the default, so no layout switch is needed at all. Height is sized for
grid, so a mid-take switch to `stack` clips or opens a large gap under Power.
(Since v1.9.x `l` also raises a toast, which would land in the frame.) A
stack-based tape is a *separate* tape with its own `Height`, not an `l` press
bolted onto this one.
- Choreography (all on-camera, gapless): dots → `g` (block charts) → `c`
(per-core panels) → `p` (process table + watt attribution) → `t` ×8 (theme
cycle, ending back at the `textual-dark` default). The process-table frame —
grid + block charts + per-process **watt attribution** (workload procs top the
PWR column) — is the strongest hero frame.

### Authoring a new tape

Start from `actop-demo.tape`, change `Output`, and keep the off-camera warm-up.
Keybindings available to script (`Type "…"`): `g` glyph, `l` layout, `t`
processes, `s` sort, `p` pause, `/` filter, `?` help, `q` quit (see run-actop for
the full table). Put custom tapes under `tmp/` (repo convention).
Keybindings available to script (`Type "…"`): `g` glyph, `l` layout, `c` per-core
panels, `p` process table, `s` sort, `t` theme, `space` pause, `/` filter, `?`
help, `q` quit (see run-actop for the full table). Put custom tapes under `tmp/`
(repo convention).

## Verify the result

Expand Down
29 changes: 13 additions & 16 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,19 @@ This project follows a Keep a Changelog-style format and uses version tags for r

### Changed

- **`CLAUDE.md`: the PyPI break-glass token is retained and refreshed, not
deleted — and agents are now barred from deleting credentials at all.** The
hygiene note used to say to delete the project-scoped token once OIDC Trusted
Publishing was confirmed on a release. That contradicted the failure playbook
two paragraphs above it, which names the token-driven Flow B as the recovery
path when `publish-pypi` fails on an OIDC / trusted-publisher error — so
following the hygiene rule removed the fallback exactly when a broken release
would need it. It was also a silent failure: `~/.zshrc` builds
`TWINE_PASSWORD` with `$(cat … 2>/dev/null)`, so a deleted file yields an
empty password and a confusing PyPI auth error rather than a missing-file one.
Three changes: the hygiene note is reversed (retain, refresh on expiry, revoke
only on leak/replacement); the break-glass credential is documented as coming
from the **system environment**, not a file hunt; and *Security &
Configuration Tips* gains a hard rule against deleting, revoking, or rotating
any credential, plus secret-handling rules (never print a value; assert on
presence, not content). Docs only — no code or CLI change.
- **`record-tui-gif` skill: prose re-synced with the bundled tape.** `SKILL.md`
still described a pre-v1.9 stack-based recipe and contradicted
`actop-demo.tape`'s own comments: it recommended `Width 1400` (which the tape
documents as silently degrading grid to stack mid-take), a `Sleep 6s` warm-up
(the tape covers the full ~330s chart span, noting 7s fills 2% of the chart),
`Height 1050`/`900` (actual: `930`), an off-camera `l` grid->stack switch and an
`l -> g -> t` choreography the tape never performs, plus a stale keybinding
table (`t` labelled processes, `p` labelled pause). An agent following it would
have set the known-broken width and warm-up, pressed `l` on camera against a
grid-sized `Height`, and used the wrong keys. The prose now matches the tape,
states explicitly that the hero take is grid start-to-finish and that `l` must
not be pressed on camera, and lists the real bindings. The skill description no
longer claims an on-camera layout toggle. No change to the tape itself.

## [1.9.11] - 2026-08-23

Expand Down