<aside>

Player control

The primitives. These map almost 1:1 onto Thrall's /actions surface - fire-and-forget by default, with wait to block until the input releases and screenshot to attach a PNG of the result.

<aside>

Gameplay shortcuts

Composed conveniences. Each of these is a small chain over the primitives above - they exist because the same two-step ritual (equip a slot, then do the thing) kept showing up in scripts and chat workflows. Pulling them up to first-class commands removes that boilerplate.

<aside>

Inventory & Menus

The bottom-up version of the same surface. /peek above is the convenience wrapper; these are the parts.

<aside>

Eyes & ears

The read-state commands. Neither mutates the game; both are how you find out what's going on.

<aside>

Chat

<aside>

Session

Anything that moves the client between worlds, servers, or the title screen. The list commands (/worlds, /servers) are doing more than they look - they're rendering interactive UI on top of plain HTTP data.

<aside>

Auth

This is the chunkiest command in the catalogue because online-mode auth is the chunkiest part of the system. Thrall doesn't ship with an account - it inherits whichever account the player launched the game with. To join servers as a different account (or to refresh an expired token), the bot drives a full Microsoft → Xbox Live → Minecraft auth chain.

Flow:

  1. /auth start - Issues a Microsoft sign-in URL. If a refresh token from a previous session is cached on disk, it fast-paths: the chain re-runs silently and the response immediately reads logged_in: true with the account details.
  2. User authorises in their browser. Microsoft redirects to a localhost URL with ?code=...
  3. /auth complete input: <paste> - Accepts the full redirect URL or just the bare code value. The bot does the XBL → XSTS → Minecraft login_with_xbox → profile-fetch dance, then asks Thrall to swap the active session.
  4. Session swap timing. If the player is currently in-world, the swap is deferred - applies on the next /auth start after they leave. The embed surfaces this clearly so operators know why the active account hasn't changed yet.

Status & logout. /auth status reports logged_out / pending / logged_in with token expiry and the resolved profile. /auth logout clears the on-disk refresh token; the live MC session is untouched until the next auth cycle.

Pre-auth on server join. /server join and /server connect quietly call into this same chain — refreshing silently when possible, prompting the user when interactive sign-in is required.

Examples: /auth start/auth complete input: <http://localhost/?code=M.R3_BAY>...Calls: POST /auth/start, POST /auth/complete, GET /auth/status, POST /auth/logout

</aside>

<aside>

Scripting

The scripting layer is where the bot stops being a remote control and starts being a small programming environment. Tasks are JSON schemas - an array of named steps, each one a Thrall action - that you can author inline, attach as a file, save to a library, and re-run by name.

/task run - opens a modal where you paste a schema (≤4000 chars), or you can attach a file: for larger schemas (≤256KB). Optional save-as: <name> persists it under that name in one step. verbose: true posts each step's result as a separate follow-up message; off, you only get the screenshots that steps explicitly produce.

/task save name: <name> file: <json> - persists a schema to the library without running it. Names are kebab-case, ≤50 chars. overwrite: true is required to replace an existing entry - guards against fat-finger collisions.

/task run-saved name: <auto> - re-runs a saved schema. name autocompletes against the library so you don't need to remember spelling.

/task show name: <auto> - prints the schema's metadata + steps and attaches the JSON file for inspection or copy-paste.

/task delete name: <auto> - confirmation-button deletion.

Storage. Saved schemas live as plain JSON files under <jarl-data>/schemas/. You can hand-edit them in your text editor and they'll show up in autocomplete immediately - no reload required. That makes the library feel like just another folder, which is the point.

Execution model. A schema runs step-by-step. Each step is {action, args, label?}; the executor maps action onto the corresponding Thrall endpoint, passes args through, and reports a per-step result. Failures are non-blocking by default - the run continues, so an operator can see "step 3 failed, steps 4-7 succeeded, here's the screenshot at the end" rather than getting halted at the first hiccup.

Examples:

Calls: Any Thrall endpoint named by schema steps.

</aside>