The Robot executes an automation and reports what happened. It is deliberately small: it loads a definition, composes the services the automation calls, runs the transaction loop through the framework and writes evidence. Everything else lives elsewhere.
#What the Robot is
The Robot is a thin facade over RobotService. The command line parses arguments and prints a summary; the service does the work. On each run the service:
- loads and validates the automation from the registry,
- establishes the robot identity and environment,
- composes the credential chain,
- hands the automation to the framework's transaction runner with browser, tracing, retry, screenshot and logging,
- returns the run summary for reporting.
The Robot has no designer, no AI and no business rules. It does not decide what to click. It does not hold a process in a proprietary format. It runs code. The code owns the decisions.
#How you invoke it
# list the automations this robot can see
tsx robot/cli.ts list
# run one from source, through the full transaction lifecycle
tsx robot/cli.ts run process-orders --headed --url http://127.0.0.1:4100
# print the recorded state of a finished run
tsx robot/cli.ts show process-orders 2026-10-03T09-15-00-abc
# build a portable package
tsx robot/cli.ts package process-orders --out ./out
# run a package, with no source tree in sight
tsx robot/cli.ts run-package ./out/process-orders
run and run-package produce identical transaction semantics. run reads the automation from the repo registry. run-package reads a built package. A Robot that only ever runs packages never needs the source.
The flags on run:
| Flag | Meaning |
|---|---|
--headed |
show the browser (default is headless) |
--no-trace |
disable Playwright tracing |
--url <base> |
override the target application URL |
--runId <id> |
a caller-chosen run id, which Studio uses |
--artifacts <dir> |
override the artifact root |
--console |
mirror structured logs to stdout |
run-package takes --headed, --no-trace, --url, --artifacts and --console. package takes --out <dir>. generate takes --skip-tests, --artifact <file>, --remote, --bind and --url <app>. It drives the AI authoring pipeline rather than a normal run.
Exit codes are part of the contract:
0 run finished (success, or completed with errors: the robot did its job)
2 run failed fatally (system or init failure)
3 run stopped by the operator
1 usage or configuration error
Exit 0 covering "completed with errors" is deliberate. A run that finishes with three business exceptions is a successful execution whose totals live in the summary, not a crashed worker.
#What the Robot provides to an automation
The automation receives a context with the engines it declared. ctx.credentials resolves a credential by name. ctx.page is the browser. ctx.excel, ctx.files, ctx.api, ctx.db, ctx.email and ctx.pdf are the other capabilities. ctx.log is the structured logger, ctx.screenshot writes evidence, ctx.settings carries the robot identity and environment. ctx.checkAborted gives between-operation stop checks. The same members exist on every OS, which is the portability promise.
Every run writes to artifacts/<automationId>/<runId>/: logs.jsonl and logs.txt, state.json as a pollable heartbeat, summary.json as the final report, trace.zip when tracing is on. Screenshots are written on business and system failures.
#Why it is thin
The Robot is sized on purpose. All the intelligence lives in the framework and the Orchestrator, so the Robot stays a few hundred lines of orchestration code. A behaviour that belongs to RPA, such as queue semantics, the exception taxonomy or engine management, belongs in the framework and not in the worker.
That shape buys portability. The identical service can run on a remote machine, in a container or as a service on the same host. The automation does not change. The Robot does not need to know the Orchestrator exists: the Orchestrator keeps the registry, the queue and the vault. It hands the Robot an environment when it runs a package.
#Things that catch people out
The usage block lists a status verb, but the command switch does not implement it, so robot status reaches the unknown-command branch. Use show for a finished run and read the artifact folder for anything else.
--runId is the Studio's flag, not a random id. Passing the same id twice is how the Studio attaches to a run in progress. A repeated id can collide with a run that already finished.