The oar command
oar is the command line of the relay machine. It writes the config, starts and
stops the relay, prints the address you open in a browser, installs the
start-at-login service, updates OAR, checks the install and
removes it again. It acts on the
install it was started from, on the machine where it runs; it does not talk to
a relay on another machine.
Run oar with nothing after it for a menu, or oar help for the usage text.
How to install OAR is on Install, the first
start on First run.
The commands #
| Command | What it does |
|---|---|
oar |
A menu in a terminal; the status and the usage text elsewhere |
oar setup |
Writes the config: auth token, access (this machine or LAN) and port; on Windows also the autostart mode |
oar start |
Starts the relay in the background |
oar stop |
Stops the relay once no turn is running |
oar restart |
Restarts a running relay, or starts a stopped one |
oar status |
Says whether the relay runs; exit code 0 or 3 |
oar url |
Prints the relay address with the token, and a QR code where a phone can use it |
oar update |
Installs the newest release, or one you name, and restarts the relay |
oar service |
Installs, removes or reports the start-at-login service |
oar autostart |
Added in 0.9.15 Switches how the relay starts by itself: at sign-in, at boot, or off |
oar uninstall |
Added in 0.9.15 Removes the autostart entries and the package; the data stays unless you add --purge |
oar copilot |
Starts the relay and a GitHub Copilot terminal session |
oar doctor |
Prints the install, the config and the provider CLIs it finds |
oar help |
Prints the usage text |
oar version |
Prints the version |
Most messages start with [oar]. Errors go to standard error, normal output to
standard output.
How the command line is read #
- The command is the first word that is not an option. Options may come before
it:
oar --port 3400 setupisoar setup --port 3400. --port,--migrate-,from --toand--autostarttake a value, as the next word or as--port=. Without a value3400 oarprints--port needs a value.and exits 2. Foroar update --toandoar copilot --migrate-use the space-separated form; see the notes under those commands.from --helpor-hbefore a--prints the usage text and exits 0, whatever else is on the line.--setup,--start,--stopand--statusname a command when no other is given:oar --setup --startisoar setup --start.--install-,extension --no-,install- extension --migrate-or afrom --part without a command meanoar copilot.--versionor-vwithout a command print the version.- Each command accepts only its own options and prints the usage text after one of these messages (to standard error), exit code 2:
[oar] Unknown command: backup
[oar] Unknown option: --verbose
[oar] Unknown option for oar start: --port
[oar] Unexpected argument: extra
[oar] --lan needs a command.
[oar] oar start takes no "--" part.
Only oar copilot takes a -- part.
The menu: oar #
In a terminal, oar shows the version, whether the relay runs, the URL
(without the token), the port, the access, the service state and any warning,
then these entries:
| Key | Entry | Runs |
|---|---|---|
1 |
Start | oar start |
2 |
Stop | oar stop |
3 |
Restart | oar restart |
4 |
Show URL and QR code | oar url |
5 |
Settings | oar setup, with its questions |
6 |
Install or remove the service | oar service install when none is installed; oar service remove after Remove the service? [y/ when one is; oar service status where no service is available |
7 |
Update | oar update. After a successful update the menu closes, because its own files were replaced |
8 |
Doctor | oar doctor |
9 |
Copilot session | oar copilot |
q |
Quit |
Move with the arrow keys (or j and k) and press Enter, or press a digit or
q. After an entry has run, any key goes back to the menu. Ctrl+C inside a
question returns to the menu; in the menu it ends oar with exit code 130. The
NO_ environment variable switches colour off. A terminal that cannot
read single keys gets the same list with a Choose (1- prompt.
When standard input or output is not a terminal, oar prints what
oar status prints, an empty line and the usage text, and exits 0
whatever the status is.
oar setup #
oar setup [--port <port>] [--lan | --local] [--new-token] [--autostart signin|boot|off] [--defaults] [--start] [--migrate-from <dir>]
Writes config. in OAR's state folder (Where oar keeps its files;
the keys are on config.json). Run it after
installing and whenever you want another port, access or token. Settings the
command does not touch stay as they are in an existing config.
In a terminal, and when you pass none of --port, --lan, --local,
--new-, --autostart or --defaults, it asks three questions and shows
the current value in brackets; Enter keeps it. Added in 0.9.15 On Windows a
fourth asks how the relay starts, with the mode in force as the default; it is
left out when the boot task cannot be read. First run
walks through them.
New auth token? It signs every device out. [y/N]
Access: 1 = this machine only, 2 = LAN (other devices on your network) [1]:
Port [3333]:
Autostart: 1 = at sign-in, 2 = at boot, before anyone signs in (one administrator prompt), 3 = off [3]:
| Option | Value | Default | Effect |
|---|---|---|---|
--port |
digits, 1 to 65535 | the config's port; for a new config the first free port from 3333 up (of 20 tried, else 3333) | Sets the port without asking. A port that something else holds is refused |
--lan |
none | the config's access | Access for other devices on your network (localhost). Not together with --local |
--local |
none | the config's access; this machine only for a new config | Access for this machine only |
--new- |
none | keep the token; a new config gets a random one | Writes a new auth token. It signs every device out |
--autostart |
signin, boot or off |
the mode in force | Added in 0.9.15 Switches the autostart without asking, as oar autostart does: on Windows the sign-in entry or the boot task (one administrator prompt), on Linux the service. Global installs only: a git checkout is refused and nothing is written |
--defaults |
none | off | Asks nothing, even in a terminal, and restarts a running relay without asking |
--start |
none | off | Global installs only (the installer uses it). Where a systemd user session exists it also writes the service unit; then it starts the relay, through the service when there is one. Ignored in a git checkout |
--migrate- |
a folder | none | Copies the state of a git checkout from before the project was renamed (<folder>/) into OAR's state folder. The source is never changed. A relay still running from it blocks the copy. Global installs only. It runs every time you name a folder: a folder already brought over whose database is still there only says <state folder> is already migrated from <folder>; nothing to do.; a folder with nothing to bring over is an error (Nothing to migrate from <folder>: <reason>.); a state folder whose database already has conversations refuses it, and nothing is overwritten. See Files and folders |
A port is free when nothing answers on it and it can be bound on this machine.
The port of this install's own running relay counts as free. In WSL a port that
Windows holds is refused too. For a new config whose port 3333 is taken,
setup says Port 3333 is in use — using <port>. A global install also picks
up state from the earlier managed config folder once, without the option.
What it does:
- Migrates old state (global installs): the earlier managed config folder
once by itself, or the folder
--migrate-names.from [oar] Migrated <folder or "earlier relay state"> into <state folder> (<n> items, sources untouched; receipt in backups/MIGRATION. md). - Writes
config.(permission 600 outside Windows) and printsjson [oar] Wrote <path>. A new config holdsauth,Token port,localhost,Only poll(3000),Interval Ms processing(600000) andTimeout Ms conversation(Session Mode isolated). - Added in 0.9.15 Switches the autostart, as
--autostartor the question says (global installs). It runsoar autostartwith that mode and prints its lines. - If the relay runs and the token, port or access changed, it restarts the
relay and waits for it to answer with the new settings. In a terminal it
asks
The relay is running. Restart it now to apply the change? [Y/; on no it printsn] The running relay keeps its earlier settings until it restarts: oar restart. Without a terminal it restarts without asking. - Prints the relay URL with the token, and a QR code when a phone can reach the
address (LAN access with a network address that is not internal to WSL).
If the autostart step did not go through, it then says
The config is written; the autostart step did not go through (see above).and exits 1. - When the relay is not running, says how to start it:
oar start(with a hint aboutoar service installwhen no service exists); in a git checkout,npm start.
| Exit code | When |
|---|---|
| 0 | The config is written, and the restart or start that was asked for worked |
| 1 | The port is taken; the relay did not restart or come up; the migration is refused or fails (a relay running from the source or on the state folder, a database with conversations already there, nothing to migrate from the folder you named); the autostart step did not go through; --autostart in a git checkout |
| 2 | --port is not a number from 1 to 65535 (--port expects a number from 1 to 65535.), --autostart is not signin, boot or off (--autostart expects signin, boot or off.), or --lan and --local are both given |
| 130 | Ctrl+C in a question |
oar start #
oar start
Starts the relay in the background and prints the relay URL (with the token,
without a QR code). It has no options. It needs a config: without one it
prints No config yet — run: oar setup. A git checkout is refused (This is a git checkout — start the relay with: npm start). Both exit 1.
- A relay that already answers is left alone:
The relay is already running. It keeps the version and settings it started with until you restart it: oar restart. - If the relay runs with settings from before a
oar setup,oar startsays so and points tooar restart. - With a systemd user service installed (Linux), the service is enabled and
started. Otherwise the relay starts as a background process that outlives the
terminal and writes
server.andlog server-to the log folder. After a reboot, runerr. log oar startagain, or set up start at login. - It waits up to 20 seconds for the relay to answer, and stops waiting early
when the process it started ends. Then:
The relay did not come up — see <log folder>/(through the service:server- err. log see journalctl --user -u oar). Added in 0.9.14 When a live relay holds the lock, a second line names the lock and says what to do:The lock <path> is held by relay process <pid> (started <time>): oar stop, or end process <pid>.When the lock names a process that cannot be told to be a relay:The lock <path> names process <pid>, which cannot be told to be a relay: if no relay is running, end process <pid> or delete the lock. - Added in 0.9.14 A relay that is still bringing over the database it ran on
until now (the first start after the update to 0.9.14) is not counted as
failed:
oar startsaysThe relay (process <pid>) is bringing over the database it ran on until now (…) and is still running; it answers once that is done.and names its log. - A lock whose relay is still starting is waited for, up to 5 seconds. A lock
of an earlier version whose relay does not answer is removed (
Removing a leftover relay lock); Added in 0.9.14 a lock this version wrote is left to the relay, which tells a stale one itself (see One relay per data folder). - A port that another program holds, or a relay with another token:
Port <port> is in use by another program, or by a relay with another token.and a hint to pick another port withoar setup --port <port>. - In WSL it warns when Windows holds the port (WSL).
Exit code 0: the relay runs, or is still bringing over its database. Exit code 1: no config, a git checkout, the port is taken, or the relay did not come up.
oar stop #
oar stop
No options; needs a config (exit 1 without one).
- With the systemd service running, it runs
systemctl --user stop oarat once and saysThe relay service is stopped. It starts again at the next boot (without lingering: at the next login); to take it out: oar service remove. - Any other relay is asked to stop through its own interface and stops once no
turn is running. If turns are running,
Waiting for the relay's running turns to finish …is printed.oar stopwaits up to 30 seconds, then printsThe relay is stopped., orThe relay is still busy; it stops by itself when its running turns finish.Both exit 0. - No relay running:
The relay is not running., exit 0. - Port held by something else:
Port <port> is in use by another program, or by a relay with another token., exit 1. If the lock file names a live process of this install, a second line gives its process id and tells you to restart it from its web UI (⋯ → Restart web relay) or to end that process. The relay did not accept the stop request.or a failedsystemctl: exit 1.
On Windows, and where the service is installed but not running, the relay is stopped through its own interface. See Restarting the relay for what a stop does to running turns.
oar restart #
oar restart
Restarts a running relay so that it loads a new version and reads the config
again, then prints the relay URL. A stopped relay is started instead, as with
oar start. No options; needs a config.
- With the systemd service running, systemd restarts it at once; a running turn ends (Restarting the relay).
- Any other relay is asked to restart and waits for its running turns. The
command waits up to 60 seconds for the relay to answer on the config's port
with the config's token, then prints
The relay restarted.If turns are still running:The relay is still busy; it restarts by itself when its running turns finish., exit 0. Added in 0.9.13 The restart is queued as with 🌄 Restart web relay: the browsers show its banner, and after Ask after a queued relay restart has waited it asks there whether to restart now, keep waiting or cancel (The restart waits). - Exit 1 with
The relay came back on its earlier port and token: it was started with fixed ones (oar copilot). End that session, then run: oar start: a relay started byoar copilotkeeps the port and token it was given. - Exit 1 with
The relay did not accept the restart request. Restart it from the web UI (⋯ → Restart web relay).(Restart web relay),systemctl --user restart oar failed, orThe relay did not come back — see <log folder>/(through the service:server- err. log see journalctl --user -u oar). - A port held by something else: the message of
oar stop, exit 1.
oar status #
oar status
Prints the state of the relay and exits with a code a script can test.
[oar] OAR 0.9.19
[oar] The relay is running on port 3333 (this machine only): http://localhost:3333/
[oar] Service: installed, running
| Line | Meaning |
|---|---|
Not set up yet — run: oar setup |
No config; only the version line comes before it |
The relay is running on port <port> (<access>): <url> |
The relay answers with the config's token. Access is LAN access or this machine only. The URL has no token; oar url prints it |
The relay is stopped (port <port>, <access>). Start it with: oar start |
Nothing answers on the port |
Port <port> is in use by another program, or by a relay with another token. |
Something answers, but it is not this relay with this token |
Service: <state> |
installed, running, installed or not installed. Left out where there is nothing to report: a git checkout, macOS, a Linux without a systemd user session |
Tunnel: <state> |
Only when the built-in Cloudflare tunnel is on in the config. For a running relay: running, not connected, not connected (<reason>) or off: <reason>. Otherwise managed (cloudflared: <path>) or managed, cannot start: <reason> |
| a warning | The relay runs with its earlier settings; restart it to apply the new ones. after a oar setup that changed the port or token; in WSL, that Windows holds the port |
Exit code 0: the relay runs. Exit code 3: it is stopped, the port is held by something else, or there is no config.
oar url #
oar url
Prints the address to open in a browser, with the auth token, the same way
oar setup ends. No options; needs a config (exit 1 without one). Otherwise
exit 0.
[oar] Relay URL: http://localhost:3333/?token=...
[oar] This machine only. For a phone, switch on LAN access (oar setup --lan) or use a tunnel (README: Remote access).
- With LAN access, the address is the machine's first non-internal IPv4 address, and a QR code for it follows the first line.
- With LAN access but no network address:
LAN access is on, but this machine has no network address.In WSL's default (NAT) networking the address is internal to WSL; the output says so and names a tunnel or mirrored networking as ways out. No QR code in these cases. - When the running relay reports a tunnel address, a
Tunnel URL:line follows with the token added, and a QR code for it. - A last line says
The relay is not running. Start it with: oar start, or, after a setting change, that the relay runs with its earlier settings untiloar restart.
oar update #
oar update [--beta] [--to <version>]
Installs a newer release of OAR from npm and asks a running relay to restart.
It is the terminal twin of the Update button in Settings → General (Updating OAR). A
git checkout prints This install runs from a git checkout — update with git pull, then restart the relay. and exits 1.
| Option | Value | Default | Effect |
|---|---|---|---|
--beta |
none | off | Takes the version of the beta channel from the update manifest (Channels). Without it, a beta version follows the beta channel and any other follows stable. A channel with no version falls back to stable |
--to |
X., optionally with a prerelease (X.) |
newest of the channel | Installs exactly this version straight from npm, without the manifest. Older versions work too; it does not compare with the running one |
Write --to with a space
--to 0. works. --to= passes the check on the command line but is
ignored: oar update then installs the newest release of the channel.
What it does:
- Without
--to, fetcheshttps://(5 seconds), on every run, whether or not the automatic check is on in the web UI.oar. sh/ latest. json - If the channel's version is not newer than the running one:
Already up to date (<version>)., exit 0. - Prints
Updating @oar-and runssh/ oar <old> -> <new> ... npm install -g @oar-, with the flag that lets the install scripts of OAR and its native dependencies run. Away from Windows it runs the npm beside the Node.js that runssh/ oar@<version> oar, into the prefix the package sits in; on Windows,npm.. npm prints its own output; thencmd Installed @oar-sh/ oar@<version>. - If a relay runs, asks it to restart once the queue is idle (
Relay restart requested — it restarts once the queue is idle.); with none,No running relay detected — the update loads on the next start.A refusal printsCould not request a relay restart; restart it manually to load the update.
Exit code 0: installed, or already up to date. Exit code 1: a git checkout;
--to is not a version like 0.; the manifest cannot be fetched (Could not fetch <url>.), has another schema than 1, or carries no usable
version; npm install failed (the running install is unchanged).
| Variable | Effect |
|---|---|
OAR_ |
Blocks the manifest request. oar update then exits 1 and points to oar update --to X., which still works |
OAR_ |
Reads the manifest from this URL instead |
oar service #
oar service [install | remove | status]
Starts the relay at every login. oar service alone is oar service status. A
git checkout is refused (exit 1). The
Start at login page explains the service
from the owner's side.
Linux #
A systemd user unit, oar., in ~/.. It runs the
relay with the config, data and log folders of this install and the PATH of
your shell plus ~/. and the folder of the Node.js in use. systemd
restarts it 5 seconds after a crash.
| Word | What it does |
|---|---|
install |
Needs a config. Writes the unit; runs loginctl enable- so the relay survives a logout (if that fails it prints the command to run yourself); reloads systemd; stops a relay you started by hand so the service can take the port; enables and starts the service. If that relay does not stop, the service is enabled and takes over at the next boot (without lingering, at the next login), or once that relay has stopped and you run oar start |
remove |
Disables and stops the service, deletes the unit, reloads systemd. The service is not installed. if there is none |
status |
Service: installed, running, installed, not running or not installed |
Without a systemd user session the command says so and exits 1. In WSL the
message adds how to switch systemd on: systemd= under [boot] in
/, then wsl --terminate <distro> from Windows.
Windows #
An entry in your Startup folder starts the relay when you sign in.
| Word | What it does |
|---|---|
install |
Needs a config. Switches the sign-in start on; it does not start the relay now (Start it now with: oar start) |
remove |
Switches it off: Autostart is off. A running relay keeps running; stop it with: oar stop |
status |
Autostart: on, at sign-, on, at boot (scheduled task) or off |
A start at boot through a scheduled task is set up with
oar autostart boot or in the web UI under
Settings → General → Autostart (Windows) (Windows). While that task is ready, install and remove
refuse (exit 1) with The relay starts at boot through a scheduled task. Change that with oar autostart signin|off, or in the web UI: Settings → General → Autostart (Windows).; status reports it.
macOS #
The service is not supported on mac,
exit 1 for every word.
Exit code 0: done, or status. Exit code 1: a git checkout, macOS, no systemd
user session, no config on install, a scheduled boot task on Windows, or the
relay did not come up after install. Exit code 2: a word other than the
three, or a second word.
oar autostart Added in 0.9.15 #
oar autostart [signin | boot | off | status] [--replace]
Switches how the relay of this install starts by itself. oar autostart alone
is oar autostart status. A git checkout is refused (This is a git checkout — autostart is for global installs., exit 1). signin and boot need a config;
off and status do not. Autostart
explains the modes from the owner's side.
Windows #
| Word | What it does |
|---|---|
signin |
Writes the entry in your Startup folder, and removes the boot task if there is one (one administrator prompt). Prints The relay starts when you sign in to Windows. It does not start the relay now |
boot |
Registers the scheduled task oar- and its launcher (one administrator prompt: Confirm the administrator prompt to register the boot task …), and removes the sign-in entry. Prints The relay starts at boot, before anyone signs in (scheduled task \ In boot mode already, it changes nothing and asks for no prompt; if the generated launcher is missing or from an earlier version, it registers the task again, with one administrator prompt |
off |
Removes the boot task (one administrator prompt) and the sign-in entry. Autostart is off. A running relay keeps running; stop it with: oar stop |
status |
The mode and every entry, each (generated by OAR) or (hand-; see Status |
The administrator prompt appears on the PC's own desktop and is waited for up
to 2 minutes. Only the schtasks call runs elevated. A declined prompt
changes nothing (Nothing changed: the administrator prompt was declined.).
After a switch with --replace, each copy is named: Kept a copy of <entry> as <copy>. A switch that failed after the prompt puts back the tasks it
deleted, and its error line ends with Copies kept: ….
Only entries that OAR generated are deleted or written over. While an entry made or edited by hand would stay beside the new mode, or be replaced by it, nothing changes and the entry is named; see Entries OAR did not make.
| Option | Effect |
|---|---|
--replace |
Replaces hand-made entries with OAR's own. It keeps a copy of each first, as <name>. in the OAR folder: a launcher's beside it, a task's exported XML (<task>.), a Startup entry's. Without --replace, a hand-made entry is never changed |
A boot task that cannot be read (for example Access is denied) stops every
switch, --replace included: Nothing changed: the boot task could not be read (<reason>).
Linux and macOS #
On Linux the words map onto oar service: signin and boot run
oar service install, off runs oar service remove, status runs
oar service status. With lingering the service starts at boot. On macOS:
Autostart is not supported on mac,
exit 1.
Exit code 0: done, or status. Exit code 1: a git checkout, macOS, no config
for signin or boot, a hand-made entry in the way, a declined or failed
administrator prompt, a boot task that cannot be read, or a sign-in entry that
cannot be changed; on Linux, those of oar service. Exit code 2: another
word, a second word, or another option.
oar uninstall Added in 0.9.15 #
oar uninstall [--purge]
Takes OAR off the machine and keeps your data. A git checkout is refused
(This is a git checkout — there is no global package to uninstall., exit 1).
With --purge it first asks its questions (below); then, in order:
- Stops the relay, as
oar stopdoes: it waits for running turns. A relay that is still busy afterwards ends the command (The relay finishes its running turns first; it stops by itself after them.), and nothing else is changed. A relay that holds its lock without answering, while it brings over a database or starts, ends it too:The relay (process <pid>) is bringing over its database and does not answer yet; once oar status says it runs, run oar uninstall again., orA relay (process <pid>) holds <lock> without answering; stop it (oar stop, or end process <pid>). - Removes the autostart entries OAR generated for this install: on Windows the
boot task (one administrator prompt) with its launcher and task XML, and the
sign-in entry; on Linux the systemd unit, if it is the one
oar service installwrote. Then the Copilot extension wrapper in~/.that OAR wrote for this install. An entry or wrapper made or changed by hand, or one of another install, stays and is named (copilot/ extensions/ web- relay/ Left as it is: <path> (hand-).made) - With
--purge, deletes the data (below). - Starts
npm uninstall -g @oar-in the background, with the npm beside the Node.js that runssh/ oar oarand into the prefix the package sits in (on Windows,npm.). npm cannot remove a package while it runs, so this waits untilcmd oarhas ended (up to 2 minutes), then writes npm's outcome tooar-: in the OARuninstall. log logsfolder, or with--purgein the temp folder.
It ends with what it did:
[oar] Done: stopped the relay.
[oar] Done: removed C:\Users\dev\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\oar-web-relay.cmd.
[oar] Your data stays in C:\Users\dev\AppData\Roaming\oar (config, database, uploads, logs). A later install picks it up again; delete the folder yourself if you no longer need it.
[oar] npm removes @oar-sh/oar once this command has ended (log: C:\Users\dev\AppData\Roaming\oar\logs\oar-uninstall.log).
When the data folder lies outside the state folder, the line names both.
Session workers keep running when the relay stops, and npm cannot remove the
files a running program holds. When programs still run from the package, the
command names their process ids, and npm leaves their files in a hidden
. folder beside where the package was; the log names that folder.
Delete it once they have ended, at the latest after a reboot.
If a step fails, the command stops with the reason (for example Uninstall stopped: <reason>. or The relay did not stop.), then Done: … and
Not done: the autostart entries; the package. (with --purge also the data), and Run oar uninstall again once that is sorted out. (with
--purge: oar uninstall --purge).
| Option | Effect |
|---|---|
--purge |
Also deletes the state folder for good: the config, the database with every conversation, the uploads and the logs. It first says --purge deletes <folder> for good: …, then asks you to type delete (Type "delete" to confirm: ); anything else ends it with Not confirmed. Nothing was changed. Ctrl+C, or no input to read, ends it with exit code 130 and nothing changed |
With --purge, some folders get a question of their own, [y/, after the
delete: the state folder when it lies inside a git checkout,
rescued- (data an earlier version kept inside its package), and
a data folder outside the state folder (data in the config, or
COPILOT_). Whatever you type, --purge deletes nothing in
a state folder that is a drive or file-system root, your home folder or a
folder above it, a system folder or a folder above one, a folder inside the
Windows folder, a git checkout, or a folder without an OAR config or database
in it: --purge deletes nothing in <folder> (<reason>). Nothing was changed.
An extra folder like that is not offered (Not deleted, and not offered: …).
Exit code 0: the package removal is started. Exit code 1: a git checkout; a
state folder --purge refuses; delete not typed; a relay that did not stop
or holds its lock without answering; an autostart entry that could not be
removed (a declined prompt, a boot task that cannot be read); a folder that
could not be deleted; npm could not be started (remove it yourself: npm uninstall -g @oar-). Exit code 2: another option. Exit code 130:
Ctrl+C at a question.
oar copilot #
oar copilot [--port <port>] [--install-extension] [--no-install-extension] [--migrate-from <dir>] [-- <gh copilot args>]
Starts the relay if none answers, then runs the GitHub Copilot CLI
(gh copilot) in your terminal. A relay it started stops when the session
ends. GitHub Copilot explains
when to use it. The same options without the word copilot still run it:
oar -- <args>, oar --install-, oar --port 3400 --no-.
| Option | Value | Default | Effect |
|---|---|---|---|
--port |
1 to 65535 | the config's port, else 3333 | Finds or starts the relay on this port for this run, without changing the config; a config this command creates saves it. A relay already running there is used. A value that is not a port number is ignored without a message |
--install- |
none | off | Writes or refreshes the user-global extension wrapper in ~/. (COPILOT_ moves ~/.) and exits. Needs no gh |
--no- |
none | off | Skips the wrapper for this run. Without it every run writes or refreshes it |
--migrate- |
a folder | none | As for oar setup. Write it with a space: --migrate- is ignored |
-- |
the rest of the line | none | Passed to gh copilot after a -- of its own |
In order: checks that gh exists; refreshes the wrapper (a failure is
reported, and only stops --install-); migrates old state (global
installs); finds the relay on the port; starts it if it does not answer,
waiting up to 20 seconds (Relay did not become ready at <url>); then runs
gh copilot in the current folder with the terminal attached. A relay that
already ran keeps running. A missing config is created with access for this
machine only.
--help or -h before the -- prints the general usage text, not one for
copilot. A --help or -h after the -- prints the usage of oar copilot and exits 0. --install- and --no- after
the -- are read by oar too. None of them reach gh.
The relay of a Copilot session has the port and token it was started with.
oar restart cannot move it; see oar restart.
| Exit code | When |
|---|---|
the code of gh copilot |
The session ran (1 if gh was ended by a signal) |
| 0 | --install- wrote the wrapper |
| 1 | gh is not installed (The Copilot session needs the Git); the wrapper cannot be written with --install-; the port is taken; the relay did not become ready; the relay is still bringing over its database; the state migration failed (a blocked one is reported, Nothing was migrated; starting on the state root as it is., and the session starts anyway) |
oar doctor #
oar doctor
Prints what oar finds. No options, changes nothing, exits 0.
OAR 0.9.19
node : v22.13.0 (linux)
mode : global install
state root : /home/dev/.oar
config : /home/dev/.oar/config.json
port : 3333 (localhostOnly: yes)
auth token : set
tunnel : disabled
database : /home/dev/.oar/data/copilot.db (12.4 MB)
provider CLIs :
gh (Copilot) : gh version 2.60.0 (2025-01-01)
claude : 2.1.0 (Claude Code)
grok : not found
cursor : bundled (@cursor/sdk)
| Line | Meaning |
|---|---|
mode |
global install or git checkout |
state root |
The state folder; (repo- in a git checkout |
config |
The config path, with (missing — run: oar setup) when there is none; port, auth token and tunnel are then left out |
port |
The config's port; localhost is this machine only, no is the network |
auth token |
set or MISSING |
tunnel |
disabled, managed (cloudflared: <path>), or managed, cannot start: <reason> |
database |
The path and size in MB, or (not created yet) |
provider CLIs |
gh (Copilot), claude and grok: the first line of <cli> --version (cut at 60 characters), installed if there is none, not found if the command fails or is missing (5 second limit). cursor is always bundled (@cursor/: Cursor needs no CLI |
warning |
In WSL, when Windows holds the relay's port |
oar help and oar version #
oar help # also: oar --help, oar -h, oar <command> --help
oar version # also: oar --version, oar -v
help prints the usage text. version prints the installed version, for
example 0.. Both exit 0. --version and -v work only without a
command.
Where oar keeps its files #
oar works on one install: the package it was started from and its state
folder.
| Install | State folder | Config | Data | Logs |
|---|---|---|---|---|
| Global, macOS and Linux | ~/. |
config. in it |
data/ |
logs/ |
| Global, Windows | %APPDATA%\ |
config. in it |
data\ |
logs\ |
| Git checkout | server/ of the checkout |
server/ |
server/ |
~/. (Windows: %LOCALAPPDATA%\); npm start writes to server/ |
OAR_ moves the state folder of a global install. A package folder
that contains . counts as a git checkout. The data folder holds the
database copilot., the lock file relay- and, between a
oar setup and the restart that applies it, relay-. The logs
are server. and server-. Other places oar writes:
~/. (Linux service), oar- in
the Windows Startup folder, oar-, the boot task's XML,
oar-, oar- and oar- in %APPDATA%\, and ~/..
Added in 0.9.15 oar autostart --replace keeps its copies as <name>. in
the state folder, and oar uninstall writes oar- to the log
folder (with --purge, to the temp folder).
Environment variables #
| Variable | Used by | Effect |
|---|---|---|
OAR_ |
all | The state folder of a global install |
OAR_ |
update |
1 blocks the manifest request; --to still works |
OAR_ |
update |
Another URL for the manifest |
COPILOT_ |
all | Another log folder |
COPILOT_ |
copilot only |
A config file to use when it exists. The other commands always use the install's own config. |
COPILOT_ |
copilot, start, restart, setup, uninstall, Windows autostart |
Handed to the relay as its data folder when these start it, except by the Linux service. setup migrates into it, and uninstall names it and offers it under --purge. oar itself looks for the lock file in the default data folder |
COPILOT_, COPILOT_, COPILOT_ |
status, doctor |
Change the Tunnel: line of status and the tunnel line of doctor, as they change the relay's tunnel |
COPILOT_ |
copilot |
The Copilot home folder for the wrapper, default ~/. |
APPDATA, USERPROFILE, LOCALAPPDATA, XDG_ |
all | Windows and legacy folder locations |
NO_ |
menu | Switches colour off |
PATH |
service install |
The service gets this PATH (plus ~/. and the Node.js folder) |
How oar finds the relay #
oar reads the port and token from the install's config. and asks
http:// with the token:
| Answer | oar reads it as |
|---|---|
| The status of a relay | The relay runs |
| Any other answer (a wrong token, another program), or no reply within 2.5 seconds | The port is held by another program, or by a relay with another token |
| The connection is refused | The relay is stopped |
A lock file is no proof: it can outlive its relay. oar start and
oar copilot wait for a relay that holds it and does not answer yet, and
remove only a lock an earlier version wrote. oar update takes a live lock as
a running relay. oar uninstall does not go on while a live process holds
it. Between an oar setup that changed the port or
token and the restart that applies it, the relay still answers on the old
ones; oar finds it through relay- and says it runs with its
earlier settings.
With the service installed, start, stop and restart go through systemd on
Linux (at once, without waiting for turns); otherwise start launches a
detached process and stop and restart use the relay's own interface, which
waits until no turn is running. On Windows autostart is never involved in
start; status shows Service: installed when autostart or the boot task is
on.
WSL #
In WSL, oar detects the distribution (WSL_ or WSL_, or
the kernel release) and asks Windows which program holds a port. oar setup
refuses a port Windows holds. oar setup, start, status and doctor print
Windows holds port <port> (<program>): a browser on Windows reaches that program, not this relay. Pick another port: oar setup --port N. With LAN
access on in WSL's default networking, oar url says the address is internal
to WSL.
Exit codes #
| Code | Meaning | Commands |
|---|---|---|
| 0 | Done; stop and restart also when the relay is still busy and finishes by itself |
all; status only when the relay runs |
| 1 | The command could not do what you asked: no config, a git checkout, the port is taken, the relay did not come up or accept the request, npm install failed, gh is missing, an administrator prompt was declined, a hand-made autostart entry is in the way, --purge was not confirmed; also an unexpected error |
setup, start, stop, restart, url, update, service, autostart, uninstall, copilot |
| 2 | Usage error: unknown command or option, a missing value, a bad --port (not copilot) or --autostart, --lan with --local |
all |
| 3 | The relay is not running (stopped, held by something else, or not set up) | status only |
| 130 | Ctrl+C in a question or in the menu | setup, uninstall, the menu |
the code of gh copilot |
The Copilot session ended | copilot |