Skip to content

assets: demo GIF for the reach-layer flow - #111

Merged
frahlg merged 2 commits into
mainfrom
111-demo-gif
Aug 30, 2026
Merged

assets: demo GIF for the reach-layer flow#111
frahlg merged 2 commits into
mainfrom
111-demo-gif

Conversation

@frahlg

@frahlg frahlg commented Aug 30, 2026

Copy link
Copy Markdown
Member

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:

Two more found while reading:

  • mir share <machine> --ttl 1h does not parse. cmdShare uses
    flag.FlagSet.Parse(args), which stops at the first positional, so a flag
    after the machine name lands in fs.Args() and trips the arity check —
    error: usage: mir share <machine> [--ttl 1h] | mir share ls | .... The
    working order is mir share --ttl 1h workstation, which is what the demo
    shows. Worth noting because the usage string itself reads share <machine> [--ttl 1h].
  • Two different detach hints for the same gesture. mir attach <name>
    prints Ctrl-C goes to the shell; close the client to detach (no detach
    key 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

~t What is on screen
0.2–1.1 s ~ $ mir
1.1–3.3 s the overview: mir — your machines, ▸ ● workstation / ● builder / ○ pi, and the keybar
3.3–4.0 s Enter: the overview drops the alt screen and prints [mir] attached to workstation — Ctrl-O then d comes back to your machines
4.0–7.2 s the far end paints: a tmux session with a long-running agent, [main] 0:agent* 1:build- 2:logs on the status bar
7.2–9.4 s Ctrl-O d: the overview is back, and the workstation row now carries 3 windows — agent, build, logs
9.4–10.3 s q, then ~ $ mir share --ttl 1h workstation
10.3–12.8 s Share "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 quit is in the keybar. Nothing in the GIF is a caption, an
arrow, 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. Pairing
was done for real against relay.sourceful-labs.net with a throwaway identity
in a temp --dir, and mir 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:

  • the whole mir share block — header, QR, …or open:, …or on the CLI:,
    waiting for your guest (5 min)…. Copied byte-for-byte out of the captured
    run; 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 attach
    over the data channel to the temp machine.
  • mir share --ttl 1h <name> argument order, and the mir share <name> --ttl 1h
    refusal quoted above.
  • the guide, mir list rows, mir share ls empty state, and the unknown-machine
    refusal (not shown in the GIF, used to check nothing else had drifted).

Reproduced from code, not run:

  • the overview screen. Bare mir reads ~/.miranda/client with no --dir
    override, 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, dim
    keybar — is go/internal/cli/overview_model.go:144-189 verbatim, including
    the / glyphs, which are the only state indicator (there are no state
    words, and no "connecting" state).
  • the alt-screen sequences around attach and detach: overview.go's
    altScreenOn / altScreenOff / clearScreen, in the order ov.attach uses
    them.
  • 3 windows — agent, build, logs is windowsSummary()'s format, and it only
    appears 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.
  • Every installed monospace family I probed through vhs — the default, Menlo,
    Andale Mono, generic monospace — falls back to that same Apple glyph.
  • Set FontFamily "JetBrains Mono,Apple Color Emoji" breaks the cell metrics
    outright: 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.tape from the repo root — unchanged, so both header comments
keep that command.

214 KB, 12.8 s, 884x878. Well under the 3 MB bar. Verified by pulling
frames out with ffmpeg and reading them: the finale holds the whole mint
block — 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 ./... and cd web && npm ci && npm test both pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KeiotDVE94wEzvc7wcvm1y

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
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 30, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-08-30T14:29:48.577583Z 854a678 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. Cursor Bugbot completed with no findings that need human review, and no approval policy requires extra review. No reviewers were assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread assets/demo.tape
Sleep 600ms
Show
Sleep 12s
Sleep 13800ms

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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
@frahlg
frahlg merged commit 910d7d0 into main Aug 30, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant