Skip to content

How to Run a Local Battle ​

Local battles execute entirely on your machine. No cloud account, no auth, no credits required. New state is persisted in user runtime storage outside the project. Legacy .lenserfight/local-battles/<id>.json files are still read for compatibility.


Overview ​

lf battle local <subcommand> [options]
SubcommandDescription
initCreate a new local battle
add-contenderAdd or replace a contender slot (A or B)
runExecute both contenders with BYOK keys
voteRecord a vote on an executed battle
statusShow state, contenders, and vote tally
listList all local battles
pushPublish a local battle to LenserFight Cloud

State files live in the CLI user runtime directory under local-battles/<uuid>.json. Do not commit legacy project-root local battle JSON files.


lf battle local init ​

Create a new local battle in draft state.

lf battle local init --name <name> --task <prompt> [--json]
FlagRequiredDescription
--nameyesHuman-readable battle name
--taskyesTask prompt both contenders will answer
--jsonnoOutput full state as JSON

Example:

bash
lf battle local init \
  --name "CSV Parser Duel" \
  --task "Write a Python function parse_csv(path) -> list[dict]"

lf battle local add-contender ​

Add or replace contender slot A or B. The battle transitions to ready once both slots are filled.

lf battle local add-contender <A|B> --provider <p> --model <m> [options]
Arg / FlagRequiredDefaultDescription
<A|B>yes—Slot to assign
--provideryes—anthropic | openai | google | mistral | ollama
--modelyes—Model key, e.g. claude-sonnet-4-6
--labelnomodel nameDisplay label shown in output
--key-varno—Custom env var name for API key (overrides default)
--idnomost recentBattle UUID or prefix
--jsonnofalseOutput updated state as JSON

Examples:

bash
# Anthropic (reads ANTHROPIC_API_KEY automatically)
lf battle local add-contender A --provider anthropic --model claude-sonnet-4-6

# OpenAI with explicit env var name
lf battle local add-contender B --provider openai --model gpt-4o --key-var MY_OPENAI_KEY

# Ollama — no key needed
lf battle local add-contender B --provider ollama --model llama3

lf battle local run ​

Execute both contenders simultaneously. Streams tokens to the terminal color-coded by slot.

lf battle local run [<id>] [--json]
Arg / FlagRequiredDefaultDescription
<id>nomost recentBattle UUID or prefix
--jsonnofalseOutput execution result as JSON

Terminal output uses ANSI color codes:

  • [A] prefix in blue
  • [B] prefix in green

Both contenders run in parallel via Promise.all(). Results are saved to the state file on completion.


lf battle local vote ​

Record a vote on an executed battle. Multiple votes are allowed (each is appended).

lf battle local vote --slot <A|B|draw> [options]
FlagRequiredDefaultDescription
--slotyes—A | B | draw
--idnomost recentBattle UUID or prefix
--rationaleno—Optional explanation for your vote
--jsonnofalseOutput updated state as JSON

Example:

bash
lf battle local vote --slot A --rationale "More concise and idiomatic"

lf battle local status ​

Show the current state, contenders, and vote tally.

lf battle local status [<id>] [--json]
Arg / FlagRequiredDefaultDescription
<id>nomost recentBattle UUID or prefix
--jsonnofalseOutput raw state as JSON

The winner is computed as the slot with the highest vote count. Ties are shown as "Tied".


lf battle local list ​

List all local battles, sorted by creation date (newest first).

lf battle local list [--json]

lf battle local push ​

Create a draft cloud battle from a local battle's name and task. Requires lf auth login.

lf battle local push [<id>] --slug <slug> [--json]
Arg / FlagRequiredDefaultDescription
<id>nomost recentBattle UUID or prefix
--slugyes—URL-safe cloud slug (must be unique on LenserFight)
--jsonnofalseOutput cloud battle record as JSON

What is pushed: battle title and task prompt.
What stays local: contender configs, outputs, and votes.

After pushing, continue with lf battle open <cloud-id> to accept entries.


Key resolution order ​

When a contender runs, keys are resolved in this priority order:

  1. --key-var — env var name set on the contender (e.g. MY_ANTHROPIC_KEY)
  2. Default provider env var — standard name per provider (see table below)
  3. Error — if no key found and provider is not Ollama

Supported providers ​

ProviderDefault env varNotes
anthropicANTHROPIC_API_KEY
openaiOPENAI_API_KEY
googleGOOGLE_AI_API_KEY
mistralMISTRAL_API_KEY
ollamanoneRuns locally, no key needed

Resuming after power-off ​

State files persist across restarts. Find your battle IDs with:

bash
lf battle local list

Then continue from any step:

bash
lf battle local run <id>       # re-run (overwrites outputs)
lf battle local vote --id <id> --slot A
lf battle local status <id>

See also ​