assets: demo GIF for the reach-layer flow - #111
Conversation
The old demo told a story the software no longer tells: a `LAN-direct on (mDNS + QUIC)` line for a transport deleted in #92, `wallet …` for what v0.7 renamed to identity, and a `mir up → mir list → mir attach` flow that predates the overview (#97), the first-run pairing QR, the tmux-style aliases, and session sharing (#101–#104). The new take is the current one, in four beats: bare `mir` opens the live overview; Enter attaches and the tmux session with a long-running agent is right there; Ctrl-O d comes back, and the row now remembers what runs over there; then one invite, read-only, gone in an hour. Every line the script prints is a line `mir` prints. The overview screen is overviewModel.Render()'s output, the attach banner is overview.go's, and the whole `mir share` block — header, QR, both invite lines, the wait line — was captured verbatim from a real run against relay.sourceful-labs.net. The QR in the rendered GIF decodes to the join URL printed beside it. Only the tmux screen and the shell prompt are authored, and neither is mir's output. The canvas grew to 1100x880 (43 rows x 102 cols) so the invite QR fits on one screen without scrolling. 219 KB, 12.8 s. Part of #106 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KeiotDVE94wEzvc7wcvm1y
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 854a678ab6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| Sleep 600ms | ||
| Show | ||
| Sleep 12s | ||
| Sleep 13800ms |
There was a problem hiding this comment.
Record until the invite details become visible
In the committed assets/miranda-demo.gif, the final frame still shows only the share header and QR; the …or open:, CLI join code, and waiting for your guest lines emitted after the heredoc never appear. This means the rendered asset does not show the complete sharing flow promised by the tape comments, so extend the capture and re-render the GIF until those final lines are visible.
Useful? React with 👍 / 👎.
1100x880 at 102 columns left the 📱 in the mint header about 8 px wide once GitHub scaled the GIF into its 900px column, small enough to read as a box. No font fixes that: `fc-list ':charset=1F4F1'` finds exactly one face on this machine, Apple Color Emoji, and a 10x crop shows that is already the glyph being drawn — bezel, dark screen, colored icons. It is Apple's black phone on a dark theme, not a tofu box. Naming a font in the tape only makes it worse: every installed monospace face falls back to the same Apple glyph, and a comma list starting with JetBrains Mono breaks the cell metrics outright, because vhs supplies that face as a webfont and the list form defeats it. So the lever is columns, not fonts. 884x878 gives 42 rows x 80 columns: the last beat needs 41 rows, and 80 is the narrowest width that still wraps each invite URL to two lines rather than three. Every cell — the emoji included — grows about a quarter, and the frame stops being mostly empty. Widths must stay even. 883 defeated the palette pass and turned the same recording into 14 MB; 884 renders it at 214 KB. 214 KB, 12.8 s, 884x878. The QR still decodes to the join URL printed beside it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KeiotDVE94wEzvc7wcvm1y


Part of #106.
The README GIF told a story the software no longer tells. This rewrites it for
the reach layer as it works today, and rerenders.
What was stale
Everything on the known list, all confirmed against the current tree:
LAN-direct on (mDNS + QUIC)— that transport was deleted in feat: one transport, two ICE modes — delete the LAN QUIC path, zero stagger (T1) #92. There isone connection with two ICE modes now, and no CLI surface names either mode:
I grepped the
cliandclientpackages and nothing prints direct / TURN /relay at attach time. So the new script claims no transport at all.
wallet …— renamed to identity in v0.7 (feat: harden Miranda for v0.7.0 release candidate #51).mir up → mir list → mir attach— predates the overview (feat(cli): mir opens your machines — the live overview (O1) #97),mir up'sfirst-run pairing QR, the tmux-style aliases, and sharing (feat: mir share / mir join — grant bootstrap over the pair room (G1b) #101–feat(web): guest shares — join link, ro terminal, guest state (G1e) #104).
Two more found while reading:
mir share <machine> --ttl 1hdoes not parse.cmdShareusesflag.FlagSet.Parse(args), which stops at the first positional, so a flagafter the machine name lands in
fs.Args()and trips the arity check —error: usage: mir share <machine> [--ttl 1h] | mir share ls | .... Theworking order is
mir share --ttl 1h workstation, which is what the demoshows. Worth noting because the usage string itself reads
share <machine> [--ttl 1h].mir attach <name>prints
Ctrl-C goes to the shell; close the client to detach(no detachkey at all); Enter from the overview prints
Ctrl-O then d comes back to your machines. The demo attaches from the overview, so it uses the second.Not fixed here — flagging it.
The story, beat by beat
~ $ mirmir — your machines,▸ ● workstation / ● builder / ○ pi, and the keybar[mir] attached to workstation — Ctrl-O then d comes back to your machines[main] 0:agent* 1:build- 2:logson the status barworkstationrow now carries3 windows — agent, build, logsq, then~ $ mir share --ttl 1h workstationShare "workstation" — read-only access until 16:42., the invite QR, both invite lines,waiting for your guest (5 min)…The detach beat needs no caption because the banner one beat earlier names the
gesture, and
q quitis in the keybar. Nothing in the GIF is a caption, anarrow, or an overlay — it is all terminal output.
Honesty: what came from where
Built the branch's
mir(cd go && go build ./cmd/mir) and ran it. Pairingwas done for real against
relay.sourceful-labs.netwith a throwaway identityin a temp
--dir, andmir up's tmux was pinned to an isolated socket(
--shell tmux:-L:mirdemo:new:-A:-s:main) so no real session was touched.Verified by running the real binary:
mir shareblock — header, QR,…or open:,…or on the CLI:,waiting for your guest (5 min)…. Copied byte-for-byte out of the capturedrun; the QR block is spliced from that capture, never retyped. The QR in
the rendered GIF decodes to exactly the join URL printed beside it (that
invite is a one-time token and expired long ago).
[mir] attached to workstation — …— the attach banner, from a real attachover the data channel to the temp machine.
mir share --ttl 1h <name>argument order, and themir share <name> --ttl 1hrefusal quoted above.
mir listrows,mir share lsempty state, and the unknown-machinerefusal (not shown in the GIF, used to check nothing else had drifted).
Reproduced from code, not run:
mirreads~/.miranda/clientwith no--diroverride, and the brief was not to touch the user's state, so instead I drove
overviewModel.Render()directly with a scratch test (deleted before commit)and copied its bytes. The result — blank line,
<bold>mir</bold><dim> — your machines</dim>,▸ ● name, the 5-space dim windows sub-line, blank, dimkeybar — is
go/internal/cli/overview_model.go:144-189verbatim, includingthe
●/○glyphs, which are the only state indicator (there are no statewords, and no "connecting" state).
overview.go'saltScreenOn/altScreenOff/clearScreen, in the orderov.attachusesthem.
3 windows — agent, build, logsiswindowsSummary()'s format, and it onlyappears after an attach, because that is the only thing that fills
ov.windows. The first overview correctly shows no sub-line.Authored, and not mir's output: the tmux screen (a real tmux paints its own
alt screen and default status bar — format checked against a live capture) and
the shell prompt.
The 📱 in the mint header
It looked like a tofu box in the first render. It is not one. A 10x crop shows
Apple Color Emoji's phone — grey bezel, dark screen, tiny colored icons — drawn
correctly and then read as a box because it is a black phone on a dark theme
at roughly 8 px.
No font setting fixes that here:
fc-list ':charset=1F4F1'returns exactly one usable face on this machine,Apple Color Emoji. That is already the face being used.
Menlo,Andale Mono, genericmonospace— falls back to that same Apple glyph.Set FontFamily "JetBrains Mono,Apple Color Emoji"breaks the cell metricsoutright: vhs supplies JetBrains Mono as a webfont, and the comma-list form
defeats it, so the whole recording renders in a proportional fallback.
So the fix was columns, not fonts, and it is a real improvement rather than a
shrug: 1100x880 at 102 columns → 884x878 at 80 columns. Same rows (42, of
which the last beat needs 41), same theme, same font, but every cell — the
emoji included — is about a quarter larger once GitHub scales the GIF into its
900px column, and the frame is no longer mostly empty. 80 is the narrowest
width that still wraps each invite URL to two lines rather than three.
Flagging the residual honestly: on a dark theme the phone emoji still reads
dark. That is what a real terminal shows, and mir's output is not something to
edit around it.
Rendering
vhs assets/demo.tapefrom the repo root — unchanged, so both header commentskeep that command.
214 KB, 12.8 s, 884x878. Well under the 3 MB bar. Verified by pulling
frames out with
ffmpegand reading them: the finale holds the whole mintblock — header, QR, both links, the wait line — on one screen with nothing
truncated at 80 columns, the two long invite URLs wrap once each (what a real
terminal does at this width), and the tmux status bar sits on one row.
One trap recorded in the tape: keep the dimensions even. At width 883 the
palette pass gives up and the identical recording lands at 14 MB; 884 renders
it at 214 KB.
README's alt text now describes what the GIF shows. Nothing outside
assets/and that one attribute changed;
cd go && go test ./...andcd web && npm ci && npm testboth pass.🤖 Generated with Claude Code
https://claude.ai/code/session_01KeiotDVE94wEzvc7wcvm1y