| name | bepy-project-setup-roblox |
| description | Triggers on /bepy-project-setup-roblox only. Scaffolds a new Roblox/Luau project from the sirbepy_roblox/templates/default/ skeleton, or fills missing files in an existing one. Idempotent - never clobbers without asking. Verifies with aftman install + wally install + rojo build. |
/bepy-project-setup-roblox
Roblox-flavored counterpart to /bepy-project-setup-web.
Source of truth for the template: ../sirbepy_roblox/templates/default/.
Tool pins are read live from ../sirbepy_roblox/aftman.toml.
sirbepy_* wally pins are read live from ../sirbepy_roblox/packages/<pkg>/wally.toml.
Flags
auto - Skip all prompts. Use safe defaults: project name = current folder name (Title Case), no clobber on conflicts (skip and report).
Step 0 - Locate sibling sirbepy_roblox
The template lives in a sibling clone. The skill cannot run without it.
- Resolve the project root (current working directory).
- Check for
../sirbepy_roblox/templates/default/.
- If missing:
- With
auto flag: abort with a clear error.
- Without
auto flag: AskUserQuestion - "Sibling ../sirbepy_roblox/ is missing. Clone it now?" Options: "Clone it" / "Abort". On clone, run git clone https://github.com/SirBepy/sirbepy_roblox.git ../sirbepy_roblox. After clone, re-check for the templates folder; if still missing the clone is on the wrong branch and the skill must abort.
Step 1 - Git init
Run /git-init if not already a git repo.
Step 2 - Detect project metadata
Resolve the three placeholder values. In order:
{{PROJECT_NAME}} - human display name.
- If a
wally.toml exists at the project root, parse the name = "sirbepy/<slug>" line, slug -> Title Case as a default suggestion.
- Else default to the basename of the current folder converted to Title Case (
tycoon_or_die -> Tycoon Or Die).
- With
auto flag: use the default. Otherwise AskUserQuestion to confirm.
{{PROJECT_SLUG}} - kebab-case slug.
- Derive from
{{PROJECT_NAME}}: lowercase, spaces -> -, strip non-alphanumeric.
- Confirm with AskUserQuestion (skipped with
auto).
{{PROJECT_NAME_NOSPACES}} - PascalCase no-spaces.
- Derive from
{{PROJECT_NAME}}: strip spaces, capitalize each word boundary.
- Confirm with AskUserQuestion (skipped with
auto).
Step 3 - Copy template tree (idempotent fill, never clobber)
Walk ../sirbepy_roblox/templates/default/ recursively. For each file:
- Compute the substituted contents: read the template file, replace
{{PROJECT_NAME}} / {{PROJECT_SLUG}} / {{PROJECT_NAME_NOSPACES}} everywhere.
- Compute the destination path. Note: filenames in the template do not currently use placeholders, but if a future template introduces them, substitute in the path too.
- Skip TEMPLATE.md - it is documentation for the template itself, not a project artifact.
- If the destination does not exist -> write it.
- If the destination exists and contents match -> skip silently.
- If the destination exists and contents differ:
- With
auto flag: skip and print one line to chat output: "skipped during bepy-project-setup-roblox: differs from template". Collect all such lines into the final run summary.
- Without
auto: print a unified diff (or a short summary if large), then AskUserQuestion: "Overwrite", "Keep existing", "Show full diff". Keep existing is the default-safe choice.
Always preserve the existing destination's encoding and line endings if you have to merge.
.gitkeep files: write only if the directory is missing or empty.
Step 4 - Write aftman.toml from live sibling pins
aftman.toml is NOT in the template. Generate it fresh:
- Read
../sirbepy_roblox/aftman.toml.
- Copy the entire
[tools] block verbatim.
- Add a header comment:
# Auto-generated by /bepy-project-setup-roblox from ../sirbepy_roblox/aftman.toml.
- Write to
aftman.toml at the project root using the same idempotent fill rules as Step 3 (skip if matches, prompt on diff).
If the sibling has luau-lsp and the project does not, this is where the new project picks it up automatically.
Step 5 - Auto-pin sirbepy_* wally deps
wally.toml in the template ships with sirbepy_* deps commented out. Replace the comment block with concrete pins:
- Glob
../sirbepy_roblox/packages/*/wally.toml.
- For each one, parse
version = "X.Y.Z" and name = "sirbepy/<slug>".
- Map each package's slug to the PascalCase dep alias the rojo project expects:
core -> Core
highlight-manager -> HighlightManager
ui-framework -> UIFramework
ui-components -> UIComponents
- any others present in the sibling -> derive PascalCase from kebab-case automatically
- Build a
[dependencies] block:
[dependencies]
Fusion = "elttob/fusion@0.3.0"
Core = "sirbepy/core@^X.Y.Z"
HighlightManager = "sirbepy/highlight-manager@^A.B.C"
UIFramework = "sirbepy/ui-framework@^M.N.O"
UIComponents = "sirbepy/ui-components@^P.Q.R"
- With
auto flag: include all sibling packages. Without: AskUserQuestion multiSelect to let the dev pick which to include (default-checked: Fusion, UIFramework, UIComponents - the common UI set).
- Merge into the existing
wally.toml (replace any pre-existing [dependencies] block content, keep [package] and [place] blocks intact). If wally.toml already has a non-default [dependencies] block, prompt before overwriting.
Step 6 - Smoke verify
Run, in order. Stop on first failure.
aftman install - hydrates the toolchain. Required because the freshly-written aftman.toml may include tools the user does not have yet.
bash scripts/wally-install.sh - installs runtime + test wally deps.
rojo build default.project.json -o build/smoke.rbxlx - confirms the project compiles.
If any step fails, print the failing stage's stderr and stop. Do NOT proceed to commit.
Step 7 - Check for /jest-lua skill
Verify ~/.claude/skills/jest-lua/ exists. If missing, print:
WARN: /jest-lua skill is not installed. You will need it to write tests in this project.
Do not abort.
Step 8 - Commit
If anything was written or modified, run /commit with the message:
MAJOR: bepy roblox project setup
If everything was already in place (zero writes), skip the commit step and print "Nothing to commit - project already aligned with template."
Step 9 - Summary
Print a summary of what ran. For each template file: created, already up to date, kept existing (differed), or overwritten. Also report the auto-pinned wally deps, the smoke verify result, and any warnings.
Example output:
Done. Here is what ran:
template files:
default.project.json - created
test.project.json - created
wally.toml - kept existing (differed)
CLAUDE.md - created
scripts/check.sh - already up to date
... (etc)
aftman.toml - created (5 tools pinned from sirbepy_roblox)
wally deps auto-pinned - Fusion, Core@^0.3.3, UIFramework@^0.1.0, UIComponents@^0.1.0
smoke verify - OK
/jest-lua skill - present
Don't forget to review the diff before committing.
Notes
- This skill is for Roblox/Luau projects only. The web counterpart is
/bepy-project-setup-web.
- No dispatcher. The dev invokes the right one for the project type.
- Idempotent: safe to re-run on an existing project to refresh template-aligned files.
- Source of truth is
../sirbepy_roblox/templates/default/. To improve the scaffold for everyone, edit the template there and commit.