{"id":51845693,"url":"https://github.com/flying-dice/luabox","last_synced_at":"2026-07-23T12:01:31.598Z","repository":{"id":371392763,"uuid":"1300691389","full_name":"flying-dice/luabox","owner":"flying-dice","description":"A cargo-style toolchain for Lua: type checker (stock LuaCATS, verified), linter, formatter, bundler, and LSP. Works with Lua 5.1–5.4 and LuaJIT. Not a runtime.","archived":false,"fork":false,"pushed_at":"2026-07-14T20:01:41.000Z","size":3410,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-14T21:04:09.404Z","etag":null,"topics":["cli","language-server","lsp","lua","luacats","rust","type-checker"],"latest_commit_sha":null,"homepage":"https://github.com/flying-dice/luabox","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flying-dice.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-14T16:01:30.000Z","updated_at":"2026-07-14T20:41:34.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/flying-dice/luabox","commit_stats":null,"previous_names":["flying-dice/luabox"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/flying-dice/luabox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flying-dice%2Fluabox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flying-dice%2Fluabox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flying-dice%2Fluabox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flying-dice%2Fluabox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flying-dice","download_url":"https://codeload.github.com/flying-dice/luabox/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flying-dice%2Fluabox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35801473,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-23T02:00:06.683Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","language-server","lsp","lua","luacats","rust","type-checker"],"created_at":"2026-07-23T12:01:30.643Z","updated_at":"2026-07-23T12:01:31.590Z","avatar_url":"https://github.com/flying-dice.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# luabox\n\n**A cargo-style toolchain for Lua.** One static binary that gives Lua the\nworkflow Rust developers expect — `check`, `lint`, `fmt`, `run`,\n`build`, `doc` — with a type checker that speaks stock\n[LuaCATS](https://luals.github.io/wiki/annotations/) annotations (the\nlua-language-server dialect) but *verifies* what luals only trusts:\n`---@class` conformance, `---@generic` generics, and types shared across\nmodules and packages. Works with Lua 5.1–5.4 and LuaJIT. It **acquires** Lua\nruntimes — nvm/rustup for Lua: `luabox toolchain` installs and pins\ninterpreters (and a matching luarocks) that `run` spawns. It is never a runtime\nitself. **Not a runtime.**\n\n## Quickstart\n\nInstall the binary (see [Install](#install) below), then:\n\n```sh\nluabox new hello\ncd hello\n```\n\n`luabox new` scaffolds a project — a `luabox.toml` manifest, a `.gitignore`,\nand `src/main.lua`:\n\n```\nCreated binary project `hello` (edition 5.4)\n```\n\nWrite an annotated function in `src/main.lua`. The `---@param` / `---@return`\ncomments are ordinary LuaCATS — the same annotations lua-language-server reads:\n\n```lua\n---@param name string\n---@return string\nlocal function greet(name)\n    return \"Hello, \" .. name .. \"!\"\nend\n\nprint(greet(\"world\"))\nprint(greet(42))\n```\n\nTypecheck it. luabox catches the `42` — a plain Lua editor would not:\n\n```\n$ luabox check\nerror[LB0300]: type mismatch: expected `string`, found `42`\n  --\u003e src/main.lua:8:13\n  |\n8 | print(greet(42))\n  |             ^^ expected `string`\n\ncheck: 1 errors, 0 warnings in 1 files\n```\n\nFix line 8 to `print(greet(\"luabox\"))` and it passes:\n\n```\n$ luabox check\ncheck: 0 errors, 0 warnings in 1 files\n```\n\nRun it, format it, lint it:\n\n```\n$ luabox run src/main.lua\nHello, world!\nHello, luabox!\n\n$ luabox fmt\nformatted 1 files (0 changed)\n\n$ luabox lint\nlint: 0 errors, 0 warnings in 1 files\n```\n\nThat is the whole loop — one binary for check, run, format, and lint, no build\nconfig. `run` executes on the runtime the project pins via `luabox toolchain`,\nfalling back to a Lua on `PATH`. When a toolchain is pinned, `run` also resolves\nbare executables — `lua`, `luarocks` — from the toolchain first, so\n`luabox run luarocks -- install \u003crock\u003e` reaches the toolchain's own luarocks\n(the `node_modules/.bin`-first model). See [`examples/`](examples/) for larger,\nreal projects —\na LÖVE game, a multi-package workspace, and a 5.4-to-5.1 cross-version lowering\ndemo.\n\n## Install\n\nPrebuilt binaries are attached to every tagged\n[GitHub release](https://github.com/flying-dice/luabox/releases) (`v*`, built\nby [`.github/workflows/release.yml`](.github/workflows/release.yml) — see\n[RELEASING.md](RELEASING.md)). The one-line installers fetch the latest one:\n\n```sh\n# Linux / macOS\ncurl -fsSL https://raw.githubusercontent.com/flying-dice/luabox/main/scripts/install.sh | bash\n```\n\n```powershell\n# Windows\nirm https://raw.githubusercontent.com/flying-dice/luabox/main/scripts/install.ps1 | iex\n```\n\nEach release ships prebuilt binaries for **Linux x86_64**, **macOS Apple\nSilicon**, and **Windows x86_64**, with `SHA256SUMS` alongside them. Already\ninstalled? `luabox upgrade` self-updates from the latest release.\n\nTo build from source instead — or to track the tip of `main`:\n\n```sh\ncargo install --git https://github.com/flying-dice/luabox luabox-cli\n# or, from a checkout:\ncargo build --release            # target/release/luabox\n```\n\n## Why luabox\n\nLua's ecosystem already has rich type annotations — LuaCATS, as read by\nlua-language-server. luabox's edge is that it treats those annotations as\n**claims to be verified**, not hints to be trusted, on the exact same format:\n\n- **`---@class` conformance.** A `---@class Dog : Animal` must actually provide\n  `Animal`'s fields and methods with compatible signatures — missing members\n  are errors, not silent gaps.\n- **Real generics.** `---@generic T` functions and generic classes are\n  monomorphized: `id(42)` returns `integer`, and flowing that into a `string`\n  slot is caught.\n- **Cross-module and cross-package types.** A `---@class` declared in one file\n  is checked at every use site across the workspace; a dependency's types\n  (shared via `[types] defs`) are visible and checked in the consumer.\n- **Undefined globals and fields.** Typo'd globals and unknown fields on\n  declared classes are flagged.\n\nAll on stock LuaCATS — there is no second, luabox-specific type file format.\nSee [DIRECTION.md](DIRECTION.md) for the governing decision record and\n[SPEC.md](SPEC.md) for the full design.\n\n## Editor setup\n\nEditor integrations live in their own repos and release independently:\n\n| Editor | Repo | Install |\n|---|---|---|\n| VS Code | [flying-dice/luabox-vscode](https://github.com/flying-dice/luabox-vscode) | `.vsix` from that repo's releases → `code --install-extension` |\n| JetBrains | [flying-dice/luabox-jetbrains](https://github.com/flying-dice/luabox-jetbrains) | plugin `.zip` from that repo's releases → install from disk |\n\nBoth wrap the `luabox lsp` stdio language server (diagnostics with\nquick-fixes, completion with auto-require imports, hover, goto\ndefinition/type-definition/implementation, find-references, rename, document\n\u0026 workspace symbols, signature help, call hierarchy, inlay hints, semantic\ntokens, formatting, folding and selection ranges; `.lua` files), resolving\nthe `luabox` binary from `PATH` (overridable in settings). Neither is on its\nmarketplace yet\n([#102](LIMITATIONS.md#editor-extensions-are-not-on-marketplaces-yet-102)).\nAny other editor can point its LSP client at `luabox lsp`.\n\n## Limitations\n\nluabox 0.1 is alpha software — there is no hosted package registry, and the\neditor extensions are not yet on their marketplaces (each ships installable\nartifacts from its own repo's releases). The full LuaCATS tag vocabulary is\nenforced.\nEvery remaining gap is\ndocumented honestly in\n[**LIMITATIONS.md**](LIMITATIONS.md). Read it before you rely on luabox for\nanything load-bearing.\n\n---\n\n## Commands\n\n| | |\n|---|---|\n| `init` / `new` | scaffold a project (`--lib`, `--edition 5.1..5.4\\|luajit`) |\n| `check` | typecheck: LuaCATS + rich inference, dialect legality, `--target`, `--watch`, `--format json\\|sarif\\|github\\|gitlab` |\n| `fmt` | canonical formatter for `.lua` (`--check`, `--watch`) |\n| `lint` | type-informed rules, `---@luabox-ignore`, per-rule `[lint]` levels |\n| `build` | one tsc/esbuild-style emit driven by `[build]`: lower `edition → target` (goto, bitops, `\u003cclose\u003e`, `_ENV`, …) with tree-shaken polyfills; `bundle = true` inlines the require graph into one file per `entry` (`--minify`, `--sourcemap`); `mode = love\\|nvim-plugin` packages a `.love` / Neovim plugin. Flags (`--target`/`--out`/`--outfile`/`--entry`/`--bundle`/`--no-bundle`/`--sourcemap`/`--minify`/`--mode`) override config |\n| `unmap` | decode a production traceback back to source lines via the `\u003cbundle\u003e.map` that `build --sourcemap` writes next to the bundle |\n| `add` / `remove` / `install` / `update` / `vendor` | PubGrub resolver, `luabox.lock`, CAS store with hard-link installs. `add \u003crock\u003e` / `remove \u003crock\u003e` edit the rockspec's `dependencies` (`--dev` → `test_dependencies`) comment-preservingly; `--path`/`--git` manage source deps in `luabox.toml`. `update \u003cname\u003e` re-pins a git dep to its repo's latest release tag |\n| `publish` | upload the authored rockspec to luarocks.org (`--dry-run` to preview). Gates on a valid canonically-named rockspec, a green `check`, and pure-Lua-only; needs an API key (`login --luarocks`) |\n| `search` / `outdated` | search luarocks.org (the registry) for rocks by name, and report dependencies behind their latest version (registry rocks vs. luarocks.org, git deps vs. their repo's latest GitHub release); `--format json\\|text` |\n| `login` / `logout` / `whoami` | sign in to GitHub via the browser (OAuth device flow), storing the token encrypted in the OS keychain; sign out; show the signed-in identity. Authenticates git-source operations (`outdated`/`update` release probing) — registry reads are anonymous. `login --luarocks` stores a luarocks.org API key for `publish`. `login`/`whoami` take `--format json\\|text` |\n| `run` | `[tasks]` entries or scripts via the pinned runtime. Bare executables (and `[tasks]` shells) resolve from the pinned toolchain's bin dirs — including its provisioned luarocks — before the system `$PATH` (npm-run/`node_modules/.bin` semantics); the `$PATH` fallback is kept with that purpose. `run luarocks -- install \u003crock\u003e` is the C-rock escape hatch |\n| `toolchain` | acquire managed Lua runtimes (nvm for Lua): install/pin/list. `install \u003cid\u003e` provisions a matching luarocks alongside the interpreter, wired to it and a project-local `lua_modules` tree |\n| `upgrade` | self-update from GitHub releases (`luabox upgrade` for latest, or a specific `v0.1.1`), checksum-verified |\n| `lsp` | language server: diagnostics + quick-fixes, completion (auto-require), hover, goto def/type/impl, references, rename, symbols, signature help, call hierarchy, inlay hints, semantic tokens, formatting |\n| `doc` | static docs from annotations |\n| `explain LBnnnn` | rustc-style diagnostic pages |\n\n### Shipping a bundle: crash-to-source with `unmap`\n\nA minified bundle's tracebacks name the *bundle's* lines, not your source.\nEnable source maps at build time and keep the `.map` around to decode\nproduction crashes back to their real file and line:\n\n```toml\n[build]\nbundle    = true\noutfile   = \"dist/game.lua\"\nminify    = true\nsourcemap = true          # writes dist/game.lua.map next to the bundle\n```\n\n```sh\nluabox build              # emits dist/game.lua + dist/game.lua.map\n# ship dist/game.lua to players; keep dist/game.lua.map in your build artifacts\n```\n\nWhen a player pastes a traceback like `dist/game.lua:842: attempt to index a\nnil value`, pipe it back through `unmap` (map is read from `\u003cbundle\u003e.map` next\nto the bundle):\n\n```sh\necho 'dist/game.lua:842: attempt to index a nil value' | luabox unmap dist/game.lua\n# → src/player.lua:10: attempt to index a nil value\n```\n\nThe traceback can come from stdin (above) or as trailing arguments. The map is\nrecorded only at build time, so `sourcemap = true` is what makes this possible\n— there is no way to reconstruct it after the fact.\n\n## Dependencies \u0026 registries\n\nluabox follows the pnpm/bun model:\n[**luarocks.org is the registry**](https://luarocks.org), and the\n**rockspec is the package manifest**\n([flying-dice/luabox#2](https://github.com/flying-dice/luabox/issues/2)).\n\n- Your project's `*.rockspec` owns its **name**, **version**, and **registry\n  dependencies** — its `dependencies` (and `test_dependencies`) are bare rock\n  names in LuaRocks constraint syntax (`\"lpeg \u003e= 1.0\"`), resolved against\n  luarocks.org. `luabox init`/`new` scaffold one for you.\n- `luabox.toml` is **tool configuration** (edition, build, types, tasks) plus\n  the **source** dependencies a rockspec cannot express — `path`, `git`\n  (`rev`/`tag`/`branch`), and `workspace` entries. A version-requirement entry\n  in `luabox.toml` is an error that points you at the rockspec.\n\n```toml\n# hello-0.1.0-1.rockspec — the package manifest\npackage = \"hello\"\nversion = \"0.1.0-1\"\ndependencies = { \"lua \u003e= 5.4\", \"lpeg \u003e= 1.0\" }   # resolved from luarocks.org\n```\n\n```toml\n# luabox.toml — tool config + git/path sources\n[package]\nedition = \"5.4\"\n\n[dependencies]\nmylib = { path = \"../mylib\" }                     # a path source dependency\ngitlib = { git = \"https://github.com/owner/gitlib\", tag = \"v1.2.0\" }\ntarball = { url = \"https://example.com/pkg.tar.gz\", sha256 = \"…\" }  # bun-style, pinned by digest\n```\n\nThe `url` source is a bun-style http(s) (or `file://`/local) tarball pinned by\nits SHA-256: the digest is captured once at `luabox add --url` time and verified\nbefore extraction on every install after, so a corrupt or tampered download\ninstalls nothing.\n\n`luabox install`/`update` resolve the merged graph (rockspec registry deps +\nluabox.toml source deps) with the PubGrub solver, write `luabox.lock`, and\nhard-link packages into `lua_modules/`. C-module rocks are out of scope and\nrejected with a clear error — luabox is not a C build system. There is no\nfirst-party registry, and `LUABOX_REGISTRY` is gone; set\n`LUABOX_LUAROCKS_MIRROR` to a local mirror directory for hermetic/offline\nresolves.\n\n**Dialect compatibility.** Every dependency has a **family set** of the Lua\ndialects it supports — never a range (a range implies an order LuaJIT breaks: it\nis 5.1-plus-extensions, not a point between 5.1 and 5.2). A registry rock's set\nis translated from its rockspec `lua` constraint (`lua \u003e= 5.1, \u003c 5.4` →\n`{5.1, 5.2, 5.3}`, plus `luajit` whenever 5.1 is admitted); a path/git package's\nset is its `luabox.toml` `[package] lua-versions`; an absent set means all\ndialects. A dependency is accepted for your **`[build] target`** (default\n`edition`) when the target is in its set, **or** its own edition is *lowerable*\nto the target — luabox lowers dependency sources alongside yours at build. When\nneither holds, resolution fails with the `explain`-able\n[`LB1003`](https://github.com/flying-dice/luabox/issues/5) (`luabox explain\nLB1003`). Luau is fenced off: it has no lowering path to a PUC target.\n\n### Discovering \u0026 managing dependencies\n\n**luarocks.org is the discovery surface** for registry dependencies. `luabox\nsearch` reads luarocks.org's root manifest and matches your query as a\ncase-insensitive substring of rock names — an anonymous registry read, no\nGitHub, no token. Git dependencies remain a public GitHub repo pinned to a\nrelease tag.\n\n```sh\nluabox search penlight      # rocks on luarocks.org whose name contains \"penlight\"\nluabox search               # the first 50 rocks by name (the registry is large)\nluabox add penlight         # add the latest penlight to the rockspec + install\nluabox add penlight@1.14    # a lower bound: writes \"penlight \u003e= 1.14\"\nluabox add busted --dev     # a test-only dep → the rockspec's test_dependencies\nluabox remove penlight      # delete the entry from the rockspec + re-sync\nluabox add cool-lib --git https://github.com/owner/cool-lib --tag v1.2.0\nluabox add tarball --url https://example.com/pkg.tar.gz  # captures \u0026 pins its sha256\nluabox outdated             # which deps are behind their latest version?\nluabox update cool-lib      # re-pin cool-lib to its repo's latest release tag\n```\n\n`luabox add \u003crock\u003e` edits your **rockspec** the way `pnpm add` edits\n`package.json`: it resolves the rock on luarocks.org, splices one entry into the\n`dependencies` table (or `test_dependencies` with `--dev`), and re-installs.\nThe edit is surgical — indentation, quote style, comments, and the `lua \u003e= X.Y`\npin are all preserved, and only the touched line changes:\n\n```diff\n dependencies = {\n    \"lua \u003e= 5.4\",\n+   \"penlight \u003e= 1.14.0\",\n }\n```\n\nAn explicit `add penlight@1.14` writes `\u003e= 1.14` (`@=1.14` for an exact `== 1.14`);\na bare `add penlight` looks up and pins `\u003e= \u003clatest\u003e`. `remove \u003crock\u003e` deletes\nexactly that entry. A `--path`/`--git` add still edits `luabox.toml`, since those\nsource dependencies a rockspec cannot express.\n\n`search` and `outdated` take `--format json|text` (`text` is the default;\neditors pass `json` for a stable contract — `{\"results\":[…]}` and\n`{\"dependencies\":[…]}` respectively). `search` reports each rock's highest\ntranslated semver and its version count. `outdated` compares each **registry**\nrock's locked version against luarocks.org's highest, and each **git** dep's tag\nagainst its GitHub repo's latest release; it always exits 0 (a report, not a\ngate). `update \u003cname\u003e` re-pins a **tag**-pinned git dependency to the latest\nrelease tag of its GitHub repo; a `rev`/`branch` pin is left untouched, and\nregistry deps are re-resolved within their rockspec constraints.\n\nSet `LUABOX_LUAROCKS_MIRROR` to a local mirror directory to run `search` (and\nresolution) offline/hermetically. The git-source paths (`outdated`'s release\nprobing, `update`'s re-pin) honor a GitHub token (see **Authentication**),\nsent as `Authorization: Bearer …`, which raises the anonymous 60 req/hr limit to\n5000/hr; they work without one, just against the lower anonymous limit.\n\n### Authentication\n\nSign in to GitHub through the browser — no Personal Access Token to paste:\n\n```sh\nluabox login        # opens the browser, prints a device code, stores a token\nluabox whoami       # -\u003e your GitHub login (and where the token came from)\nluabox logout       # removes the stored GitHub token (and any luarocks.org API key)\n```\n\n`luabox login` runs the OAuth 2.0 **device flow**: it shows a short `user_code`\nand a verification URL (and best-effort opens your browser), you approve there,\nand the resulting token is stored **encrypted at rest in your OS keychain**\n(macOS Keychain, Windows Credential Manager, Linux Secret Service). No scope is\nrequested — an unscoped token already lifts the rate limit (least privilege).\nluabox's git-source operations — `luabox outdated`'s release probing and `luabox\nupdate`'s re-pin — then use it automatically. (`luabox search` is an anonymous\nluarocks.org read and never consults it.)\n\n`login` and `whoami` accept `--format json` (newline-delimited events for\n`login`; one object for `whoami`) — that is what the editor extensions'\n\"Sign in with GitHub\" buttons drive.\n\nToken precedence for every GitHub request is:\n\n```\nLUABOX_GITHUB_TOKEN  →  GITHUB_TOKEN  →  keychain (from `luabox login`)  →  anonymous\n```\n\nEnvironment variables win over the keychain, so CI and one-off overrides are\nalways honored. On a headless box with no keychain (common in CI), `luabox\nlogin` can't store the token and tells you to set `LUABOX_GITHUB_TOKEN`\ninstead; nothing crashes.\n\n## Publishing\n\nluabox follows the pnpm/bun model: **[luarocks.org](https://luarocks.org) is\nthe registry**, and your **rockspec is the package manifest**. `luabox publish`\nis a thin proxy that uploads the rockspec you authored (`luabox init`/`new`\nscaffold one; `luabox add`/`remove` edit it) to luarocks.org *verbatim* — it\ncompiles and generates nothing.\n\n```sh\nluabox login --luarocks     # once: paste your luarocks.org API key (stored in the keychain)\nluabox publish --dry-run    # preview: prints the rockspec + upload target, no network\nluabox publish              # upload the authored rockspec to luarocks.org\n```\n\nGet an API key from \u003chttps://luarocks.org/settings/api-keys\u003e. `luabox login\n--luarocks` reads it from stdin and stores it **encrypted at rest in your OS\nkeychain**; `LUABOX_LUAROCKS_API_KEY` overrides it (CI/one-off). The key is\n**never** logged — it is redacted from every echoed command and error.\n\nBefore uploading, `publish` gates entirely offline: your project must have a\nsingle root `*.rockspec` that parses and carries `package`, `version`, and a\n`source.url`; its filename must be the canonical `\u003cpackage\u003e-\u003cversion\u003e.rockspec`;\n`luabox check` must be green; and the rock must be **pure-Lua** (`build.type =\nbuiltin`, no C sources — luabox is a toolchain, not a C build system). A\nduplicate version or a server-side validation error surfaces luarocks.org's own\nmessage. Point `publish` at a different server with `LUABOX_LUAROCKS_URL`.\n\nConsumers install your published rock with plain `luarocks install \u003cname\u003e` — no\nluabox required on their side.\n\n## Project layout (for contributors)\n\nCargo workspace, one crate per bounded context (SPEC.md §16):\n\n| Crate | Owns |\n|---|---|\n| `luabox-syntax` | lossless parser: Lua dialects + LuaCATS annotations |\n| `luabox-hir` | desugared IR, name resolution |\n| `luabox-types` | LuaCATS type IR, inference |\n| `luabox-db` | incremental query database |\n| `luabox-lower` | target lowering + polyfills |\n| `luabox-bundle` | require-graph, tree-shake, minify, sourcemaps |\n| `luabox-resolve` | PubGrub solver, luarocks.org bridge, rockspec + `luabox.toml` manifests |\n| `luabox-store` | content-addressed cache |\n| `luabox-lsp` | language server |\n| `luabox-cli` | the `luabox` binary |\n\n```sh\ncargo build\ncargo test --workspace          # unit + cucumber acceptance tests\ncargo fmt --all --check\ncargo clippy --workspace --all-targets\n```\n\nAcceptance tests are Gherkin feature files under\n`crates/luabox-cli/tests/features/` driving the real binary against temp-dir\nfixture projects — the executable spec (SPEC.md §16.2).\n\n## Status\n\n**0.1.0** — released 2026-07-14, the full command surface works end to end.\nAlpha quality: the executable spec drives the real binary through cucumber\nscenarios, perf gates block CI, and lowering is verified by differential\nexecution against real runtimes in CI. Prebuilt binaries are attached to each\n[GitHub release](https://github.com/flying-dice/luabox/releases); editor\nextensions release from their own repos;\nnot yet published to a package registry (crates.io, Homebrew, etc.). Luau is\nexplicitly out of scope. See [LIMITATIONS.md](LIMITATIONS.md) for known gaps.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflying-dice%2Fluabox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflying-dice%2Fluabox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflying-dice%2Fluabox/lists"}