Agent skill

Pull Request Demo

by speakeasy-api in speakeasy-api/gram

Always use after creating a pull request that proposes user-visible changes.

AGPL-3.0Auto-check passedDevelopment

Install Pull Request Demo

skills CLI
$ npx skills add speakeasy-api/gram --skill pull-request-demo -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install speakeasy-api/gram pull-request-demo --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/speakeasy-api/gram.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/pull-request-demo .claude/skills/pull-request-demo && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
pull-request-demo
GitHub stars
272
Token cost
~3.3k tokens
SKILL.md length
1,637 words
Files
1
Skills in repo
39
Repo updated
First seen
Licence
AGPL-3.0

At a glance

Always use after creating a pull request that proposes user-visible changes.

  • Works in 5 steps: Namespace everything by PR number → Rehearse → Capture → …
  • Tasks that involve Pull requests
  • SKILL.md covers Prerequisites, 0. Namespace everything by PR…, 1. Rehearse and 2. Capture, plus 3 more sections
  • Calls mise, ffmpeg and gh; needs GITHUB_TOKEN and GH_TOKEN

What it does

Pull Request Demo is an agent skill from speakeasy-api/gram. Always use after creating a pull request that proposes user-visible changes.

Its SKILL.md is about 3.3k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Development, covering Pull requests. The repository describes itself as: Securely scale AI usage across your organization. A single stack to Connect, Secure, Observe and Distribute agents, MCPs, and Skills within your company. The licence is AGPL-3.0.

When your agent uses it

  • Tasks that involve Pull requests

Example prompts

  • “Use the pull-request-demo skill to alway use after creating a pull request that proposes user-visible changes”
  • “/pull-request-demo”

Requirements

  • A credential in GITHUB_TOKEN

Workflow steps

5 steps, taken from the step headings in SKILL.md.

  1. Namespace everything by PR number
  2. Rehearse
  3. Capture
  4. Inspect before uploading
  5. Post the PR comment

What it can do on your machine

Read from SKILL.md and the folder at commit ad78247. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • mise
    • ffmpeg
    • gh
    • psql
    • git

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use gh and git, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • GITHUB_TOKEN
    • GH_TOKEN

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Pull Request Demo loads about 3.3k tokens when it runs. Until then it costs about 24 tokens; SKILL.md has 1,637 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~24
When it runs · the whole SKILL.md, loaded when a task matches
~3.3k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from speakeasy-api/gram at commit ad78247, republished under its AGPL-3.0 licence (© speakeasy-api). 1,637 words, ~3,312 tokens.

Download SKILL.mdSave it as .claude/skills/pull-request-demo/SKILL.md (or your agent's skills folder).
name
pull-request-demo
description
Always use after creating a pull request that proposes user-visible changes.

Demos for frontend PRs

Capture only the changed dashboard behavior and post it as a PR comment. Use one or two PNGs for a static visual change; use a 10-20 second WebM recording for an interaction.

REQUIRED SUB-SKILL: Use gram-playwright-cli for browser commands.

Uploads cannot be undone. gh attachments have no delete endpoint, and deleting the comment does not unpublish the asset: it stays live at an unauthenticated URL. The inspect step in section 3 is the last reversible moment in this workflow.

Change typeCapturePublish as
Static visualscreenshot --hiresPNG, embedded with alt text
Interactionvideo-start / video-stopWebM, rendered as a player
Interaction needing inline email visibilityWebM, then ffmpegGIF, embedded with alt text

Prerequisites

  • Discover the dashboard URL with mise run zero:summary — read the address from the Gram dashboard row (don't assume a port). The same table shows whether each service is RUNNING. A paused worktree shows Database and ClickHouse as STOPPED: run mise run wake (containers, then daemons) and expect two to four minutes. Do not use mise start here, which launches the foreground process-manager TUI and starts only the daemons, leaving the server wedged against a stopped Postgres with no diagnostic. Dev-idp auto-login is enabled, and the local TLS cert is browser-trusted (mkcert CA in the NSS store, set up by mise run zero:tls — rerun that if you see cert errors).

  • Use the default project for all flows — mise run seed (the demo seed retargeted at your dev org) provisions exactly one project. Before recording, verify the database is seeded by probing it directly (the connection string is in the Database row of zero:summary; drop its &search_path=public parameter, which psql rejects with invalid URI query parameter):

    bash
    psql "postgres://gram:gram@127.0.0.1:<port>/gram?sslmode=disable" -c "SELECT p.slug, om.gram_account_type FROM projects p JOIN organization_metadata om ON om.id = p.organization_id WHERE p.slug = 'default' AND NOT p.deleted;"

    Expect at least one row, every row reading gram_account_type = 'enterprise'. Two rows is normal, because your dev org and the demo org each own a default project. Run mise run seed only on zero rows or a non-enterprise tier.

  • Invoke Playwright only through mise run playwright. The task uses the repo configuration and installs Chromium on demand.

  • Use ./tools/ffmpeg for the trim, frame-extraction, and GIF steps. The PNG path needs no conversion.

The login flow is credential-less: open the dashboard, click Login if redirected, and wait for /speakeasy. If the first load is blank after a fresh browser install, navigate to the URL again.

0. Namespace everything by PR number

Concurrent agent sessions share a worktree and share the Playwright browser. Key the artifact directory and the Playwright session name on the PR number, so two sessions cannot overwrite each other's files or drive each other's browser:

bash
PR=<pr-number>
DIR=.playwright-cli/pr-demos/$PR
mkdir -p "$DIR"

Use -s=pr-demo-$PR as the session flag in every Playwright command below. If your tooling runs each command in a fresh shell, these variables do not survive between calls: re-export them in every command, or write the literal paths. .playwright-cli/ is gitignored at any depth. Relative paths resolve against your current directory, so stay at the repo root for the whole workflow: a path that resolves differently at capture time and at upload time silently breaks the body rewrite in section 4.

1. Rehearse

bash
mise run playwright -s=pr-demo-$PR open "<dashboard-url>"
mise run playwright -s=pr-demo-$PR snapshot

Navigate to the feature and rehearse the exact interaction using snapshot refs. Keep the browser open. Video recording starts only when requested, so rehearsal does not create footage.

Return to the intended starting state before capture. Hide the fixed development dock with eval before every capture, whether or not it obscures the change: it is dev-only chrome and reads as a product bug to a reviewer. Page navigation removes DOM-only adjustments, so re-apply it after navigating.

2. Capture

Static change

Prepare the exact frame, then capture a viewport or element screenshot:

bash
mise run playwright -s=pr-demo-$PR screenshot --hires --filename="$DIR/demo.png"
mise run playwright -s=pr-demo-$PR screenshot <element-ref> --hires --filename="$DIR/demo-detail.png"

The shared config keeps the CSS viewport at 1440x900 and uses a 2x device scale factor, so --hires produces a crisp 2880x1800 viewport image. Use --full-page only when the changed layout cannot fit in the viewport.

Interaction change

Start recording only after the page is ready:

bash
mise run playwright -s=pr-demo-$PR video-start "$DIR/demo.webm" --size=1440x900
mise run playwright -s=pr-demo-$PR video-show-actions --duration=700 --position=top-right --cursor=pointer

Perform the rehearsed clicks, fills, and navigation with normal CLI commands. The action overlay supplies the pointer, target highlight, and action label; do not inject a fake cursor. Let each important state remain visible long enough to read. When a longer hold is needed:

bash
mise run playwright -s=pr-demo-$PR run-code "async page => await page.waitForTimeout(1000)"

For a meaningful transition, optionally add a short chapter card:

bash
mise run playwright -s=pr-demo-$PR video-chapter "<title>" --description="<what changes>" --duration=1200

Stop recording to flush the WebM, then close the session:

bash
mise run playwright -s=pr-demo-$PR video-stop
mise run playwright -s=pr-demo-$PR close

Every mise run playwright subcommand costs one to two seconds of process startup, and all of it lands in the recording as dead air. Budget for it: a take with six commands and six seconds of deliberate holds runs near thirty seconds. Trim the lead-in and tail before uploading:

bash
./tools/ffmpeg -y -ss <start> -to <end> -i "$DIR/demo.webm" \
  -c:v libvpx -b:v 1M -crf 30 -an "$DIR/demo-trimmed.webm"

The trimmed file is the one you publish, so it is the one section 3 applies to. GitHub serves .webm back as video/webm and renders it as a player, so no further conversion is needed. If a take goes wrong, stop it, restore the starting state in a new session, and record again. Do not include setup, login, exploration, or unrelated page tours.

GIF fallback

Convert only when the reviewer needs the demo inline where a player will not render, notably GitHub notification emails. Convert the trimmed file, not the raw take, so the GIF does not carry the dead air you just removed. Two-pass palette:

bash
./tools/ffmpeg -i "$DIR/demo-trimmed.webm" \
  -vf "fps=10,scale=1200:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" \
  "$DIR/demo.gif"

A GIF is hard-refused over 10 MB. Increase the scale toward 1440 for small text, or crop to the relevant region before fps= instead of shrinking the whole frame.

Show full SKILL.md (739 more words)Show less

3. Inspect before uploading

You cannot watch a WebM. Extract frames first, then look at them:

bash
./tools/ffmpeg -i "$DIR/demo-trimmed.webm" -vf "fps=1/2,scale=1200:-1" "$DIR/frame-%02d.png"

One frame every two seconds gives eight to ten frames for a trimmed 15 to 20 second take. Raise the interval on anything longer, because reading twenty near-identical frames is the slowest step in this workflow. Read every extracted frame, or the PNG or GIF for the other paths, and confirm all of the following before running any --attach command:

  1. It shows the changed behavior, and nothing before or after it.
  2. No real identity: the user menu, avatar, and member columns show no real name or email. Dev-idp signs you in as dev@example.com in Local Dev Org, so this is normally satisfied already. If your stack points at a real identity provider and the sidebar shows your actual name, collapse the sidebar and recapture rather than editing the DOM.
  3. No customer organization: check the org switcher, breadcrumbs, and URL bar. Your own dev org and Speakeasy's own name are fine; a customer's is not. mise run seed retargets the demo seed at your own org, so the rows are synthetic but the chrome around them is not.
  4. No secrets: no API keys, tokens, or environment variable values in view.
  5. Within limits: images and GIFs under 10 MB, video under 100 MB.

A recording crosses far more of these surfaces than a deliberately framed screenshot. Recapture rather than publishing a frame you are unsure about.

4. Post the PR comment

Two environment gotchas, both of which produce misleading errors:

  • Prefix with env -u GH_TOKEN -u GITHUB_TOKEN. An environment token wins over your keyring credential, and Actions' GITHUB_TOKEN is not allowed to upload attachments.
  • Invoke gh through mise exec so you get the pinned 2.100.0. A shell without mise active falls through to a system gh, and an older one fails with unknown flag: --attach.

Write the body to a file so the same shell variable supplies the path in both the markdown and the flag. gh rewrites a body reference in place only when the two paths match byte for byte; any mismatch silently appends the image below your text instead, and still exits 0.

bash
cat > "$DIR/comment.md" <<EOF
### Demo

![<alt text>]($DEMO)

What it shows:
1. <starting state>
2. <interaction>
3. <changed behavior>
EOF

env -u GH_TOKEN -u GITHUB_TOKEN mise exec -- gh pr comment "$PR" \
  --body-file "$DIR/comment.md" --attach "$DEMO#<alt text>"

Set DEMO="$DIR/demo.png" or DEMO="$DIR/demo.gif" first. The heredoc is intentionally unquoted so $DEMO expands; escape any literal ` or $ in your text. A path containing # cannot be attached, because # delimits the alt text.

Video differs. A video renders as a bare URL on its own line and cannot carry alt text, so passing #<alt text> is a hard error. Attach it with no alt text and let it append below your body:

bash
env -u GH_TOKEN -u GITHUB_TOKEN mise exec -- gh pr comment "$PR" \
  --body-file "$DIR/comment.md" --attach "$DIR/demo-trimmed.webm"

Write that body with the numbered list above the player, and no image reference.

Keep the numbered list short and aligned with the visible steps.

Common mistakes

  • HTTP 404 from --attach means you lack write access, not that the PR is missing. Attachments need ADMIN, MAINTAIN, or WRITE; READ and TRIAGE both 404. Fine-grained PATs are per-repo, so one minted elsewhere fails on a repo you can otherwise push to. From a fork, fall back to a secret gist: write any text file into $DIR, run gh gist create on it (binaries passed directly are silently dropped), clone the returned gist repo, copy $DEMO in (or $DIR/demo-trimmed.webm for a recording, which the video path never assigns to $DEMO), commit, push with git -c credential.helper='!gh auth git-credential' push, then reference the raw URL.
  • Uploads stop at the first failure and the body is written only if at least one file uploaded, so a partial failure posts a comment containing unresolved local paths. Attach one file at a time unless you need them in a single comment.
  • Attaching the demo to the PR body with gh pr edit instead of a comment. Use a comment, so the demo sits in the timeline next to the change it describes.
Verified refusals

gh validates every attachment locally before it resolves the repository, so these all fail without uploading or posting anything:

CommandError
--attach demo.webm#altcannot set alt text on video
--attach missing.pngmissing.png: no such file or directory
--attach empty.pngempty.png is empty
--attach some-dirsome-dir is a directory
--attach notes.txtnotes.txt is not a supported file type (supported: png, jpg, jpeg, gif, webp, svg, mp4, mov, webm)
--attach a.png --attach a.pnga.png and a.png are the same file; attached files must be unique

Duplicate detection also catches a symlink or hard link to an already-attached file.

© speakeasy-api, AGPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/pull-request-demo of speakeasy-api/gram.

Open the folder on GitHubat commit ad78247

Compare with similar skills

Pull Request Demo next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Pull Request Demo compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Pull Request Demo this skillspeakeasy-api/gram272—~3.3kAutomated safety check: PassAGPL-3.0
Finishing a Development Branchobra/superpowers296k5 repos~1.9kAutomated safety check: PassMIT
PR Babysitteropeninterpreter/openinterpreter69k3 repos~4.2kAutomated safety check: PassApache-2.0
Check PRonyx-dot-app/onyx32k2 repos~2.3kAutomated safety check: PassMIT
Understand Diff AnalysisEgonex-AI/Understand-Anything86k1 repos~1.4kAutomated safety check: PassMIT
PR Design DocOpenHands/OpenHands90k—~2.4kAutomated safety check: PassMIT

Similar skills

  • Walks the last step of a branch: confirm tests pass, detect the git environment, ask how to integrate, carry out your choice and clean up the worktree.

    296k GitHub starsUsed in 5 repos~1.9k tokens
    DevelopmentAuto-check passed
  • PR Babysitter

    openinterpreter/openinterpreter

    Watches an open GitHub pull request until it merges, handling review comments, diagnosing CI failures and retrying flaky checks along the way.

    69k GitHub starsUsed in 3 repos~4.2k tokens
    DevelopmentAuto-check passed
  • Check PR

    onyx-dot-app/onyx

    Checks a GitHub, GitLab, or Perforce (p4) pull request (or merge request, or shelved changelist) for unresolved review comments, failing status checks, and incomplete PR descriptions.

    32k GitHub starsUsed in 2 repos~2.3k tokens
    DevelopmentAuto-check passed
  • Understand Diff Analysis

    Egonex-AI/Understand-Anything

    Reads your git changes or a pull request against a prebuilt knowledge graph of the project to explain what changed, which components are affected and what is risky.

    86k GitHub starsUsed in 1 repo~1.4k tokens
    DevelopmentAuto-check passed
  • PR Design Doc

    OpenHands/OpenHands

    For a non-trivial pull request, write a self-contained HTML design doc under the temporary .pr/ directory and link a visibility-appropriate preview in the PR description, so maintainers grasp the…

    90k GitHub stars~2.4k tokensUpdated today
    DevelopmentAuto-check passed
  • WooCommerce Code Review

    woocommerce/woocommerce

    Reviews WooCommerce code changes against the project's standards, flagging backend PHP architecture, naming, documentation, data integrity and testing violations.

    11k GitHub starsUsed in 3 repos~1.1k tokens
    DevelopmentAuto-check passed

More from speakeasy-api/gram

All 39 skills in this repo
  • Gram Playwright CLI

    speakeasy-api/gram

    A skill your agent uses when automating the Gram dashboard in a browser, capturing screenshots, inspecting pages.

    272 GitHub stars~3.4k tokensUpdated today
    Auto-check passed
  • Transactional Email

    speakeasy-api/gram

    A skill your agent uses when adding, changing, restyling, reviewing, validating, or previewing a Gram/Speakeasy transactional email, in Go or in LMX/MJML — a template<name.go, a TemplateKey…

    272 GitHub stars~4.7k tokensUpdated today
    Auto-check passed
  • Admin Shadcn

    speakeasy-api/gram

    A skill your agent uses when adding, changing, or styling UI in client/admin (the Gram admin dashboard) that touches shadcn/ui — a button, dialog, table, sidebar, badge, select, tabs, tooltip, card…

    272 GitHub stars~1k tokensUpdated today
    Auto-check passed
  • A skill your agent uses when adding, editing, reviewing, testing, or locating a reviewed skill distributed with the Platform MCP plugin; triggers include "Platform MCP skill", "platformmcpskills"…

    272 GitHub stars~2.2k tokensUpdated today
    Auto-check passed
  • Clickhouse

    speakeasy-api/gram

    A skill your agent uses when changing or reviewing Gram ClickHouse schemas, migrations, queries, inserts, access principals, bootstrap SQL, Cloud compatibility, partial migration failures, or…

    272 GitHub stars~3.2k tokensUpdated today
    Auto-check passed
  • Feature Flag

    speakeasy-api/gram

    A skill your agent uses when gating a feature behind a flag, dogfooding or gradually rolling out a change, choosing between productfeatures and PostHog feature flags, adding or checking a product…

    272 GitHub stars~2.6k tokensUpdated today
    Auto-check passed

Categories

Questions about Pull Request Demo

What does Pull Request Demo do?

Always use after creating a pull request that proposes user-visible changes. Pull Request Demo is an agent skill from speakeasy-api/gram. Always use after creating a pull request that proposes user-visible changes.

When should I use Pull Request Demo?

Pull Request Demo fits situations like: tasks that involve Pull requests.

How do I install Pull Request Demo in Claude Code?

Run `npx skills add speakeasy-api/gram --skill pull-request-demo -a claude-code`. Or copy the skill folder (.agents/skills/pull-request-demo in speakeasy-api/gram) into .claude/skills/pull-request-demo in your project. Claude Code loads it when a task matches its description.

How do I install Pull Request Demo in Codex?

Run `npx skills add speakeasy-api/gram --skill pull-request-demo -a codex`. Or copy the skill folder (.agents/skills/pull-request-demo in speakeasy-api/gram) into .agents/skills/pull-request-demo in your project. Codex loads it when a task matches its description.

Can I use Pull Request Demo in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add speakeasy-api/gram --skill pull-request-demo -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/pull-request-demo, .gemini/skills/pull-request-demo, .github/skills/pull-request-demo and .opencode/skills/pull-request-demo in your project.

What does Pull Request Demo need to run?

Going by SKILL.md and its folder, Pull Request Demo needs the command-line tools its instructions call (mise, ffmpeg, gh, psql and git) and credentials named GITHUB_TOKEN and GH_TOKEN. Our summary lists: A credential in GITHUB_TOKEN.

Does Pull Request Demo access the network?

SKILL.md contains no URLs. Its commands use gh and git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Pull Request Demo safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Pull Request Demo use?

Pull Request Demo is published under the AGPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Pull Request Demo use?

About 3.3k tokens (SKILL.md is roughly 13k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Pull Request Demo?

Skills that share tags, products or a category with Pull Request Demo: Finishing a Development Branch (obra/superpowers, 296k stars), PR Babysitter (openinterpreter/openinterpreter, 69k stars), Check PR (onyx-dot-app/onyx, 32k stars) and Understand Diff Analysis (Egonex-AI/Understand-Anything, 86k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Pull Request Demo?

speakeasy-api (a GitHub organization) maintains it in speakeasy-api/gram, which has 272 GitHub stars. The repository holds 39 skills in this directory. The repository was last updated on October 8, 2026.

Source: speakeasy-api/gram on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.