CLI reference

banto is the only command you need to install. It scaffolds a project, compiles your .banto files, formats them, manages your image/audio assets, and publishes your game to banto.tv.

If you’ve never used it, start with Getting started; this doc is the keep-it-open-while-you-work reference.

Install

npm install -g @bantohq/cli
banto --help

You should see the subcommands: init, build, fmt, auth, publish, and assets.

You can also install per-project (npm install --save-dev @bantohq/cli) and invoke as npx banto ….

Get the editor extension too. The Banto DSL VS Code extension gives you syntax highlighting, inline diagnostics, and completions as you type — it’s the fastest way to catch mistakes before you build. See Getting started → the extension.

The workflow at a glance

Your game runs on banto.tv, but you can test it without real phones using the sandbox. The loop is:

  1. Write .banto files (the editor extension flags errors live).
  2. banto build to typecheck and catch anything the editor missed.
  3. banto publish — publish as a private game ("public": false) while you iterate.
  4. banto sandbox — open the owner-only sandbox: the host screen plus simulated player windows in one browser, no phones needed.
  5. Edit, re-publish (it updates in place), reload the sandbox, repeat. Host it live on banto.tv from a few phones/tabs for a real multi-device round, and flip "public": true to list it.

Subcommands

banto init <dir>

Scaffolds a new project at ./<dir>. The directory must not already exist (or must be empty). The starter is the empty lobby template: host shows the room code with a kick list, players see a “you’re in” message.

banto init my-game

Files created:

my-game/
├── globals.banto
├── start.banto
├── styles.banto.css
├── banto.config.json
└── .gitignore

banto build

Compiles the project to a single game.json IR file at the project root. Run it from anywhere inside the project — the CLI walks up until it finds globals.banto.

banto build              # quiet
banto build --verbose    # print per-file progress

Output on success:

Wrote ./game.json (487 bytes, 0 error(s), 0 warning(s)).

On a syntax/type error, you get the same diagnostics your editor shows, then a non-zero exit code:

start.banto:14:17 error [banto.cstate-write-interleaved]: …
Compilation aborted: 1 error(s), 0 warning(s).

game.json is a build artifact — keep it out of version control (the starter’s .gitignore already does this). banto publish builds for you, so you rarely need to run build by hand except to verify a change compiles.

banto fmt [path]

Formats .banto files in place using the canonical formatter — the same output as Format Document in the editor.

banto fmt                 # format every .banto file under the current dir
banto fmt start.banto     # format a single file
banto fmt --check         # report unformatted files, exit 1 if any (CI-friendly)
OptionWhat it does
-c, --checkDon’t rewrite anything — just list files that aren’t formatted and exit 1 if there are any.

path may be a file or a directory (defaults to .).

banto auth

Logs you into banto.tv using a browser-based loopback flow:

  1. The CLI starts a tiny local web server.
  2. It opens your browser to a banto.tv consent page.
  3. You approve, banto.tv redirects to localhost, and the CLI captures the token.
banto auth

You only need to run this explicitly the first time. banto publish and banto assets will trigger the same flow automatically if your token is missing or expired.

banto publish

Compiles your project and ships it to banto.tv. The settings in banto.config.json (title, description, default datasets) become your game’s listing.

banto publish

Re-running banto publish after edits updates the existing game in place — same ID, no duplicate listing. The CLI uses banto.lock.json (sibling of banto.config.json) to remember which remote game your project is bound to.

Publish with "public": false while you iterate — the game is reachable only by you (and anyone you send a direct link) so you can host and playtest it privately. Set "public": true to list it in the public catalog.

Publishing is admin-gated on banto.tv by default. If you get a 403, your account doesn’t have publishing permissions.

banto sandbox

Opens the sandbox for your currently-published game in the browser — an owner-only test harness that runs the real game with the host screen and simulated player windows side by side, so you can play a full round without real phones.

banto sandbox            # default layout (host + 2 player windows)
banto sandbox -t 3       # a different layout preset
  • -t, --template <0-3> picks a layout preset (how many player windows to tile); defaults to 2. Use + Add player in the UI to add or drop players live.
  • The sandbox opens the published build, so run banto publish first (and again after each change, then reload).
  • It’s owner-gated — the browser must be signed in to banto.tv as the project’s owner (the account from banto auth).
  • Click the Inspector button (top-right) for a live view of every var.* and state-param, the datasets, each window’s cstate, and a Logs panel showing your func.log(...) output and any runtime errors.

banto assets

Manage the custom image/audio assets your game renders with cpnt.image, cpnt.audio, or client.playSound. Drop media files in an assets/ directory at your project root; reference them from .banto as asst.<name> (the file’s base name, no extension). See Custom image & audio assets for the language side.

banto assets push        # upload new/changed files from ./assets
banto assets ls          # list this project's assets + moderation state
banto assets rm <name|id># delete an owned asset (by base name or id)
banto assets catalog     # open the public asset catalog in your browser
SubcommandWhat it does
push [dir]Uploads new or changed files from ./assets (or dir) to your account, records their ids in banto.lock.json, and reconciles moderation status.
lsLists each asset with its kind, moderation status, and id.
rm <name|id>Deletes one of your assets from the server and the lock file.
catalogOpens the shared, admin-approved asset catalog on banto.tv.

Titles come from an assets map in banto.config.json, keyed by the file’s base name:

{
    "assets": {
        "logo": { "title": "Game logo" },
        "victory-fanfare": { "title": "Victory fanfare" }
    }
}

Moderation. Uploaded assets start pending and are visible only in your own games until an admin approves them. asst.<name> references still build and render for you while pending — approval just makes the asset usable by others and listable in the catalog.

Config files

banto.config.json (per project)

How your game appears on banto.tv. Lives next to globals.banto.

{
    "title": "Grant's Trivia Tournament",
    "description": "It's like Trivia, but as a tournament!",
    "public": false,
    "default": {
        "questionSet": "this"
    },
    "new": {
        "questionSet": [
            {
                "prompt": "Which of these are programming languages?",
                "options": ["Python", "HTML", "JavaScript", "HTTP"],
                "correctOptions": [0, 2]
            }
        ]
    },
    "assets": {
        "logo": { "title": "Game logo" }
    }
}
FieldWhat it does
titleDisplay name on the banto.tv listing.
descriptionShort blurb on the listing page.
publicfalse = only you and people with a direct link can find it. true = listed in the public catalog.
default.*For each data block your project declares (questionSet, promptSet, or dynamic), the data source pre-selected when a host starts a game. Use a banto.tv data-source ID, or the literal "this" to point at the matching new.* entry.
new.*Inline contents of a fresh data source to create on banto.tv as part of publishing. Shape matches the data block: questions for questionSet, strings for promptSet, or a (string | number | (string | number | (string | number)[])[])[] list for dynamic.
assets.*Titles for your custom assets, keyed by the media file’s base name. Used by banto assets push.

Where credentials live

banto auth saves your bearer token outside the project, scoped to your OS user:

OSPath
Linux / macOS~/.config/banto/
Windows%APPDATA%\banto\

The folder holds credentials.json — your bearer token. Treat it like a password. You don’t normally need to edit it by hand; banto auth writes it for you.

banto.lock.json (next to banto.config.json, in your project) is different: it remembers which remote game and assets this project is bound to. Commit it — it’s how re-publishing updates in place instead of creating a duplicate.

Troubleshooting

SymptomFix
banto build says “no globals.banto found in this directory or any parent”You’re not inside a Banto project. cd into one or run banto init <name>.
banto build reports unknown-assetYou referenced asst.<name> for a file you haven’t pushed yet. Run banto assets push, or check the base name matches a file in assets/.
banto publish returns 403Your account isn’t allowed to publish. Publishing is admin-gated by default.
banto init says “target is not empty”Pick a different name, or move the existing files out. There’s no --force flag.
The browser-opened consent page errors outRe-run banto auth. The loopback listener uses a random port and the previous attempt’s port may have been blocked.