Shasta is a browser that runs in a browser tab. Its Store is a catalog of HTML5 games and web apps that people install with one click; each one runs sandboxed on its own origin.
shasta is the Store's command line, and it is the main way to publish. It checks a game the way the Store will, runs it locally in the Store's exact sandbox, and publishes it in one command. Plain text, --json on every command, and exit codes, so a script or an AI agent can drive it too. The web dashboard is still there for everyday management.
This tool is open source; Shasta itself is not. Anyone can use the tool to build and check a package. Publishing is by application: the Store is curated. The Store owner answers every application, and new contributors' apps are reviewed before they go live.
bun add -g github:dazacode/shasta-cli # needs Bun 1.1+ (https://bun.sh)
shasta init ./my-game # detect the engine, write shasta.json
shasta check ./my-game # everything the Store would refuse, before you upload
shasta preview ./my-game # run it locally, sandboxed like the Store
shasta apply --url <store> --name "You" --about "What you want to publish" --yes
shasta apply status # once approved: you are signed in as a contributor
shasta publish ./my-game # check, upload, validate, submitOr without installing: bunx github:dazacode/shasta-cli check ./my-game.
check, preview and publish all take the same <source>:
| Source | Example |
|---|---|
a folder with index.html |
shasta publish ./my-game |
a ZIP (it may carry its own shasta.json) |
shasta publish game.zip |
| one self-contained HTML file | shasta publish game.html |
| HTML on standard input: an embed snippet, or what a tool generated | cat embed.html | shasta publish - --name "My Game" |
| a ZIP on the web (a game's CDN or release page) | shasta publish https://host/game.zip --credit developer:"Maker" |
| a website, as a linked web app | shasta publish https://my-app.example.com --name "My App" |
| one web page, packaged | shasta publish https://host/game.html --download --credit ... |
Something downloaded is somebody's work, so publish refuses it until you say who made it (--credit). The CLI never invents credits. Only publish what you have the right to: see the rules.
- Everything the Store's upload validator refuses. It is the same code the server runs, with the target server's limits: a missing
index.html, disallowed file types, executables in disguise, path traversal, ZIP bombs, sizes, file counts. - Wrong-case paths.
img/Leaf.pngreferenced asimg/leaf.pngworks on Windows and macOS and 404s in the Store, which is case-sensitive. This is the most common reason a game that "works on my machine" shows a black screen. - Files loaded from other sites at runtime: they break when that site is down or a school filter blocks it.
- Frame-busters and "site locks" (
top.location = ...), which the sandbox blocks. shasta.jsonmistakes: category, credit roles, a missing or oversized icon or screenshot.
Problems print as ✗ and the exit code is 1. publish runs the same check first and does not upload a package that fails it. The server checks again either way, because the client cannot be trusted.
shasta apply --url https://<store> --name "Your name" --about "A Godot platformer I made" --links https://you.itch.io --yes
shasta apply statusYou can also apply on the web (Store → Publish) or with /apply in the Shasta Discord: all three go to the same queue. apply stores nothing but a private ticket on your computer. When you are approved, apply status turns the invite into a contributor sign-in on this computer and prints your recovery key. Keep it: shasta login <url> --key <key> signs you in anywhere else.
| Contributor (default) | Trusted contributor | |
|---|---|---|
| Your own storefront | yes | yes |
| Publish packages and linked web apps | yes | yes |
| New apps and updates go live | after review | straight away |
Every failure says what happened, what to do next, and what kind of failure it was. The exit code tells you the kind, so you can decide whether to fix, wait or stop without parsing the text:
| Exit | Kind | What to do |
|---|---|---|
| 0 | ok | it worked |
| 1 | invalid | fix what the message names; the same command unchanged fails the same way |
| 2 | usage | fix the command line (shasta help) |
| 3 | auth | stop: a person signs in or the Store owner grants access. Never try other accounts, keys or servers |
| 4 | not_found | look it up (shasta apps --json) and use the exact id; don't guess |
| 5 | conflict | the state changed or a step was already done: read it again before the next step |
| 6 | rate_limited | wait (retryAfter), then try once more |
| 7 | unavailable | server or connection down: at most two more tries, a minute apart, then stop and report |
| 8 | confirm | stop: a person has to say yes before you add --yes |
| 70 | bug | stop and report the output |
With --json (or SHASTA_JSON=1), stdout holds exactly one JSON document. Progress goes to stderr. A failure looks like this:
{ "ok": false, "error": { "kind": "not_found", "code": "no_app", "message": "No app matches \"x\".",
"next": "Look it up first ...", "retry": "after-fix", "needsPerson": false, "exitCode": 4 } }retry is no, after-fix, after-check or later. needsPerson: true means hand the decision back. If publish fails part-way, done lists the steps it finished and resume says how to continue: running the same command again reuses the app and the draft, so it never makes copies. Read-only requests are retried twice on a dropped connection before anything is reported. shasta help errors prints this table.
Never invent a credit. If no source names the maker, ask.
- PUBLISHING.md: packages,
shasta.json, updates, storefronts - RULES.md: what the Store accepts
- examples/hello-game: the smallest complete package
shasta help: every command, including storefront and version management
This CLI is AGPL-3.0-only. lib/packageCheck.ts is the Store server's own package validator, copied here unchanged on every release. The example in examples/ is CC0.