Add GitGlimpse workflow for automated demo recording#41
Merged
DeDuckProject merged 3 commits intomainfrom Mar 15, 2026
Merged
Conversation
Adds GitGlimpse GitHub Action to automatically record and post visual demo GIFs of UI changes on pull requests. Includes: - .github/workflows/git-glimpse.yml: main pipeline triggered on PR push or /glimpse comment; installs deps, records demo, posts to PR - .github/workflows/git-glimpse-ack.yml: fast acknowledgment workflow that reacts with 👀 emoji when /glimpse is triggered - git-glimpse.config.ts: project config pointing to Vite dev server at http://localhost:5173/epp-demo/ Requires ANTHROPIC_API_KEY secret set in repository settings. https://claude.ai/code/session_01L74tc3msNfg2KcEuUef4Wf
🧐 UI Demo PreviewChanges detected in: What changed: This change adds GitGlimpse CI automation — a GitHub Actions workflow that automatically records a demo video of UI changes when a pull request is opened or when '/glimpse' is commented on a PR. No visible UI changes were made; this is purely infrastructure for automated demo generation. 📱 Can't see the preview? Open it directly Demo script (auto-generated)import type { Page } from '@playwright/test';
export async function demo(page: Page): Promise<void> {
await page.setViewportSize({ width: 1280, height: 720 });
// Navigate to home page
await page.goto('http://localhost:5173');
await page.waitForLoadState('networkidle');
await page.waitForTimeout(400);
// Gently scroll down to reveal content
await page.mouse.move(640, 360);
await page.waitForTimeout(400);
await page.mouse.wheel(0, 300);
await page.waitForTimeout(400);
await page.mouse.wheel(0, 300);
await page.waitForTimeout(400);
// Scroll back to top
await page.mouse.wheel(0, -600);
await page.waitForTimeout(400);
// Hover over navigation links if present
const navLinks = page.locator('nav a, header a');
const navCount = await navLinks.count();
if (navCount > 0) {
const firstNav = navLinks.first();
const firstBox = await firstNav.boundingBox();
if (firstBox) {
await page.mouse.move(640, 360);
await page.waitForTimeout(200);
await page.mouse.move(firstBox.x + firstBox.width / 2, firstBox.y + firstBox.height / 2);
await page.waitForTimeout(400);
}
}
if (navCount > 1) {
const secondNav = navLinks.nth(1);
const secondBox = await secondNav.boundingBox();
if (secondBox) {
await page.mouse.move(secondBox.x + secondBox.width / 2, secondBox.y + secondBox.height / 2);
await page.waitForTimeout(400);
}
}
// Hover over any prominent buttons
const buttons = page.locator('button, [role="button"]');
const buttonCount = await buttons.count();
if (buttonCount > 0) {
const firstButton = buttons.first();
const btnBox = await firstButton.boundingBox();
if (btnBox) {
await page.mouse.move(640, 400);
await page.waitForTimeout(200);
await page.mouse.move(btnBox.x + btnBox.width / 2, btnBox.y + btnBox.height / 2);
await page.waitForTimeout(400);
}
}
// Try navigating to a second meaningful route via nav link click
if (navCount > 1) {
const secondNav = navLinks.nth(1);
const secondBox = await secondNav.boundingBox();
if (secondBox) {
await page.mouse.move(640, 360);
await page.waitForTimeout(200);
await page.mouse.move(secondBox.x + secondBox.width / 2, secondBox.y + secondBox.height / 2);
await page.waitForTimeout(400);
await secondNav.click();
await page.waitForLoadState('networkidle');
await page.waitForTimeout(400);
// Scroll gently on this page
await page.mouse.move(640, 360);
await page.waitForTimeout(200);
await page.mouse.wheel(0, 250);
await page.waitForTimeout(400);
await page.mouse.wheel(0, -250);
await page.waitForTimeout(400);
}
}
// Try navigating to a third route if available
if (navCount > 2) {
const thirdNav = navLinks.nth(2);
const thirdBox = await thirdNav.boundingBox();
if (thirdBox) {
await page.mouse.move(640, 360);
await page.waitForTimeout(200);
await page.mouse.move(thirdBox.x + thirdBox.width / 2, thirdBox.y + thirdBox.height / 2);
await page.waitForTimeout(400);
await thirdNav.click();
await page.waitForLoadState('networkidle');
await page.waitForTimeout(400);
await page.mouse.move(640, 360);
await page.mouse.wheel(0, 200);
await page.waitForTimeout(400);
await page.mouse.wheel(0, -200);
await page.waitForTimeout(400);
}
}
// Return home to finish the tour
await page.goto('http://localhost:5173');
await page.waitForLoadState('networkidle');
await page.waitForTimeout(400);
// Final gentle scroll and settle
await page.mouse.move(640, 360);
await page.waitForTimeout(200);
await page.mouse.wheel(0, 150);
await page.waitForTimeout(400);
await page.mouse.wheel(0, -150);
await page.waitForTimeout(400);
}Generated by git-glimpse |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
This PR adds automated demo recording capabilities to the repository using GitGlimpse, a tool that generates visual recordings of application interactions. The implementation includes GitHub Actions workflows and configuration to automatically record demos on pull requests and via comment commands.
Key Changes
GitHub Actions Workflows:
git-glimpse.yml: Main workflow that triggers on pull requests and/glimpsecomments, sets up the environment (Node.js, FFmpeg, Playwright), and runs the GitGlimpse action with appropriate permissions and error handlinggit-glimpse-ack.yml: Acknowledgment workflow that reacts with an "eyes" emoji when a/glimpsecommand is detected on a PR commentGitGlimpse Configuration (
git-glimpse.config.ts):npm run devhttp://localhost:5173/epp-demo/Implementation Details
/glimpsecomments on PRsANTHROPIC_API_KEYandGITHUB_TOKENsecrets for operationhttps://claude.ai/code/session_01L74tc3msNfg2KcEuUef4Wf