Skip to content

Add headless Linux CLI and dashboard#10

Merged
gitcommit90 merged 1 commit into
mainfrom
feature/linux-cli-dashboard
Jul 18, 2026
Merged

Add headless Linux CLI and dashboard#10
gitcommit90 merged 1 commit into
mainfrom
feature/linux-cli-dashboard

Conversation

@gitcommit90

@gitcommit90 gitcommit90 commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Outcome

Adds a Linux/headless distribution path around the existing ReRouted router: interactive terminal onboarding, the shared app control plane at /dashboard/, XDG persistence, process locking, and npm-compatible GitHub Release tarballs while preserving the native macOS shell.

Verification

  • 297 Node tests pass on Linux
  • Full Electron renderer capture harness passes
  • Dashboard inspected at 1200x900 and 390x844
  • Clean-prefix Linux tarball install passes version, /health, /dashboard/, and SIGTERM/PID cleanup checks
  • git diff --check passes

Open in Devin Review

@gitcommit90
gitcommit90 merged commit 3200098 into main Jul 18, 2026
1 of 2 checks passed

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

Open in Devin Review

Comment on lines +162 to +167
if (started) {
return {
address: gateway.getAddress(),
dashboard: gateway.getAddress()?.replace(/\/v1$/, "/dashboard/"),
};
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Restarting the already-running local service reports its address in the wrong format

When the headless service is asked to start again after it is already running (start() at src/lib/headless-runtime.js:162-167), it returns an object with a different structure than the first start, so any code that reads the gateway address (for example the endpoint field) from the second call gets nothing back.

Impact: A caller relying on the returned address after a repeat start would print or use an undefined endpoint/port instead of the real one.

Return-shape mismatch between first and repeat start

The normal (first) start returns { ...address, endpoint, dashboard } where address is { port, host }, so callers such as src/cli/index.js:135-137 read address.endpoint, address.dashboard, and address.port. The early-return branch when started is already true instead returns { address: gateway.getAddress(), dashboard: ... } — a string under address and no endpoint/port/host keys. Currently every caller (src/cli/index.js:134, scripts/capture-dashboard.js:63, tests) invokes start() exactly once, so this path is not exercised today, but the two shapes are not interchangeable and would break a future repeat caller.

Suggested change
if (started) {
return {
address: gateway.getAddress(),
dashboard: gateway.getAddress()?.replace(/\/v1$/, "/dashboard/"),
};
}
if (started) {
const port = gateway.getListeningAddress?.()?.port;
return {
port,
endpoint: gateway.getAddress(),
dashboard: port ? `http://127.0.0.1:${port}/dashboard/` : null,
};
}
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread src/lib/control-plane.js
Comment on lines +200 to +201
if (!password || String(password).length < 4) {
return { ok: false, error: "Password must be at least 4 characters" };

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟨 Weak 4-character minimum for the admin password that now guards the network-reachable dashboard

The shared control plane accepts an admin password as short as 4 characters (src/lib/control-plane.js:200-201, and likewise src/lib/control-plane.js:228). This same password is now the sole credential protecting the new /dashboard/ control plane, which can be exposed beyond loopback when the gateway is bound to 0.0.0.0 (LAN/Tailscale). Combined with only 6 login attempts per minute of throttling in src/lib/dashboard.js:13, a 4-character password provides weak protection for a network-reachable admin surface that exposes providers, OAuth credentials, gateway keys, routes, and activity.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@gitcommit90
gitcommit90 deleted the feature/linux-cli-dashboard branch July 19, 2026 17:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant