Skip to content

Commit 19810b9

Browse files
committed
Add headless Linux CLI and dashboard
1 parent 5e87052 commit 19810b9

31 files changed

Lines changed: 2983 additions & 775 deletions

.github/ISSUE_TEMPLATE/bug_report.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ body:
2020
validations:
2121
required: true
2222
- type: input
23-
id: macos
23+
id: environment
2424
attributes:
25-
label: macOS version and Mac
26-
placeholder: "macOS 15.5, M2 MacBook Air"
25+
label: Operating system and installation
26+
placeholder: "macOS 15.5 DMG, or Ubuntu 24.04 Linux CLI tarball"
2727
validations:
2828
required: true
2929
- type: input

.github/ISSUE_TEMPLATE/question.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ body:
2020
- type: input
2121
id: environment
2222
attributes:
23-
label: macOS version and client
24-
placeholder: "macOS 15.5, client name/version"
23+
label: Operating system, installation, and client
24+
placeholder: "Ubuntu 24.04, Linux CLI tarball, client name/version"
2525
validations:
2626
required: true
2727
- type: textarea

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Please do not open a pull request with code or documentation changes yet. It may
1212

1313
1. Install the latest stable release and check existing issues.
1414
2. Confirm the behavior with the smallest route and request that reproduce it.
15-
3. Record the ReRouted version, macOS version, provider type, authentication method, model, client, and whether the request streamed.
15+
3. Record the ReRouted version, operating system, installation method, provider type, authentication method, model, client, and whether the request streamed.
1616
4. Replace account names, model identifiers, or request content when they are not essential to the report.
1717

1818
Never attach `config.json` or paste full, unreviewed diagnostics. Remove API keys, gateway keys, tokens, OAuth callback URLs or codes, cookies, account IDs, email addresses, prompts, and private provider responses.
@@ -40,7 +40,7 @@ npm test
4040
git diff --check
4141
```
4242

43-
Node.js 22.13 or newer is required. The packaged application currently targets Apple Silicon and macOS 12 Monterey or newer.
43+
Node.js 22.13 or newer is required. The headless runtime is supported on Linux. The packaged desktop application targets Apple Silicon and macOS 12 Monterey or newer.
4444

4545
Maintainers handle package version changes, signing, notarization, release publication, and installation verification. Reproduction branches should not include generated release artifacts or real provider credentials.
4646

PRIVACY.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
11
# Privacy
22

3-
ReRouted is a local macOS application. It has no ReRouted account, hosted control plane, or third-party product analytics service.
3+
ReRouted is a local macOS application and Linux headless service. It has no ReRouted account, hosted control plane, or third-party product analytics service.
44

55
This document describes the application as shipped. The upstream providers and clients you connect have their own privacy policies and data practices.
66

77
## Website
88

99
The public `rerouted.dev` website is a static site delivered through Cloudflare and loads its display fonts from Google Fonts. Those services may receive ordinary web-request metadata such as your IP address, browser headers, and requested asset URLs under their own privacy policies. The website does not include ReRouted product analytics or an account system.
1010

11-
## Data stored on your Mac
11+
## Data stored on your machine
1212

13-
ReRouted stores application data in its macOS Application Support directory, normally `~/Library/Application Support/ReRouted`. Existing installations may use `~/Library/Application Support/rerouted`.
13+
On macOS, ReRouted stores application data in its Application Support directory, normally `~/Library/Application Support/ReRouted`; existing installations may use `~/Library/Application Support/rerouted`. On Linux, the headless runtime uses `$XDG_CONFIG_HOME/rerouted`, normally `~/.config/rerouted`. `REROUTED_USER_DATA` or the CLI `--data-dir` option can override the headless location.
1414

1515
Local data includes:
1616

1717
- Provider settings, OAuth credentials, API keys, gateway keys, routes, and application preferences in `config.json`.
1818
- Request metadata, provider and route selections, statuses, timestamps, and token counts in the uncapped `usage.sqlite` database.
1919
- Gateway, OAuth, update, and routing diagnostics in `rerouted.log`.
2020

21-
Prompt bodies are not intentionally persisted. Provider credentials and gateway keys are not encrypted at rest. ReRouted restricts local file permissions where macOS supports doing so, but anyone who can access your macOS user account or its files may be able to read them.
21+
Prompt bodies are not intentionally persisted. Provider credentials and gateway keys are not encrypted at rest. ReRouted restricts local file permissions where the operating system supports doing so, but anyone who can access your local user account or its files may be able to read them.
2222

2323
Diagnostics can contain provider error text, model and route names, account identifiers, and OAuth metadata. Treat logs as sensitive and review every line before sharing an excerpt.
2424

2525
## Local credential discovery
2626

27-
Credential discovery happens when you choose to scan or import accounts. Depending on the providers installed on the Mac, ReRouted may inspect supported entries in the Codex configuration, the Claude Code macOS Keychain or supported local auth files, ReRouted auth-profile folders, and Antigravity-named JSON files in supported folders including `~/Downloads`. ReRouted summarizes discoveries before import; selected credentials are copied into its own configuration.
27+
Credential discovery happens when you choose to scan or import accounts. Depending on the providers installed on the machine, ReRouted may inspect supported entries in the Codex configuration, the Claude Code macOS Keychain or supported local auth files, ReRouted auth-profile folders, and Antigravity-named JSON files in supported folders including `~/Downloads`. ReRouted summarizes discoveries before import; selected credentials are copied into its own configuration.
2828

2929
At startup, ReRouted may also read the local `~/.grok/auth.json` file to attach a human-readable identity to an xAI account that is already connected. This startup lookup only updates local account labeling; it does not import a new account by itself.
3030

@@ -35,23 +35,23 @@ ReRouted makes network requests only as needed to operate features you choose:
3535
- Completion requests, credentials, and supported image inputs are sent to the selected upstream provider.
3636
- OAuth authorization and token refresh requests are sent to the relevant provider.
3737
- Quota checks are sent to supported providers when you open the Quota page, every 60 seconds while that page remains open, or when you manually refresh it.
38-
- Automatic update checks contact `update.electronjs.org` shortly after launch and about every six hours; signed update downloads come from GitHub Releases.
38+
- The macOS app checks `update.electronjs.org` shortly after launch and about every six hours; signed update downloads come from GitHub Releases. The Linux CLI does not perform automatic update checks and is updated through its package manager.
3939

40-
The gateway binds to `127.0.0.1` by default. If you enable network access, it binds to `0.0.0.0`; devices that can reach the Mac can attempt to access it, and the gateway bearer key becomes the primary access boundary.
40+
The gateway binds to `127.0.0.1` by default. If you enable network access, it binds to `0.0.0.0`; devices that can reach the machine can attempt to access it. Gateway API routes require a generated gateway key. In the headless runtime, `/dashboard/` uses a separate browser session and the local admin password; first-time browser setup is allowed only over loopback.
4141

4242
## OAuth and subscription notice
4343

4444
ReRouted is independent and is not affiliated with or endorsed by any upstream provider. This provider's subscription or OAuth session is not officially licensed for proxy or router use. Using it this way may result in account restrictions or bans. Proceed at your own risk, review the provider's current terms, and prefer a documented API-key integration when you need a stable production path.
4545

4646
## Retention and deletion
4747

48-
Usage history is not automatically pruned and remains on the Mac until the Application Support data is removed. Existing installations may also retain the former `usage.json` as a one-time migration backup. Logs can be cleared from the Activity diagnostics view.
48+
Usage history is not automatically pruned and remains on the machine until the local data directory is removed. Existing installations may also retain the former `usage.json` as a one-time migration backup. Logs can be cleared from the Activity diagnostics view.
4949

5050
Uninstalling the application bundle does not automatically remove Application Support data. To remove ReRouted and its stored credentials completely:
5151

52-
1. Quit ReRouted.
53-
2. Delete `/Applications/ReRouted.app`.
54-
3. Delete the ReRouted Application Support directory listed above.
52+
1. Stop ReRouted.
53+
2. On macOS, delete `/Applications/ReRouted.app`; on Linux, uninstall `@gitcommit90/rerouted` through npm.
54+
3. Delete the relevant ReRouted data directory listed above.
5555

5656
Deleting the Application Support directory permanently removes connected accounts, keys, routes, settings, usage history, and logs. Back up only the data you intentionally want to retain.
5757

README.md

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
<h1>ReRouted</h1>
44
<p><strong>Stop rewiring your AI tools every time an account hits quota.</strong></p>
55
<p>
6-
A macOS menu-bar router that puts your connected accounts, models,
7-
API keys, and fallback routes behind one local endpoint.
6+
A local router for macOS and Linux that puts your connected accounts,
7+
models, API keys, and fallback routes behind one endpoint.
88
</p>
99
<p>
1010
<a href="https://rerouted.dev">Website</a> |
@@ -18,6 +18,7 @@
1818
<p>
1919
<a href="https://github.com/gitcommit90/rerouted/releases/latest"><img alt="GitHub release" src="https://img.shields.io/github/v/release/gitcommit90/rerouted?color=ef5b2a&label=release" /></a>
2020
<img alt="macOS Apple Silicon" src="https://img.shields.io/badge/macOS-Apple%20Silicon-1b1d18?logo=apple&logoColor=white" />
21+
<img alt="Linux headless" src="https://img.shields.io/badge/Linux-headless%20%2B%20dashboard-1b1d18?logo=linux&logoColor=white" />
2122
<img alt="Local first" src="https://img.shields.io/badge/gateway-local--first-247454" />
2223
<a href="./LICENSE"><img alt="MIT license" src="https://img.shields.io/badge/license-MIT-ef5b2a" /></a>
2324
</p>
@@ -51,9 +52,9 @@ The promise is deliberately focused: ReRouted exposes model discovery, OpenAI-st
5152
| A model name hard-codes a provider or account | A named route describes intent: `coding`, `fast`, `review` |
5253
| Quota means stopping to edit settings | The next route member is attempted automatically |
5354
| Multiple OAuth accounts are managed by hand | OAuth accounts share a provider pool and fall through in order |
54-
| Requests and failures are scattered | Activity, quota, token counts, and logs live in the menu bar |
55+
| Requests and failures are scattered | Activity, quota, token counts, and logs live in one control plane |
5556

56-
No hosted control plane. No account with ReRouted. No Dock icon. The gateway and panel run together on your Mac.
57+
No hosted control plane and no ReRouted account. On macOS, the gateway and panel run together in the menu bar. On Linux, one headless process serves the gateway, interactive CLI setup, and the same control plane at `/dashboard/`.
5758

5859
## How it works
5960

@@ -87,7 +88,7 @@ Timeouts and retryable `408`, `429`, and `5xx` responses can advance the route.
8788
- **OAuth accounts:** ChatGPT, Claude, Antigravity, and xAI.
8889
- **API-key presets:** OpenRouter, NVIDIA NIM, Cloudflare, and GLM Coding.
8990
- **Custom upstreams:** any service that exposes the OpenAI chat-completions shape ReRouted expects.
90-
- **Local credential discovery:** supported credentials already stored in known files or the macOS Keychain can be imported instead of re-entered.
91+
- **Local credential discovery:** supported credentials already stored in known files, or in the macOS Keychain where available, can be imported instead of re-entered.
9192
- **Multiple accounts:** connect more than one account for the same provider and use shared or account-specific model routes.
9293

9394
OAuth accounts and keyed providers can live in the same route. ReRouted handles request translation and normalizes supported upstream responses back into the shape your client expects.
@@ -98,7 +99,7 @@ ReRouted is an independent project and is not affiliated with or endorsed by any
9899
99100
## Quick start
100101

101-
### 1. Install
102+
### 1. Install on macOS
102103

103104
[Download the latest ReRouted release for Apple Silicon](https://github.com/gitcommit90/rerouted/releases/latest), open the DMG, and drag ReRouted to Applications.
104105

@@ -108,6 +109,41 @@ The macOS release is Developer ID signed, notarized by Apple, and stapled for a
108109

109110
After the first install, ReRouted checks stable releases in the background. You can also use **Settings → Software updates** at any time; new versions download inside the app and install on restart.
110111

112+
### Or install the headless Linux CLI
113+
114+
ReRouted requires Node.js 22.13 or newer. Install the current CLI tarball from the stable GitHub Release; it provides the short `rerouted` command:
115+
116+
```bash
117+
npm install --global https://github.com/gitcommit90/rerouted/releases/latest/download/ReRouted-linux-node.tgz
118+
rerouted
119+
```
120+
121+
The first run opens the interactive terminal setup when a TTY is attached and prints both local URLs:
122+
123+
```text
124+
Gateway http://127.0.0.1:4949/v1
125+
Dashboard http://127.0.0.1:4949/dashboard/
126+
```
127+
128+
When started by systemd, Docker, SSH automation, or another non-interactive process, open the printed dashboard URL from the same machine to finish first-time setup. The browser flow covers the same providers, routes, activity, quota, keys, and settings as the menu-bar app. Dashboard sessions require the local admin password after onboarding. Run `rerouted help` for bind, port, and data-directory options.
129+
130+
For a persistent user service after setup:
131+
132+
```ini
133+
# ~/.config/systemd/user/rerouted.service
134+
[Unit]
135+
Description=ReRouted local AI gateway
136+
137+
[Service]
138+
ExecStart=%h/.local/bin/rerouted --no-interactive
139+
Restart=on-failure
140+
141+
[Install]
142+
WantedBy=default.target
143+
```
144+
145+
Use the actual path from `command -v rerouted` if npm installed it elsewhere, then run `systemctl --user enable --now rerouted`.
146+
111147
### 2. Connect what you already use
112148

113149
Import a detected credential, complete an OAuth flow, or add an API key. ReRouted keeps OAuth accounts and keyed providers side by side.
@@ -152,28 +188,29 @@ Claude Code uses the Anthropic Messages route. Point it at the gateway with its
152188

153189
ReRouted accepts both `/v1/messages` and `/v1/v1/messages`, so current Claude Code versions work whether they append `/messages` or `/v1/messages` to that base URL.
154190

155-
## The menu-bar control plane
191+
## One control plane, two shells
156192

157193
- **Status:** gateway health, endpoint, latest route, and recent traffic.
158194
- **Accounts:** OAuth sessions, imported credentials, API keys, and model availability.
159195
- **Routes:** named fallback or round-robin model groups with explicit ordering controls.
160196
- **Activity:** requests, failures, token counts, route choices, and account usage.
161197
- **Quota:** provider-specific subscription windows where supported.
162-
- **Settings:** gateway keys, localhost or network binding, login launch, security controls, and signed software updates.
198+
- **Settings:** gateway keys, localhost or network binding, security controls, and platform-appropriate startup/update information.
163199

164200
<p align="center">
165201
<img src="./docs/images/status.png" width="400" alt="ReRouted status panel" />
166202
<img src="./docs/images/route-editor.png" width="400" alt="ReRouted route editor" />
167203
</p>
168204

169-
The gateway continues running when the panel is hidden. Quitting ReRouted stops both.
205+
On macOS, hiding the panel leaves the gateway running. On Linux, keep the `rerouted` process or your service manager running; closing the dashboard tab does not stop it.
170206

171207
## API surface
172208

173209
| Endpoint | Purpose |
174210
| --- | --- |
175211
| `GET /` | Same unauthenticated local health response as `/health` |
176212
| `GET /health` | Local gateway health and listening port |
213+
| `GET /dashboard/` | Local web control plane in the headless runtime |
177214
| `GET /v1/models` | Enabled direct models and named routes |
178215
| `POST /v1/chat/completions` | Streaming or non-streaming routed chat completions |
179216
| `POST /v1/responses` | Streaming or non-streaming routed Responses API requests |
@@ -192,6 +229,7 @@ Requests require a generated gateway key except for `/` and `/health`. OpenAI ro
192229
- Provider credentials are not encrypted at rest.
193230
- Requests and the credentials needed to authorize them are sent to the upstream services you choose.
194231
- Enabling network access binds the gateway to `0.0.0.0`; only do that on a network you trust.
232+
- The dashboard uses a separate, per-browser session protected by the local admin password. First-time browser setup is restricted to loopback.
195233

196234
See [Privacy](./PRIVACY.md) for the local files ReRouted keeps, the network services it contacts, and how to remove its data.
197235

@@ -203,9 +241,9 @@ See [Privacy](./PRIVACY.md) for the local files ReRouted keeps, the network serv
203241

204242
ReRouted is open source under the [MIT License](./LICENSE). External code contributions are not currently accepted while the contribution process is finalized; focused issues and sanitized reproduction reports are welcome. See [Contributing](./CONTRIBUTING.md) for the current policy.
205243

206-
## Build from source
244+
## Build or run from source
207245

208-
Requires Node.js 22.13 or newer. Packaging requires macOS and produces an Apple Silicon DMG.
246+
Requires Node.js 22.13 or newer. The test suite and headless runtime run on Linux; DMG packaging remains a separate macOS-only path.
209247

210248
```bash
211249
git clone https://github.com/gitcommit90/rerouted.git
@@ -215,17 +253,23 @@ npm test
215253
npm start
216254
```
217255

256+
Run the headless CLI instead:
257+
258+
```bash
259+
npm run start:headless
260+
```
261+
218262
Package the macOS app and DMG:
219263

220264
```bash
221265
npm run package:dmg
222266
```
223267

224-
The implementation is intentionally small: Electron, Node's built-in HTTP server, and a vanilla HTML/CSS/JavaScript renderer. See [the architecture document](./docs/architecture.md) for the runtime, routing, persistence, and packaging details.
268+
The shared implementation uses Node's built-in HTTP server and a vanilla HTML/CSS/JavaScript control plane. Electron supplies the macOS menu-bar shell; the Linux CLI supplies the headless shell and serves that same renderer from `/dashboard/`. See [the architecture document](./docs/architecture.md) for the runtime, routing, persistence, and packaging details.
225269

226270
## Current release
227271

228-
Public builds are Developer ID signed, notarized, stapled, and distributed through stable GitHub Releases with in-app updates. The public API is intentionally limited to health, model discovery, chat completions, Responses, and Anthropic Messages compatibility; a published third-party client compatibility matrix is still forthcoming.
272+
macOS builds are Developer ID signed, notarized, stapled, and distributed through stable GitHub Releases with in-app updates. The Linux CLI is a separate npm-compatible tarball on the same stable release and is updated by rerunning its npm install command. The public API is intentionally limited to health, model discovery, chat completions, Responses, and Anthropic Messages compatibility; a published third-party client compatibility matrix is still forthcoming.
229273

230274
## License
231275

0 commit comments

Comments
 (0)