Headless runs, CI, and editor protocols
The UI is the default. The same harness is a CLI, a JSON-RPC server, and an ACP server.
blazorly run
blazorly run "summarize this repo"
blazorly run --workspace /srv/app --timeout 180 --json "run the test suite and report failures"
The invoking directory becomes the workspace on first use. Flags: --workspace, --provider, --model, --effort, --resume, --timeout, --json, --quiet.
Exit codes are part of the product:
0— completed or max-tokens2— turn error or blocked3— aborted or interrupted (including--timeout)1— harness failure
Do not treat 3 as a flake. The run was cancelled on purpose or hit the watchdog. Retry with a longer timeout or a narrower brief.
CI sketch
# after the installer has put blazorly on PATH
export DEEPSEEK_API_KEY
blazorly run --timeout 300 --quiet "run tests; if they fail, stop and print the failures"
echo $? # 0 only if the turn completed
Pin the binary version in the image. Do not curl the installer on every job without checking the checksum story — the installer verifies release checksums; skipping verify is BLAZORLY_SKIP_VERIFY=1 and that is a footgun.
JSON-RPC — serve-stdio
blazorly serve-stdio speaks an automation protocol on stdin/stdout: initialize, session/new, session/prompt, session/cancel, shutdown, plus session.event and session.status notifications. Use this when you are wiring a custom client, not a human.
ACP — serve-acp
blazorly serve-acp is the Agent Client Protocol server for editors and SDK clients: initialize, session/new, session/prompt, session/load, session/cancel, session/set_config_option. Notifications: session/update. In --permission ask, every tool call is routed back as session/request_permission. Default permission mode is auto.
eval
blazorly eval --tasks eval/tasks runs scored tasks in isolated workspaces against a matrix of sandbox backends. Results land in a timestamped directory as results.json and summary.md. This is how the interruption contract is kept from rotting.
init
blazorly init drafts AGENTS.md files from a repo scan. Dry-run by default; --write creates or merges; --force replaces; --deterministic uses an offline template with no model calls.