Automated summary
Explains how to add or iterate Gravel Rally visual assets (trees, props, cars, liveries, procedural textures) while keeping the engine's instancing and LOD budgets intact.
Strengths
- Clear two-file workflow: metadata in catalog.ts, builder registered in library.ts
- Concrete performance rules (merge into few parts, draw calls per variant/LOD, far LODs without shadows)
- Precise list of materials and shading defines (RALLY_WIND, RALLY_FOLIAGE, RALLY_GROUND) including the ground-level origin constraint
- Ships the existing vegetation and prop inventory, encouraging reuse of existing ids instead of duplicates
Limitations
- Tightly bound to the Gravel Rally repository: exact paths, files and internal conventions make it non-portable
- The document is cut off at the end (the asset-debug URL is truncated), so the iteration loop is incomplete
- Assumes deep engine knowledge (geo.ts, world-shading.ts) and gives no full builder code example
Use it for any task inside the Gravel Rally repo involving models, trees, props, cars, liveries or textures, especially when render performance matters.
Skip it for projects other than Gravel Rally, or for 3D work unrelated to the geo.ts/material-library pipeline it describes.
Security analysis
CautionThe skill is a detailed internal workflow guide for a specific rally game codebase (asset builders, car models, liveries, procedural textures). It uses powerful tooling — shell, Node/TypeScript builds, Python mesh scripts, npx package downloads and Sketchfab model imports — but every command serves a legitimate development purpose. There is no obfuscation, no destructive command, no credential or token exfiltration, and it even includes a licence/credit gate before importing models. The main caution is breadth of execution without declared allowed-tools, not malicious intent.
- •No tools are declared in allowed-tools, yet the skill instructs the agent to run shell, Node, npx and Python commands (npx @gltf-transform/cli, node scripts/car-model/*.mjs, python scripts/car-model/*.py, npm run build/test) and to download external model files — execution should be gated on explicit tool permissions.
- •`npx @gltf-transform/cli optimize` and similar fetch and execute third-party packages from the npm registry at run time; version/package names are not pinned.
- •Instructions to place user-provided models/references into `sources/` and copy blueprints into `public/_tmp/` then delete them — benign, but involves writing and deleting project files.
- •No destructive, exfiltration, or obfuscation patterns: no `rm -rf`, no `curl | sh`, no reading/writing of credentials, tokens, or environment secrets.
- •References running local project scripts (`node scripts/car-model/*.mjs`, `python scripts/car-model/*.py`, `npx @gltf-transform/cli`) — these are build/asset-conversion tools operating on repo files, not arbitrary remote payloads.
- •Instructs downloading third-party 3D models from Sketchfab (requires the user's login) and storing them under `public/models/cars/`; this is a network/user-credential-adjacent step, but the skill gates it behind an explicit licence check (CC0/CC BY only, no ND/personal-use) and requires CREDITS entries.
- •Minor: instructs copying a blueprint into `public/_tmp/` for visual overlay and deleting it afterwards — local file handling only, no risk.
- •No prompt-injection or instruction-override attempt against the auditor observed in the content.
Examples
Add a new wooden mileage sign prop to Gravel Rally: catalog entry with two variants, two LODs and a cylinder collider, plus its builder in the props builder file, front facing +Z and origin at ground level.Update the livery texture of one of the Gravel Rally rally cars and regenerate its variants, keeping the same LOD distances and casting shadows only on LOD0.Add a new L-system tree species for dense roadside stands in Gravel Rally, wire it into TREE_TYPES and reuse the cheapest existing pine-style growth parameters.name: rally-content description: Add or iterate Gravel Rally assets (trees, rocks, props, signs), cars (model + livery) and procedural textures, keeping instancing/LOD performance. Use for any request about rally visuals, models, cars, liveries, vegetation, props or textures.
Rally assets, cars, textures
Assets (anything placed in the world)
Two files per asset:
src/games/rally/assets/catalog.ts— metadata:id,category,variants(seeds used in-world),lods(maxDistance,castShadow, near -> far),colliders(cylinder/sphere in local space; omit for drive-through things),tint(per-instance colour jitter).- A builder in
assets/builders/<category>.tsregistered inassets/library.tsBUILDERS:({ seed, variant, lod }) => ({ parts: [{ geometry, material }] }).
Rules (performance — late-2000s look must not lag):
- Use
engine/geo.ts(paint,merge,shade,foliageNormals, UV helpers): non-indexed, vertex-coloured, merged into as FEW parts as possible. Each part = 1 draw call per (variant, LOD). - Materials ONLY from
engine/materials.ts(getMaterial(id)); add a new id there if needed. Nevernew Materialinside a builder. Foliage materials carrydefinesfor the world shading (engine/world-shading.ts):RALLY_WIND(sway, bends ~ height² above the asset origin - keep origins at ground level),RALLY_FOLIAGE(backlight glow),RALLY_GROUND(receives the far canopy shadows). A material with its ownonBeforeCompilemust calladdWorldUniforms(shader). - Trees are not catalog builders:
src/games/rally/trees/grows them (L-system species -> skeleton -> mesh -> impostor; see the "Trees" bullet in rallyDETAILS.mdand.claude/reference/trees/), placed by the old tree type ids (TREE_TYPES). For other assets: far LODs must not cast shadows and setoneVariant(all variants share one bucket = one draw call). - Variants are cheap in draw calls: other LODs are drawn as variant sets (one draw per asset / LOD / material, see DETAILS.md "Draw calls"). Every variant's parts must share the same attributes (position, normal, color, uv) or the asset falls back to one draw per variant; keep LOD0 tree crowns small - sets over the cap are not merged.
- Front of props faces +Z, origin at ground level.
- Alpha grass cards:
foliage_card(olive green) /foliage_card_spring(bright green) /foliage_card_dry(golden) - the card TEXTURE carries the colour, vertex colour only varies it (a green texture x golden vertex colour = dark olive). - Buildings (
assets/builders/buildings.ts): UNIT footprint (x, z in [-0.5, 0.5], y 0..1), scaled per instance withScatterInstance.sx / sy / sz(width / height / depth) and aboxcollider; keep details relative.house_pitchedwalls end atHOUSE_WALL_FRACTIONof the height (roof above),building_flatstyles 0/1 hall, 2 brick block, 3 rendered block; variants 4-7 = two floors of windows. - Vegetation palette so far (trees: one L-system species each,
trees/species.tsTREE_TYPES):pine_tree,plantation_pine(a cheaper pine for dense stands),black_pine(umbrella crown),juniper,birch_tree,oak_tree,beech_tree(mountain beech),hornbeam_tree(bright-green coppice),walnut_tree,willow_tree(weeping),poplar_tree(columnar),cypress_tree(dark column),locust_tree(black locust),bramble_shrub,fruit_tree(orchard rows),hazelnut_tree(plantation rows),pale_tree(tall plane / ash),young_tree(sapling),thicket_shrub(autumn roadside brush, drive-through),broom_shrub(yellow flowering broom),bush(green),scrub_bush(dark olive hill scrub),grass_tuft,spring_grass,dry_grass; props incl.street_lamp,road_barrier(red-white police / marshal barrier, solid, closes side-road junctions),tape_post(5.2 m of red / white tape along local X),fan_flag(generic designs, no national / club flags).
Iterate at /games/rally/asset-debug.html?asset=<id>&seed=<n>&lod=<n>&grid=20&bounds=1&collider=1
(seed=-1 shows the in-world variant). grid is an instancing stress test; watch F3 stats.
Cars
One folder per car: src/games/rally/cars/<car>/<car>.ts exporting a CarDef, registered in ALL_CARS in cars/index.ts.
Release flags (src/games/rally/release.ts - one file tracks all cars + maps): add a new car to CARS_LIST with
hideInProd: true (required - tests/rally/release.test.ts fails for an unlisted car). It is then dev server + test build only (npm run dev / npm run build:test
use ALL_CARS), marked TEST in the menus / HUD / tool pages, and left out of npm run build. Remove the flag to ship it
(or set it again to pull it from the published build).
Car-specific extras (e.g. a custom part builder) go in the car's folder; code used by every car (types, body,
model, parts, livery, glTF import) lives in cars/shared/.
sound: engine layout, displacement, exhaust / intake, turbo + anti-lag, pops, gearbox, whine, cam - match the real engine (rallyDETAILS.md"Sound";tests/rally/engine-sound.test.tschecks the ranges).- Every car needs a body for when it has no GLB or the GLB fails:
model.custom(hand-built, below) ormodel.profile(an imported car's boxy stand-in: its side outline extruded to the body width with glass + lamps,cars/shared/profile-body.ts; it wears the livery when the car'sCarAtlassetslayout= its model.source.jsonatlasblock). Bake it from the plain GLB into the car folder:node scripts/car-model/side-profile.mjs public/models/cars/<file>.glb --axles <front z>,<rear z> --wheel <radius> > src/games/rally/cars/<car>/profile.ts. The city maps' parked cars use these profiles too (assets/builders/vehicles.tsSHAPES). Required for every imported car: rally-car-import step 6c.tests/rally/car-fallback.test.tschecks it; see it withcar-viewer.html?car=<id>&fallback=1. model.wheels(radius, width)= car-specific tyre + rim geometry (a tyre with acolorattribute is drawn with vertex colours);model.glass= window tint;model.paintFinish: 'satin'= old paint;rim.style: 'steel'= holed steel wheel, no caliper.model.wheelModel= a wheel GLB made from rim + tyre STLs (scripts/car-model/wheel-stl-to-glb.mjs, unit wheel space, scaled per car bycars/shared/stl-wheel.ts; adds a brake disc + hat + caliper behind the open spokes).skoda_rally_wheel.glb(the imported model's own rim,--keep) is on the Skoda Rally. For another wheel STL, re-measure the rim with cross-sections and adjust the strip rules in the script (print-only tubes / plates hide the brakes).model.rim:color,spokes,stylespoke|steel (the procedural wheel, until / unless a wheel GLB loads).- Livery = the car's atlas painter (
CarAtlas.paint, rally-livery skill) with seeded colours fromcars/shared/livery.ts(liveryInfo: base + 2 accents; seed 0 =model.paint; no real brand logos). Liveries carry no numbers / lettering: the car number + rally name are the door plate (cars/shared/rally-badge.ts, a decal projected onto the paint). Place it per car withmodel.doorBadge(z,y, optionaltiltin degrees to follow a sloping body line; check both sides in the car viewer with&num=7&rally=<map>- clear of handles / seams). - Model space: y = 0 ground at ride height, z = 0 centre of mass. For wide-arch cars set physics
trackso the tyre's outer face sits just inside the arch. - Per-car performance bands live in
tests/rally/vehicle.test.ts(BANDS) - add one for every new car.
Free camera for close-ups / screenshots: add &cam=x,y,z&look=x,y,z&fov=10&clean=1 (model space, +z nose, +x car's left; clean=1 hides the panel; the panel's "Copy camera link" button copies the current view). Liveries (create / fix / debug): the rally-livery skill + scripts/car-model/chart-probe.py.
Iterate at /games/rally/car-viewer.html?car=<id>&seed=<n>&view=side&hull=1&wire=1 (pose sliders for
steer/suspension, specs + torque/power chart, "Test drive" link). Physics changes -> rally-physics-tuning skill.
Console: __carViewer.model.
Hand-built bodies (model.custom) - example: cars/zastava-101/
When there is no mesh but there is a blueprint, build the body in code (which cannot do crisp creases, leaning noses or clean window openings):
- Measure: crop + upscale each blueprint view with a pixel grid, find the scale from the wheelbase (hub centres),
and write every curve into
<car>/blueprint.ts(centreline silhouette, pillar / rail edges, crease, plan half width, arches, windows, seams). Use the dimensioned numbers where the drawing gives them. <car>/body.tsbuilds the mesh withcars/shared/mesh-kit.ts(Soup:grid,polygonwith holes,sweep, creased normals): body-side columns at stations (dense round arches + corners, rows on circles round the arch so the lip is crisp), top rows from nose to tail ending on the side / pillar edges, a polygon for the cabin sides with the window openings, nose / tail panels; then glass, rubbers, lamps, bumpers, cabin. It returns{ paint, parts }(CarCustomBody.build):paintgets the atlas texture,partsis the usualCarPartGeometry(trim, mesh, glass, lights, tail, amber, interior, cage = bright metal, lining, optionalchrome= polished reflectors / bezels andlens= clear lamp glass). Lamps: build them as geometry on a local plane (cars/zastava-101/lamps.ts: frames, reflector dishes, ribbed lens slabs), not flat boxes.<car>/paint.ts: atlas layout (atlasKit) + UV functions used bybody.ts+ the painter - plain projections (sides z-y, top z-x, ends x-y), so seams / dirt are drawn in model-space metres.- Check against the blueprint: copy it to
public/_tmp/(delete afterwards), overlay it as a fixed<img>(mix-blend-mode: multiply) on an orthographic car-viewer render -__carViewer.shell.camerafov ~2.6 from 60 m,near20, aspect set, panel hidden - scaled / placed from two projected model points. Side, top, front, rear. - Pin the key dimensions in a test (
tests/rally/zastava-body.test.ts); keep the car under ~35k triangles.
Importing a model? Start in .claude/skills/rally-car-import/SKILL.md
That skill is the workflow (scan gate -> orient -> measure -> naked check -> parts -> materials -> livery -> verify -> docs);
the two sections below are the API reference it points at. Its step 1 (scan-mesh.py verdict) decides whether a model is
imported at all - a blob verdict (image-to-3D) means the model is abandoned, not hand-cut.
Imported models (glTF / GLB, e.g. Sketchfab)
A real model replaces the car's custom / profile body when its file exists; that body is the fallback.
- Licence gate first (
.claude/skills/rally-car-import/SKILL.md): the model must allow redistribution of derivatives (CC0 / CC BY; no ND, no "personal use" / Standard Digital File licences). Then download it as glTF/GLB (Sketchfab: needs your login; CC BY needs credit). - Inspect / slim it (big models hurt: aim < 60k triangles, textures ≤ 2k, webp):
npx @gltf-transform/cli inspect model.glb npx @gltf-transform/cli optimize model.glb public/models/cars/<file>.glb --texture-compress webp --texture-size 2048 --simplify-ratio 0.25 - Reference it in the car:
model.gltf = { file, credit, rotationY?, scale?, offset?, hideNodes? }(cars/shared/types.tsCarGltfDef) and bake itsmodel.profile(above). Auto-fit: scaled to physicslength, centred between the axles, ground = lowest mesh (tyres). Node names matchinghideNodes(default wheel|tire|tyre|rim|brake|caliper|disc) are hidden - physics-driven procedural wheels are used. - The file list is baked in at startup (
rsbuild.config.ts->__CAR_MODEL_FILES__); the dev server restarts by itself when a file is added / removed inpublic/models/cars/(dev.watchFiles). Production builds list what exists at build time. If the car viewer still saysprocedural, reload the page. Commit the GLB plain: the build serves it meshopt-compressed (scripts/car-model/glb-meshopt.mjs, dev server too; already-compressed files pass through). - Car viewer "model" row must say
imported glTF; fix orientation withrotationY(front must be +Z), position withoffset. Add a row topublic/models/CREDITS.md. Files are served page-relative (<base>/models/cars/…), so subfolder hosting works.
STL bodies (untextured meshes, e.g. 3D-print / generated models) - example: cars/bimmer-m3/
The end-to-end order of work + every gotcha hit so far is in .claude/skills/rally-car-import/SKILL.md; the steps
below are the tool reference.
- Put the settings in the car folder:
model.source.json(axes, scale, offset, wheel cut-outs, target triangles, atlas layout). Measure first: render the STL (or run the converter once) and read off the wheel centres / radius - scale so the wheel radius matches physicswheelRadius;offsetputs the front axle on physicsfront.z. - Convert (the original STL lives in
sources/cars/<car>/): If the STL is exported tilted (print-bed orientation), level it first withscripts/car-model/orient-tilted-stl.py(PCA + pitch / roll; check left / right symmetry and hub heights).
It welds, re-orients to model space, cuts the wheels out (cylinders atnode scripts/car-model/stl-to-glb.mjs src/games/rally/cars/<car>/model.source.json sources/cars/<car>/<model>.stl --preview atlas.pngwheels.centres- procedural physics wheels replace them; that centre-based cut leaves saw teeth on big arch-lip triangles when a modelled tyre sits 1 cm from the lip - then label the wheel with aregioncircle insegment-stl.pyand list its material inparts.drop: an exact clip, worked examplecars/bimmer-m3/; give the regionany: trueso it also cuts triangles an earlier segment pick labelled, andparts.fills(converter) adds flat patches (e.g. glass continued under wipers:[{material, poly:[[x,y,z],...]}]);wheels.linerfloorYto close the well's inner wall for a view from below; the liner takes the atlas' matte texel, so the car's atlas needsmatteRect+ a black patch there), simplifies (meshoptimizer, ~45k tris) and writes creased normals + projection UVs: each triangle goes to the left / right / top / front / rear chart by its facing, charts laid out in metres (+ abottomchart like the top one when the atlas has room for it - otherwise one underside texel). - Livery =
<car>/livery.tsexporting aCarAtlas(model.gltf.atlas, withautoFit: false): a canvas painter that draws in model-space metres (side(z, y)on both sides,top(z, x),end('front'|'rear', x, y), multi-contour shapes, per-side'left' | 'right'). Use the--previewimage (10 cm grid) to find window / light / vent positions. Shapes and plain boxes only - never text (the painter has no text helpers; number + rally name are the door-plate decal), no real brand logos. Build the livery up step by step with the user from a clean base colour - automatic photo tracing was tried on the GR Yaris and rejected (rally-car-import, "Livery"). Chart overrides:atlas.chartBoxes(stl-to-glb.mjs, boxes in model space, x mirrored):chart: 'top'sends up-facing triangles (normal y >minNy, default 0) to the top chart (crease walls inside a painted bonnet shape, a roof edge wall);chart: 'side'sends front / rear-facing ones - plus, withmaxNy/minNy, steep or horizontal ones - to their own side chart (arch flares that share end-chart texels, shoulders next to a painted edge, sill ledges);chart: 'rear'/'front'sends up-facing ones to the end chart (a low bumper lip among colour rows). Example + reasons:atlas.chartBoxes$comments incars/bimmer-m3/model.source.json(summary: DETAILS.md "Livery chart boxes"); how to find the faces:rally-livery. - Wheel arches:
wheels.arch(faceRadius,radius,maxNormalX,minAbsX) sends arch triangles to the atlas' matte texel; livery painters callatlasKit(...).matteRect(black fill) and export it asCarAtlas.matteRect.wheels.lineradds a dark wheel-well cup if the arch is see-through (lip: truealso seals the slit between the cup rim and a cut edge further out; the rings are raycast to stay behind the skin).model.suspension: truedraws uprights + wishbones + damper behind the wheels. - Accent parts (glass, lamps, grille, vents, wing, trim): never paint them on the atlas - projection charts
overlap (a wing over the rear window) and triangle-by-triangle colouring gives saw-tooth edges. Split them off
as real parts instead (example:
cars/bimmer-m3/,partsblock of itsmodel.source.json):python scripts/car-model/segment-stl.py <model.source.json> <in.stl> <parts.stl> --preview seg --by segment node scripts/car-model/stl-to-glb.mjs <model.source.json> <parts.stl> python scripts/car-model/view-glb.py <model.source.json> checksegment-stl.pysplits the mesh into smooth patches along its creases andparts.picksassign patches to materials:seeds=[view, a, b](the patch seen at those model coordinates; read them off the--by segmentpreview,--grid 0.02 --scale 2600 --crop ...for thin strips) and / orinsideboxes. Usemirror: falsewith per-side seeds where the two sides are creased differently;hubpicks (per triangle: surfaces inside a wheel arch that face the hub) make arch lips black without relying on creases. The converter writes one primitive per material name;cars/shared/part-materials.tsmaps names to shared materials (trim, gloss, mesh, carbon, glass, headlight, lens, tail, reflector) - add new names there.parts.wrapmaterials get UVs fitted to 0..1 over the part (cornerfor lamps,sidefor side windows), so their textures are drawn in part space. Crease segments need a clean mesh with real feature edges (CAD / print models). Image-to-3D blobs (the former GR Yaris, deleted) have none - the import gate rejects them.region(an outline polygon measured in a view; triangles crossing it are cut along it) andboxpicks exist insegment-stl.pyfor the rare soft feature on a CAD mesh. Measure outlines on crease-highlighted renders (dihedral angle > 14 deg = the mesh's recess rings) at 1200+ px/m, one section at a time, and check each in the car viewer close up before the next. - Check in the car viewer (
modelrow = imported glTF), add a CREDITS row.
Textures
Procedural canvas textures in engine/textures.ts (TextureId + entry in DEFS). Colour maps set color: true
(sRGB); multipliers/masks false. View at asset-debug.html?asset=tex:<id>&repeat=4.
To replace with real images later, return a loaded texture for the same id.
Done checklist
npx tsc --noEmit -p tsconfig.json, npm run lint, npm run test + npm run test:integration:rally (stage test catches colliders on the road),
check F3 stats in game (__rally.benchmark(240) in the console). Open game URLs with mute=1 (AGENTS.md "Sound while testing").
Source files
Files / links the user provides (models, reference photos, data downloads) go to sources/ (git-ignored) and are
listed in the car / map folder DETAILS.md - follow .claude/skills/source-files/SKILL.md. Models / references
a player should see credited also go in CarDef.sources (label / url / note) - listed on the main menu About screen.
Tyres, rims and coil-overs
Every tyre comes from cars/shared/tyre-mesh.ts (size from CarPhysicsDef.tyres, tread per compound, compound ring); a car only
supplies its rim (model.wheelModel GLB rim - rescaled per tyre size - or model.wheels for a custom rim + caliper) and flags
(tyreDust). Coil-overs / struts for the setup screen: cars/shared/suspension-mesh.ts, pick model.suspensionStyle
(rally / road / race). Verify in the car viewer (?tyre=tarmac|mixed|gravel) and on the setup screen (parts bench).
From the file to a first result
The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.
View the source and supporting filesThis download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.
1. Download the file
Download SKILL.mdFrom the root of a test project, save the file as .skill-downloads/gravel-rally-assets-cars-textures-mvda86ym/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.
Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.
mkdir -p '.skill-downloads/gravel-rally-assets-cars-textures-mvda86ym' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/gravel-rally-assets-cars-textures-mvda86ym/download' --output '.skill-downloads/gravel-rally-assets-cars-textures-mvda86ym/SKILL.md.part' && mv '.skill-downloads/gravel-rally-assets-cars-textures-mvda86ym/SKILL.md.part' '.skill-downloads/gravel-rally-assets-cars-textures-mvda86ym/SKILL.md'2. Check prerequisites
Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.
No recognized prerequisites section in this file. This does not mean it is self-contained: libraries, tools and access requirements may be mentioned elsewhere in the content or source repository.
The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.
3. Load the skill
After inspection, copy the complete folder into your project using one of the commands below, then open a new tool session. The command stops if a folder with the same name already exists: compare the files before replacing it.
Claude Code
test -f '.skill-downloads/gravel-rally-assets-cars-textures-mvda86ym/SKILL.md' && test -s '.skill-downloads/gravel-rally-assets-cars-textures-mvda86ym/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/rally-content' && cp -R '.skill-downloads/gravel-rally-assets-cars-textures-mvda86ym' '.claude/skills/rally-content'OpenSkills
OpenSkills must already be installed. The local install/read procedure is checked with OpenSkills 1.5.0, which requires Node.js ≥ 20.6.0. Catalog slugs are not resolved automatically.
Official OpenSkills installationopenskills install './.skill-downloads/gravel-rally-assets-cars-textures-mvda86ym'openskills read 'gravel-rally-assets-cars-textures-mvda86ym'Reading should display the installed file content and its base directory. It does not run the skill or install its dependencies.
For an agent that reads AGENTS.md, then sync the index. This command changes AGENTS.md: review the diff before using it.
openskills syncManual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.
4. Try a first task
Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:
Read .skill-downloads/gravel-rally-assets-cars-textures-mvda86ym/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.
React Hook Form Best Practices
Development
Master React Hook Form: avoid anti-patterns, manage subscriptions, and handle reset, dirty state, and controlled inputs correctly.
Emotion to Mantine Migration
Development
Migrate Emotion styled-components to Mantine components with style props and CSS modules. Use when converting .styled.tsx files or removing @emotion imports.
Scope Creep Detector
Development
Analyzes git diffs against a stated intent to detect scope creep, unrelated files, broad PRs, and oversized changes, then suggests keep, split, or justify actions.