Add Mac client mode and simplify local proxy UI
This commit is contained in:
74
docs/superpowers/plans/2026-05-19-macos-client.md
Normal file
74
docs/superpowers/plans/2026-05-19-macos-client.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# macOS Docker Client Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Build a macOS Docker client mode that exposes a local HTTP/SOCKS proxy on `127.0.0.1:8080` with a friendlier UI and a curl installer.
|
||||
|
||||
**Architecture:** Reuse the current Node API, React UI, subscription parser, sing-box process manager, and routing rule generator. Add `APP_MODE=client` so the same backend emits a proxy-only sing-box config without TProxy, and use a dedicated Dockerfile/compose path for Mac installation.
|
||||
|
||||
**Tech Stack:** Node.js ESM, React/Vite, sing-box, Docker Compose, POSIX shell, `node:test`.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Client Mode Config Contract
|
||||
|
||||
**Files:**
|
||||
- Create: `test/server/singbox-client-mode.test.js`
|
||||
- Modify: `package.json`
|
||||
- Modify: `src/server/config.js`
|
||||
- Modify: `src/server/singbox.js`
|
||||
- Modify: `src/server/index.js`
|
||||
|
||||
- [ ] Add `node:test` coverage that proves `APP_MODE=client` config has `mixed-in`, no `tproxy-in`, no transparent fallback, and a VPN proxy fallback.
|
||||
- [ ] Add `npm test` script.
|
||||
- [ ] Add `settings.appMode`.
|
||||
- [ ] Make `buildGatewayConfig()` conditionally emit client-only inbounds and route rules.
|
||||
- [ ] Expose `mode` and hide irrelevant tproxy fields in public state.
|
||||
|
||||
### Task 2: macOS Client Docker Runtime
|
||||
|
||||
**Files:**
|
||||
- Create: `entrypoint.client.sh`
|
||||
- Create: `Dockerfile.client`
|
||||
- Create: `docker-compose.client.yml`
|
||||
|
||||
- [ ] Add an entrypoint that starts only the Node control server.
|
||||
- [ ] Add a Dockerfile that builds the Vite frontend inside Docker and installs only client runtime dependencies plus sing-box.
|
||||
- [ ] Add compose with loopback-only port publishing for UI and proxy.
|
||||
|
||||
### Task 3: User-Friendly Client UI
|
||||
|
||||
**Files:**
|
||||
- Create: `src/web/components/ClientOverviewPage.jsx`
|
||||
- Modify: `src/web/App.jsx`
|
||||
- Modify: `src/web/components/Sidebar.jsx`
|
||||
- Modify: `src/web/components/Topbar.jsx`
|
||||
- Modify: `src/web/components/StatusPane.jsx`
|
||||
- Modify: `src/web/components/RouteChecker.jsx`
|
||||
- Modify: `src/web/styles.css`
|
||||
|
||||
- [ ] Add a client overview with status, active server, copyable proxy URLs, and macOS setup commands.
|
||||
- [ ] Hide gateway-only navigation and side status pane in client mode.
|
||||
- [ ] Rename topbar brand to match current mode.
|
||||
- [ ] Keep servers, logs, and settings reachable in client mode.
|
||||
|
||||
### Task 4: curl Installer and Docs
|
||||
|
||||
**Files:**
|
||||
- Create: `scripts/install-macos-client.sh`
|
||||
- Modify: `README.md`
|
||||
- Modify: `.env.example`
|
||||
|
||||
- [ ] Add curl-friendly installer with Docker/Git checks and update-or-clone behavior.
|
||||
- [ ] Document one-line install command and manual compose command.
|
||||
- [ ] Add client mode environment examples.
|
||||
|
||||
### Task 5: Verification
|
||||
|
||||
**Commands:**
|
||||
- `npm test`
|
||||
- `npm run build`
|
||||
- `docker compose -f docker-compose.client.yml config`
|
||||
|
||||
- [ ] Run all commands and fix any failures.
|
||||
- [ ] Inspect the diff to confirm existing CI/runtime-base edits remain untouched.
|
||||
48
docs/superpowers/specs/2026-05-19-macos-client-design.md
Normal file
48
docs/superpowers/specs/2026-05-19-macos-client-design.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# macOS Docker Client Design
|
||||
|
||||
## Goal
|
||||
|
||||
Add a simple macOS-friendly Docker client that behaves like the previous local proxy product: the user runs one container, opens a web UI, loads a subscription, chooses a server, and points macOS apps at `127.0.0.1:8080`.
|
||||
|
||||
## Product Shape
|
||||
|
||||
The client is not a transparent gateway. It must not require router changes, host networking, `NET_ADMIN`, iptables, ipset, or TProxy. The first-screen UI should explain the current proxy state, active server, and exact local proxy addresses. Gateway-only controls remain available only when the app runs in gateway mode.
|
||||
|
||||
## Runtime Architecture
|
||||
|
||||
`APP_MODE=client` switches the config generator to proxy-only sing-box config:
|
||||
|
||||
- one `mixed` inbound on `PROXY_PORT`;
|
||||
- no `tproxy` inbound;
|
||||
- custom routing rules still apply before fallback;
|
||||
- `proxyDefaultMode` controls the mixed proxy fallback and defaults to VPN;
|
||||
- generated configs still pass `sing-box check` before restart.
|
||||
|
||||
The client Docker image builds the React frontend inside Docker so macOS installation does not require local Node.js. Docker publishes only loopback ports:
|
||||
|
||||
- `127.0.0.1:3456` for the UI;
|
||||
- `127.0.0.1:8080` for HTTP/SOCKS proxy.
|
||||
|
||||
## Installer
|
||||
|
||||
The macOS installer is a curl-friendly shell script. It checks macOS, Docker, Docker Compose, and Git, clones or updates the repository under `~/.vpn-proxy-client`, then runs the client compose file with `--build`. It prints the UI URL, proxy URLs, and optional `networksetup` commands, but does not change system proxy settings automatically.
|
||||
|
||||
## UI
|
||||
|
||||
Client mode gets a user-facing overview based on the old workflow:
|
||||
|
||||
- status: ready, stopped, not configured, applying, error;
|
||||
- active server and traffic quota;
|
||||
- copyable HTTP and SOCKS5 proxy URLs;
|
||||
- short macOS setup commands;
|
||||
- primary actions: load subscription, choose server, restart, stop.
|
||||
|
||||
Gateway terminology such as TProxy, devices, router, transparent fallback, and direct bypass cache is hidden in client mode.
|
||||
|
||||
## Verification
|
||||
|
||||
Use `node:test` for server config behavior, then run:
|
||||
|
||||
- `npm test`;
|
||||
- `npm run build`;
|
||||
- `docker compose -f docker-compose.client.yml config`.
|
||||
Reference in New Issue
Block a user