CLI reference

Every graphdom command, what it is for and when to use it, with its options.

View as MarkdownAsk Claude about this page
graphdom <command> [options]

The commands follow the work: record a task, review it, build its spider, run the spider. Every command prints its usage when an argument is missing, and graphdom --version prints the Graphdom and Node.js versions.

Step Command Use it to
Record record Record a task in a Chrome that Graphdom opens
relay Record a task in the expert’s own Chrome, through the extension
Review studio Browse sessions, spiders and their evidence
sandbox Open a session served offline and watch what it answers
Build build Turn a task’s sessions into one tested spider
Run runtime test Check a spider against a session, offline
runtime run Run a spider on the real site
Production fleet Run approved spiders at scale on your cluster
Advanced spider, graph Work on a single session’s spider, or rebuild session graphs

record

Records one session of a task. Graphdom opens Chrome on the URL you give, the expert does the task, and the session is saved when Chrome closes or you press Ctrl-C. Use it when you can sit with the expert on your machine. To record in the expert’s own browser, use relay.

graphdom record <url> [options]
graphdom record https://quotes.toscrape.com --task "search quotes"

Prints the session directory, such as archive/sessions/2026-11-06T09-12-44-101Z-3f9a1c, and, on stderr, the address of Chrome’s DevTools (devtools ws://…), so a script or an agent can drive the recording with no person.

Option Default Description
--task <name> the site’s host Name of the task. Sessions with the same task name are built into one spider.
--root <dir> archive Workspace directory to write to: state.db (sites, tasks, sessions), blobs/ and sessions/
--stealth off Uses the stealth profile, for sites that block automated browsers
--http-auth off Also records HTTP authentication prompts. Slower: every request pauses once.
--outputs <file> none The task’s outputs, named by whoever drives the recording. The file is read when the recording stops, so it can be written at the end of the task.
--progress off Prints a line on stderr for each page and each step the expert takes (action a3 click Next), never a value typed

The recording also stops on SIGTERM, as on Ctrl-C. Studio’s Record, on a task’s page, runs this command with --progress and shows the steps as they come; its Stop ends it the same way.

An outputs file names each output and what to read on the page where the task ended: one element by its CSS, or a results list by the CSS of its items and of each field inside one item.

{ "title": { "css": "h1" }, "quotes": { "list": ".quote", "fields": { "text": ".text", "author": ".author" } } }

When the recording stops, before the last snapshot, Graphdom looks them up on every open page and records what it found as output annotations. A name that matches nothing is a recorder error in the session. The spider gets one output per name, quotes a list of {text, author}, and its tests compare what the spider reads with what the page showed.

site, project, task

The registry the workspace keeps in state.db. record fills it in when it meets a new origin or task; these commands edit it by hand, with the same checks as Studio’s API.

graphdom site add segugio --env prod=https://www.segugio.it --env staging=https://staging.segugio.it
graphdom project add quotes --default staging:portale=segugio/staging
graphdom task add send-quote --project quotes --role portale=segugio
graphdom task edit send-quote --name "Send a quote"
graphdom task list --project quotes

A site has environments (origins). A task names the roles it uses, each on a site, and a run says which environment each role points to. A project’s --default says, for one environment, where a role points when the run does not say.

add refuses an id that already exists; edit changes one that does. On edit, the options you give replace what the row had: site edit takes every environment again, --role every role, --default every default; an option you leave out keeps its value. An environment cannot be dropped while a session was recorded on it or a project’s default names it. Origins must be http:// or https:// addresses, and one origin belongs to one environment of one site. A role must point to a site that exists, and --project to a project that exists (default, the project a task goes to when none is given, is made when needed).

Each write records who made it, your user as Studio resolves it (see studio), and when: the row’s by and at. add and edit print the row, list one JSON line per row. A refusal exits 2 with the reason. Each takes --root <dir> (default archive). Nothing is deleted from the registry yet.

relay

Lets experts record in their own Chrome, with their own profile and logins. Run relay on the machine, install the extension from extension/ in the expert’s Chrome, and the expert starts and stops each recording from the extension’s popup. Sessions land in the workspace <root> as with record.

graphdom relay [--root <dir>] [--port <n>]
Option Default Description
--root <dir> archive The workspace directory
--port <n> 7358 Port the extension connects to

Runs until Ctrl-C, saving recordings in progress first. A script can also start and stop recordings on the same port with POST /start {task?, url, tabId?} and POST /stop {id}, once the extension has connected.

studio

Opens Studio, the app for reviewing what Graphdom recorded and built: each session’s actions, requests and pages on one timeline, and each spider’s versions with their test reports. Studio never changes a recording: what you add, such as an output or a step left out of the task, is kept in annotations.json beside it.

On a spider version, Export downloads its spider.json or its Playwright script, named after the spider and the version.

In a task’s Flow, select a step every expert took that is not part of the task, such as closing a cookie banner, and press Leave out: the flow and the next build leave it out of every session. Put back, in the list of steps left out, undoes it.

graphdom studio [--root <dir>] [options]

Studio also keeps the registry: New site, New project and a project’s New task open a form each (the + beside Projects and Sites in the left column too), and Edit on a site, project or task changes it. A new task opens on its page at Record a session. An empty workspace opens on the way to its first recording: add the site, make a project, name the task, record. A form refuses what graphdom site|project|task refuses, with the same words.

graphdom studio --root archive
Option Default Description
--root <dir> archive One site’s archive, or a directory of them
--spiders <dir> spiders/ next to the archive Where built spiders are
--port <n> 7357 Port on 127.0.0.1. Keep it fixed so shared links keep working. 0 picks a free one.
--no-open Serves Studio without opening a window
--read-only Adding or removing annotations (and so Leave out), changing sites, projects and tasks, Record and real runs are off, each saying why

Studio also starts some commands for you, each from a button: Build, Test in sandbox and Open in sandbox run build, spider run or runtime test, and sandbox as if you had typed them, and their log shows at the bottom of the window, with who started the command. A task’s Runs names who started each run. The chevron beside a button sets the command’s options: Show the browser (--headed), the sandbox level (--level), and for a build the number of candidates (--budget) and a file on your machine for each file the recordings picked (--file).

On a version that does not pass, Repair v runs build --repair <n>: its Attempts tab shows the loop as it runs, each attempt with its tests and what the model’s reply cost, and the version it writes opens compared with the one it repaired. A task’s Drift lists its runs that met a changed site, with the same Repair.

Studio’s window reads the workspace through one API under /api/v1 on the same port, the one a hosted Studio will serve: the projects, sites, tasks and sessions, with each session’s events, graph, files and annotations; each task’s flow, runs and drift; the spiders’ versions. The same API creates and edits sites, projects and tasks (POST /api/v1/sites, /projects, /tasks with a JSON body, PATCH /api/v1/sites/<id> and the like), with the checks of graphdom site|project|task (see site, project, task). A value it refuses answers 400 with {"error": "..."}, the reason in words; an id already taken 409; one that does not exist 404. Under --read-only these are refused too.

Studio acts as one user, you, with no login: your git config user.name and user.email, read in the archive’s folder. Without git, or with neither set, it uses your login name on this computer, and failing that local. GET /api/v1/me says who it is. Each annotation you add, each site, project or task you create or edit, and each command Studio starts for you (/api/v1/jobs, its by) records your user, and Studio shows your name at the top right and on an annotation. Scripts that read the earlier /api/... paths must add v1. A change sent from a script (an annotation, a site, a project, a task) must send the Origin of the page Studio serves (http://127.0.0.1:<port>), as the window does.

When the recordings typed a password, Studio asks for it as the job starts, unless you started Studio with GRAPHDOM_SECRET_<NAME> set. The value goes to that one command’s environment and nowhere else: not its log, not the archive, not a file of Studio’s.

sandbox

Opens Chrome on a recorded session, served entirely offline, so you can click through it as if it were the site. Every answer is printed as it is served. Use it to check what the sandbox knows before building, or to see why a spider failed in it.

graphdom sandbox --root <dir> --session <id> [options]
graphdom sandbox --root archive --session 2026-11-06T09-12-44-101Z-3f9a1c
Option Default Description
--root <dir> required The site’s archive
--session <id> required Session to serve, by its directory name
--level <1-3> 2 How far answers may depart from the recording. See Level.
--sessions <id,…> The task’s other sessions. Levels 2 and 3 learn from them.
--secret <value> A secret the session typed, so the sandbox can match it. Repeatable.

A line marked GENERALISED is an answer the sandbox made up from the task’s sessions rather than replayed.

build

Turns all the sessions of a task into one spider and runs it against every session in its sandbox. The spider ships only if every session passes. This is the command that produces something you can run.

graphdom build [root] [options]
graphdom build archive --task "search quotes"

[root] is the workspace directory (default archive); --task names the task by its id, and may be left out when the workspace has one task. Each build writes the next version of the task, v2 beside v1 and so on, and leaves the earlier ones as they are. On success the command prints the spider’s directory, such as spiders/search_quotes/v1/. On failure it exits with 1, prints where each session failed, and keeps the closest attempt as a draft you can open in Studio.

Option Default Description
--task <name> every finished session Build only from sessions recorded with this task name
--out <dir> spiders Where spiders are written
--model <id> gemini-3.5-flash on Vertex if GOOGLE_CLOUD_PROJECT is set, else claude-opus-5-5 if ANTHROPIC_API_KEY is set Model that repairs a spider that fails. none turns repair off.
--budget <n> 3 with a model, 1 without How many spiders to try before giving up
--secret <name>=<value> A secret the sessions typed, such as a password. Repeatable. Also read from GRAPHDOM_SECRET_<NAME>.
--file <name>=<path> A file the sessions uploaded, by its recorded name. Repeatable.
--level <1-2> 2 Sandbox level for the tests
--headed off Shows the sandboxes’ Chrome while testing
--repair <n> Repairs version n of the task’s spider: the build starts from it instead of from the recordings, tests it on the task’s sessions as they are now, and writes the next free version. Its report.json says repairs: n. Record new sessions first when the site changed.

runtime test

Runs a spider against one recorded session, offline, and checks it makes the same requests and ends on the same page. Use it after a build, or after editing spider.json by hand (see Spider IR).

graphdom runtime test <spider.json> --session <session-dir> [--test <tests.json>] [--secret <name>=<value>]… [--input <name>=<value>]… [--level 1|2] [--sessions <id,id…>]

A session the build tested is checked the way the build checked it: against its entry in the tests.json written beside spider.json, with that session’s own inputs, and its path, final page and outputs compared too. Any other session (one you held out of the build) is checked against a replay of itself, with the inputs the spider’s examples give; pass the session’s own values with --input.

Option Description
--session <session-dir> The recorded session to run the spider against
--test <tests.json> The tests file to look the session up in, instead of the one beside the spider
--secret <name>=<value> A secret the session typed, such as a password. Repeatable.
--input <name>=<value> A value for one of the spider’s inputs, over the session’s own or the example. Repeatable.
--level <1-2> Sandbox level, as in build: 1 answers only byte-for-byte matches. Default 2.
--sessions <id,id…> At level 2, the sessions the sandbox’s site model is built from. Default: the sessions the tests file lists.
--headed Shows the sandbox’s Chrome, to watch the spider run
graphdom runtime test spiders/search_quotes/v1/spider.json \
  --session archive/sessions/2026-11-06T09-12-44-101Z-3f9a1c

Exits with 0 when the test passes and 1 when it fails.

runtime run

Runs a spider on the real site, in a Chrome that Graphdom opens, and prints its outputs as JSON.

graphdom runtime run <spider.json> [options]
graphdom runtime run spiders/search_quotes/v1/spider.json --input query=love
Option Description
--input <name>=<value> A value for one of the spider’s inputs. Repeatable.
--inputs <file.json> All inputs from a JSON file
--file <name>=<path> The file a file input of the spider uploads. Repeatable. A name that is not a file input, or a path with no file, stops the command before Chrome starts. With --root, the run’s session names the file by name, size and sha256, never by its path.
--secret <name>=<value> A secret, such as a password. Repeatable. Also read from GRAPHDOM_SECRET_<NAME>.
--origin <role>=<url> Runs a role of the spider on another origin, such as staging. Repeatable.
--headed Shows Chrome
--yes Runs submit steps without asking
--json Never asks on the terminal: without --yes, stops before the first submit step. Prints the whole report as JSON, with gate (the submit step it stopped before) and session.
--ask With --json: before each submit step, prints ask submit step <id> in <state> by <edge> on stderr and waits for one line on stdin, y or yes to send it, anything else to stop there. Studio’s Runs answers it from its confirmation.
--root <workspace> Records the run as a session of the workspace, listed among the runs of its task (Studio’s Runs) and never among the sessions a build uses. A file the run downloads is kept in the workspace’s blobs/, named by the sha256 its output reports.
--task <task> With --root, the task the run belongs to: a task of the workspace (graphdom task add makes one), else the command exits with 2 before Chrome starts. Default: the spider’s.
--by <user> With --root, who started the run, a user of the workspace by id, kept in the run’s session. A user the workspace does not know exits with 2. Default: you, as Studio resolves you (see studio). Studio’s Run on the site passes the user who started it.

With --json or --root, a line of progress per step goes to stderr: state <state>, step <id> ok, stop before submit step <id>, end <status>. Studio’s Run on the site is this command with --json --root, and --ask for a version that passes in the sandbox unless its submit steps were allowed up front.

The spider stops and reports drift when the site no longer matches what was recorded.

fleet

Runs the production fleet: a control plane that queues jobs and workers that run them. Deploy the fleet explains the files these commands read.

graphdom fleet serve --tokens <file> [options]
graphdom fleet worker --control <url> --vault <file> --storage <dir|s3-url> [options]
graphdom fleet submit --control <url> --spider <id> [options]

serve and worker run until Ctrl-C or SIGTERM. A worker stops claiming jobs, lets its runs finish, then exits.

fleet serve

Option Default Description
--tokens <file> The users with their roles, and the user each bearer token acts as (format). Required.
--db <file> fleet.db The control plane’s database file
--host <address> 127.0.0.1 Address to listen on. Use 0.0.0.0 in a container.
--port <n> 7400 Port of the API
--lease-ms <n> 30000 How long a run may go without a heartbeat before it is lost
--drift-threshold <n> 2 Runs that drift at the same step before an incident opens

fleet worker

Option Default Description
--control <url> The control plane. Required.
--vault <file> The secrets file. Required.
--storage <dir | s3://bucket/prefix?endpoint=url> Where runs are archived. Required.
--token <token> GRAPHDOM_TOKEN A token with the worker role
--id <name> The worker’s name in runs and logs
--slots <n> 2 Chromes run at once
--spool <dir> a temporary directory Runs kept here until they are pushed to storage
--host <address>, --port <n> 127.0.0.1, a free port The live endpoint hand-overs use
--advertise <url> Where the control plane reaches the live endpoint
--headed Show the Chromes, for debugging

fleet submit

Queues jobs and prints their ids, one per line.

graphdom fleet submit --control http://localhost:7400 --spider search_quotes --inputs job.json --count 5
Option Default Description
--control <url> The control plane. Required.
--spider <id> The spider to run. Required.
--token <token> GRAPHDOM_TOKEN A token with the admin role
--account <id> The account to run on
--inputs <file> A JSON object of the job’s inputs
--version <n> the approved version Pin a version
--count <n> 1 How many identical jobs to queue

Secrets

Any command that takes --secret <name>=<value> also reads GRAPHDOM_SECRET_<NAME> from the environment, which keeps the value out of your shell history. A flag wins over the environment.

export GRAPHDOM_SECRET_PASSWORD='…'
graphdom runtime run spiders/login/v1/spider.json

Exit codes

Code Meaning
0 Success
1 The command ran and failed, for example a test did not pass
2 Wrong usage: unknown command, missing argument, invalid option

Advanced

spider

Works on the spider of a single session, step by step. build does all of this for many sessions at once; use spider to see what each step produces.

Subcommand Does
spider derive <session-dir> [--out <file>] [--name <task>] Writes the spider (spider.json) of one session
spider compile <spider.json> [--out <dir>] Compiles it to a Playwright script, spider.ts and prelude.ts
spider run <spider.json> --session <session-dir> Runs the Playwright script against the session, offline
spider test <spider.json> --session <session-dir> --faults <seeds> Runs the spider on the runtime again and again under injected faults (slow answers, server errors, dropped connections, hangs, clock jumps, overlays) to find what breaks it. Seeds are a range, 1-20, or a list, 3,7,9.

With --out, spider derive writes the file, making its folder, and prints its path; spider compile prints the folder it wrote.

Studio runs three of them for you. Derive a spider on a session writes spiders/<task>/derived/<session>.json. Compile to Playwright on a version with no compiled file writes spiders/<task>/playwright/v<n>/. Chaos test on a version runs spider test on a session you pick, with the seeds and level you give, and shows each seed’s verdict as it comes.

Both spider run and spider test take --secret and --input; spider run also takes --headed, to watch it in the sandbox’s Chrome. spider test also takes --level, --sessions and --file, as in sandbox and build.

graph

Rebuilds each session’s graph.json from its event log. Run it after updating Graphdom, so old sessions get the newer graph.

graphdom graph archive/sessions/*