Command line
Flags, environment variables, exit codes and output formats.
The agent is configured by a .env file in the directory it runs from, plus flags on the
command line. One invocation is one cycle unless --watch is passed.
Flags
Usage: sync-agent [options] (version 1.0.0)
Reads .env from the current directory, syncs once, then exits.
Options:
-w, --watch Stay resident and repeat on the school's sync interval
--interval=<min> Override the interval, in minutes
--plain One timestamped line per cycle, no colour
-v, --version Print the version and exit
-h, --help Show this message| Flag | Effect |
|---|---|
-w, --watch | Stay resident, repeating on the school's sync interval |
--interval=<min> | Override the interval in minutes. Wins over the dashboard value |
--plain | Force the timestamped single-line form, without colour |
-v, --version | Print the version, such as 1.0.0, and exit 0 |
-h, --help | Print usage and exit 0 |
The version is also on the first line of --watch output, and every agent reports it to the
server. The school's Overview shows which version each side runs.
--interval only changes how often the agent wakes, so it does nothing without --watch. It
expects a positive number of minutes. An unrecognised flag exits before connecting to
anything.
Environment variables
The agent reads .env from the directory it is run from. It does not search parent
directories.
| Variable | Required | Default | Notes |
|---|---|---|---|
MONITORING_URL | yes | — | Base URL of the monitoring server |
SCHOOL_CODE | yes | — | The school's code, exactly as registered |
SYNC_TOKEN | yes | — | The school's sync token |
SYNC_SOURCE | no | LOCAL | LOCAL or ONLINE |
DB_HOST | no | 127.0.0.1 | |
DB_PORT | no | 3306 | |
DB_USER | yes | — | DB_USERNAME also accepted |
DB_PASSWORD | no | empty | |
DB_NAME | yes | — | DB_DATABASE also accepted |
SYNC_SOURCE decides both halves of the agent's job: LOCAL captures UP tables and applies
DOWN changes, ONLINE does the reverse. Any value other than ONLINE is treated as
LOCAL.
Laravel spellings are accepted
DB_USERNAME and DB_DATABASE are read as alternatives to DB_USER and DB_NAME, so the
agent can share a host application's existing .env instead of duplicating credentials.
A missing required variable stops the agent before it connects to anything, naming the variable it wanted.
Exit codes
| Code | Meaning |
|---|---|
0 | The cycle completed |
1 | Configuration was invalid, or the cycle failed |
A failed cycle in watch mode does not exit — the agent reports the error and waits for the
next tick. When a watch-mode agent is stopped, its exit code reflects the last cycle it ran,
so one that has since recovered exits 0.
A request to the monitoring server that gets no complete answer within 60 seconds fails the cycle rather than holding the run open.
Output
The agent writes for whoever is reading. Attached to a terminal it uses a compact coloured line per cycle, showing only the numbers that are non-zero:
15:35:50 DOWN applied 3, skipped 1 · UP pushed 12 1.2sA cycle that moved nothing reads idle rather than a row of zeros.
The moment output is piped or redirected — which is what a scheduler does — it falls back to one self-contained line per cycle:
2026-08-05T07:36:00.132Z [agent] PAC001 LOCAL — DOWN applied 0, skipped 0, failed 0 | UP scanned 0, pushed 0, dropped 0 across 1 table(s) | counted 0 table(s) | 911msEvery number is always present here, so the line stays greppable and each entry carries its
own timestamp. --plain forces this form in a terminal. NO_COLOR=1 keeps the compact
layout but drops the escape codes.
Failures are called out on their own line with the cause attached, rather than a bare
fetch failed:
15:32:50 cycle failed
! fetch failed (ECONNREFUSED)When an apply fails, that line names the table and row id that stopped the queue, which is usually enough to diagnose without opening the dashboard.
What the numbers mean
| Number | Counts |
|---|---|
applied | Rows written from the other side's queue |
skipped | Rows already identical, so nothing was written |
failed | Rows that could not be written; the queue stops here |
conflicts | Rows both sides created independently |
scanned | Outbox rows read this cycle |
pushed | Changes sent to the server |
dropped | Outbox rows for tables no longer configured, or for a disallowed operation |
counted | Tables whose row count was reported |