Discovery: wide-area bridge DNS-SD

# Conflicts:
#	apps/ios/Sources/Bridge/BridgeDiscoveryModel.swift
#	src/cli/dns-cli.ts
This commit is contained in:
Peter Steinberger
2025-12-17 20:25:40 +01:00
parent e9bfe34850
commit 557ffdbe35
24 changed files with 293 additions and 19 deletions

View File

@@ -36,12 +36,12 @@ pnpm clawdis gateway --force
- If a token is configured, clients must include it in `connect.params.auth.token` even over the tunnel.
## Protocol (operator view)
- Mandatory first frame from client: `req {type:"req", id, method:"connect", params:{minProtocol,maxProtocol,client:{name,version,platform,mode,instanceId}, caps, auth?, locale?, userAgent? } }`.
- Mandatory first frame from client: `req {type:"req", id, method:"connect", params:{minProtocol,maxProtocol,client:{name,version,platform,deviceFamily?,modelIdentifier?,mode,instanceId}, caps, auth?, locale?, userAgent? } }`.
- Gateway replies `res {type:"res", id, ok:true, payload:hello-ok }` (or `ok:false` with an error, then closes).
- After handshake:
- Requests: `{type:"req", id, method, params}` → `{type:"res", id, ok, payload|error}`
- Events: `{type:"event", event, payload, seq?, stateVersion?}`
- Structured presence entries: `{host, ip, version, mode, lastInputSeconds?, ts, reason?, tags?[], instanceId? }`.
- Structured presence entries: `{host, ip, version, platform?, deviceFamily?, modelIdentifier?, mode, lastInputSeconds?, ts, reason?, tags?[], instanceId? }`.
- `agent` responses are two-stage: first `res` ack `{runId,status:"accepted"}`, then a final `res` `{runId,status:"ok"|"error",summary}` after the run finishes; streamed output arrives as `event:"agent"`.
## Methods (initial set)

View File

@@ -20,6 +20,8 @@ Presence entries are structured objects with (some) fields:
- `host`: a human-readable name (often the machine name)
- `ip`: best-effort IP address (may be missing or stale)
- `version`: client version string
- `deviceFamily` (optional): hardware family like `iPad`, `iPhone`, `Mac`
- `modelIdentifier` (optional): hardware model identifier like `iPad16,6` or `Mac16,6`
- `mode`: e.g. `gateway`, `app`, `webchat`, `cli`
- `lastInputSeconds` (optional): “seconds since last user input” for that client machine
- `reason`: a short marker like `self`, `connect`, `periodic`, `instances-refresh`

View File

@@ -23,7 +23,7 @@ Goal: replace legacy gateway/stdin/TCP control with a single WebSocket Gateway,
## Phase 1 — Protocol specification
- Frames (WS text JSON, all with explicit `type`):
- `req {type:"req", id, method:"connect", params:{minProtocol,maxProtocol,client:{name,version,platform,mode,instanceId}, caps, auth:{token?}, locale?, userAgent?}}`
- `req {type:"req", id, method:"connect", params:{minProtocol,maxProtocol,client:{name,version,platform,deviceFamily?,modelIdentifier?,mode,instanceId}, caps, auth:{token?}, locale?, userAgent?}}`
- `res {type:"res", id, ok:true, payload: hello-ok }` (or `ok:false` then close)
- `hello-ok {type:"hello-ok", protocol:<chosen>, server:{version,commit,host,connId}, features:{methods,events}, snapshot:{presence[], health, stateVersion:{presence,health}, uptimeMs}, policy:{maxPayload, maxBufferedBytes, tickIntervalMs}}`
- `req {type:"req", id, method, params?}`
@@ -31,7 +31,7 @@ Goal: replace legacy gateway/stdin/TCP control with a single WebSocket Gateway,
- `event {type:"event", event, payload, seq?, stateVersion?}` (presence/tick/shutdown/agent)
- `close` (standard WS close codes; policy uses 1008 for slow consumer/unauthorized, 1012/1001 for restart)
- Payload types:
- `PresenceEntry {host, ip, version, mode, lastInputSeconds?, ts, reason?, tags?[], instanceId?}`
- `PresenceEntry {host, ip, version, platform?, deviceFamily?, modelIdentifier?, mode, lastInputSeconds?, ts, reason?, tags?[], instanceId?}`
- `HealthSnapshot` (match existing `clawdis health --json` fields)
- `AgentEvent` (streamed tool/output; `{runId, seq, stream, data, ts}`)
- `TickEvent {ts}`