--- name: roblox-agent-checks description: "Verify Roblox Luau code without opening Studio, the way an agent should before saying a change is done: one script (rbx_check.py) runs rojo build, rojo sourcemap, selene, stylua --check, luau-lsp analyze with the Roblox type definitions, and an optional Lune test, and prints one JSON report; plus the verification ladder (static checks, Lune unit tests, place-file assertions with @lune/roblox, engine tests on Roblox servers, a Studio playtest) and a GitHub Actions workflow for a Roblox repo. Use whenever the user asks to 'check my Roblox code', 'lint the Luau', 'type check with luau-lsp', 'does this build', 'set up CI for my Roblox game', 'run the tests', 'why does luau-lsp say Unknown global game', or after the agent edits Luau in a Rojo project, or says 'refresh roblox-agent-checks'. Engine tests through Open Cloud are roblox-agent-cloud; playtests in Studio are roblox-agent-studio." --- # Roblox checks without Studio Outcome: a change to Luau code is reported done only with a passing `rbx_check.py` report (or the failing checks named and fixed), and each claim in the reply points at a check that ran. ## Step 0: freshness (every use, one read) Read `evergreen.json` next to this file. If `contradiction` is set or today is on or after `next_due`, tell the user in one line, do the task with the current content, then refresh (`evergreen-refresh`) in the same session. If `tests.failing` is non-empty, say so in one line and run `evergreen-tune` after the task. ## Step 1: run the checks The project needs a `*.project.json` (Rojo layout) and the tools in its `rokit.toml` (roblox-agent-project sets that up). From any folder: ``` python /scripts/rbx_check.py --fetch-defs [--lune tests/run.luau] ``` - Prints one JSON object: `ok`, `sources` (the `$path` folders read from the project file), `tools` found, and per check `status` (pass, fail or skip), `exit`, `seconds`, `command` and `output_tail`. Exit 0 when nothing failed, 1 when a check failed, 2 when the folder is not a Rojo project. - `--fetch-defs` downloads luau-lsp's `globalTypes.d.luau` (about 0.9 MB) once into the user cache (`%LOCALAPPDATA%\roblox-agent` or `~/.cache/roblox-agent`). Without it the types check is skipped with the reason. Ask before the first download if the user has said network calls need approval. `--defs ` uses a copy the project already has; a `--defs` path that does not exist is a usage error (exit 2) from 0.1.2. - `--only types,lint` or `--skip format` narrow the run. Build output and the sourcemap go to a temporary folder, so the check writes nothing into the project. - It finds tools on PATH or in `~/.rokit/bin`, and runs them from the project folder, because Rokit's shims resolve only where a manifest lists them. Read the JSON, fix what failed, and run it again until `ok` is true. Quote the summary line (`pass`, `fail`, `skip` counts) in the reply. A skip is not a pass: say which checks were skipped and why. ## Step 2: what each check means | Check | Tool | Catches | Notes | |---|---|---|---| | build | `rojo build` | broken project file, bad `$path`, invalid property values | proves the files map to a place | | sourcemap | `rojo sourcemap` | the same, plus gives luau-lsp the DataModel paths | add `--include-non-scripts` by hand when code reaches parts by path | | lint | `selene` with `std = "roblox"` | unused variables, shadowing, deprecated globals, likely bugs | selene builds its Roblox std on first run; warnings exit non-zero | | format | `stylua --check` | style drift (prints a diff) | fix with `stylua `, then re-check | | types | `luau-lsp analyze --platform=roblox --defs=... --sourcemap=...` | type errors, unknown requires, wrong instance paths in `--!strict` files | without the definitions every Roblox global is "Unknown global"; plain `luau-analyze` has no Roblox globals at all | | lune | `lune run