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
251 changes: 85 additions & 166 deletions README.md

Large diffs are not rendered by default.

Binary file added assets/hero.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
81 changes: 81 additions & 0 deletions assets/hero.tape
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# assets/hero.tape — generates the README hero GIF with VHS (charmbracelet/vhs).
#
# Run from the repo root:
# vhs assets/hero.tape # writes assets/hero.gif
#
# Prereqs (vhs 0.11.0 + jq are pinned in mise's [tools]):
# - `agent-tty` on PATH (npm i -g agent-tty, or `npm run build && npm link`)
# - `jq`
# It uses the fast, browser-free `libghostty-vt` renderer so the GIF stays short
# (no Chromium boot). For a crisper, tighter, more "terminal" look, tune
# FontFamily (must be installed!), FontSize, LineHeight, LetterSpacing, and
# Padding below, plus the per-step Sleeps. The session is sized to 72x18 so a
# 26pt font fills the frame without the 80-col default wrapping. Regenerate,
# then replace the HERO DEMO comment block in README.md with:
# ![agent-tty: drive a terminal session and inspect it as reviewable text](./assets/hero.gif)

Output assets/hero.gif

Require agent-tty
Require jq

Set Shell bash
# Use a font that's actually installed (VHS silently falls back to an ugly
# default otherwise). FiraCode Nerd Font Mono is on this machine and reads clean.
# Bulletproof alternatives: "Menlo", "SF Mono", "Monaco", "JetBrains Mono".
Set FontFamily "FiraCode Nerd Font Mono"
Set FontSize 26
Set Width 1280
Set Height 640
Set Padding 16 # tighter frame (was 28)
Set LineHeight 1.0 # tight lines; nudge to ~1.15 if they touch
Set LetterSpacing 0 # no extra tracking
Set Theme "Catppuccin Mocha" # any VHS theme works; try "Dracula", "Nord"
Set TypingSpeed 40ms
Set PlaybackSpeed 1.0

# --- hidden setup: isolated home + fast native renderer, then a clean screen ---
Hide
Type "export AGENT_TTY_HOME=$(mktemp -d) AGENT_TTY_RENDERER=libghostty-vt" Enter
Type "clear" Enter
Show

Sleep 800ms
Type "# open a long-lived terminal session" Enter
Sleep 500ms
Type 'SID=$(agent-tty create --json --cols 72 --rows 18 -- bash | jq -r .result.sessionId)' Enter
Sleep 1200ms

Type "# run a command inside it" Enter
Sleep 500ms
Type 'agent-tty run "$SID" "echo hello from agent-tty"' Enter
Sleep 1500ms

Type "# wait for the screen — no sleeps, no grep" Enter
Sleep 500ms
Type 'agent-tty wait "$SID" --text "hello from agent-tty"' Enter
Sleep 1500ms

Type "# inspect the rendered screen as text you can diff" Enter
Sleep 500ms
Type 'agent-tty snapshot "$SID" --format text' Enter
Sleep 2800ms

Type "# screenshots, asciicasts and WebM export come from the same session" Enter
Sleep 1200ms

# --- hidden teardown ---
Hide
Type 'agent-tty destroy "$SID" >/dev/null 2>&1' Enter
Show
Sleep 500ms

# -----------------------------------------------------------------------------
# ALTERNATIVE — dogfood it: record the loop with agent-tty itself, then convert.
# Drive the same create/run/wait/snapshot sequence, then:
# agent-tty record export "$SID" --format webm --out demo.webm
# ffmpeg -i demo.webm -vf "fps=12,scale=1200:-1:flags=lanczos" assets/hero.gif
# This makes the hero GIF literally the tool's own output ("recorded by the tool
# it documents"), at the cost of the Chromium-backed ghostty-web render path.
# ffmpeg isn't in mise's [tools] (it can't be cross-locked on Linux via conda);
# install it yourself for this path (brew install ffmpeg / apt-get install ffmpeg).
40 changes: 40 additions & 0 deletions assets/render-social-preview.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Renders assets/social-preview.html -> assets/social-preview.png (OG card, 1200x630).
// Supersamples at 2x then downscales with `sips` (macOS) so text stays crisp at
// the recommended OG size. Usage: node assets/render-social-preview.mjs
import { chromium } from 'playwright';
import { execFileSync } from 'node:child_process';
import { dirname, join } from 'node:path';
import { rmSync } from 'node:fs';
import { fileURLToPath, pathToFileURL } from 'node:url';

const W = 1200;
const H = 630;
const dir = dirname(fileURLToPath(import.meta.url));
const htmlPath = join(dir, 'social-preview.html');
const outPath = join(dir, 'social-preview.png');
const hiResPath = join(dir, 'social-preview@2x.png');

const browser = await chromium.launch();
const page = await browser.newPage({
viewport: { width: W, height: H },
deviceScaleFactor: 2, // -> 2400x1260 supersample
});
await page.goto(pathToFileURL(htmlPath).href);
await page.evaluate(() => document.fonts.ready);
await page.waitForTimeout(150);
await page.screenshot({
path: hiResPath,
clip: { x: 0, y: 0, width: W, height: H },
});
await browser.close();

// Downscale 2400x1260 -> 1200x630 (sips is built into macOS).
execFileSync(
'sips',
['--resampleHeightWidth', String(H), String(W), hiResPath, '--out', outPath],
{
stdio: 'ignore',
},
);
rmSync(hiResPath, { force: true });
console.log(`wrote ${outPath} (${W}x${H})`);
79 changes: 79 additions & 0 deletions assets/social-preview-spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Social preview (Open Graph) image spec

This is the image GitHub shows when `github.com/coder/agent-tty` is shared on
Hacker News, X, Slack, LinkedIn, etc. The repo currently has **no custom image**
(`usesCustomOpenGraphImage: false`), so it falls back to GitHub's auto-generated
avatar+stats card. Replacing it is the single highest-leverage pre-launch task —
it's what people see _before_ they click.

Target output: **`assets/social-preview.png`** (generated — see "How to produce"
below) → upload via **repo Settings → General → Social preview → Edit → Upload an
image**.

## Hard specs

| Property | Value |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Dimensions | **1200 × 630 px** (universal OG 1.91:1 — passes opengraph.xyz; GitHub also accepts it. GitHub's own rec is 1280×640, but 1200×630 is the safer cross-platform card for X/Slack/LinkedIn) |
| File size | **< 1 MB** (a flat dark bg + text exports well under this; run `pngquant` if needed) |
| Format | PNG, sRGB (JPG/GIF also accepted) |
| Min accepted | 640 × 320 px |

**Safe area:** keep the wordmark and tagline inside a centered **~1120 × 500**
region (≈80 px side / ≈70 px top-bottom margins). X/LinkedIn/Facebook re-crop to
1.91:1, so anything near the edges can get clipped.

## Layout

```
┌──────────────────────────────────────────────────────────────┐
│ (dark terminal background — #11111b / #0d1117, flat) │
│ │
│ agent-tty ▏ ← optional │
│ ───────── block cursor │
│ Drive and inspect terminal sessions from the CLI — │
│ reviewable snapshots, screenshots & recordings. │
│ │
│ $ agent-tty snapshot $SID --format text │
│ ┌ hello from agent-tty ───────────────────┐ ← faux captured │
│ │ user@host:~$ █ │ screen, dim │
│ └──────────────────────────────────────────┘ │
│ │
│ github.com/coder/agent-tty Apache-2.0 · Ghostty VT │
└──────────────────────────────────────────────────────────────┘
```

## Copy (use verbatim — matches the README + repo description)

- **Wordmark:** `agent-tty`
- **Tagline (one line):** `Drive and inspect terminal sessions from the CLI — reviewable snapshots, screenshots & recordings.`
- If it's too long at your font size, shorten to: `Scriptable terminal sessions with reviewable snapshots, screenshots & recordings.`
- **Footer:** `github.com/coder/agent-tty` · optional honest credit `Powered by Ghostty's VT engine`
- Do **not** put "for AI agents" in the image headline (saturated/risky per the launch research); the agent angle lives in the README body and your HN first comment.

## Type & color

- **Monospace throughout** (JetBrains Mono / Berkeley Mono / IBM Plex Mono / Geist Mono). It reads as an authentic terminal tool, not a marketing site.
- High contrast: light text (`#cdd6f4` / `#e6edf3`) on a dark base. One accent color max (e.g. a green `#a6e3a1` for the prompt `$`).
- Wordmark large (~96–120 px), tagline ~34–40 px, footer ~24 px.

## Do / Don't

- ✅ Flat dark terminal aesthetic, monospace, a real command + a snippet of captured screen.
- ✅ Let the _artifact_ (a text snapshot of a real screen) be the visual idea.
- ❌ Gradient hero blobs, neon glows, glassmorphism, "pulsing live" pills, emoji, 3D shapes, stock dev illustrations. These read as AI-generated "slop" and HN calls them out within minutes — the image must not undercut a launch built on "honest, inspectable tooling."

## How to produce it

**Implemented (HTML/CSS → Playwright screenshot):** edit [`social-preview.html`](./social-preview.html) and run `node assets/render-social-preview.mjs`. It renders at 2× and downscales with `sips` to a crisp 1200×630 PNG. This is the source of truth for the card.

Other approaches if you'd rather start over:

1. **Figma / design tool** — 1200×630 frame, paste the copy, export PNG.
2. **VHS still** — a one-frame `.tape` (`Output assets/social-preview.png`, `Set Width 1200`, `Set Height 630`, type the command + snapshot, no playback) gives a real captured screen as the card.

## Verify before launch

Paste the repo URL into <https://www.opengraph.xyz> (or just DM yourself the link
in Slack) and confirm the card renders with no clipped text. GitHub can take a
few minutes to refresh its cache after upload.
111 changes: 111 additions & 0 deletions assets/social-preview.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<!doctype html>
<!-- Source for assets/social-preview.png (OG/social card, 1200x630).
Render with: node assets/render-social-preview.mjs -->
<html>
<head>
<meta charset="utf-8" />
<style>
:root {
--crust: #11111b;
--text: #cdd6f4;
--subtext: #a6adc8;
--dim: #6c7086;
--green: #a6e3a1;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
width: 1200px;
height: 630px;
}
body {
background: var(--crust);
color: var(--text);
font-family: 'FiraCode Nerd Font Mono', 'SF Mono', 'Menlo', monospace;
font-variant-ligatures: none;
font-feature-settings:
'liga' 0,
'calt' 0;
-webkit-font-smoothing: antialiased;
}
.card {
position: relative;
width: 1200px;
height: 630px;
padding: 76px;
display: flex;
flex-direction: column;
justify-content: center;
}

.word {
font-size: 112px;
font-weight: 700;
letter-spacing: -3px;
line-height: 1;
color: var(--text);
}
/* underscore cursor: low, with a small gap from the wordmark */
.word .cursor {
color: var(--green);
font-weight: 400;
margin-left: 14px;
}

.tag {
margin-top: 32px;
font-size: 32px;
line-height: 1.45;
color: var(--subtext);
max-width: 1048px;
}
.tag .accent {
color: var(--text);
}

.cta {
margin-top: 40px;
font-size: 31px;
color: var(--text);
}
.cta .p {
color: var(--green);
}

.foot {
position: absolute;
left: 76px;
right: 76px;
bottom: 52px;
display: flex;
justify-content: space-between;
font-size: 22px;
color: var(--dim);
}
.foot .url {
color: var(--subtext);
}
</style>
</head>
<body>
<div class="card">
<div class="word">agent-tty<span class="cursor">_</span></div>
<div class="tag">
Drive and inspect terminal sessions from the CLI —<br />
<span class="accent"
>reviewable snapshots, screenshots &amp; recordings.</span
>
</div>
<div class="cta"><span class="p">$</span> npm install -g agent-tty</div>

<div class="foot">
<span class="url">github.com/coder/agent-tty</span>
<span>Apache-2.0 · powered by Ghostty's VT engine</span>
</div>
</div>
</body>
</html>
Binary file added assets/social-preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading