fix(ios): improve bridge discovery and pairing UX

This commit is contained in:
Peter Steinberger
2025-12-13 17:58:03 +00:00
parent 61ab07ced3
commit 7c3502f031
6 changed files with 263 additions and 83 deletions

View File

@@ -47,6 +47,7 @@ import {
getLastHeartbeatEvent,
onHeartbeatEvent,
} from "../infra/heartbeat-events.js";
import { getMachineDisplayName } from "../infra/machine-name.js";
import {
approveNodePairing,
listNodePairing,
@@ -118,6 +119,13 @@ type Client = {
presenceKey?: string;
};
function formatBonjourInstanceName(displayName: string) {
const trimmed = displayName.trim();
if (!trimmed) return "Clawdis";
if (/clawdis/i.test(trimmed)) return trimmed;
return `${trimmed} (Clawdis)`;
}
type GatewaySessionsDefaults = {
model: string | null;
contextTokens: number | null;
@@ -797,11 +805,14 @@ export async function startGatewayServer(
}
};
const machineDisplayName = await getMachineDisplayName();
if (bridgeEnabled && bridgePort > 0) {
try {
const started = await startNodeBridgeServer({
host: bridgeHost,
port: bridgePort,
serverName: machineDisplayName,
onAuthenticated: (node) => {
const host = node.displayName?.trim() || node.nodeId;
const ip = node.remoteIp?.trim();
@@ -887,6 +898,7 @@ export async function startGatewayServer(
tailnetDnsEnv && tailnetDnsEnv.length > 0 ? tailnetDnsEnv : undefined;
const bonjour = await startGatewayBonjourAdvertiser({
instanceName: formatBonjourInstanceName(machineDisplayName),
gatewayPort: port,
bridgePort: bridge?.port,
sshPort,

43
src/infra/machine-name.ts Normal file
View File

@@ -0,0 +1,43 @@
import { execFile } from "node:child_process";
import os from "node:os";
import { promisify } from "node:util";
const execFileAsync = promisify(execFile);
let cachedPromise: Promise<string> | null = null;
async function tryScutil(key: "ComputerName" | "LocalHostName") {
try {
const { stdout } = await execFileAsync("/usr/sbin/scutil", ["--get", key], {
timeout: 1000,
windowsHide: true,
});
const value = String(stdout ?? "").trim();
return value.length > 0 ? value : null;
} catch {
return null;
}
}
function fallbackHostName() {
return (
os
.hostname()
.replace(/\.local$/i, "")
.trim() || "clawdis"
);
}
export async function getMachineDisplayName(): Promise<string> {
if (cachedPromise) return cachedPromise;
cachedPromise = (async () => {
if (process.platform === "darwin") {
const computerName = await tryScutil("ComputerName");
if (computerName) return computerName;
const localHostName = await tryScutil("LocalHostName");
if (localHostName) return localHostName;
}
return fallbackHostName();
})();
return cachedPromise;
}