diff --git a/packages/app/src/app/_layout.tsx b/packages/app/src/app/_layout.tsx
index 51cfb836c..7cca7987d 100644
--- a/packages/app/src/app/_layout.tsx
+++ b/packages/app/src/app/_layout.tsx
@@ -13,7 +13,6 @@ import { View, ActivityIndicator, Text } from "react-native";
import { UnistylesRuntime, useUnistyles } from "react-native-unistyles";
import { darkTheme } from "@/styles/theme";
import { DaemonRegistryProvider, useDaemonRegistry } from "@/contexts/daemon-registry-context";
-import { DaemonConnectionsProvider, useDaemonConnections } from "@/contexts/daemon-connections-context";
import { MultiDaemonSessionHost } from "@/components/multi-daemon-session-host";
import { QueryClientProvider } from "@tanstack/react-query";
import { useState, useEffect, type ReactNode, useMemo, useRef } from "react";
@@ -449,37 +448,35 @@ export default function RootLayout() {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/app/src/components/file-explorer-pane.tsx b/packages/app/src/components/file-explorer-pane.tsx
index c634dc43c..86fb80602 100644
--- a/packages/app/src/components/file-explorer-pane.tsx
+++ b/packages/app/src/components/file-explorer-pane.tsx
@@ -49,7 +49,7 @@ import type {
ExplorerEntry,
ExplorerFile,
} from "@/stores/session-store";
-import { useDaemonConnections } from "@/contexts/daemon-connections-context";
+import { useDaemonRegistry } from "@/contexts/daemon-registry-context";
import { useSessionStore } from "@/stores/session-store";
import { useDownloadStore } from "@/stores/download-store";
import {
@@ -95,8 +95,11 @@ export function FileExplorerPane({ serverId, agentId }: FileExplorerPaneProps) {
UnistylesRuntime.breakpoint === "xs" || UnistylesRuntime.breakpoint === "sm";
const showDesktopWebScrollbar = Platform.OS === "web" && !isMobile;
- const { connectionStates } = useDaemonConnections();
- const daemonProfile = connectionStates.get(serverId)?.daemon;
+ const { daemons } = useDaemonRegistry();
+ const daemonProfile = useMemo(
+ () => daemons.find((daemon) => daemon.serverId === serverId),
+ [daemons, serverId]
+ );
const agentExists = useSessionStore((state) =>
agentId && state.sessions[serverId]
? state.sessions[serverId]?.agents.has(agentId)
diff --git a/packages/app/src/components/left-sidebar.tsx b/packages/app/src/components/left-sidebar.tsx
index 576971063..89d7c5c3a 100644
--- a/packages/app/src/components/left-sidebar.tsx
+++ b/packages/app/src/components/left-sidebar.tsx
@@ -1,4 +1,11 @@
-import { useCallback, useMemo, useState, useEffect, useRef } from "react";
+import {
+ useCallback,
+ useMemo,
+ useState,
+ useEffect,
+ useRef,
+ useSyncExternalStore,
+} from "react";
import { View, Pressable, Text, Platform } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import Animated, {
@@ -20,7 +27,7 @@ import { useTauriDragHandlers, useTrafficLightPadding } from "@/utils/tauri-wind
import { useKeyboardShortcutsStore } from "@/stores/keyboard-shortcuts-store";
import { Combobox } from "@/components/ui/combobox";
import { useDaemonRegistry } from "@/contexts/daemon-registry-context";
-import { useDaemonConnections } from "@/contexts/daemon-connections-context";
+import { getHostRuntimeStore } from "@/runtime/host-runtime";
import { useSessionStore } from "@/stores/session-store";
import { formatConnectionStatus } from "@/utils/daemons";
import { HEADER_INNER_HEIGHT, HEADER_INNER_HEIGHT_MOBILE } from "@/constants/layout";
@@ -57,7 +64,12 @@ export function LeftSidebar({ selectedAgentId }: LeftSidebarProps) {
const closeToAgent = usePanelStore((state) => state.closeToAgent);
const pathname = usePathname();
const { daemons } = useDaemonRegistry();
- const { connectionStates } = useDaemonConnections();
+ const runtime = getHostRuntimeStore();
+ const runtimeVersion = useSyncExternalStore(
+ (onStoreChange) => runtime.subscribeAll(onStoreChange),
+ () => runtime.getVersion(),
+ () => runtime.getVersion()
+ );
const activeServerIdFromPath = useMemo(
() => parseServerIdFromPathname(pathname),
[pathname]
@@ -70,7 +82,7 @@ export function LeftSidebar({ selectedAgentId }: LeftSidebarProps) {
return trimmed && trimmed.length > 0 ? trimmed : activeServerId;
}, [activeServerId, daemons]);
const activeHostStatus = activeServerId
- ? (connectionStates.get(activeServerId)?.status ?? "idle")
+ ? runtime.getSnapshot(activeServerId)?.connectionStatus ?? "connecting"
: "idle";
const activeHostStatusColor =
activeHostStatus === "online"
@@ -84,10 +96,10 @@ export function LeftSidebar({ selectedAgentId }: LeftSidebarProps) {
id: daemon.serverId,
label: daemon.label?.trim() || daemon.serverId,
description: formatConnectionStatus(
- connectionStates.get(daemon.serverId)?.status ?? "idle"
+ runtime.getSnapshot(daemon.serverId)?.connectionStatus ?? "connecting"
),
})),
- [connectionStates, daemons]
+ [daemons, runtime, runtimeVersion]
);
const hostTriggerRef = useRef(null);
const [isHostPickerOpen, setIsHostPickerOpen] = useState(false);
diff --git a/packages/app/src/components/voice-panel.tsx b/packages/app/src/components/voice-panel.tsx
index 2b07edcf7..ed2165f2d 100644
--- a/packages/app/src/components/voice-panel.tsx
+++ b/packages/app/src/components/voice-panel.tsx
@@ -3,11 +3,11 @@ import { StyleSheet, useUnistyles } from "react-native-unistyles";
import { MicOff, Square } from "lucide-react-native";
import { VolumeMeter } from "./volume-meter";
import { useVoice } from "@/contexts/voice-context";
-import { useDaemonConnections } from "@/contexts/daemon-connections-context";
+import { useDaemonRegistry } from "@/contexts/daemon-registry-context";
export function VoicePanel() {
const { theme } = useUnistyles();
- const { connectionStates } = useDaemonConnections();
+ const { daemons } = useDaemonRegistry();
const {
volume,
isMuted,
@@ -18,8 +18,9 @@ export function VoicePanel() {
activeServerId,
} = useVoice();
- const activeHost = activeServerId ? connectionStates.get(activeServerId) ?? null : null;
- const hostLabel = activeHost?.daemon.label ?? null;
+ const hostLabel = activeServerId
+ ? daemons.find((daemon) => daemon.serverId === activeServerId)?.label ?? null
+ : null;
const hostSuffix = hostLabel ? ` (${hostLabel})` : "";
return (
diff --git a/packages/app/src/contexts/daemon-connections-context.tsx b/packages/app/src/contexts/daemon-connections-context.tsx
deleted file mode 100644
index c7bbd79f2..000000000
--- a/packages/app/src/contexts/daemon-connections-context.tsx
+++ /dev/null
@@ -1,97 +0,0 @@
-import { createContext, useContext, useMemo, useSyncExternalStore } from "react";
-import type { ReactNode } from "react";
-import {
- getHostRuntimeStore,
- type HostRuntimeAgentDirectoryStatus,
- type HostRuntimeConnectionStatus,
-} from "@/runtime/host-runtime";
-import { useDaemonRegistry, type HostProfile } from "./daemon-registry-context";
-
-export type ActiveConnection =
- | { type: "direct"; endpoint: string; display: string }
- | { type: "relay"; endpoint: string; display: "relay" };
-
-export type ConnectionStatus = HostRuntimeConnectionStatus;
-
-export type DaemonConnectionRecord = {
- daemon: HostProfile;
- status: HostRuntimeConnectionStatus;
- activeConnection: ActiveConnection | null;
- lastError: string | null;
- lastOnlineAt: string | null;
- agentDirectoryStatus: HostRuntimeAgentDirectoryStatus;
- agentDirectoryError: string | null;
- hasEverLoadedAgentDirectory: boolean;
-};
-
-interface DaemonConnectionsContextValue {
- connectionStates: Map;
- isLoading: boolean;
-}
-
-const DaemonConnectionsContext = createContext(null);
-
-function buildConnectionStates(input: {
- daemons: HostProfile[];
- runtime: ReturnType;
-}): Map {
- const { daemons, runtime } = input;
- const next = new Map();
-
- for (const daemon of daemons) {
- const snapshot = runtime.getSnapshot(daemon.serverId);
- next.set(daemon.serverId, {
- daemon,
- status: snapshot?.connectionStatus ?? "connecting",
- activeConnection: snapshot?.activeConnection ?? null,
- lastError: snapshot?.lastError ?? null,
- lastOnlineAt: snapshot?.lastOnlineAt ?? null,
- agentDirectoryStatus: snapshot?.agentDirectoryStatus ?? "initial_loading",
- agentDirectoryError: snapshot?.agentDirectoryError ?? null,
- hasEverLoadedAgentDirectory:
- snapshot?.hasEverLoadedAgentDirectory ?? false,
- });
- }
-
- return next;
-}
-
-export function useDaemonConnections(): DaemonConnectionsContextValue {
- const ctx = useContext(DaemonConnectionsContext);
- if (!ctx) {
- throw new Error(
- "useDaemonConnections must be used within DaemonConnectionsProvider"
- );
- }
- return ctx;
-}
-
-export function DaemonConnectionsProvider({ children }: { children: ReactNode }) {
- const { daemons, isLoading: registryLoading } = useDaemonRegistry();
- const runtime = getHostRuntimeStore();
-
- const runtimeVersion = useSyncExternalStore(
- (onStoreChange) => runtime.subscribeAll(onStoreChange),
- () => runtime.getVersion(),
- () => runtime.getVersion()
- );
-
- const connectionStates = useMemo(
- () => buildConnectionStates({ daemons, runtime }),
- [daemons, runtime, runtimeVersion]
- );
-
- const value = useMemo(
- () => ({
- connectionStates,
- isLoading: registryLoading,
- }),
- [connectionStates, registryLoading]
- );
-
- return (
-
- {children}
-
- );
-}
diff --git a/packages/app/src/hooks/use-aggregated-agents.ts b/packages/app/src/hooks/use-aggregated-agents.ts
index 4f8487e7f..fda5c2dbf 100644
--- a/packages/app/src/hooks/use-aggregated-agents.ts
+++ b/packages/app/src/hooks/use-aggregated-agents.ts
@@ -1,6 +1,6 @@
-import { useMemo, useCallback } from "react";
+import { useMemo, useCallback, useSyncExternalStore } from "react";
import { useShallow } from "zustand/shallow";
-import { useDaemonConnections } from "@/contexts/daemon-connections-context";
+import { useDaemonRegistry } from "@/contexts/daemon-registry-context";
import { useSessionStore } from "@/stores/session-store";
import type { AgentDirectoryEntry } from "@/types/agent-directory";
import type { Agent } from "@/stores/session-store";
@@ -20,8 +20,13 @@ export interface AggregatedAgentsResult {
}
export function useAggregatedAgents(): AggregatedAgentsResult {
- const { connectionStates } = useDaemonConnections();
+ const { daemons } = useDaemonRegistry();
const runtime = getHostRuntimeStore();
+ const runtimeVersion = useSyncExternalStore(
+ (onStoreChange) => runtime.subscribeAll(onStoreChange),
+ () => runtime.getVersion(),
+ () => runtime.getVersion()
+ );
const sessionAgents = useSessionStore(
useShallow((state) => {
@@ -39,13 +44,16 @@ export function useAggregatedAgents(): AggregatedAgentsResult {
const result = useMemo(() => {
const allAgents: AggregatedAgent[] = [];
+ const serverLabelById = new Map(
+ daemons.map((daemon) => [daemon.serverId, daemon.label] as const)
+ );
// Derive agent directory from all sessions
for (const [serverId, agents] of Object.entries(sessionAgents)) {
if (!agents || agents.size === 0) {
continue;
}
- const serverLabel = connectionStates.get(serverId)?.daemon.label ?? serverId;
+ const serverLabel = serverLabelById.get(serverId) ?? serverId;
for (const agent of agents.values()) {
const nextAgent: AggregatedAgent = {
id: agent.id,
@@ -85,11 +93,12 @@ export function useAggregatedAgents(): AggregatedAgentsResult {
const hasAnyData = allAgents.length > 0;
// Align list loading with the runtime directory-sync machine.
- const isLoading = Array.from(connectionStates.values()).some(
- (connection) =>
- connection.agentDirectoryStatus === "initial_loading" ||
- connection.agentDirectoryStatus === "revalidating"
- );
+ const isLoading = daemons.some((daemon) => {
+ const status =
+ runtime.getSnapshot(daemon.serverId)?.agentDirectoryStatus ??
+ "initial_loading";
+ return status === "initial_loading" || status === "revalidating";
+ });
const isInitialLoad = isLoading && !hasAnyData;
const isRevalidating = isLoading && hasAnyData;
@@ -99,7 +108,7 @@ export function useAggregatedAgents(): AggregatedAgentsResult {
isInitialLoad,
isRevalidating,
};
- }, [sessionAgents, connectionStates]);
+ }, [daemons, runtime, runtimeVersion, sessionAgents]);
return {
...result,
diff --git a/packages/app/src/hooks/use-all-agents-list.ts b/packages/app/src/hooks/use-all-agents-list.ts
index b30b31bcb..af1ba8ae5 100644
--- a/packages/app/src/hooks/use-all-agents-list.ts
+++ b/packages/app/src/hooks/use-all-agents-list.ts
@@ -1,5 +1,5 @@
import { useCallback, useMemo } from "react";
-import { useDaemonConnections } from "@/contexts/daemon-connections-context";
+import { useDaemonRegistry } from "@/contexts/daemon-registry-context";
import { useSessionStore, type Agent } from "@/stores/session-store";
import {
getHostRuntimeStore,
@@ -37,7 +37,7 @@ function toAggregatedAgent(params: {
export function useAllAgentsList(options?: {
serverId?: string | null;
}): AggregatedAgentsResult {
- const { connectionStates } = useDaemonConnections();
+ const { daemons } = useDaemonRegistry();
const runtime = getHostRuntimeStore();
const serverId = useMemo(() => {
@@ -64,7 +64,8 @@ export function useAllAgentsList(options?: {
if (!serverId || !liveAgents) {
return [];
}
- const serverLabel = connectionStates.get(serverId)?.daemon.label ?? serverId;
+ const serverLabel =
+ daemons.find((daemon) => daemon.serverId === serverId)?.label ?? serverId;
const list: AggregatedAgent[] = [];
for (const agent of liveAgents.values()) {
@@ -95,7 +96,7 @@ export function useAllAgentsList(options?: {
});
return list;
- }, [connectionStates, liveAgents, serverId]);
+ }, [daemons, liveAgents, serverId]);
const isDirectoryLoading = Boolean(serverId && isHostRuntimeDirectoryLoading(snapshot));
const isInitialLoad = isDirectoryLoading && agents.length === 0;
diff --git a/packages/app/src/hooks/use-sidebar-agents-list.ts b/packages/app/src/hooks/use-sidebar-agents-list.ts
index 40ebbedcb..10fd2d488 100644
--- a/packages/app/src/hooks/use-sidebar-agents-list.ts
+++ b/packages/app/src/hooks/use-sidebar-agents-list.ts
@@ -1,5 +1,5 @@
import { useCallback, useMemo } from "react";
-import { useDaemonConnections } from "@/contexts/daemon-connections-context";
+import { useDaemonRegistry } from "@/contexts/daemon-registry-context";
import { useSessionStore, type Agent } from "@/stores/session-store";
import {
getHostRuntimeStore,
@@ -149,7 +149,7 @@ export function useSidebarAgentsList(options?: {
serverId?: string | null;
selectedProjectFilterKeys?: string[];
}): SidebarAgentsListResult {
- const { connectionStates } = useDaemonConnections();
+ const { daemons } = useDaemonRegistry();
const runtime = getHostRuntimeStore();
const serverId = useMemo(() => {
const value = options?.serverId;
@@ -184,7 +184,8 @@ export function useSidebarAgentsList(options?: {
};
}
- const serverLabel = connectionStates.get(serverId)?.daemon.label ?? serverId;
+ const serverLabel =
+ daemons.find((daemon) => daemon.serverId === serverId)?.label ?? serverId;
const seenAgentIds = new Set();
const byProject = new Map();
const mergedEntries: SidebarAgentListEntry[] = [];
@@ -261,7 +262,7 @@ export function useSidebarAgentsList(options?: {
hasAnyData: ordered.entries.length > 0,
hasMoreEntries: ordered.hasMore,
};
- }, [connectionStates, liveAgents, selectedProjectFilterKeys, serverId]);
+ }, [daemons, liveAgents, selectedProjectFilterKeys, serverId]);
const refreshAll = useCallback(() => {
if (!serverId || snapshot?.connectionStatus !== "online") {
diff --git a/packages/app/src/runtime/host-runtime.ts b/packages/app/src/runtime/host-runtime.ts
index 5ea19f376..136f1256b 100644
--- a/packages/app/src/runtime/host-runtime.ts
+++ b/packages/app/src/runtime/host-runtime.ts
@@ -5,7 +5,6 @@ import {
type FetchAgentsOptions,
} from "@server/client/daemon-client";
import type { HostConnection, HostProfile } from "@/contexts/daemon-registry-context";
-import type { ActiveConnection } from "@/contexts/daemon-connections-context";
import {
buildDaemonWebSocketUrl,
buildRelayWebSocketUrl,
@@ -28,6 +27,10 @@ export type HostRuntimeConnectionStatus =
| "offline"
| "error";
+export type ActiveConnection =
+ | { type: "direct"; endpoint: string; display: string }
+ | { type: "relay"; endpoint: string; display: "relay" };
+
export type HostRuntimeAgentDirectoryStatus =
| "idle"
| "initial_loading"
diff --git a/packages/app/src/screens/agent/agent-ready-screen.tsx b/packages/app/src/screens/agent/agent-ready-screen.tsx
index 642178e83..04fbdf9b2 100644
--- a/packages/app/src/screens/agent/agent-ready-screen.tsx
+++ b/packages/app/src/screens/agent/agent-ready-screen.tsx
@@ -40,7 +40,7 @@ import {
ExplorerSidebarAnimationProvider,
} from "@/contexts/explorer-sidebar-animation-context";
import { usePanelStore } from "@/stores/panel-store";
-import { useDaemonConnections } from "@/contexts/daemon-connections-context";
+import { useDaemonRegistry } from "@/contexts/daemon-registry-context";
import { useSessionStore } from "@/stores/session-store";
import {
useHostRuntimeSession,
@@ -112,7 +112,7 @@ export function AgentReadyScreen({
const router = useRouter();
const resolvedAgentId = agentId?.trim() || undefined;
const resolvedServerId = serverId?.trim() || undefined;
- const { connectionStates } = useDaemonConnections();
+ const { daemons } = useDaemonRegistry();
const runtimeServerId = resolvedServerId ?? "";
const {
snapshot: runtimeSnapshot,
@@ -121,12 +121,12 @@ export function AgentReadyScreen({
} = useHostRuntimeSession(runtimeServerId);
const connectionServerId = resolvedServerId ?? null;
- const connection = connectionServerId
- ? connectionStates.get(connectionServerId)
+ const daemon = connectionServerId
+ ? daemons.find((entry) => entry.serverId === connectionServerId) ?? null
: null;
const serverLabel =
- connection?.daemon.label ?? connectionServerId ?? "Selected host";
- const isUnknownDaemon = Boolean(connectionServerId && !connection);
+ daemon?.label ?? connectionServerId ?? "Selected host";
+ const isUnknownDaemon = Boolean(connectionServerId && !daemon);
const connectionStatus: HostRuntimeConnectionStatus =
runtimeSnapshot?.connectionStatus ??
(isUnknownDaemon ? "offline" : "connecting");
diff --git a/packages/app/src/screens/agent/draft-agent-screen.tsx b/packages/app/src/screens/agent/draft-agent-screen.tsx
index 134059059..2cb8522c7 100644
--- a/packages/app/src/screens/agent/draft-agent-screen.tsx
+++ b/packages/app/src/screens/agent/draft-agent-screen.tsx
@@ -1,4 +1,4 @@
-import { useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react'
+import { useCallback, useEffect, useMemo, useReducer, useRef, useState, useSyncExternalStore } from 'react'
import { createNameId } from 'mnemonic-id'
import type { ImageAttachment } from '@/components/message-input'
import { View, Text, Pressable, ScrollView, Keyboard, Platform } from 'react-native'
@@ -26,7 +26,6 @@ import {
checkoutStatusQueryKey,
} from '@/hooks/use-checkout-status-query'
import { useAllAgentsList } from '@/hooks/use-all-agents-list'
-import { useDaemonConnections } from '@/contexts/daemon-connections-context'
import { useDaemonRegistry } from '@/contexts/daemon-registry-context'
import { buildBranchComboOptions, normalizeBranchOptionName } from '@/utils/branch-suggestions'
import { shortenPath } from '@/utils/shorten-path'
@@ -35,7 +34,7 @@ import { buildWorkingDirectorySuggestions } from '@/utils/working-directory-sugg
import { useExplorerOpenGesture } from '@/hooks/use-explorer-open-gesture'
import { useSessionStore } from '@/stores/session-store'
import { useCreateFlowStore } from '@/stores/create-flow-store'
-import { useHostRuntimeSession } from '@/runtime/host-runtime'
+import { getHostRuntimeStore, useHostRuntimeSession } from '@/runtime/host-runtime'
import { ExplorerSidebarAnimationProvider } from '@/contexts/explorer-sidebar-animation-context'
import { usePanelStore, type ExplorerCheckoutContext } from '@/stores/panel-store'
import { MAX_CONTENT_WIDTH } from '@/constants/layout'
@@ -139,8 +138,13 @@ function DraftAgentScreenContent({
const { theme } = useUnistyles()
const router = useRouter()
const insets = useSafeAreaInsets()
- const { connectionStates } = useDaemonConnections()
const { daemons } = useDaemonRegistry()
+ const runtime = getHostRuntimeStore()
+ const runtimeVersion = useSyncExternalStore(
+ (onStoreChange) => runtime.subscribeAll(onStoreChange),
+ () => runtime.getVersion(),
+ () => runtime.getVersion()
+ )
const params = useLocalSearchParams()
const { height: keyboardHeight } = useReanimatedKeyboardAnimation()
@@ -174,11 +178,11 @@ function DraftAgentScreenContent({
if (daemons.length === 0) return []
const out: string[] = []
for (const daemon of daemons) {
- const status = connectionStates.get(daemon.serverId)?.status ?? 'idle'
+ const status = runtime.getSnapshot(daemon.serverId)?.connectionStatus ?? 'connecting'
if (status === 'online') out.push(daemon.serverId)
}
return out
- }, [connectionStates, daemons])
+ }, [daemons, runtime, runtimeVersion])
const initialValues = useMemo((): CreateAgentInitialValues => {
const values: CreateAgentInitialValues = {}
@@ -228,7 +232,6 @@ function DraftAgentScreenContent({
isCreateFlow: true,
onlineServerIds,
})
- const hostEntry = selectedServerId ? connectionStates.get(selectedServerId) : undefined
const isMobile = UnistylesRuntime.breakpoint === 'xs' || UnistylesRuntime.breakpoint === 'sm'
const mobileView = usePanelStore((state) => state.mobileView)
const desktopFileExplorerOpen = usePanelStore((state) => state.desktop.fileExplorerOpen)
diff --git a/packages/app/src/screens/agent/legacy-agent-id-screen.tsx b/packages/app/src/screens/agent/legacy-agent-id-screen.tsx
index 3bdebaa73..c18cae9ef 100644
--- a/packages/app/src/screens/agent/legacy-agent-id-screen.tsx
+++ b/packages/app/src/screens/agent/legacy-agent-id-screen.tsx
@@ -5,7 +5,7 @@ import { useRouter } from "expo-router";
import { StyleSheet, useUnistyles } from "react-native-unistyles";
import { BackHeader } from "@/components/headers/back-header";
import { useSessionDirectory } from "@/hooks/use-session-directory";
-import { useDaemonConnections } from "@/contexts/daemon-connections-context";
+import { useDaemonRegistry } from "@/contexts/daemon-registry-context";
import type { Agent } from "@/contexts/session-context";
import {
buildHostAgentDetailRoute,
@@ -21,7 +21,7 @@ type AgentMatch = {
export function LegacyAgentIdScreen({ agentId }: { agentId: string }) {
const router = useRouter();
const { theme } = useUnistyles();
- const { connectionStates } = useDaemonConnections();
+ const { daemons } = useDaemonRegistry();
const sessionDirectory = useSessionDirectory();
const resolvedAgentId = typeof agentId === "string" ? agentId.trim() : undefined;
@@ -39,12 +39,13 @@ export function LegacyAgentIdScreen({ agentId }: { agentId: string }) {
if (!agent) {
return;
}
- const serverLabel = connectionStates.get(serverId)?.daemon.label ?? serverId;
+ const serverLabel =
+ daemons.find((daemon) => daemon.serverId === serverId)?.label ?? serverId;
results.push({ serverId, serverLabel, agent });
});
return results;
- }, [resolvedAgentId, sessionDirectory, connectionStates]);
+ }, [daemons, resolvedAgentId, sessionDirectory]);
const hasSessions = sessionDirectory.size > 0;
const isRedirecting = Boolean(resolvedAgentId && matches.length === 1);
diff --git a/packages/app/src/utils/daemons.ts b/packages/app/src/utils/daemons.ts
index e323c05fc..8379c7fa6 100644
--- a/packages/app/src/utils/daemons.ts
+++ b/packages/app/src/utils/daemons.ts
@@ -1,7 +1,7 @@
-import type { ConnectionStatus } from "@/contexts/daemon-connections-context";
+import type { HostRuntimeConnectionStatus } from "@/runtime/host-runtime";
import { assertUnreachable } from "./exhaustive";
-export function formatConnectionStatus(status: ConnectionStatus): string {
+export function formatConnectionStatus(status: HostRuntimeConnectionStatus): string {
switch (status) {
case "online":
return "Online";
@@ -20,7 +20,9 @@ export function formatConnectionStatus(status: ConnectionStatus): string {
export type ConnectionStatusTone = "success" | "warning" | "error" | "muted";
-export function getConnectionStatusTone(status: ConnectionStatus): ConnectionStatusTone {
+export function getConnectionStatusTone(
+ status: HostRuntimeConnectionStatus
+): ConnectionStatusTone {
switch (status) {
case "online":
return "success";