feat: add WiFi provisioning for headless devices (AP + Captive Portal)

- Add lib/network.js: WiFi scan, connect, AP hotspot via nmcli
- Add lib/dns-hijack.js: dnsmasq management for DNS hijack + DHCP
- Add lib/captive-server.js: embedded HTTP captive portal with WiFi setup page
- Add lib/provisioning.js: orchestrator (detect network -> AP mode -> wait -> exit)
- Update client.js: call ensureNetwork() before WS connection
- Update install.sh: auto-install dnsmasq dependency

Made-with: Cursor
This commit is contained in:
stswangzhiping
2026-03-16 08:58:51 +08:00
parent b3770d21d4
commit eb9f4ab1c3
7 changed files with 712 additions and 2 deletions

View File

@@ -7,6 +7,7 @@ const log = require('./logger');
const { getBoxId } = require('./fingerprint');
const { collect } = require('./metrics');
const { getDashboardInfo, startTtyd, FrpcManager } = require('./frpc');
const { ensureNetwork } = require('./provisioning');
const MAX_BACKOFF_MS = 60_000;
const PONG_TIMEOUT_MS = 15_000;
@@ -58,6 +59,10 @@ class ClawClient {
async start() {
log.info('clawd', `启动中... 服务器 = ${this._cfg.server}`);
// 第一步:确保网络可用(无网时进入 AP 配网模式)
await ensureNetwork({ clawId: this._cfg.claw_id });
// 第二步:并行获取 dashboard 信息 + 启动 ttyd
const [dashInfo] = await Promise.all([
getDashboardInfo(),
startTtyd().catch(e => log.warn('ttyd', '启动失败:', e.message)),