chore(naming): remove Iris codename
This commit is contained in:
10
CHANGELOG.md
10
CHANGELOG.md
@@ -7,7 +7,7 @@
|
||||
|
||||
## 2.0.0-beta1 — 2025-12-14
|
||||
|
||||
First Clawdis release post rebrand. This is a semver-major because we dropped legacy providers/agents and moved defaults to new paths while adding a full macOS companion app, a WebSocket Gateway, and an iOS node (Iris).
|
||||
First Clawdis release post rebrand. This is a semver-major because we dropped legacy providers/agents and moved defaults to new paths while adding a full macOS companion app, a WebSocket Gateway, and an iOS node.
|
||||
|
||||
### Breaking
|
||||
- Renamed to **Clawdis**: defaults now live under `~/.clawdis` (sessions in `~/.clawdis/sessions/`, IPC at `~/.clawdis/clawdis.sock`, logs in `/tmp/clawdis`). Launchd labels and config filenames follow the new name; legacy stores are copied forward on first run.
|
||||
@@ -19,7 +19,7 @@ First Clawdis release post rebrand. This is a semver-major because we dropped le
|
||||
### Gateway, nodes, and automation
|
||||
- New typed Gateway WS protocol (JSON schema validated) with `clawdis gateway {health,status,send,agent,call}` helpers and structured presence/instance updates for all clients.
|
||||
- Optional LAN-facing bridge (`tcp://0.0.0.0:18790`) keeps the Gateway loopback-only while enabling direct Bonjour-discovered connections for paired nodes.
|
||||
- Node pairing + management via `clawdis nodes {pending,approve,reject,invoke}` (used by the iOS node “Iris” and future remote nodes).
|
||||
- Node pairing + management via `clawdis nodes {pending,approve,reject,invoke}` (used by the iOS node and future remote nodes).
|
||||
- Cron jobs are Gateway-owned (`clawdis cron …`) with run history stored as JSONL and support for “isolated summary” posting into the main session.
|
||||
|
||||
### macOS companion app
|
||||
@@ -29,10 +29,10 @@ First Clawdis release post rebrand. This is a semver-major because we dropped le
|
||||
- **Browser control**: manage clawd’s dedicated Chrome/Chromium with tab listing/open/focus/close, screenshots, DOM query/dump, and “AI snapshots” (aria/domSnapshot/ai) via `clawdis browser …` and UI controls.
|
||||
- **Remote gateway control**: Bonjour discovery for local masters plus SSH-tunnel fallback for remote control when multicast is unavailable.
|
||||
|
||||
### iOS node (Iris)
|
||||
### iOS node
|
||||
- New iOS companion app that pairs to the Gateway bridge, reports presence as a node, and exposes a WKWebView “Canvas” for agent-driven UI.
|
||||
- `clawdis nodes invoke` supports `canvas.eval` and `canvas.snapshot` to drive and verify the iOS Canvas (fails fast when Iris is backgrounded).
|
||||
- Voice wake words are configurable in-app; Iris reconnects to the last bridge when credentials are still present in Keychain.
|
||||
- `clawdis nodes invoke` supports `canvas.eval` and `canvas.snapshot` to drive and verify the iOS Canvas (fails fast when the iOS node is backgrounded).
|
||||
- Voice wake words are configurable in-app; the iOS node reconnects to the last bridge when credentials are still present in Keychain.
|
||||
|
||||
### WhatsApp & agent experience
|
||||
- Group chats fully supported: mention-gated triggers (including media-only captions), sender attribution, session primer with subject/member roster, allowlist bypass when you’re @‑mentioned, and safer handling of view-once/ephemeral media.
|
||||
|
||||
12
README.md
12
README.md
@@ -30,7 +30,7 @@ WhatsApp / Telegram
|
||||
├─ CLI (clawdis …)
|
||||
├─ WebChat (loopback UI)
|
||||
├─ macOS app (Clawdis.app)
|
||||
└─ iOS node (Iris) via Bridge + pairing
|
||||
└─ iOS node via Bridge + pairing
|
||||
```
|
||||
|
||||
## Why "CLAWDIS"?
|
||||
@@ -53,7 +53,7 @@ Because every space lobster needs a time-and-space machine. The Doctor has a TAR
|
||||
- 🎤 **Voice & transcription hooks** — Voice Wake (macOS/iOS) + optional transcription pipeline
|
||||
- 🔧 **Tool Streaming** — Real-time display (💻📄✍️📝)
|
||||
- 🖥️ **macOS Companion (Clawdis.app)** — Menu bar controls, Voice Wake, WebChat, onboarding, remote gateway control
|
||||
- 📱 **iOS Node (Iris)** — Pairs as a node, exposes a Canvas surface, forwards voice wake transcripts
|
||||
- 📱 **iOS node** — Pairs as a node, exposes a Canvas surface, forwards voice wake transcripts
|
||||
|
||||
Only the Pi CLI is supported now; legacy Claude/Codex/Gemini paths have been removed.
|
||||
|
||||
@@ -69,7 +69,7 @@ Only the Pi CLI is supported now; legacy Claude/Codex/Gemini paths have been rem
|
||||
|
||||
- **TypeScript (ESM)**: CLI + Gateway live in `src/` and run on Node ≥ 22.
|
||||
- **macOS app (Swift)**: menu bar companion lives in `apps/macos/`.
|
||||
- **iOS app (Swift)**: Iris node prototype lives in `apps/ios/`.
|
||||
- **iOS app (Swift)**: iOS node prototype lives in `apps/ios/`.
|
||||
|
||||
## Quick Start
|
||||
|
||||
@@ -118,9 +118,9 @@ If delivery fails (e.g. WhatsApp disconnected / Telegram token missing), Clawdis
|
||||
|
||||
Build/run the mac app with `./scripts/restart-mac.sh` (packages, installs, and launches), or `swift build --package-path apps/macos && open dist/Clawdis.app`.
|
||||
|
||||
### iOS Node (Iris) (internal)
|
||||
### iOS node (internal)
|
||||
|
||||
Iris is an internal/prototype iOS app that connects as a **remote node**:
|
||||
The iOS node app is an internal/prototype app that connects as a **remote node**:
|
||||
|
||||
- **Voice trigger:** forwards transcripts into the Gateway (agent runs + wakeups).
|
||||
- **Canvas screen:** a WKWebView + `<canvas>` surface the agent can control (via `canvas.eval` / `canvas.snapshot` over `node.invoke`).
|
||||
@@ -164,7 +164,7 @@ Optional: enable/configure clawd’s dedicated browser control (defaults are alr
|
||||
- [Troubleshooting](./docs/troubleshooting.md)
|
||||
- [The Lore](./docs/lore.md) 🦞
|
||||
- [Telegram (Bot API)](./docs/telegram.md)
|
||||
- [iOS node runbook (Iris)](./docs/ios/connect.md)
|
||||
- [iOS node runbook](./docs/ios/connect.md)
|
||||
- [macOS app spec](./docs/clawdis-mac.md)
|
||||
|
||||
## Clawd
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Clawdis Node (Android) (internal)
|
||||
|
||||
Modern Android “node” app (Iris parity): connects to the **Gateway-owned bridge** (`_clawdis-bridge._tcp`) over TCP and exposes **Canvas + Chat + Camera**.
|
||||
Modern Android node app: connects to the **Gateway-owned bridge** (`_clawdis-bridge._tcp`) over TCP and exposes **Canvas + Chat + Camera**.
|
||||
|
||||
Notes:
|
||||
- The node keeps the connection alive via a **foreground service** (persistent notification with a Disconnect action).
|
||||
|
||||
@@ -6,12 +6,12 @@ import Testing
|
||||
@Suite struct BridgeEndpointIDTests {
|
||||
@Test func stableIDForServiceDecodesAndNormalizesName() {
|
||||
let endpoint = NWEndpoint.service(
|
||||
name: "Clawdis\\032Bridge \\032 Iris\n",
|
||||
name: "Clawdis\\032Bridge \\032 Node\n",
|
||||
type: "_clawdis-bridge._tcp",
|
||||
domain: "local.",
|
||||
interface: nil)
|
||||
|
||||
#expect(BridgeEndpointID.stableID(endpoint) == "_clawdis-bridge._tcp|local.|Clawdis Bridge Iris")
|
||||
#expect(BridgeEndpointID.stableID(endpoint) == "_clawdis-bridge._tcp|local.|Clawdis Bridge Node")
|
||||
}
|
||||
|
||||
@Test func stableIDForNonServiceUsesEndpointDescription() {
|
||||
|
||||
@@ -8,7 +8,7 @@ import Testing
|
||||
nodes: [
|
||||
ControlRequestHandler.GatewayNodeListPayload.Node(
|
||||
nodeId: "n1",
|
||||
displayName: "Iris",
|
||||
displayName: "Node",
|
||||
platform: "iOS",
|
||||
version: "1.0",
|
||||
deviceFamily: "iPad",
|
||||
@@ -36,10 +36,10 @@ import Testing
|
||||
#expect(res.pairedNodeIds.sorted() == ["n1", "n2"])
|
||||
#expect(res.connectedNodeIds == ["n1"])
|
||||
|
||||
let iris = res.nodes.first { $0.nodeId == "n1" }
|
||||
#expect(iris?.remoteAddress == "192.168.0.88")
|
||||
#expect(iris?.deviceFamily == "iPad")
|
||||
#expect(iris?.modelIdentifier == "iPad14,5")
|
||||
#expect(iris?.capabilities?.sorted() == ["camera", "canvas"])
|
||||
let node = res.nodes.first { $0.nodeId == "n1" }
|
||||
#expect(node?.remoteAddress == "192.168.0.88")
|
||||
#expect(node?.deviceFamily == "iPad")
|
||||
#expect(node?.modelIdentifier == "iPad14,5")
|
||||
#expect(node?.capabilities?.sorted() == ["camera", "canvas"])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ Clawdis uses Bonjour (mDNS / DNS-SD) as a **LAN-only convenience** to discover a
|
||||
|
||||
## Wide-Area Bonjour (Unicast DNS-SD) over Tailscale
|
||||
|
||||
If you want Iris/iPad auto-discovery while the Gateway is on another network (e.g. Vienna ⇄ London), you can keep the `NWBrowser` UX but switch discovery from multicast mDNS (`local.`) to **unicast DNS-SD** (“Wide-Area Bonjour”) over Tailscale.
|
||||
If you want iOS node auto-discovery while the Gateway is on another network (e.g. Vienna ⇄ London), you can keep the `NWBrowser` UX but switch discovery from multicast mDNS (`local.`) to **unicast DNS-SD** (“Wide-Area Bonjour”) over Tailscale.
|
||||
|
||||
High level:
|
||||
|
||||
@@ -59,7 +59,7 @@ In the Tailscale admin console:
|
||||
- Add a nameserver pointing at the gateway’s tailnet IP (UDP/TCP 53).
|
||||
- Add split DNS so the domain `clawdis.internal` uses that nameserver.
|
||||
|
||||
Once clients accept tailnet DNS, Iris can browse `_clawdis-bridge._tcp` in `clawdis.internal.` without multicast.
|
||||
Once clients accept tailnet DNS, iOS nodes can browse `_clawdis-bridge._tcp` in `clawdis.internal.` without multicast.
|
||||
|
||||
### Bridge listener security (recommended)
|
||||
|
||||
@@ -82,7 +82,7 @@ Only the **Node Gateway** (`clawd` / `clawdis gateway`) advertises Bonjour beaco
|
||||
## Service types
|
||||
|
||||
- `_clawdis-master._tcp` — “master gateway” discovery beacon (primarily for macOS remote-control UX).
|
||||
- `_clawdis-bridge._tcp` — bridge transport beacon (used by Iris/iOS nodes).
|
||||
- `_clawdis-bridge._tcp` — bridge transport beacon (used by iOS/Android nodes).
|
||||
|
||||
## TXT keys (non-secret hints)
|
||||
|
||||
@@ -93,7 +93,7 @@ The Gateway advertises small non-secret hints to make UI flows convenient:
|
||||
- `sshPort=<port>` (defaults to 22 when not overridden)
|
||||
- `gatewayPort=<port>` (informational; the Gateway WS is typically loopback-only)
|
||||
- `bridgePort=<port>` (only when bridge is enabled)
|
||||
- `canvasPort=<port>` (only when the optional canvas host is enabled; default `18793`)
|
||||
- `canvasPort=<port>` (only when the canvas host is running; enabled by default; default `18793`)
|
||||
- `tailnetDns=<magicdns>` (optional hint; may be absent)
|
||||
|
||||
## Debugging on macOS
|
||||
@@ -119,9 +119,9 @@ Look for `bonjour:` lines, especially:
|
||||
- `bonjour: ... name conflict resolved` / `hostname conflict resolved`
|
||||
- `bonjour: watchdog detected non-announced service; attempting re-advertise ...` (self-heal attempt after sleep/interface churn)
|
||||
|
||||
## Debugging on iOS (Iris)
|
||||
## Debugging on iOS node
|
||||
|
||||
Iris discovers bridges via `NWBrowser` browsing `_clawdis-bridge._tcp`.
|
||||
The iOS node app discovers bridges via `NWBrowser` browsing `_clawdis-bridge._tcp`.
|
||||
|
||||
To capture what the browser is doing:
|
||||
|
||||
|
||||
@@ -178,9 +178,9 @@ When enabled, the server:
|
||||
}
|
||||
```
|
||||
|
||||
### `bridge` (Iris/node bridge server)
|
||||
### `bridge` (node bridge server)
|
||||
|
||||
The Gateway can expose a simple TCP bridge for nodes (iOS/Android “Iris”), typically on port `18790`.
|
||||
The Gateway can expose a simple TCP bridge for nodes (iOS/Android), typically on port `18790`.
|
||||
|
||||
Defaults:
|
||||
- enabled: `true`
|
||||
|
||||
@@ -10,7 +10,7 @@ read_when:
|
||||
Clawdis has two distinct problems that look similar on the surface:
|
||||
|
||||
1) **Operator remote control**: the macOS menu bar app controlling a “master” gateway running elsewhere.
|
||||
2) **Node pairing**: Iris/iOS (and future nodes) finding a gateway and pairing securely.
|
||||
2) **Node pairing**: iOS/Android (and future nodes) finding a gateway and pairing securely.
|
||||
|
||||
The design goal is to keep all network discovery/advertising in the **Node Gateway** (`clawd` / `clawdis gateway`) and keep clients (mac app, iOS) as consumers.
|
||||
|
||||
@@ -55,7 +55,7 @@ Troubleshooting and beacon details: `docs/bonjour.md`.
|
||||
- `sshPort=22` (or whatever is advertised)
|
||||
- `gatewayPort=18789` (loopback WS port; informational)
|
||||
- `bridgePort=18790` (when bridge is enabled)
|
||||
- `canvasPort=18793` (when the optional canvas host is enabled)
|
||||
- `canvasPort=18793` (when the canvas host is running; enabled by default)
|
||||
- `tailnetDns=<magicdns>` (optional hint)
|
||||
|
||||
Disable/override:
|
||||
|
||||
@@ -34,15 +34,15 @@ WhatsApp / Telegram
|
||||
▼
|
||||
┌──────────────────────────┐
|
||||
│ Gateway │ ws://127.0.0.1:18789 (loopback-only)
|
||||
│ (single source) │ tcp://0.0.0.0:18790 (optional Bridge)
|
||||
│ │ http://0.0.0.0:18793 (optional Canvas host)
|
||||
│ (single source) │ tcp://0.0.0.0:18790 (Bridge)
|
||||
│ │ http://0.0.0.0:18793 (Canvas host)
|
||||
└───────────┬───────────────┘
|
||||
│
|
||||
├─ Pi agent (RPC)
|
||||
├─ CLI (clawdis …)
|
||||
├─ Chat UI (SwiftUI)
|
||||
├─ macOS app (Clawdis.app)
|
||||
└─ iOS node (Iris) via Bridge + pairing
|
||||
└─ iOS node via Bridge + pairing
|
||||
```
|
||||
|
||||
Most operations flow through the **Gateway** (`clawdis gateway`), a single long-running process that owns provider connections and the WebSocket control plane.
|
||||
@@ -52,7 +52,7 @@ Most operations flow through the **Gateway** (`clawdis gateway`), a single long-
|
||||
- **One Gateway per host**: it is the only process allowed to own the WhatsApp Web session.
|
||||
- **Loopback-first**: Gateway WS is `ws://127.0.0.1:18789` (not exposed on the LAN).
|
||||
- **Bridge for nodes**: optional LAN/tailnet-facing bridge on `tcp://0.0.0.0:18790` for paired nodes (Bonjour-discoverable).
|
||||
- **Canvas host (optional)**: LAN/tailnet HTTP file server (default `18793`) for node WebViews; see `docs/configuration.md` (`canvasHost`).
|
||||
- **Canvas host**: LAN/tailnet HTTP file server (default `18793`) for node WebViews; see `docs/configuration.md` (`canvasHost`).
|
||||
- **Remote use**: SSH tunnel or tailnet/VPN; see `docs/remote.md` and `docs/discovery.md`.
|
||||
|
||||
## Features (high level)
|
||||
@@ -65,7 +65,7 @@ Most operations flow through the **Gateway** (`clawdis gateway`), a single long-
|
||||
- 📎 **Media Support** — Send and receive images, audio, documents
|
||||
- 🎤 **Voice notes** — Optional transcription hook
|
||||
- 🖥️ **WebChat + macOS app** — Local UI + menu bar companion for ops and voice wake
|
||||
- 📱 **iOS node (Iris)** — Pairs as a node and exposes a Canvas surface
|
||||
- 📱 **iOS node** — Pairs as a node and exposes a Canvas surface
|
||||
|
||||
Note: legacy Claude/Codex/Gemini/Opencode paths have been removed; Pi is the only coding-agent path.
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ read_when:
|
||||
This repo supports “remote over SSH” by keeping a single Gateway (the master) running on a host (e.g., your Mac Studio) and connecting clients to it.
|
||||
|
||||
- For **operators (you / the macOS app)**: SSH tunneling is the universal fallback.
|
||||
- For **nodes (Iris/iOS and future devices)**: prefer the Gateway **Bridge** when on the same LAN/tailnet (see `docs/discovery.md`).
|
||||
- For **nodes (iOS/Android and future devices)**: prefer the Gateway **Bridge** when on the same LAN/tailnet (see `docs/discovery.md`).
|
||||
|
||||
## The core idea
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ Who receives it:
|
||||
- Uses the global list to gate `VoiceWakeRuntime` triggers.
|
||||
- Editing “Trigger words” in Voice Wake settings calls `voicewake.set` and then relies on the broadcast to keep other clients in sync.
|
||||
|
||||
### iOS node (Iris)
|
||||
### iOS node
|
||||
|
||||
- Uses the global list for `VoiceWakeManager` trigger detection.
|
||||
- Editing Wake Words in Settings calls `voicewake.set` (over the bridge) and also keeps local wake-word detection responsive.
|
||||
@@ -59,4 +59,3 @@ Who receives it:
|
||||
|
||||
- Exposes a Wake Words editor in Settings.
|
||||
- Calls `voicewake.set` over the bridge so edits sync everywhere.
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ export type BridgeConfig = {
|
||||
enabled?: boolean;
|
||||
port?: number;
|
||||
/**
|
||||
* Bind address policy for the Iris bridge server.
|
||||
* Bind address policy for the node bridge server.
|
||||
* - auto: prefer tailnet IP when present, else LAN (0.0.0.0)
|
||||
* - lan: 0.0.0.0 (reachable on local network + any forwarded interfaces)
|
||||
* - tailnet: bind only to the Tailscale interface IP (100.64.0.0/10)
|
||||
|
||||
@@ -405,7 +405,7 @@ describe("gateway server", () => {
|
||||
type: "req",
|
||||
id: "pair-req-1",
|
||||
method: "node.pair.request",
|
||||
params: { nodeId: "n1", displayName: "Iris" },
|
||||
params: { nodeId: "n1", displayName: "Node" },
|
||||
}),
|
||||
);
|
||||
const res1 = await onceMessage<{
|
||||
@@ -432,7 +432,7 @@ describe("gateway server", () => {
|
||||
type: "req",
|
||||
id: "pair-req-2",
|
||||
method: "node.pair.request",
|
||||
params: { nodeId: "n1", displayName: "Iris" },
|
||||
params: { nodeId: "n1", displayName: "Node" },
|
||||
}),
|
||||
);
|
||||
const res2 = await onceMessage<{
|
||||
@@ -827,7 +827,7 @@ describe("gateway server", () => {
|
||||
(p) =>
|
||||
typeof p === "object" &&
|
||||
p !== null &&
|
||||
(p as { instanceId?: unknown }).instanceId === "iris-1" &&
|
||||
(p as { instanceId?: unknown }).instanceId === "node-1" &&
|
||||
(p as { reason?: unknown }).reason === reason,
|
||||
);
|
||||
},
|
||||
@@ -835,20 +835,20 @@ describe("gateway server", () => {
|
||||
);
|
||||
};
|
||||
|
||||
const presenceConnectedP = waitPresenceReason("iris-connected");
|
||||
const presenceConnectedP = waitPresenceReason("node-connected");
|
||||
await bridgeCall?.onAuthenticated?.({
|
||||
nodeId: "iris-1",
|
||||
displayName: "Iris",
|
||||
nodeId: "node-1",
|
||||
displayName: "Node",
|
||||
platform: "ios",
|
||||
version: "1.0",
|
||||
remoteIp: "10.0.0.10",
|
||||
});
|
||||
await presenceConnectedP;
|
||||
|
||||
const presenceDisconnectedP = waitPresenceReason("iris-disconnected");
|
||||
const presenceDisconnectedP = waitPresenceReason("node-disconnected");
|
||||
await bridgeCall?.onDisconnected?.({
|
||||
nodeId: "iris-1",
|
||||
displayName: "Iris",
|
||||
nodeId: "node-1",
|
||||
displayName: "Node",
|
||||
platform: "ios",
|
||||
version: "1.0",
|
||||
remoteIp: "10.0.0.10",
|
||||
|
||||
@@ -1263,7 +1263,7 @@ export async function startGatewayServer(port = 18789): Promise<GatewayServer> {
|
||||
thinking: p.thinking,
|
||||
deliver: p.deliver,
|
||||
timeout: Math.ceil(timeoutMs / 1000).toString(),
|
||||
surface: `Iris(${nodeId})`,
|
||||
surface: `Node(${nodeId})`,
|
||||
abortSignal: abortController.signal,
|
||||
},
|
||||
defaultRuntime,
|
||||
@@ -1367,7 +1367,7 @@ export async function startGatewayServer(port = 18789): Promise<GatewayServer> {
|
||||
sessionId,
|
||||
thinking: "low",
|
||||
deliver: false,
|
||||
surface: "Iris",
|
||||
surface: "Node",
|
||||
},
|
||||
defaultRuntime,
|
||||
deps,
|
||||
@@ -1442,7 +1442,7 @@ export async function startGatewayServer(port = 18789): Promise<GatewayServer> {
|
||||
typeof link?.timeoutSeconds === "number"
|
||||
? link.timeoutSeconds.toString()
|
||||
: undefined,
|
||||
surface: "Iris",
|
||||
surface: "Node",
|
||||
},
|
||||
defaultRuntime,
|
||||
deps,
|
||||
@@ -1508,7 +1508,7 @@ export async function startGatewayServer(port = 18789): Promise<GatewayServer> {
|
||||
const platform = node.platform?.trim() || undefined;
|
||||
const deviceFamily = node.deviceFamily?.trim() || undefined;
|
||||
const modelIdentifier = node.modelIdentifier?.trim() || undefined;
|
||||
const text = `Node: ${host}${ip ? ` (${ip})` : ""} · app ${version} · last input 0s ago · mode remote · reason iris-connected`;
|
||||
const text = `Node: ${host}${ip ? ` (${ip})` : ""} · app ${version} · last input 0s ago · mode remote · reason node-connected`;
|
||||
upsertPresence(node.nodeId, {
|
||||
host,
|
||||
ip,
|
||||
@@ -1517,7 +1517,7 @@ export async function startGatewayServer(port = 18789): Promise<GatewayServer> {
|
||||
deviceFamily,
|
||||
modelIdentifier,
|
||||
mode: "remote",
|
||||
reason: "iris-connected",
|
||||
reason: "node-connected",
|
||||
lastInputSeconds: 0,
|
||||
instanceId: node.nodeId,
|
||||
text,
|
||||
@@ -1554,7 +1554,7 @@ export async function startGatewayServer(port = 18789): Promise<GatewayServer> {
|
||||
const platform = node.platform?.trim() || undefined;
|
||||
const deviceFamily = node.deviceFamily?.trim() || undefined;
|
||||
const modelIdentifier = node.modelIdentifier?.trim() || undefined;
|
||||
const text = `Node: ${host}${ip ? ` (${ip})` : ""} · app ${version} · last input 0s ago · mode remote · reason iris-disconnected`;
|
||||
const text = `Node: ${host}${ip ? ` (${ip})` : ""} · app ${version} · last input 0s ago · mode remote · reason node-disconnected`;
|
||||
upsertPresence(node.nodeId, {
|
||||
host,
|
||||
ip,
|
||||
@@ -1563,7 +1563,7 @@ export async function startGatewayServer(port = 18789): Promise<GatewayServer> {
|
||||
deviceFamily,
|
||||
modelIdentifier,
|
||||
mode: "remote",
|
||||
reason: "iris-disconnected",
|
||||
reason: "node-disconnected",
|
||||
lastInputSeconds: 0,
|
||||
instanceId: node.nodeId,
|
||||
text,
|
||||
@@ -1589,7 +1589,7 @@ export async function startGatewayServer(port = 18789): Promise<GatewayServer> {
|
||||
if (started.port > 0) {
|
||||
bridge = started;
|
||||
defaultRuntime.log(
|
||||
`bridge listening on tcp://${bridgeHost}:${bridge.port} (Iris)`,
|
||||
`bridge listening on tcp://${bridgeHost}:${bridge.port} (node)`,
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
@@ -137,7 +137,7 @@ export async function startGatewayBonjourAdvertiser(
|
||||
svc: master as unknown as BonjourService,
|
||||
});
|
||||
|
||||
// Optional bridge beacon (same type used by Iris/iOS today).
|
||||
// Optional bridge beacon (same type used by iOS/Android nodes today).
|
||||
if (typeof opts.bridgePort === "number" && opts.bridgePort > 0) {
|
||||
const bridge = responder.createService({
|
||||
name: safeServiceName(instanceName),
|
||||
|
||||
@@ -263,7 +263,7 @@ describe("node bridge server", () => {
|
||||
sendLine(socket, {
|
||||
type: "pair-request",
|
||||
nodeId: "n4",
|
||||
displayName: "Iris",
|
||||
displayName: "Node",
|
||||
platform: "ios",
|
||||
version: "1.0",
|
||||
deviceFamily: "iPad",
|
||||
@@ -315,7 +315,7 @@ describe("node bridge server", () => {
|
||||
|
||||
expect(lastAuthed?.nodeId).toBe("n4");
|
||||
// Prefer paired metadata over hello payload (token verifies the stored node record).
|
||||
expect(lastAuthed?.displayName).toBe("Iris");
|
||||
expect(lastAuthed?.displayName).toBe("Node");
|
||||
expect(lastAuthed?.platform).toBe("ios");
|
||||
expect(lastAuthed?.version).toBe("1.0");
|
||||
expect(lastAuthed?.deviceFamily).toBe("iPad");
|
||||
@@ -425,7 +425,7 @@ describe("node bridge server", () => {
|
||||
sendLine(socket, {
|
||||
type: "pair-request",
|
||||
nodeId: "n-caps",
|
||||
displayName: "Iris",
|
||||
displayName: "Node",
|
||||
platform: "ios",
|
||||
version: "1.0",
|
||||
deviceFamily: "iPad",
|
||||
|
||||
Reference in New Issue
Block a user