diff --git a/packages/app/e2e/helpers/settings.ts b/packages/app/e2e/helpers/settings.ts
index 40f128572..7b8c63bda 100644
--- a/packages/app/e2e/helpers/settings.ts
+++ b/packages/app/e2e/helpers/settings.ts
@@ -393,9 +393,9 @@ export async function expectLocalHostEntryFirst(page: Page, _serverId: string):
await expect(sidebar).toBeVisible({ timeout: 15_000 });
// Single-host fixture: the picker is a non-interactive chip (no dropdown to
- // open) that surfaces the local host by its label. The "Local" marker only
- // appears on dropdown rows in the multi-host case, which this fixture does not
- // exercise.
+ // open) that surfaces the local host by its label. The per-row connection
+ // endpoint only appears on dropdown rows in the multi-host case, which this
+ // fixture does not exercise.
const picker = sidebar.getByTestId("settings-host-picker");
await expect(picker).toBeVisible();
await expect(picker.getByText(TEST_HOST_LABEL, { exact: true })).toBeVisible();
diff --git a/packages/app/e2e/settings-host-page.spec.ts b/packages/app/e2e/settings-host-page.spec.ts
index a25786de1..e20480724 100644
--- a/packages/app/e2e/settings-host-page.spec.ts
+++ b/packages/app/e2e/settings-host-page.spec.ts
@@ -118,7 +118,7 @@ test.describe("Settings host page", () => {
await expectHostActionCards(page, serverId);
});
- test("sidebar pins the local daemon host first with a Local marker", async ({ page }) => {
+ test("sidebar pins the local daemon host first", async ({ page }) => {
const serverId = getServerId();
// Simulate the Electron desktop bridge so `useIsLocalDaemon` resolves the
diff --git a/packages/app/src/components/hosts/host-picker.tsx b/packages/app/src/components/hosts/host-picker.tsx
index 86101d857..d39bd0b5b 100644
--- a/packages/app/src/components/hosts/host-picker.tsx
+++ b/packages/app/src/components/hosts/host-picker.tsx
@@ -1,11 +1,12 @@
import { useCallback, useMemo, type ReactElement, type ReactNode } from "react";
-import { Pressable, Text, View } from "react-native";
+import { Pressable, View } from "react-native";
import type { GestureResponderEvent } from "react-native";
import { Plus, Server, Settings } from "lucide-react-native";
import { StyleSheet, useUnistyles } from "react-native-unistyles";
import { HostStatusDot } from "@/components/host-status-dot";
import { Combobox, ComboboxItem, type ComboboxProps } from "@/components/ui/combobox";
import { useLocalDaemonServerId } from "@/hooks/use-is-local-daemon";
+import { useHostRuntimeSnapshot, type ActiveConnection } from "@/runtime/host-runtime";
import { orderHostsLocalFirst } from "@/types/host-connection";
import {
ADD_HOST_OPTION_ID,
@@ -30,30 +31,48 @@ export function HostStatusDotSlot({ serverId }: { serverId: string }): ReactElem
);
}
+// Standard secure/plain web ports carry no information in the host display, so
+// "relay.paseo.sh:443" reads as "relay.paseo.sh" while "127.0.0.1:6767" is kept.
+function formatConnectionEndpoint(endpoint: string): string {
+ return endpoint.replace(/:(?:443|80)$/, "");
+}
+
+// Socket/pipe transports have no host:port — their endpoint is a filesystem
+// path, so they read as "Local". TCP and relay show the address being used.
+function formatActiveConnectionLabel(connection: ActiveConnection): string {
+ if (connection.type === "directSocket" || connection.type === "directPipe") {
+ return "Local";
+ }
+ return formatConnectionEndpoint(connection.endpoint);
+}
+
export interface HostPickerOptionProps {
serverId: string;
label: string;
- isLocal: boolean;
+ showActiveConnection: boolean;
selected?: boolean;
active: boolean;
onPress: () => void;
onOpenHostSettings?: (serverId: string) => void;
- localMarkerTestID?: string;
testID?: string;
}
export function HostPickerOption({
serverId,
label,
- isLocal,
+ showActiveConnection,
selected,
active,
onPress,
onOpenHostSettings,
- localMarkerTestID,
testID,
}: HostPickerOptionProps): ReactElement {
const { theme } = useUnistyles();
+ const activeConnection = useHostRuntimeSnapshot(serverId)?.activeConnection ?? null;
+ const connectionLabel =
+ showActiveConnection && activeConnection
+ ? formatActiveConnectionLabel(activeConnection)
+ : undefined;
const leadingSlot = useMemo(() => , [serverId]);
const handleSettingsPress = useCallback(
(event: GestureResponderEvent) => {
@@ -63,31 +82,20 @@ export function HostPickerOption({
[onOpenHostSettings, serverId],
);
const trailingSlot = useMemo(() => {
- if (!isLocal && !onOpenHostSettings) return undefined;
+ if (!onOpenHostSettings) return undefined;
return (
- <>
- {isLocal ? (
-
- Local
-
- ) : null}
- {onOpenHostSettings ? (
-
-
-
- ) : null}
- >
+
+
+
);
}, [
handleSettingsPress,
- isLocal,
label,
- localMarkerTestID,
onOpenHostSettings,
theme.colors.foregroundMuted,
theme.iconSize.sm,
@@ -96,6 +104,7 @@ export function HostPickerOption({
return (
void;
- showLocalMarker?: boolean;
+ showActiveConnection?: boolean;
onOpenHostSettings?: (serverId: string) => void;
searchable?: boolean;
title?: string;
@@ -157,7 +166,6 @@ export interface HostPickerProps {
desktopMinWidth?: number;
addHostTestID?: string;
hostOptionTestID?: (serverId: string) => string;
- hostLocalMarkerTestID?: (serverId: string) => string;
children: ReactNode;
}
@@ -171,7 +179,7 @@ export function HostPicker({
includeAllHost,
includeAddHost,
onAddHost,
- showLocalMarker,
+ showActiveConnection,
onOpenHostSettings,
searchable,
title,
@@ -179,7 +187,6 @@ export function HostPicker({
desktopMinWidth,
addHostTestID,
hostOptionTestID,
- hostLocalMarkerTestID,
children,
}: HostPickerProps): ReactElement {
const localServerId = useLocalDaemonServerId();
@@ -243,23 +250,20 @@ export function HostPicker({
);
},
[
addHostTestID,
- hostLocalMarkerTestID,
hostOptionTestID,
- localServerId,
onOpenHostSettings,
- showLocalMarker,
+ showActiveConnection,
handleOpenHostSettings,
],
);
@@ -292,9 +296,4 @@ const styles = StyleSheet.create((theme) => ({
alignItems: "center",
justifyContent: "center",
},
- localMarker: {
- fontSize: theme.fontSize.xs,
- color: theme.colors.foregroundMuted,
- marginLeft: theme.spacing[1],
- },
}));
diff --git a/packages/app/src/components/left-sidebar.tsx b/packages/app/src/components/left-sidebar.tsx
index 00b027236..6c6fd9c09 100644
--- a/packages/app/src/components/left-sidebar.tsx
+++ b/packages/app/src/components/left-sidebar.tsx
@@ -290,10 +290,6 @@ function sidebarHostOptionTestID(serverId: string): string {
return `sidebar-host-row-${serverId}`;
}
-function sidebarHostLocalMarkerTestID(serverId: string): string {
- return `sidebar-host-local-marker-${serverId}`;
-}
-
function FooterIconButton({
buttonRef,
onPress,
@@ -365,13 +361,12 @@ function SidebarHostPicker({
anchorRef={triggerRef}
includeAddHost
onAddHost={onAddHost}
- showLocalMarker
+ showActiveConnection
onOpenHostSettings={onOpenHostSettings}
searchable
desktopMinWidth={240}
addHostTestID="sidebar-host-add"
hostOptionTestID={sidebarHostOptionTestID}
- hostLocalMarkerTestID={sidebarHostLocalMarkerTestID}
>
. The local host is listed first and tagged "Local"; an "Add host"
- * row is always reachable from the list — even with a single host.
+ * . The local host is listed first, each row shows the connection it
+ * is using right now; an "Add host" row is always reachable from the list —
+ * even with a single host.
*/
function HostPicker({ activeServerId, sortedHosts, onSelectHost, onAddHost }: HostPickerProps) {
const { t } = useTranslation();
@@ -906,7 +907,6 @@ function HostPicker({ activeServerId, sortedHosts, onSelectHost, onAddHost }: Ho
sortedHosts.find((host) => host.serverId === activeServerId) ?? sortedHosts[0] ?? null;
const handleOpen = useCallback(() => setIsOpen(true), []);
- const hostLocalMarkerTestID = useCallback(() => "settings-host-local-marker", []);
const hostOptionTestID = useCallback(
(serverId: string) => `settings-host-picker-item-${serverId}`,
[],
@@ -929,12 +929,11 @@ function HostPicker({ activeServerId, sortedHosts, onSelectHost, onAddHost }: Ho
anchorRef={triggerRef}
includeAddHost
onAddHost={onAddHost}
- showLocalMarker
+ showActiveConnection
searchable={false}
title={t("settings.hostPicker.switchHost")}
desktopMinWidth={240}
addHostTestID="settings-add-host"
- hostLocalMarkerTestID={hostLocalMarkerTestID}
hostOptionTestID={hostOptionTestID}
>