Skip to main content

Headless mode (CLI / batchmode)

Buril ships a thin CLI named buril that launches Unity in batchmode, executes one or more tool calls, and exits with a structured result. This is the entry point for CI/CD pipelines, scheduled jobs, and anything that needs Buril without a human at the keyboard.

The shape

buril "your prompt here"
buril --tool scene_open --input '{"path":"Assets/Scenes/Main.unity"}'
buril --replay Assets/BurilTests/JacketRig_2026_05_19.json
buril --project /abs/path/to/UnityProject --tool editor_state

Under the hood buril resolves the Unity binary for your project (or accepts an explicit --unity), then invokes:

Unity -batchmode -nographics -projectPath <project> \
-executeMethod Buril.Bridge.Headless.Run \
-burilCommand <encoded JSON>

The encoded JSON is the equivalent of agent_team_handoff or a direct tool call. Stdout is structured (one JSON object per line), exit code is 0 on success and 1 on failure.

Three usage patterns

1. Single tool call (deterministic, no LLM)

buril --tool asset_import_fbx \
--input '{"path":"/tmp/character.fbx","destination":"Assets/Models/"}'

No LLM, no chat. The tool runs synchronously, returns its result as JSON on stdout, Unity exits.

This is the most common CI pattern: a build script that imports a freshly exported FBX, runs a deterministic chain of tools, and commits the resulting prefab.

2. Prompt-driven (LLM in the loop)

buril "Import /tmp/character.fbx, attach AnimatorController.controller, and save as Player.prefab in Assets/"

Buril spins up the agent loop using the configured provider key. Cost is whatever the provider charges. Useful for one-off automation tasks where writing the exact tool chain would take longer than the LLM call.

Best practice: pin the model with --model anthropic/sonnet-4-7 so the prompt is reproducible.

3. Replay (deterministic, recorded)

buril --replay Assets/BurilTests/JacketRig_2026_05_19.json

Re-runs a previously recorded agent_team_* trace. No LLM call, no cost. This is how Buril's CI validates that refactors don't break shipped tool behavior.

CI/CD examples

GitHub Actions (smoke test)

name: Buril smoke test
on: pull_request
jobs:
smoke:
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- name: Install Buril CLI
run: npm i -g @buril/cli
- name: Run editor state check
env:
BURIL_ANTHROPIC_API_KEY: ${{ secrets.BURIL_ANTHROPIC_API_KEY }}
run: |
buril --tool editor_state --project ./UnityProject

Nightly regression (replay)

name: Nightly Buril regression
on:
schedule:
- cron: '0 6 * * *'
jobs:
replay:
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- name: Replay recorded traces
run: |
for trace in Assets/BurilTests/*.json; do
buril --replay "$trace" --project ./UnityProject || exit 1
done

Flags

FlagPurpose
--project <path>Unity project root. Defaults to $PWD.
--unity <path>Explicit Unity binary. Defaults to the first Unity Hub install that matches the project's ProjectVersion.txt.
--tool <name>Run a single tool by name. Mutually exclusive with the prompt arg.
--input <json>JSON payload for --tool.
--replay <path>Replay a recorded trace.
--record <path>Record this run to a trace at <path> (combine with a prompt).
--model <id>Override the provider's default model.
--timeout <seconds>Hard kill after <seconds>. Default 600.
--list-toolsDump the full tool catalog.
--tool-info <name>Print one tool's description + schema.
--log-level <level>trace / debug / info / warn / error. Default info.
--jsonForce structured JSON stdout (default in batchmode).

Threading & timing

Unity's batchmode startup is slow — expect 30-90 seconds on the first invocation as the editor compiles. Subsequent runs are faster because the Library/ cache is warm. To minimize CI cost:

  • Cache Library/BurilCache/ across CI runs.
  • Use --replay instead of LLM prompts wherever possible.
  • For chains of tool calls, prefer one agent_team_handoff over many --tool invocations — startup happens once.

Exit codes

CodeMeaning
0Success. Result on stdout.
1Tool returned ok: false. Error on stderr.
2Validation failure (bad input schema).
3Provider auth failure (no key, expired key).
4Replay mismatch — recorded artifact didn't match current run.
5Timeout.
99Unity itself failed to start.

Where logs land

In batchmode, all Debug.Log output goes to ~/Library/Logs/Unity/Editor.log on macOS (or the platform equivalent). Buril additionally writes structured JSON logs to Library/BurilCache/headless/<timestamp>.jsonl, which is rotated daily and capped at 100 MB.