Skip to content

Instantly share code, notes, and snippets.

@tylergermain
Last active March 6, 2026 20:37
Show Gist options
  • Select an option

  • Save tylergermain/223e7de43e605cc6607dd672700194df to your computer and use it in GitHub Desktop.

Select an option

Save tylergermain/223e7de43e605cc6607dd672700194df to your computer and use it in GitHub Desktop.
#Requires -Version 5.1
$ErrorActionPreference = "Stop"
# -- Config ---------------------------------------------------------------
$REPO = "https://github.com/AI-Essentials/screen-recording-skill.git"
# -- Helpers ---------------------------------------------------------------
$ESC = [char]27
$BOLD = "$ESC[1m"
$DIM = "$ESC[2m"
$RED = "$ESC[0;31m"
$GREEN = "$ESC[0;32m"
$YELLOW = "$ESC[1;33m"
$CYAN = "$ESC[0;36m"
$NC = "$ESC[0m"
function Info($msg) { Write-Host " ${GREEN}>${NC} $msg" }
function Warn($msg) { Write-Host " ${YELLOW}>${NC} $msg" }
function Fail($msg) { Write-Host " ${RED}x${NC} $msg"; exit 1 }
function Step($msg) { Write-Host "`n ${BOLD}$msg${NC}" }
function Done_() { Write-Host " ${GREEN}>${NC} ${DIM}done${NC}" }
$TMPDIR_CREATED = $null
$TARGET_DIR = Get-Location
# Detect install vs update
if (Test-Path "$TARGET_DIR\.claude\skills\screen-demo") {
$MODE = "update"
} else {
$MODE = "install"
}
Write-Host ""
Write-Host " ${CYAN} ____ ____ ____ _____ _____ _ _${NC}"
Write-Host " ${CYAN}/ ___| / ___| _ \| ____| ____| \ | |${NC}"
Write-Host " ${CYAN}\___ \| | | |_) | _| | _| | \| |${NC}"
Write-Host " ${CYAN} ___) | |___| _ <| |___| |___| |\ |${NC}"
Write-Host " ${CYAN}|____/ \____|_| \_\_____|_____|_| \_|${NC}"
Write-Host ""
Write-Host " ${CYAN} ____ _____ __ __ ___${NC}"
Write-Host " ${CYAN}| _ \| ____| \/ |/ _ \${NC}"
Write-Host " ${CYAN}| | | | _| | |\/| | | | |${NC}"
Write-Host " ${CYAN}| |_| | |___| | | | |_| |${NC}"
Write-Host " ${CYAN}|____/|_____|_| |_|\___/${NC}"
Write-Host ""
if ($MODE -eq "update") {
Write-Host " ${DIM}Updating to latest version${NC}"
} else {
Write-Host " ${DIM}Installing skill + dependencies${NC}"
}
# -- Resolve source files --------------------------------------------------
$SCRIPT_DIR = Split-Path -Parent $MyInvocation.MyCommand.Path
if (Test-Path "$SCRIPT_DIR\.claude\skills\screen-demo\SKILL.md") {
$SOURCE_DIR = $SCRIPT_DIR
} else {
Step "Fetching"
$TMPDIR_CREATED = Join-Path ([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName())
New-Item -ItemType Directory -Path $TMPDIR_CREATED -Force | Out-Null
try {
git clone --depth 1 $REPO $TMPDIR_CREATED 2>$null
if ($LASTEXITCODE -ne 0) { throw }
} catch {
Fail "Clone failed. Do you have access to the repo?"
}
$SOURCE_DIR = $TMPDIR_CREATED
Done_
}
# -- Check prerequisites ---------------------------------------------------
Step "Prerequisites"
# Python
if (-not (Get-Command python -ErrorAction SilentlyContinue)) {
if (-not (Get-Command python3 -ErrorAction SilentlyContinue)) {
Fail "Python 3 is required - https://python.org"
}
$PYTHON_CMD = "python3"
} else {
$PYTHON_CMD = "python"
}
$PYTHON_VERSION = & $PYTHON_CMD -c "import sys; v=sys.version_info; print(str(v.major)+'.'+str(v.minor))"
$vParts = $PYTHON_VERSION.Split(".")
$PYTHON_MAJOR = [int]$vParts[0]
$PYTHON_MINOR = [int]$vParts[1]
if ($PYTHON_MAJOR -lt 3 -or ($PYTHON_MAJOR -eq 3 -and $PYTHON_MINOR -lt 10)) {
Fail "Python 3.10+ required (found $PYTHON_VERSION)"
}
Info "Python ${DIM}$PYTHON_VERSION${NC}"
# Node
if (-not (Get-Command node -ErrorAction SilentlyContinue)) {
Fail "Node.js is required - https://nodejs.org"
}
$NODE_VERSION = (node -v).TrimStart("v")
$NODE_MAJOR = [int]($NODE_VERSION.Split("."))[0]
if ($NODE_MAJOR -lt 18) {
Fail "Node.js 18+ required (found v$NODE_VERSION)"
}
Info "Node ${DIM}v$NODE_VERSION${NC}"
# ffmpeg
if (-not (Get-Command ffmpeg -ErrorAction SilentlyContinue)) {
Warn "ffmpeg not found, installing via winget..."
try {
winget install --id Gyan.FFmpeg -e --accept-source-agreements --accept-package-agreements
# Refresh PATH so ffmpeg is available in this session
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
if (-not (Get-Command ffmpeg -ErrorAction SilentlyContinue)) {
Warn "ffmpeg installed but not yet on PATH - you may need to restart your terminal"
}
} catch {
Fail "ffmpeg is required - install manually: winget install Gyan.FFmpeg"
}
}
if (Get-Command ffmpeg -ErrorAction SilentlyContinue) {
$FFMPEG_LINE = (ffmpeg -version 2>&1 | Select-Object -First 1).ToString()
$FFMPEG_VERSION = $FFMPEG_LINE.Split(" ")[2]
Info "ffmpeg ${DIM}$FFMPEG_VERSION${NC}"
}
# -- Copy skill files ------------------------------------------------------
if ($SOURCE_DIR -ne "$TARGET_DIR") {
Step "Skill files"
# Skill definition
$skillDest = Join-Path $TARGET_DIR ".claude\skills\screen-demo"
New-Item -ItemType Directory -Path (Join-Path $TARGET_DIR ".claude\skills") -Force | Out-Null
if (Test-Path $skillDest) {
Remove-Item -Recurse -Force $skillDest
}
Copy-Item -Recurse (Join-Path $SOURCE_DIR ".claude\skills\screen-demo") $skillDest
Info ".claude/skills/screen-demo/"
# Remotion source
$remotionDest = Join-Path $TARGET_DIR "remotion"
New-Item -ItemType Directory -Path (Join-Path $remotionDest "src\components") -Force | Out-Null
New-Item -ItemType Directory -Path (Join-Path $remotionDest "src\lib") -Force | Out-Null
foreach ($f in @("package.json", "tsconfig.json", "render.mjs")) {
Copy-Item (Join-Path $SOURCE_DIR "remotion\$f") (Join-Path $remotionDest $f)
}
Copy-Item (Join-Path $SOURCE_DIR "remotion\src\index.ts") (Join-Path $remotionDest "src\index.ts")
Copy-Item (Join-Path $SOURCE_DIR "remotion\src\Root.tsx") (Join-Path $remotionDest "src\Root.tsx")
Copy-Item (Join-Path $SOURCE_DIR "remotion\src\components\CameraComposition.tsx") (Join-Path $remotionDest "src\components\CameraComposition.tsx")
Copy-Item (Join-Path $SOURCE_DIR "remotion\src\lib\springInterpolate.ts") (Join-Path $remotionDest "src\lib\springInterpolate.ts")
Info "remotion/"
# Requirements - merge if exists, copy if not
$reqDest = Join-Path $TARGET_DIR "requirements.txt"
$reqSrc = Join-Path $SOURCE_DIR "requirements.txt"
if (Test-Path $reqDest) {
$existing = Get-Content $reqDest
foreach ($line in Get-Content $reqSrc) {
if ([string]::IsNullOrWhiteSpace($line)) { continue }
if ($existing -notcontains $line) {
Add-Content -Path $reqDest -Value $line
}
}
} else {
Copy-Item $reqSrc $reqDest
}
Info "requirements.txt"
# .env.example
$envExDest = Join-Path $TARGET_DIR ".env.example"
if (-not (Test-Path $envExDest)) {
Copy-Item (Join-Path $SOURCE_DIR ".env.example") $envExDest
}
}
# -- Environment file ------------------------------------------------------
Push-Location $TARGET_DIR
Step "Environment"
$envFile = Join-Path $TARGET_DIR ".env"
if (-not (Test-Path $envFile)) {
Copy-Item ".env.example" ".env"
Warn "Created .env ${DIM}- add your STEEL_API_KEY${NC}"
Info "${DIM}https://app.steel.dev/settings/api-keys${NC}"
} else {
$envContent = Get-Content $envFile -Raw -ErrorAction SilentlyContinue
if ($envContent -notmatch "STEEL_API_KEY") {
Add-Content -Path $envFile -Value ""
Add-Content -Path $envFile -Value "# Cloud browser - for recording website demos"
Add-Content -Path $envFile -Value "STEEL_API_KEY=your_steel_api_key"
Warn "Added STEEL_API_KEY to .env ${DIM}- fill it in before running${NC}"
} else {
Info ".env ${DIM}ready${NC}"
}
}
# -- Python dependencies ---------------------------------------------------
Step "Python"
$venvDir = Join-Path $TARGET_DIR ".venv"
if (-not (Test-Path $venvDir)) {
& $PYTHON_CMD -m venv $venvDir
}
# Activate venv
$activateScript = Join-Path $venvDir "Scripts\Activate.ps1"
& $activateScript
pip install -q -r requirements.txt
Info "Packages installed"
$ErrorActionPreference = "Continue"
playwright install chromium 2>$null
$ErrorActionPreference = "Stop"
Info "Playwright browser installed"
# -- Remotion (video editor) -----------------------------------------------
Step "Remotion"
Push-Location (Join-Path $TARGET_DIR "remotion")
npm install --silent
Pop-Location
Info "Packages installed"
# -- Cleanup ---------------------------------------------------------------
if ($TMPDIR_CREATED -and (Test-Path $TMPDIR_CREATED)) {
Remove-Item -Recurse -Force $TMPDIR_CREATED
}
Pop-Location
# -- Done ------------------------------------------------------------------
Write-Host ""
Write-Host ""
if ($MODE -eq "update") {
Write-Host " ${GREEN}${BOLD}Updated!${NC}"
Write-Host ""
Write-Host " ${DIM}Restart Claude Code to pick up changes.${NC}"
} else {
Write-Host " ${GREEN}${BOLD}Installed!${NC}"
Write-Host ""
Write-Host " ${DIM}1.${NC} Add your STEEL_API_KEY to .env"
Write-Host " ${DIM}2.${NC} Open Claude Code in this directory"
Write-Host " ${DIM}3.${NC} Run ${CYAN}/screen-demo${NC}"
}
Write-Host ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment