所有頁面
本頁內容

oar 指令

oar 是中繼所在機器上的命令列工具。它會寫入設定檔、啟動和停止中繼、印出你要在瀏覽器中開啟的位址、安裝登入時啟動的服務、更新 OAR、檢查安裝狀態,也能再把它移除。它作用於啟動它的那個安裝,在它執行的那台機器上;它不會和另一台機器上的中繼溝通。

不加任何參數執行 oar 會出現選單,oar help 則印出用法說明。如何安裝 OAR 請見安裝,第一次啟動請見首次執行。

指令 #

指令 作用
oar 在終端機中是選單;在其他地方則印出狀態和用法說明
oar setup 寫入設定檔:驗證 token、存取範圍(僅限本機或區域網路)和連接埠;在 Windows 上還有自動啟動模式
oar start 在背景啟動中繼
oar stop 在沒有回合執行時停止中繼
oar restart 重新啟動執行中的中繼,或啟動已停止的中繼
oar status 告訴你中繼是否在執行;結束代碼為 0 或 3
oar url 印出含 token 的中繼位址,在手機可以使用它時也印出 QR 碼
oar update 安裝最新版本或你指定的版本,並重新啟動中繼
oar service 安裝、移除或回報登入時啟動的服務
oar autostart 0.9.15 新增 切換中繼自行啟動的方式:登入時、開機時或關閉
oar uninstall 0.9.15 新增 移除自動啟動項目和套件;除非加上 --purge,否則資料會保留
oar copilot 啟動中繼和一個 GitHub Copilot 終端機 session
oar doctor 印出安裝、設定檔以及它找到的供應商 CLI
oar help 印出用法說明
oar version 印出版本

大多數訊息以 [oar] 開頭。錯誤會寫到標準錯誤,一般輸出則寫到標準輸出。

命令列的解讀方式 #

  • 指令是第一個不是選項的字。選項可以放在它前面:oar --port 3400 setup 等同於 oar setup --port 3400。
  • --port、--migrate-from、--to 和 --autostart 需要一個值,可以寫成下一個字,也可以寫成 --port=3400。沒有值時,oar 會印出 --port needs a value. 並以 2 結束。oar update --to 和 oar copilot --migrate-from 請使用以空格分隔的寫法;見這兩個指令下方的說明。
  • 出現在 -- 之前的 --help 或 -h 會印出用法說明並以 0 結束,不論這一行還有什麼。
  • 沒有指定其他指令時,--setup、--start、--stop 和 --status 就代表該指令:oar --setup --start 等同於 oar setup --start。
  • 沒有指令時,--install-extension、--no-install-extension、--migrate-from 或 -- 部分代表 oar copilot。沒有指令時,--version 或 -v 會印出版本。
  • 每個指令只接受自己的選項,遇到其他選項時會印出下列其中一則訊息(到標準錯誤),再印出用法說明,結束代碼為 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.

只有 oar copilot 接受 -- 部分。

在終端機中,oar 會顯示版本、中繼是否在執行、URL(不含 token)、連接埠、存取範圍、服務狀態和任何警告,然後列出這些項目:

按鍵 項目 執行
1 Start(啟動) oar start
2 Stop(停止) oar stop
3 Restart(重新啟動) oar restart
4 Show URL and QR code(顯示 URL 與 QR 碼) oar url
5 Settings(設定) oar setup,包含它的問題
6 Install or remove the service(安裝或移除服務) 沒有安裝服務時為 oar service install;已安裝服務時,在 Remove the service? [y/N] 之後執行 oar service remove;無法使用服務的環境則為 oar service status
7 Update(更新) oar update。更新成功後選單會關閉,因為它自己的檔案已被取代
8 Doctor(診斷) oar doctor
9 Copilot session oar copilot
q Quit(結束)

用方向鍵(或 j 和 k)移動並按 Enter,或直接按數字或 q。項目執行完後,按任意鍵即可回到選單。在問題中按 Ctrl+C 會回到選單;在選單中按 Ctrl+C 則會結束 oar,結束代碼為 130。NO_COLOR 環境變數會關閉色彩。無法讀取單一按鍵的終端機會看到同一份清單,並出現 Choose (1-9, q): 提示。

當標準輸入或輸出不是終端機時,oar 會印出 oar status 印出的內容、一個空行和用法說明,並以 0 結束,不論狀態為何。

oar setup #

oar setup [--port <port>] [--lan | --local] [--new-token] [--autostart signin|boot|off] [--defaults] [--start] [--migrate-from <dir>]

在 OAR 的狀態資料夾中寫入 config.json(oar 把檔案放在哪裡;各個 key 請見 config.json)。請在安裝之後,以及每當你想換連接埠、存取範圍或 token 時執行它。這個指令不處理的設定,在現有設定檔中保持原樣。

在終端機中,且你沒有傳入 --port、--lan、--local、--new-token、--autostart 或 --defaults 中的任何一個時,它會問三個問題,並在方括號中顯示目前的值;按 Enter 會保留這個值。0.9.15 新增 在 Windows 上還有第四個問題,詢問中繼如何啟動,預設值是目前生效的模式;無法讀取開機任務時會略過這個問題。首次執行會逐一說明這些問題。

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]:
選項 值 預設值 效果
--port 數字,1 到 65535 設定檔中的連接埠;新的設定檔則是從 3333 起第一個空閒的連接埠(最多嘗試 20 個,否則為 3333) 不經詢問直接設定連接埠。其他程式占用的連接埠會被拒絕
--lan 無 設定檔中的存取範圍 讓你網路上的其他裝置可以存取(localhostOnly: false)。不能和 --local 一起使用
--local 無 設定檔中的存取範圍;新的設定檔為 this machine only(僅限本機) 僅限本機存取
--new-token 無 保留 token;新的設定檔會得到隨機的 token 寫入新的驗證 token。所有裝置都會被登出
--autostart signin、boot 或 off 目前生效的模式 0.9.15 新增 不經詢問直接切換自動啟動,和 oar autostart 的作用相同:在 Windows 上是登入項目或開機任務(一次系統管理員提示),在 Linux 上是服務。僅限全域安裝:git 檢出會被拒絕,且不會寫入任何東西
--defaults 無 關閉 什麼都不問,即使在終端機中也一樣,並且不經詢問就重新啟動執行中的中繼
--start 無 關閉 僅限全域安裝(安裝程式會使用它)。在有 systemd 使用者 session 的環境中,它也會寫入服務 unit;接著啟動中繼,有服務時透過服務啟動。在 git 檢出中會被忽略
--migrate-from 一個資料夾 無 把專案改名之前的 git 檢出的狀態(<folder>/server)複製到 OAR 的狀態資料夾。來源絕不會被更動。仍有中繼從那裡執行時,複製會被擋下。僅限全域安裝。每次你指定資料夾它都會執行:已經搬過、資料庫仍在的資料夾只會顯示 <state folder> is already migrated from <folder>; nothing to do.;沒有東西可搬的資料夾會報錯(Nothing to migrate from <folder>: <reason>.);狀態資料夾的資料庫中已經有對話時,它會拒絕,不會覆寫任何東西。見檔案與資料夾

沒有任何東西在某個連接埠上回應、而且這台機器可以綁定它時,該連接埠就是空閒的。這個安裝自己正在執行的中繼所用的連接埠也算空閒。在 WSL 中,Windows 占用的連接埠也會被拒絕。對於連接埠 3333 已被占用的新設定檔,setup 會顯示 Port 3333 is in use — using <port>.。全域安裝也會從先前的受管理設定資料夾自動搬入一次狀態,不需要這個選項。

它的步驟:

  1. 搬移舊狀態(全域安裝):先前的受管理設定資料夾會自動搬一次,或者搬 --migrate-from 指定的資料夾。[oar] Migrated <folder or "earlier relay state"> into <state folder> (<n> items, sources untouched; receipt in backups/MIGRATION.md).
  2. 寫入 config.json(在 Windows 以外權限為 600),並印出 [oar] Wrote <path>。新的設定檔包含 authToken、port、localhostOnly、pollIntervalMs(3000)、processingTimeoutMs(600000)和 conversationSessionMode(isolated)。
  3. 0.9.15 新增 依 --autostart 或問題的答案切換自動啟動(全域安裝)。它會以該模式執行 oar autostart,並印出它的輸出行。
  4. 如果中繼正在執行,且 token、連接埠或存取範圍有變更,它會重新啟動中繼,並等待中繼以新設定回應。在終端機中它會詢問 The relay is running. Restart it now to apply the change? [Y/n];回答否時印出 The running relay keeps its earlier settings until it restarts: oar restart。沒有終端機時,它不經詢問直接重新啟動。
  5. 印出含 token 的中繼 URL,並在手機能連到該位址時印出 QR 碼(區域網路存取,且網路位址不是 WSL 內部的位址)。如果自動啟動步驟沒有成功,它接著會顯示 The config is written; the autostart step did not go through (see above). 並以 1 結束。
  6. 中繼沒有在執行時,說明如何啟動它:oar start(沒有服務時會附上 oar service install 的提示);在 git 檢出中則是 npm start。
結束代碼 時機
0 設定檔已寫入,且要求的重新啟動或啟動已成功
1 連接埠被占用;中繼沒有重新啟動或沒有啟動起來;搬移被拒絕或失敗(有中繼從來源或在狀態資料夾上執行、那裡的資料庫已有對話、你指定的資料夾沒有東西可搬);自動啟動步驟沒有成功;在 git 檢出中使用 --autostart
2 --port 不是 1 到 65535 的數字(--port expects a number from 1 to 65535.)、--autostart 不是 signin、boot 或 off(--autostart expects signin, boot or off.),或同時指定了 --lan 和 --local
130 在問題中按 Ctrl+C

oar start #

oar start

在背景啟動中繼,並印出中繼 URL(含 token,不含 QR 碼)。它沒有選項。它需要設定檔:沒有設定檔時會印出 No config yet — run: oar setup。git 檢出會被拒絕(This is a git checkout — start the relay with: npm start)。兩者都以 1 結束。

  • 已經有回應的中繼不會被動到:The relay is already running. It keeps the version and settings it started with until you restart it: oar restart。
  • 如果中繼以 oar setup 之前的設定執行,oar start 會說明這一點,並指向 oar restart。
  • 安裝了 systemd 使用者服務時(Linux),會啟用並啟動該服務。否則中繼會以背景處理程序啟動,在終端機關閉後繼續執行,並把 server.log 和 server-err.log 寫到記錄資料夾。重新開機後,請再執行一次 oar start,或設定登入時啟動。
  • 它最多等待 20 秒讓中繼回應,如果它啟動的處理程序結束了,就提早停止等待。接著顯示:The relay did not come up — see <log folder>/server-err.log(透過服務時為 see journalctl --user -u oar)。0.9.14 新增 當有存活的中繼持有鎖定檔時,第二行會指出該鎖定檔並說明該怎麼做:The lock <path> is held by relay process <pid> (started <time>): oar stop, or end process <pid>.。當鎖定檔指向一個無法判斷是否為中繼的處理程序時: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.
  • 0.9.14 新增 仍在把它至今使用的資料庫搬過來的中繼(更新到 0.9.14 後的第一次啟動)不算失敗:oar start 會顯示 The relay (process <pid>) is bringing over the database it ran on until now (…) and is still running; it answers once that is done.,並指出它的記錄檔。
  • 對於中繼仍在啟動中的鎖定檔,會最多等待 5 秒。較早版本留下、且中繼沒有回應的鎖定檔會被移除(Removing a leftover relay lock);0.9.14 新增 這個版本寫入的鎖定檔則交給中繼處理,中繼會自己辨認過時的鎖定檔(見每個資料目錄一個中繼)。
  • 連接埠被其他程式占用,或被使用其他 token 的中繼占用時:Port <port> is in use by another program, or by a relay with another token.,並提示用 oar setup --port <port> 選擇其他連接埠。
  • 在 WSL 中,Windows 占用該連接埠時會發出警告(WSL)。

結束代碼 0:中繼正在執行,或仍在搬移它的資料庫。結束代碼 1:沒有設定檔、git 檢出、連接埠被占用,或中繼沒有啟動起來。

oar stop #

oar stop

沒有選項;需要設定檔(沒有時以 1 結束)。

  • systemd 服務正在執行時,它會立即執行 systemctl --user stop oar,並顯示 The relay service is stopped. It starts again at the next boot (without lingering: at the next login); to take it out: oar service remove。
  • 其他任何中繼都會透過它自己的介面被要求停止,並在沒有回合執行時停止。如果有回合在執行,會印出 Waiting for the relay's running turns to finish …。oar stop 最多等待 30 秒,然後印出 The relay is stopped.,或 The relay is still busy; it stops by itself when its running turns finish.。兩者都以 0 結束。
  • 沒有中繼在執行:The relay is not running.,以 0 結束。
  • 連接埠被其他東西占用:Port <port> is in use by another program, or by a relay with another token.,以 1 結束。如果鎖定檔指向這個安裝的一個存活處理程序,第二行會列出它的處理程序 ID,並請你用 ⋯ → Restart web relay(⋯ → 重新啟動網頁中繼)從它的網頁介面重新啟動它,或結束該處理程序。
  • The relay did not accept the stop request. 或 systemctl 失敗:以 1 結束。

在 Windows 上,以及服務已安裝但未執行時,中繼會透過它自己的介面停止。停止對執行中的回合有什麼影響,請見重新啟動中繼。

oar restart #

oar restart

重新啟動執行中的中繼,讓它載入新版本並重新讀取設定檔,然後印出中繼 URL。已停止的中繼則會被啟動,和 oar start 一樣。沒有選項;需要設定檔。

  • systemd 服務正在執行時,systemd 會立即重新啟動它;執行中的回合會結束(重新啟動中繼)。
  • 其他任何中繼都會被要求重新啟動,並等待它執行中的回合。指令最多等待 60 秒,直到中繼在設定檔的連接埠上以設定檔的 token 回應,然後印出 The relay restarted.。如果仍有回合在執行:The relay is still busy; it restarts by itself when its running turns finish.,以 0 結束。0.9.13 新增 這次重新啟動會像 🌄 Restart web relay 一樣排入佇列:瀏覽器會顯示它的橫幅,並在 Ask after a queued relay restart has waited(排入佇列的中繼重新啟動等待多久後詢問)設定的時間過後,在那裡詢問要立即重新啟動、繼續等待還是取消(重新啟動會等待)。
  • 以 1 結束並顯示 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:由 oar copilot 啟動的中繼會保留它被指定的連接埠和 token。
  • 以 1 結束並顯示 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,或 The relay did not come back — see <log folder>/server-err.log(透過服務時為 see journalctl --user -u oar)。
  • 連接埠被其他東西占用:與 oar stop 相同的訊息,以 1 結束。

oar status #

oar status

印出中繼的狀態,並以腳本可以檢查的代碼結束。

[oar] OAR 0.9.19
[oar] The relay is running on port 3333 (this machine only): http://localhost:3333/
[oar] Service: installed, running
行 意義
Not set up yet — run: oar setup 沒有設定檔;前面只有版本那一行
The relay is running on port <port> (<access>): <url> 中繼以設定檔的 token 回應。Access 為 LAN access(區域網路存取)或 this machine only。URL 不含 token;oar url 會印出含 token 的 URL
The relay is stopped (port <port>, <access>). Start it with: oar start 連接埠上沒有任何回應
Port <port> is in use by another program, or by a relay with another token. 有東西回應,但不是這個中繼搭配這個 token
Service: <state> installed, running(已安裝,執行中)、installed 或 not installed(未安裝)。沒有可回報的內容時省略:git 檢出、macOS、沒有 systemd 使用者 session 的 Linux
Tunnel: <state> 只在設定檔中開啟了內建的 Cloudflare tunnel 時出現。中繼執行中時:running、not connected、not connected (<reason>) 或 off: <reason>。否則為 managed (cloudflared: <path>) 或 managed, cannot start: <reason>
警告 在變更了連接埠或 token 的 oar setup 之後顯示 The relay runs with its earlier settings; restart it to apply the new ones.;在 WSL 中,則是 Windows 占用了該連接埠

結束代碼 0:中繼正在執行。結束代碼 3:中繼已停止、連接埠被其他東西占用,或沒有設定檔。

oar url #

oar url

印出要在瀏覽器中開啟的位址(含驗證 token),方式與 oar setup 的結尾相同。沒有選項;需要設定檔(沒有時以 1 結束)。其他情況以 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).
  • 使用區域網路存取時,位址是這台機器第一個非內部的 IPv4 位址,第一行之後會接著它的 QR 碼。
  • 使用區域網路存取但沒有網路位址時:LAN access is on, but this machine has no network address.。在 WSL 預設的(NAT)網路模式中,位址是 WSL 內部的位址;輸出會說明這一點,並提出 tunnel 或鏡像網路模式作為解法。這些情況下不會有 QR 碼。
  • 執行中的中繼回報 tunnel 位址時,接著會有一行附上 token 的 Tunnel URL:,以及它的 QR 碼。
  • 最後一行會顯示 The relay is not running. Start it with: oar start,或在設定變更後,說明中繼會以先前的設定執行,直到 oar restart。

oar update #

oar update [--beta] [--to <version>]

從 npm 安裝較新的 OAR 版本,並要求執行中的中繼重新啟動。它相當於 Settings → General(設定 → 一般)中 Update 按鈕的終端機版本(更新 OAR)。git 檢出會印出 This install runs from a git checkout — update with git pull, then restart the relay. 並以 1 結束。

選項 值 預設值 效果
--beta 無 關閉 從更新 manifest 取用 beta 通道的版本(通道)。沒有這個選項時,beta 版本會跟隨 beta 通道,其他版本則跟隨 stable。沒有版本的通道會退回 stable
--to X.Y.Z,可加上預發行標記(X.Y.Z-beta.N) 該通道的最新版本 直接從 npm 安裝這個確切的版本,不經過 manifest。較舊的版本也可以;它不會和執行中的版本比較

--to 要用空格分隔

--to 0.9.2 可以運作。--to=0.9.2 能通過命令列的檢查,但會被忽略:oar update 接著會安裝該通道的最新版本。

它的步驟:

  1. 沒有 --to 時,取得 https://oar.sh/latest.json(5 秒);每次執行都會這麼做,不論網頁介面中的自動檢查是否開啟。
  2. 如果通道的版本沒有比執行中的版本新:Already up to date (<version>).,以 0 結束。
  3. 印出 Updating @oar-sh/oar <old> -> <new> ... 並執行 npm install -g @oar-sh/oar@<version>,附上允許 OAR 及其原生相依套件執行安裝腳本的旗標。在 Windows 以外,它會執行與執行 oar 的 Node.js 位於同處的 npm,安裝到套件所在的 prefix;在 Windows 上則是 npm.cmd。npm 會印出它自己的輸出;接著是 Installed @oar-sh/oar@<version>.
  4. 如果有中繼在執行,會要求它在佇列閒置時重新啟動(Relay restart requested — it restarts once the queue is idle.);沒有中繼時則顯示 No running relay detected — the update loads on the next start.。要求被拒絕時會印出 Could not request a relay restart; restart it manually to load the update.

結束代碼 0:已安裝,或已是最新版本。結束代碼 1:git 檢出;--to 不是像 0.9.2 這樣的版本;無法取得 manifest(Could not fetch <url>.)、它的 schemaVersion 不是 1,或它沒有可用的版本;npm install 失敗(the running install is unchanged)。

變數 效果
OAR_NO_UPDATE_CHECK=1 封鎖 manifest 請求。oar update 接著會以 1 結束,並指向仍然可用的 oar update --to X.Y.Z
OAR_UPDATE_MANIFEST_URL 改從這個 URL 讀取 manifest

oar service #

oar service [install | remove | status]

讓中繼在每次登入時啟動。單獨的 oar service 等同於 oar service status。git 檢出會被拒絕(以 1 結束)。自動啟動中繼頁面從擁有者的角度說明這個服務。

Linux #

一個 systemd 使用者 unit,也就是 ~/.config/systemd/user/ 中的 oar.service。它以這個安裝的設定檔、資料目錄和記錄資料夾,以及你 shell 的 PATH 加上 ~/.local/bin 和目前使用的 Node.js 所在資料夾來執行中繼。中繼當機 5 秒後,systemd 會重新啟動它。

子指令 作用
install 需要設定檔。寫入 unit;執行 loginctl enable-linger,讓中繼在登出後繼續執行(若失敗,會印出讓你自己執行的指令);重新載入 systemd;停止你手動啟動的中繼,讓服務可以使用該連接埠;啟用並啟動服務。如果那個中繼沒有停止,服務會被啟用,並在下次開機時接手(沒有 lingering 時則是下次登入時),或在那個中繼停止、你執行 oar start 之後接手
remove 停用並停止服務、刪除 unit、重新載入 systemd。沒有服務時顯示 The service is not installed.
status Service: installed, running、installed, not running 或 not installed

沒有 systemd 使用者 session 時,指令會說明這一點並以 1 結束。在 WSL 中,訊息還會說明如何開啟 systemd:在 /etc/wsl.conf 的 [boot] 下加入 systemd=true,然後從 Windows 執行 wsl --terminate <distro>。

Windows #

你啟動資料夾中的一個項目會在你登入時啟動中繼。

子指令 作用
install 需要設定檔。開啟登入時啟動;它不會立即啟動中繼(Start it now with: oar start)
remove 關閉登入時啟動:Autostart is off. A running relay keeps running; stop it with: oar stop
status Autostart: on, at sign-in、on, at boot (scheduled task) 或 off

透過排程工作在開機時啟動,要用 oar autostart boot 設定,或在網頁介面的 Settings → General → Autostart (Windows)(設定 → 一般 → 自動啟動,Windows)中設定(Windows)。只要該工作處於就緒狀態,install 和 remove 就會拒絕執行(以 1 結束),並顯示 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 會回報它。

macOS #

The service is not supported on macOS yet. Start the relay with: oar start,每個子指令都以 1 結束。

結束代碼 0:完成,或 status。結束代碼 1:git 檢出、macOS、沒有 systemd 使用者 session、install 時沒有設定檔、Windows 上有排程的開機任務,或 install 之後中繼沒有啟動起來。結束代碼 2:這三個以外的子指令,或第二個子指令。

oar autostart 0.9.15 新增 #

oar autostart [signin | boot | off | status] [--replace]

切換這個安裝的中繼如何自行啟動。單獨的 oar autostart 等同於 oar autostart status。git 檢出會被拒絕(This is a git checkout — autostart is for global installs.,以 1 結束)。signin 和 boot 需要設定檔;off 和 status 不需要。自動啟動從擁有者的角度說明這些模式。

Windows #

子指令 作用
signin 在你的啟動資料夾中寫入項目,若有開機任務則將它移除(一次系統管理員提示)。印出 The relay starts when you sign in to Windows.。它不會立即啟動中繼
boot 註冊排程工作 oar-relay 和它的啟動器(一次系統管理員提示:Confirm the administrator prompt to register the boot task …),並移除登入項目。印出 The relay starts at boot, before anyone signs in (scheduled task \oar-relay).。已經處於開機模式時,它不做任何變更,也不會要求提示;如果產生的啟動器不見了或來自較早的版本,它會再次註冊工作,需要一次系統管理員提示
off 移除開機任務(一次系統管理員提示)和登入項目。Autostart is off. A running relay keeps running; stop it with: oar stop
status 模式和每個項目,各自標示 (generated by OAR) 或 (hand-made);見狀態

系統管理員提示會出現在這台電腦本機的桌面上,最多等待 2 分鐘。只有 schtasks 呼叫以提升的權限執行。拒絕提示不會變更任何東西(Nothing changed: the administrator prompt was declined.)。使用 --replace 切換後,每份副本都會列出名稱:Kept a copy of <entry> as <copy>。在提示之後失敗的切換,會把它刪除的工作放回去,它的錯誤行以 Copies kept: … 結尾。

只有 OAR 產生的項目會被刪除或覆寫。如果手動建立或編輯過的項目會留在新模式旁邊,或會被新模式取代,就不做任何變更,並列出該項目的名稱;見非 OAR 建立的項目。

選項 效果
--replace 以 OAR 自己的項目取代手動建立的項目。它會先為每個項目保留一份副本,以 <name>.bak 的形式存放在 OAR 資料夾中:啟動器的副本放在它旁邊,工作的副本是匯出的 XML(<task>.task.xml.bak),啟動資料夾項目也一樣保留副本。沒有 --replace 時,手動建立的項目絕不會被變更

無法讀取的開機任務,例如 Access is denied(拒絕存取),會擋下每次切換,包括 --replace:Nothing changed: the boot task could not be read (<reason>).

Linux 與 macOS #

在 Linux 上,這些子指令對應到 oar service:signin 和 boot 執行 oar service install,off 執行 oar service remove,status 執行 oar service status。有 lingering 時,服務會在開機時啟動。在 macOS 上:Autostart is not supported on macOS yet. Start the relay with: oar start,以 1 結束。

結束代碼 0:完成,或 status。結束代碼 1:git 檢出、macOS、signin 或 boot 沒有設定檔、有手動建立的項目擋路、系統管理員提示被拒絕或失敗、無法讀取的開機任務,或無法變更的登入項目;在 Linux 上則是 oar service 的那些情況。結束代碼 2:其他子指令、第二個子指令,或其他選項。

oar uninstall 0.9.15 新增 #

oar uninstall [--purge]

把 OAR 從這台機器上移除,並保留你的資料。git 檢出會被拒絕(This is a git checkout — there is no global package to uninstall.,以 1 結束)。加上 --purge 時,它會先問它的問題(見下方);接著依序:

  1. 停止中繼,和 oar stop 一樣:它會等待執行中的回合。之後仍在忙碌的中繼會讓指令結束(The relay finishes its running turns first; it stops by itself after them.),其他東西都不會變更。持有鎖定檔卻不回應的中繼(正在搬移資料庫或正在啟動)也會讓指令結束:The relay (process <pid>) is bringing over its database and does not answer yet; once oar status says it runs, run oar uninstall again.,或 A relay (process <pid>) holds <lock> without answering; stop it (oar stop, or end process <pid>).
  2. 移除 OAR 為這個安裝產生的自動啟動項目:在 Windows 上是開機任務(一次系統管理員提示)以及它的啟動器和工作 XML,還有登入項目;在 Linux 上是 systemd unit,前提是它是 oar service install 寫入的那一個。接著是 OAR 為這個安裝寫入的 Copilot 擴充功能包裝程式,位於 ~/.copilot/extensions/web-relay/。手動建立或修改過的項目或包裝程式,或屬於另一個安裝的項目,會保留下來並列出名稱(Left as it is: <path> (hand-made))。
  3. 加上 --purge 時,刪除資料(見下方)。
  4. 在背景啟動 npm uninstall -g @oar-sh/oar,使用與執行 oar 的 Node.js 位於同處的 npm,作用於套件所在的 prefix(在 Windows 上是 npm.cmd)。npm 無法在套件執行時移除它,所以這一步會等到 oar 結束(最多 2 分鐘),然後把 npm 的結果寫入 oar-uninstall.log:位於 OAR 的 logs 資料夾,或在使用 --purge 時位於暫存資料夾。

最後它會列出它做了什麼:

[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).

當資料目錄位於狀態資料夾之外時,那一行會列出兩者。中繼停止時,session worker 會繼續執行,而 npm 無法移除執行中程式所持有的檔案。仍有程式從套件執行時,指令會列出它們的處理程序 ID,npm 會把它們的檔案留在原本套件位置旁的隱藏 .oar-* 資料夾中;記錄檔會指出那個資料夾。請在那些程式結束後刪除它,最晚在重新開機之後。

如果某個步驟失敗,指令會停止並說明原因(例如 Uninstall stopped: <reason>. 或 The relay did not stop.),接著是 Done: … 和 Not done: the autostart entries; the package.(使用 --purge 時還有 the data),以及 Run oar uninstall again once that is sorted out.(使用 --purge 時為 oar uninstall --purge)。

選項 效果
--purge 同時永久刪除狀態資料夾:設定檔、含所有對話的資料庫、上傳的檔案和記錄。它會先顯示 --purge deletes <folder> for good: …,然後請你輸入 delete(Type "delete" to confirm: );輸入其他任何內容都會以 Not confirmed. Nothing was changed. 結束。按 Ctrl+C,或沒有可讀取的輸入時,會以結束代碼 130 結束,不做任何變更

使用 --purge 時,有些資料夾在 delete 之後會有自己的問題 [y/N]:位於 git 檢出內的狀態資料夾、rescued-package-data(較早版本存放在套件內的資料),以及位於狀態資料夾之外的資料目錄(設定檔中的 dataDir,或 COPILOT_WEB_RELAY_DATA_DIR)。不論你輸入什麼,--purge 都不會刪除下列狀態資料夾中的任何東西:磁碟機或檔案系統的根目錄、你的家目錄或它上層的資料夾、系統資料夾或它上層的資料夾、Windows 資料夾內的資料夾、git 檢出,或裡面沒有 OAR 設定檔或資料庫的資料夾:--purge deletes nothing in <folder> (<reason>). Nothing was changed.。像這樣的額外資料夾不會提供給你選擇(Not deleted, and not offered: …)。

結束代碼 0:已開始移除套件。結束代碼 1:git 檢出;--purge 拒絕的狀態資料夾;沒有輸入 delete;沒有停止、或持有鎖定檔卻不回應的中繼;無法移除的自動啟動項目(被拒絕的提示、無法讀取的開機任務);無法刪除的資料夾;無法啟動 npm(remove it yourself: npm uninstall -g @oar-sh/oar)。結束代碼 2:其他選項。結束代碼 130:在問題中按 Ctrl+C。

oar copilot #

oar copilot [--port <port>] [--install-extension] [--no-install-extension] [--migrate-from <dir>] [-- <gh copilot args>]

如果沒有中繼回應,就先啟動中繼,然後在你的終端機中執行 GitHub Copilot CLI(gh copilot)。由它啟動的中繼會在 session 結束時停止。GitHub Copilot 說明何時使用它。不加 copilot 這個字的相同選項仍會執行它:oar -- <args>、oar --install-extension、oar --port 3400 --no-install-extension。

選項 值 預設值 效果
--port 1 到 65535 設定檔中的連接埠,否則為 3333 這次執行在這個連接埠上尋找或啟動中繼,不會變更設定檔;由這個指令建立的設定檔會儲存它。已在那裡執行的中繼會直接被使用。不是連接埠號碼的值會被忽略,不會有任何訊息
--install-extension 無 關閉 寫入或更新 ~/.copilot/extensions/web-relay/ 中使用者層級的全域擴充功能包裝程式(COPILOT_CONFIG_HOME 會移動 ~/.copilot),然後結束。不需要 gh
--no-install-extension 無 關閉 這次執行略過包裝程式。沒有這個選項時,每次執行都會寫入或更新它
--migrate-from 一個資料夾 無 與 oar setup 相同。請用空格分隔:--migrate-from=dir 會被忽略
-- 這一行的其餘部分 無 在它自己的 -- 之後傳給 gh copilot

依序:檢查 gh 是否存在;更新包裝程式(失敗時會回報,但只會讓 --install-extension 停止);搬移舊狀態(全域安裝);在該連接埠上尋找中繼;如果它沒有回應就啟動它,最多等待 20 秒(Relay did not become ready at <url>);然後在目前的資料夾中執行 gh copilot,並連接終端機。原本就在執行的中繼會繼續執行。缺少的設定檔會以僅限本機的存取範圍建立。

出現在 -- 之前的 --help 或 -h 會印出一般用法說明,而不是 copilot 的用法說明。出現在 -- 之後的 --help 或 -h 會印出 oar copilot 的用法並以 0 結束。-- 之後的 --install-extension 和 --no-install-extension 也會由 oar 讀取。這些都不會傳到 gh。

Copilot session 的中繼使用它啟動時的連接埠和 token。oar restart 無法改變它們;見 oar restart。

結束代碼 時機
gh copilot 的結束代碼 session 已執行(如果 gh 被訊號結束則為 1)
0 --install-extension 寫入了包裝程式
1 沒有安裝 gh(The Copilot session needs the GitHub CLI (gh)...);使用 --install-extension 時無法寫入包裝程式;連接埠被占用;中繼沒有就緒;中繼仍在搬移它的資料庫;狀態搬移失敗(被擋下的搬移會回報 Nothing was migrated; starting on the state root as it is.,session 仍會啟動)

oar doctor #

oar doctor

印出 oar 找到的內容。沒有選項,不變更任何東西,以 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)
行 意義
mode global install 或 git checkout
state root 狀態資料夾;在 git 檢出中為 (repo-local server/)
config 設定檔路徑;沒有設定檔時附上 (missing — run: oar setup),並省略 port、auth token 和 tunnel
port 設定檔中的連接埠;localhostOnly: yes 表示僅限本機,no 表示網路
auth token set 或 MISSING
tunnel disabled、managed (cloudflared: <path>) 或 managed, cannot start: <reason>
database 路徑和以 MB 為單位的大小,或 (not created yet)
provider CLIs gh (Copilot)、claude 和 grok:<cli> --version 輸出的第一行(截斷在 60 個字元),沒有輸出時為 installed,指令失敗或不存在時為 not found(5 秒限制)。cursor 一律為 bundled (@cursor/sdk):Cursor 不需要 CLI
warning 在 WSL 中,Windows 占用了中繼的連接埠時

oar help 與 oar version #

oar help          # also: oar --help, oar -h, oar <command> --help
oar version       # also: oar --version, oar -v

help 印出用法說明。version 印出已安裝的版本,例如 0.9.19。兩者都以 0 結束。--version 和 -v 只在沒有指令時有效。

oar 把檔案放在哪裡 #

oar 只處理一個安裝:啟動它的那個套件,以及它的狀態資料夾。

安裝 狀態資料夾 設定檔 資料 記錄
全域,macOS 和 Linux ~/.oar 其中的 config.json data/ logs/
全域,Windows %APPDATA%\oar 其中的 config.json data\ logs\
git 檢出 檢出中的 server/ server/config.json server/data/ ~/.config/copilot-remote/logs(Windows:%LOCALAPPDATA%\copilot-remote\logs);npm start 會寫到 server/logs

OAR_STATE_ROOT 會移動全域安裝的狀態資料夾。包含 .git 的套件資料夾算是 git 檢出。資料目錄中存放資料庫 copilot.db、鎖定檔 relay-server.lock,以及在 oar setup 與套用它的重新啟動之間存在的 relay-previous.json。記錄檔是 server.log 和 server-err.log。oar 會寫入的其他位置:~/.config/systemd/user/oar.service(Linux 服務)、Windows 啟動資料夾中的 oar-web-relay.cmd,%APPDATA%\oar 中的 oar-web-relay-launcher.cmd、開機任務的 XML、oar-relay-elevate.ps1、oar-web-relay.log 和 oar-web-relay-launcher.log,以及 ~/.copilot/extensions/web-relay/extension.mjs。0.9.15 新增 oar autostart --replace 會把它的副本以 <name>.bak 保留在狀態資料夾中,oar uninstall 則把 oar-uninstall.log 寫到記錄資料夾(使用 --purge 時寫到暫存資料夾)。

環境變數 #

變數 使用的指令 效果
OAR_STATE_ROOT 全部 全域安裝的狀態資料夾
OAR_NO_UPDATE_CHECK update 1 會封鎖 manifest 請求;--to 仍然可用
OAR_UPDATE_MANIFEST_URL update manifest 的另一個 URL
COPILOT_WEB_RELAY_LOG_DIR 全部 另一個記錄資料夾
COPILOT_WEB_RELAY_CONFIG 僅 copilot 檔案存在時要使用的設定檔。其他指令一律使用該安裝自己的 config.json
COPILOT_WEB_RELAY_DATA_DIR copilot、start、restart、setup、uninstall、Windows 自動啟動 由這些項目啟動中繼時,作為資料目錄傳給中繼,Linux 服務除外。setup 會把狀態搬移到這裡,uninstall 會列出它,並在 --purge 時提供刪除選項。oar 本身會在預設的資料目錄中尋找鎖定檔
COPILOT_CLOUDFLARED_MODE、COPILOT_CLOUDFLARED_TOKEN、COPILOT_CLOUDFLARED_BINARY status、doctor 改變 status 的 Tunnel: 行和 doctor 的 tunnel 行,就像它們改變中繼的 tunnel 一樣
COPILOT_CONFIG_HOME copilot 包裝程式使用的 Copilot 主資料夾,預設為 ~/.copilot
APPDATA、USERPROFILE、LOCALAPPDATA、XDG_CONFIG_HOME 全部 Windows 和舊版的資料夾位置
NO_COLOR 選單 關閉色彩
PATH service install 服務會取得這個 PATH(加上 ~/.local/bin 和 Node.js 的資料夾)

oar 如何找到中繼 #

oar 從該安裝的 config.json 讀取連接埠和 token,並帶著 token 詢問 http://localhost:<port>/api/status:

回應 oar 的解讀
中繼的狀態 中繼正在執行
其他任何回應(錯誤的 token、其他程式),或 2.5 秒內沒有回覆 連接埠被其他程式占用,或被使用其他 token 的中繼占用
連線被拒絕 中繼已停止

鎖定檔不能當作證據:它可能在中繼結束後仍然存在。oar start 和 oar copilot 會等待持有鎖定檔但尚未回應的中繼,並且只移除較早版本寫入的鎖定檔。oar update 會把存活的鎖定檔視為執行中的中繼。只要有存活的處理程序持有鎖定檔,oar uninstall 就不會繼續。在變更了連接埠或 token 的 oar setup 與套用它的重新啟動之間,中繼仍會以舊的連接埠和 token 回應;oar 會透過 relay-previous.json 找到它,並說明它以先前的設定執行。

安裝了服務時,在 Linux 上 start、stop 和 restart 會透過 systemd 執行(立即執行,不等待回合);否則 start 會啟動一個分離的處理程序,stop 和 restart 則使用中繼自己的介面,它會等到沒有回合在執行。在 Windows 上,start 從不涉及自動啟動;當自動啟動或開機任務開啟時,status 會顯示 Service: installed。

WSL #

在 WSL 中,oar 會偵測發行版(WSL_DISTRO_NAME 或 WSL_INTEROP,或核心版本),並詢問 Windows 哪個程式占用了某個連接埠。oar setup 會拒絕 Windows 占用的連接埠。oar setup、start、status 和 doctor 會印出 Windows holds port <port> (<program>): a browser on Windows reaches that program, not this relay. Pick another port: oar setup --port N。在 WSL 預設的網路模式中開啟區域網路存取時,oar url 會說明該位址是 WSL 內部的位址。

結束代碼 #

代碼 意義 指令
0 完成;stop 和 restart 在中繼仍在忙碌、之後會自行完成時也是 0 全部;status 只在中繼執行時
1 指令無法完成你要求的事:沒有設定檔、git 檢出、連接埠被占用、中繼沒有啟動起來或不接受要求、npm install 失敗、缺少 gh、系統管理員提示被拒絕、有手動建立的自動啟動項目擋路、--purge 沒有被確認;也包括非預期的錯誤 setup、start、stop、restart、url、update、service、autostart、uninstall、copilot
2 用法錯誤:未知的指令或選項、缺少值、錯誤的 --port(copilot 除外)或 --autostart、--lan 搭配 --local 全部
3 中繼沒有在執行(已停止、被其他東西占用,或尚未設定) 僅 status
130 在問題中或選單中按 Ctrl+C setup、uninstall、選單
gh copilot 的結束代碼 Copilot session 已結束 copilot