agentleFS
lodev09lodev09/react-native-true-sheet/.agents/skills/preview/SKILL.md

preview

Skill2.1k starsChanged 4 days agoMITView on GitHub

Record and render TrueSheet preview animations for the README, docs, and blog — drive the bare example on the iOS simulator, Android emulator, iPad, or mobile Safari with argent, record a clean screen capture, and render it into a light/dark GIF pair framed in a device for GitHub and a plain MP4 for the docs. Use when asked to create, update, or re-record a preview, demo GIF, feature GIF, or blog animation, or when a preview looks outdated or bad in dark mode.

We split this skill into the rules it gives an agent

6 rules. 0 are common, 2 are distinctive, and 4 are very specific to this project.

  • 0

    Common

    Most of the 8 edited versions we read keep these.

  • 2

    Distinctive

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Read argent-device-interact and argent-screen-recording before driving a device.

    line 19
  2. Distinctive:

    Every preview uses the same clean state: 9:41, full battery, dark appearance, no watermark, no debug overlays.

    line 43
  3. Very specific:

    Use the dedicated "iPhone Duo (TrueSheet)" simulator: fold open, rotate LandscapeLeft (portrait UI, horizontal fold), launch the app, tap …

    line 108
  4. Distinctive:

    Check the result before embedding:

    line 167
  5. Very specific:

    Look at one frame of each GIF (ffmpeg -ss 4 -i <gif> -frames:v 1 /tmp/f.png): the corners and shadow should blend into the page with no box …

    line 170
  6. Very specific:

    Stop Metro, the web server, and the simulator servers as in the e2e skill §6.

    line 197

“Common” is measured: kept by at least 6 in 10 of the 8 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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Preview

Previews are scripted screen recordings of the example app, rendered by scripts/render.sh into:

FileUsed byLook
<name>-light.gif, <name>-dark.gifREADME (GitHub)Device frame and shadow, matted to GitHub's white and #0d1117 pages
<name>.mp4Docs and blogPlain screen; the docs frame it with CSS, so it fits both themes

GIF has no soft transparency, so each theme gets its own GIF and the README picks one with <picture>. Files go in docs/public/img/previews/.

Read argent-device-interact and argent-screen-recording before driving a device.

1. Prepare

Release build

Record a Release build of the bare example: no Metro, no LogBox or dev overlays, and production-speed JS, so animations don't drop frames. MapScreen's on-screen event log renders only in __DEV__, so it's gone too. The JS bundle is baked in at build time: make any example change first, and rebuild after every JS change.

iOS, from example/bare/ios (then install build/Build/Products/Release-iphonesimulator/TrueSheetExample.app with argent reinstall-app):

xcodebuild -workspace TrueSheetExample.xcworkspace -scheme TrueSheetExample \
  -configuration Release -destination 'id=<UDID>' -derivedDataPath build build \
  > /tmp/truesheet-xcodebuild-release.log 2>&1; echo "EXIT $?"

Android, from example/bare/android, with the emulator booted on the hardware GPU (e2e skill §1). Release is signed with the debug keystore, so this builds and installs in one step (about 3 min clean). Gradle only watches example/bare for the JS bundle and calls it up to date after an example/shared edit, so always rerun the bundle task:

./gradlew app:createBundleReleaseJsAndAssets --rerun app:installRelease -PreactNativeArchitectures=arm64-v8a

Device

Every preview uses the same clean state: 9:41, full battery, dark appearance, no watermark, no debug overlays. Touch markers stay on so viewers see where each tap and drag lands.

iOS simulator:

xcrun simctl status_bar <UDID> override --time 9:41 --batteryState charged --batteryLevel 100 \
  --cellularMode active --cellularBars 4 --wifiBars 3 --dataNetwork wifi
xcrun simctl ui <UDID> appearance dark

Android emulator:

adb shell settings put global sysui_demo_allowed 1
adb shell am broadcast -a com.android.systemui.demo -e command enter
adb shell am broadcast -a com.android.systemui.demo -e command clock -e hhmm 0941
adb shell am broadcast -a com.android.systemui.demo -e command battery -e level 100 -e plugged false
adb shell am broadcast -a com.android.systemui.demo -e command network -e wifi show -e level 4 -e fully true
adb shell am broadcast -a com.android.systemui.demo -e command network -e mobile hide
adb shell am broadcast -a com.android.systemui.demo -e command notifications -e visible false
adb shell cmd uimode night yes

fully true drops the Wi-Fi "no internet" mark. The mobile icon is hidden because the emulator ignores the demo datatype and always shows "3G". Run these through bash -c from zsh: zsh doesn't split an adb -s <serial> shell stored in a variable.

Both:

  • argent disable video-watermark (global flag, re-enable in §5).
  • iPad: rotate to the orientation you want before recording. In landscape, the simulator still records the portrait framebuffer with the UI turned 90°, and describe frames and gestures use those raw axes (after LandscapeLeft, UI up is +x). Turn the recording upright before rendering (ffmpeg -i <rec> -vf transpose=2 -crf 12 <upright.mp4> for LandscapeLeft), and turn the mask the same way: sips -s format png --resampleWidth <portrait width> <mask.pdf> --out mask.png, then magick mask.png -rotate -90 mask-landscape.png.
  • Web: serve the expo example and open it in iOS Simulator Safari (e2e skill, references/web.md). Safari's toolbar stays in the shot.

2. Record

  1. launch-app (or restart-app) so the scene starts from a known state, then wait ~2 s: a swipe right after launch is often ignored.
  2. Find targets with describe. Coordinates differ per device, so never reuse them across devices.
  3. Dry-run the steps once without recording, then restart-app.
  4. screen-recording-start with showTouches: true (the default) and a timeLimitSeconds a little over the scene. Set the stop reminder the recording skill requires. Argent draws a pulse for each tap and a trail for each swipe into the video, only for the gestures it drives, so every step of the scene has to go through argent. Don't also turn on Android's own show_touches: it would draw a second marker.
  5. Drive the whole scene in one run-sequence. Keep it brisk: a delayMs of 800–900 after each step, about 450 between repeated taps on the same button. End on the same state the scene started on so the loop is seamless.
  6. screen-recording-stop. The mp4 lands in .argent/recordings/ (gitignored). Static stretches are already trimmed to 1 s.

Gestures:

  • Drag a sheet up: a 300 ms gesture-swipe from the grabber. Scroll a list: a 250 ms swipe.
  • A recording slows the simulator, so a fast swipe or short flick that works in the dry run can bounce back while recording (seen from peek to auto, and on the ScrollView sheet's dismiss flick). If that happens, use a 500 ms momentum: false drag that releases past the midpoint to the target detent, or a longer flick.
  • Dismiss or collapse a sheet the way a person does: a short drag, then a flick. Use gesture-custom from the grabber or header, interpolate: 8:

    [
      { "type": "Down", "x": 0.5, "y": 0.11 },
      { "type": "Move", "x": 0.5, "y": 0.17, "delayMs": 240 },
      { "type": "Move", "x": 0.5, "y": 0.33, "delayMs": 80 },
      { "type": "Up", "x": 0.5, "y": 0.35, "delayMs": 10 }
    ]
  • Android: a flick from a middle detent doesn't skip to the lower one (Material snaps to the nearest detent by position, ignoring velocity), so end the flick past the midpoint between the two detents (e.g. drag 0.2 → 0.28, flick to 0.6). A single-detent sheet with dismissThreshold="short" dismisses on the short flick above.
  • Gate each step that depends on a sheet opening or reaching a detent with an await-ui-element step. If a swipe is ignored, the taps after it land on other buttons, and swipes after it pan the map, which changes the state the loop has to end on.

Foldables: capture the Device Hub window

The foldables preview shows the phone folding, which only Device Hub (Xcode 27's simulator window) draws, so it's a macOS capture of that window instead of an argent recording. There are no touch markers; the scene is driven by fold, not gestures.

  • The app running the agent needs Screen & System Audio Recording permission (System Settings → Privacy & Security), applied after a relaunch. Without it screencapture fails with "could not create image".
  • The whole window must be on screen; macOS doesn't render the part past the display edge. The agent can't move it without Accessibility permission, so ask the user to.
  • Find the window ID by name with CGWindowListCopyWindowInfo (a few lines of Swift run with swift; filter on owner Device Hub).
  • Use the dedicated "iPhone Duo (TrueSheet)" simulator: fold open, rotate LandscapeLeft (portrait UI, horizontal fold), launch the app, tap the main grabber (drags from the bottom edge are cancelled on the Duo), then TrueSheet View. Its foldOptions snap moves it to the hinge.
  • Record with screencapture -x -v -V 30 -l <window id> fold.mov in the background, fold half-open after ~9 s, hold ~2.5 s, fold open. Pick the loop on the polyline cycle (§3), then crop to the phone (union of the flat and folded bounds; the window's background is #1a1a1c) and encode like render.sh's MP4:

    ffmpeg -ss <start> -to <end> -i fold.mov -vf "fps=30,crop=<w>:<h>:<x>:<y>,scale=980:-2:flags=lanczos" \
      -c:v libx264 -crf 21 -preset slow -pix_fmt yuv420p -movflags +faststart -an docs/public/img/previews/foldables.mp4
  • Embed with <Preview device="duo" />: no CSS bezel, since the video already shows the phone.

Example scene (MapScreen, 9 s): swipe the grabber up from peek → tap "FlatList" → tap "Add Item" until the list scrolls → scroll it to the bottom → drag and flick it down → tap "TrueSheet View" → tap "Auto", then "Peek" → tap the dim → drag and flick the main sheet back to peek.

3. Pick the loop

Make a contact sheet, one frame per second:

ffmpeg -v error -y -i <recording.mp4> -vf "fps=1,scale=180:-1,tile=7x2" -frames:v 1 /tmp/preview-strip.png

Choose --start just before the first movement and --end just after the last state settles. Keep previews under ~12 s; the GIFs grow with length and with how much of the screen moves (the map's polyline animation counts).

MapScreen's "True Sheet" polyline draws and erases on a loop, so a cut that shows the map only loops cleanly if it spans exactly one cycle. The cycle varies between recordings (9.8–10.7 s seen). Fill it with the scene, record with trimStatic: false and a few idle seconds on each side, then compare frames to find the pair of loop points that match best:

mkdir /tmp/lp && ffmpeg -v error -i <recording.mp4> -vf "fps=10,scale=330:-1" /tmp/lp/f%04d.png
for a in <frames before the scene>; do for d in $(seq 96 108); do b=$((a + d))
  echo "$(magick compare -metric RMSE /tmp/lp/f$(printf %04d $a).png /tmp/lp/f$(printf %04d $b).png null: 2>&1 | sed 's/.*(\(.*\))/\1/') $a $b"
done; done | sort -n | head

Frame n is at (n - 1) / 10 s. Both ends of the cut must sit where the sheet is at rest and the map is back in place; under ~0.5% RMSE loops without a visible jump.

4. Render

.agents/skills/preview/scripts/render.sh <recording.mp4> <name> --start <sec> --end <sec>
OptionDefaultNotes
--devicephonetablet for iPad: thinner bezel, smaller corner radius
--width360 (phone), 744 (tablet)Screen width in the GIF. The GIF renders at 2x of its README width
--maskReal screen shape: a PDF/PNG (iOS simulators) or auto (Android)
--radius0.128 (phone), 0.025 (tablet)Circular corner radius as a ratio of the width, when there's no mask
--fps20GIF only; the MP4 stays at 30, the recording's rate
--outdocs/public/img/previews

The frame must follow the device's real screen corners: iOS draws sheet corners concentric with them, so a guessed radius shows. The bezel, edge, and shadow are grown out of that shape, so they stay concentric with it.

  • iOS simulator: pass its framebufferMask PDF. Apple's corners are continuous curves, not circles, so no --radius matches them.

    TYPE="/Library/Developer/CoreSimulator/Profiles/DeviceTypes/iPhone 18 Pro Max.simdevicetype/Contents/Resources"
    MASK="$TYPE/$(plutil -extract framebufferMask raw "$TYPE/profile.plist").pdf"
  • Android emulator: pass --mask auto. Android paints its rounded corners black over the screen, so they're in the recording, and the script takes the shape from them. Neither the radius dumpsys display reports nor the skin's corner_radius matches that black exactly, and the difference shows as a dark sliver in the corner.

Check the result before embedding:

  • At the defaults, 10 s of phone footage renders to ~7 MB per GIF and ~1.4 MB of MP4. Keep every preview at the default 20 fps; a GIF of 8–9 MB is fine. Shorten the scene if one grows well past that.
  • Look at one frame of each GIF (ffmpeg -ss 4 -i <gif> -frames:v 1 /tmp/f.png): the corners and shadow should blend into the page with no box around the device.

5. Embed and restore

README, at half the iOS GIF's height (878 → 439). Set only height, the same on every preview, so they line up; a taller GIF (Android, 456×896) comes out a little narrower:

<picture>
  <source media="(prefers-color-scheme: dark)" srcset="docs/public/img/previews/<name>-dark.gif" />
  <img alt="TrueSheet on iOS" src="docs/public/img/previews/<name>-light.gif" height="439" />
</picture>

Docs and blog (MDX):

<Preview label="TrueSheet on Android" src="/img/previews/<name>.mp4" device="android" />

Preview (docs/components/preview.tsx) frames the video like the GIFs: a #101113 bezel with a 2px #3d4048 border and a soft shadow. device (ios, the default, also for iOS Safari; android; ipad, landscape; or duo, a Device Hub window capture with no bezel) sets the screen aspect, the bezel, and the corner radius ratio that render.sh prints (0.1423 for the iPhone 18 Pro Max, 0.1270 for the Pixel 10 Pro XL, 0.0223 for the iPad Pro 13-inch). The iPad preview renders with --device tablet --width 900 (a 1500px MP4) and shows at height={558}, 744px wide. Add a device there when you record on a new one. height defaults to 652 (300px wide on iOS, 1:2 with the 600px MP4 on retina screens; bigger upscales). Side by side, use height={500} in a <div className="flex flex-wrap gap-4"> so three fit in one row.

Restore everything you changed:

  • iOS: xcrun simctl status_bar <UDID> clear, and set the appearance back (xcrun simctl ui <UDID> appearance light).
  • Android: adb shell am broadcast -a com.android.systemui.demo -e command exit and adb shell cmd uimode night no.
  • argent enable video-watermark.
  • Reinstall the Debug build (e2e skill §1) so the devices are back on Metro.
  • Stop Metro, the web server, and the simulator servers as in the e2e skill §6.

Download now (ZIP)

Trending

More talk lately.about the whole repository

Dec 2025: 3 mentionsJan 2026: 1 mentionFeb 2026: 2 mentionsMar 2026: 3 mentionsApr 2026: 1 mentionMay 2026: 1 mentionJun 2026: 5 mentionsJul 2026: 1 mentionAug 2026: 3 mentionsSep 2026: 6 mentionsOct 2026: 4 mentionsNov 2026: 0 mentions
Dec 2025Jun 2026Nov 2026
Mentions a month of the lodev09/react-native-true-sheet repository that our weekly crawl found. There is no adoption data for this file yet.

Who's talking about lodev09/react-native-true-sheet

The biggest 5 of 37 mentions linking to the repository that our crawl found. Each line is their own headline.

See all 37

Talked about on GitHub (37 times).

On GitHub · 37

32 more on GitHub
  • Other versions16 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 16

    1. companion-inc/feynman★ 10ksame name
    2. getcompanion-ai/feynman★ 10ksame name
    3. advaitpaliwal/feynman★ 10ksame name
    4. nextflow-io/training★ 277same name
    5. typv/nest-turbo-starter★ 224same name
    6. Kangentic/kangentic★ 139same name
    7. kv0906/pm-kit★ 138same name
    8. spmtitsolution/OpenBA-Kit★ 38same name
    9. sanghun0724/cmux-claude-skills★ 33same name
    10. VoTruongDanh/Skills-Agent★ 4same name

    6 more not listed

    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.

  • Used alongsideProjects with it also use ml-training-recipe, replication and 10 more.

    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.
    • advaitpaliwalSkill

      ml-training-recipe

      Find implementable ML training recipes from papers, datasets, docs, and code. Use when the user wants to fine-tune, train, reproduce, or choose a practical ML method, dataset, hyperparameter setup, or benchmark recipe.

      Also in 3 projects that use this

    • advaitpaliwalSkill

      replication

      Plan a replication of a paper, claim, or benchmark, and execute only after an explicit environment choice. Use when the user asks to replicate results, reproduce an experiment, verify a claim empirically, or build a replication package.

      Also in 3 projects that use this

    • JaimeParkerSkill

      paper-code-audit

      Perform three-way cross-validation of a research paper by comparing the original paper text (via Zotero), official code implementation (via Git), and personal Obsidian notes. Use this skill whenever the user wants to "audit a paper", "verify paper claims against code", "cross-check notes with implementation", "triangulate paper + code + notes", "find discrepancies between paper and code", or mentions wanting a deep, structured comparison of a paper's claims against its implementation and their own notes. Also trigger when the user asks to "analyze this paper thoroughly" with code available, or when they want to systematically reconcile what the paper says, what the code does, and what their notes claim.

      Also in 3 projects that use this

    • brainbytes-devSkill

      alpha-research

      Also in 3 projects that use this

    • JimLiuSkill

      pdf-explore

      Use this skill when the user has attached a PDF, paper, report, or other document and the answer needs content from more than one place in it: summarize the methods or any other section, compare sections, find where a topic is discussed, read a value or label off a figure or chart, or find/list/extract every instance of something across the whole document (datasets, benchmarks, citations, figures, table rows, accession numbers — including appendices). Skip it only for a single lookup of 1–4 pages quoted in your very next response — `read_file(pages=[...])` attaches pages as images that are dropped from context after one turn, so multi-section answers end up re-reading the same ranges repeatedly. Parses the PDF once in the Python kernel: `pdf_pages` (pages as persistent text), `pdf_outline` (TOC), `pdf_scan` (rank pages by relevance), `pdf_map`/`pdf_extract` (per-page summary / structured fields via parallel haiku calls). For PDF creation/manipulation, use reportlab/pypdf directly.

      Also in 3 projects that use this

    • KISHOR403Skill

      session-search

      This skill should be used when searching Claude Code session transcripts with semantic understanding. Triggers on queries like "find sessions about X", "when did I work on Y", "search previous conversations". Supports natural language queries with synonym matching.

      Also in 3 projects that use this

    • +1 more from advaitpaliwal
  • In this repository5 other files it gives its agents.

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

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.