record-browser-gif
Skill2 starsChanged 29 days agoMITView on GitHub
Record browser or Web UI interaction demos as verified, optimized GIFs using the available browser-control workflow, optional Playwright video for higher capture frame rates, and a deterministic encoder, then attach the GIF to a pull request with gh --attach; publication requires gh v2.99.0 or later, and a GIF over 5 MiB is split into parts. Use when asked to make, record, or generate a GIF demonstrating a browser workflow, and as evidence for pull requests that change user-visible GUI behavior.
- Commits and pushes
13 other projects use a version of this, 11 of them edited.
Adopted by
Most recently taken up by
- Fei2411/DeepSeek-Bottheir own version, first seen Nov 8, 2026
- ZeroOnehub/aipm-workbenchedited, first seen Nov 1, 2026
- See-Sol-Lab/DeepSeekGUIedited, first seen Oct 18, 2026
- Haifai-AI/baby-whaleedited, first seen Oct 13, 2026
- Yao920127/claude-code-harnessedited, first seen Oct 11, 2026
- xinyuquan985-coder/deepseek-harness-neonedited, first seen Sep 26, 2026
Used with
Projects with it also use dsh-doc-site-sync and dsh-doc-standards.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
lucaslusSkilldsh-doc-site-sync
Use when publishing, updating, moving, or removing DeepSeek Harness documentation website pages; editing website/docs.ts mappings or navigation; diagnosing a page missing from the VitePress site; fixing projected documentation links; or running the docs:dev, docs:check, and doc-sync workflow after website-content changes.
Also in 5 projects that use this
lucaslusSkilldsh-doc-standards
Use when writing, moving, reviewing, or auditing documentation in the deepseek-harness repo — choosing hierarchy and detail, separating tutorials from references, checking tutorial progression, trimming doc slop, responding to a verify-doc-budgets failure, or requests like "improve the docs", "audit the docs", "where should this be documented", or "this doc is too long".
Also in 5 projects that use this
Other versions13 projects use a version of this.
Word for word · 0
None found.
Edited · 11
- deepseek-ai/deepseek-harness★ 276k37% same
- See-Sol-Lab/DeepSeekGUI★ 27426% same
- SuperJJ007/papermachine★ 5927% same
- xinyuquan985-coder/deepseek-harness-neon★ 1717% same
- ZeroOnehub/aipm-workbench★ 227% same
- Haifai-AI/baby-whale★ 117% same
- lucaslus/dsh-desktop★ 117% same
- SparkElf/deepseek-harness-plus★ 127% same
- SuperMate-Ai/SuperMate-Harness-System★ 117% same
- Yao920127/claude-code-harness★ 127% same
1 more not listed
Wrote their own version · 2
- Fei2411/DeepSeek-Bot★ 6.3ksame name
- kevinforge/orbit★ 5same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository17 other files it gives its agents.
- agent-experienceSkill
- agent-notesSkill
- code-reviewSkill
- docs-standardSkill
- error-handlingSkill
- find-simplificationsSkill
- lifecycle-reviewSkill
- perf-evidenceSkill
- pre-push-checksSkill
- prose-standardSkill
- responsive-uiSkill
- stacked-prsSkill
- test-reliabilitySkill
- trim-cot-leakageSkill
- ui-ux-reviewSkill
- upgrade-guideSkill
- vibe-harness-bootstrapSkill
The file
We split this skill into the rules it gives an agent
8 rules. 4 are common, 1 is distinctive, and 3 are very specific to this project.
4
Common
Most of the 12 edited versions we read keep these.
1
Distinctive
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Common: line 19
Never read or expose credential values.
- Common: line 25
Treat one storyboard as one evidence run: every published frame comes from that server, state, and scenario run.
- Very specific: line 26
When switching between branches, stop the old server by PID or an exact command-line match.
- Very specific: line 80
When continuous video is unavailable or a storyboard is requested, capture three to six verified states from one isolated run, saved as …
- Common: line 92
Read the encoder's JSON summary: output path, interval and speed (or frame count), encoded frames, dimensions, duration, and byte size.
- Very specific: line 93
Look at the encoded GIF itself, not only the source frames.
- Common: line 94
Run git status --short and confirm that raw video, QA frames, and the GIF landed only under ignored paths.
- Distinctive: line 122
If earlier pull request bodies embed GIFs from dedicated assets branches, never add to, delete, rewrite, or force-push those branches: …
“Common” is measured: kept by at least 6 in 10 of the 12 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Record a browser GIF
Produce a short, truthful UI demonstration as a local GIF and, only when the task includes attaching it to a pull request, publish it through the attach workflow at the end. Prefer the available browser-control workflow; use Playwright video when continuous capture at a higher frame rate helps; use the bundled encoder for trimming, speed, final hold, dimensions, and size.
GIF evidence for GUI changes
When the project rules require GIF evidence for user-visible GUI changes, record it with this skill from the change's own code. The recording is evidence: use a real server built from that branch and the real data path. Do not substitute fixture data, mock transports, synthetic event injection, or test-only hooks unless the user explicitly asks for a fixture recording. Next to the embed, state the demonstrated commit, the server and origin that served it, any mode flags or browser-state exceptions, and whether real external services ran.
Keep recording separate from publication
- Recording produces local video or screenshots; encoding produces one
.gifartifact, or its numbered parts when it exceeds 5 MiB. Neither mutates remote state. - Publication (attaching the GIF to a pull request body with
gh --attach) is a separate final step, performed only when the task includes it. It never commits to any branch. - Preserve the requested recording conditions. If credentials or the server are unavailable, report that limitation instead of substituting a fixture.
- Never read or expose credential values; use the application's normal configuration path and a benign demonstration scenario.
Stage the application
- Require a clean worktree, record its exact commit with
git rev-parse HEAD, then build that tree with the profile'scommands.build. A GIF recorded against another commit's build misattributes the evidence. - Boot one server per port from that tree with fresh scratch state (data directories, workspaces, sessions). Give the browser a fresh isolated context; if the browser workflow cannot create one, clear that origin's cookies and site storage before navigating.
- Treat one storyboard as one evidence run: every published frame comes from that server, state, and scenario run. If capture automation fails, discard its frames and rerun from fresh state; never splice frames from separate runs.
- When switching between branches, stop the old server by PID or an exact command-line match. A broad
pkill -fpattern can kill the shell that launched it.
Record the flow
Follow the available browser-control workflow's setup, interaction, and cleanup instructions. When it can record video on its controlled context, enable that; otherwise use screenshot capture within the same workflow. Only when browser control is unavailable, use the project's own Playwright dependency in an isolated headless browser and state that fallback; do not install another driver or open the user's personal browser.
Store scripts, raw video, timing notes, QA frames, and the GIF under the gitignored .agent-scratch/ directory, in a fresh run directory.
Capture video
Match viewport and recordVideo.size explicitly; Playwright otherwise scales video down to fit 800×800, which can make text unreadable.
import { chromium } from 'playwright'
import { join } from 'node:path'
const size = { width: 1440, height: 900 }
const browser = await chromium.launch()
const context = await browser.newContext({ viewport: size, recordVideo: { dir: join(runDir, 'videos'), size } })
try {
const page = await context.newPage()
const video = page.video()
// Navigate and exercise the real application here.
await context.close()
await video.saveAs(join(runDir, 'demo.webm'))
} finally {
await context.close()
await browser.close()
}Set runDir to an absolute path. Retain the page's video handle before closing, and await context.close() before video.saveAs() or encoding; closing only the browser does not guarantee the flush. Each page has its own video; do not concatenate unrelated pages or runs.
Choose a short story with three to six meaningful states. Wait for unique semantic locators before acting, and use exact-match predicates that cannot match an echo of the input. Fixed waits may provide a reading hold after the state is verified, never readiness. Preserve animations and scrolling. When demonstrating a failure or recovery, open its detail so the recording shows the identity, status or stable error code, and downstream result.
Capture no secrets, personal data, unrelated tabs, or notifications. Review the whole selected interval, including intermediate states, and keep one viewport throughout.
Encode the GIF
Require python3, ffmpeg, and ffprobe. If a media binary is missing, report the dependency instead of installing software without authorization.
python3 <this-skill-dir>/scripts/encode_gif.py \
/absolute/path/to/demo.webm /absolute/path/to/demo.gif \
--start 2 --end 32 --speed 2 --final-hold 3 \
--fps 10 --max-width 1200 --colors 128--start and --end select one continuous source interval in seconds; defaults keep the full video at 1× speed with a two-second final hold. Disclose --speed and the selected interval beside the GIF so the demo cannot imply measured latency. Use observed video times, preserve the complete cause and outcome of the demonstrated behavior, and keep the original WebM for QA. --fps cannot recover motion the source did not capture.
The encoder probes the container duration, applies trim and speed before palette conversion, checks encoded duration, animation, width, and byte size, and refuses empty or out-of-range intervals, mode-inappropriate flags, and accidental overwrites. For a large artifact, reduce --max-width, then --colors or --fps, keeping text readable. Use --force only after resolving the exact output path.
Screenshot capture
When continuous video is unavailable or a storyboard is requested, capture three to six verified states from one isolated run, saved as 00-initial.png, 01-typed.png, and so on, with identical dimensions and crop.
python3 <this-skill-dir>/scripts/encode_gif.py \
/absolute/path/to/frames /absolute/path/to/demo.gif \
--durations 1.5,1.5,1.5,3.5 --fps 10 --max-width 1200 --colors 128One duration applies to every frame; otherwise supply one positive duration per frame and hold the settled state longest.
Verify the artifact
- Read the encoder's JSON summary: output path, interval and speed (or frame count), encoded frames, dimensions, duration, and byte size.
- Look at the encoded GIF itself, not only the source frames. If the viewer shows only the first frame, decode representative frames with
ffmpegand inspect those. - Run
git status --shortand confirm that raw video, QA frames, and the GIF landed only under ignored paths. - Return the absolute GIF path, render it when the client supports local media, and state whether the recording used real services, fixtures, or another transport. Stop here unless the task includes attaching it.
Encoder maintenance: python3 -m unittest discover -s <this-skill-dir>/scripts -p 'test_*.py' -v with the media prerequisites installed.
Publish the GIF
Never commit a GIF to the pull request's branch or any other branch: every default clone and full-history fetch downloads media committed to any branch. Publish only with gh --attach, which uploads the GIF and rewrites the body reference in one command, so no branch carries the media.
Attach with gh
Before attaching, check gh --version. gh --attach requires gh v2.99.0 or later, a repository on github.com (GitHub Enterprise Server is not supported), and write access. When gh is older, stop and ask the developer to upgrade it; keep the verified GIF for the retry, and do not install or upgrade gh without authorization. When any other requirement is unmet or the attach fails (authentication, write access, a host other than github.com, or an upload error), stop and report it. Never publish the GIF any other way.
Publish GIFs of at most 5 MiB, the encoder's default --max-bytes. When the encoder rejects the output for size, reduce --max-width, then --colors or --fps. When the GIF still exceeds 5 MiB at readable text quality, split it: encode consecutive, non-overlapping intervals of the same evidence run into numbered parts that each pass the size check (--start and --end over the one video, or consecutive screenshot subsets selected with --pattern), and verify every part as an artifact. Beside each embed, state its position (such as 2/3) and its source interval or frames.
Reference each GIF in the body file with the same local path passed to --attach; gh uploads it and rewrites the reference in place, keeping its position and alt text, so the order of references in the body sets the display order of split parts:
gh pr create --body-file body.md --attach path/to/demo.gif # new pull request
gh pr edit <pr> --body-file body.md --attach path/to/demo.gif # existing pull request--attach is repeatable but refuses the same file twice. Publish split parts in one gh pr create or gh pr edit with one --attach per part, so one pair of live-head checks covers every part.
Immediately before attaching, re-read the pull request's live head and compare it with the commit recorded next to the GIF; re-record if it moved. Afterward, re-read the live head and require it to remain at that commit, re-read the live body, confirm each reference points at its uploaded URL, and fetch each URL once to confirm 200 and image/gif.
Existing assets branches
If earlier pull request bodies embed GIFs from dedicated assets branches, never add to, delete, rewrite, or force-push those branches: merged pull request bodies reference their URLs.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

