docs/design/local-control-cli.md
Make phone access to an existing qwen serve session a single explicit command:
qwen serve --local-control
The command keeps the primary daemon on loopback, starts one selected LAN listener, mints a revocable pairing token, prints its QR code, and inhibits system sleep until Local Control is disabled. Desktop exposes the same daemon-owned workflow from the Web Shell Settings card.
--local-control is an opt-in shortcut over the existing daemon and Web Shell. It leaves the daemon's runtime token, configured origins, and resolved port intact, adds one LAN listener on a selected private IPv4 address, allowlists that advertised origin while the session is active, and puts the pairing token in the URL fragment before rendering the QR code.
The terminal remains the visible enabled indicator. Ctrl+C ends the whole daemon, not just Local Control: the graceful drain closes the LAN listener, invalidates the pairing token, and releases the existing cross-platform sleep inhibitor before the process exits. Turning Local Control off while the daemon keeps running is done from the Web Shell Settings card, which is also the only in-process re-enable path.
The mode rejects a non-default --hostname and --no-web instead of silently creating incomplete configurations. It composes with --token, --allow-origin, and ephemeral port 0; --local-control-address selects the LAN address when several candidates exist. Existing explicit qwen serve deployments are unchanged.
--local-control at boot, or an enable request served only by the primary loopback listener; enable requests arriving over the LAN listener are rejected.crypto.randomBytes(32); environment tokens are not reused on the LAN listener.--allow-origin patterns remain in effect on both listeners while the session is active); every protected LAN route still requires the pairing token.Desktop keeps its bundled daemon bound to authenticated loopback. The Web Shell Settings card enables the same daemon-owned Local Control service, which starts the LAN listener, generates a separate pairing token and QR code, and acquires the platform sleep inhibitor. The listener validates its public Host and Origin and accepts only the pairing credential for LAN traffic. The Desktop PID, daemon PID, loopback address, and live sessions do not change.
Turning Local Control off from Settings closes the listener and active connections, releases sleep inhibition, and invalidates the pairing token. A later enable gets a new token. The LAN listener does not exist while the mode is off, so the normal Desktop runtime remains loopback-only.
This mode intentionally covers same-network access only. Internet remote control requires an account-authenticated outbound relay with reconnectable session state; it must not be implemented by exposing this LAN gateway through port forwarding or an unauthenticated tunnel.
/capabilities, the Web Shell loads, and the sleep inhibitor lives only for the Local Control process.serve command and sleep-inhibitor tests remain green, followed by build and typecheck.