diff --git a/packages/app/src/app/settings.tsx b/packages/app/src/app/settings.tsx index bff2f68c9..9cdca8a9b 100644 --- a/packages/app/src/app/settings.tsx +++ b/packages/app/src/app/settings.tsx @@ -323,7 +323,7 @@ type DaemonTestState = { export default function SettingsScreen() { const { settings, isLoading: settingsLoading, updateSettings, resetSettings } = useAppSettings(); - const { daemons, isLoading: daemonLoading, addDaemon, updateDaemon, removeDaemon, setDefaultDaemon } = useDaemonRegistry(); + const { daemons, isLoading: daemonLoading, addDaemon, updateDaemon, removeDaemon } = useDaemonRegistry(); const { activeDaemon, activeDaemonId, setActiveDaemonId, connectionStates, updateConnectionStatus } = useDaemonConnections(); const activeDaemonSession = useSessionForServer(activeDaemonId ?? null); const activeDaemonConnection = activeDaemonId ? connectionStates.get(activeDaemonId) : null; @@ -511,13 +511,6 @@ export default function SettingsScreen() { [removeDaemon] ); - const handleSetDefaultDaemon = useCallback( - (profile: DaemonProfile) => { - void setDefaultDaemon(profile.id); - }, - [setDefaultDaemon] - ); - const updateDaemonTestState = useCallback((daemonId: string, state: { status: "idle" | "testing" | "success" | "error"; message?: string }) => { setDaemonTestStates((prev) => { const next = new Map(prev); @@ -617,7 +610,6 @@ export default function SettingsScreen() { label: deriveDaemonLabel(trimmedUrl), wsUrl: trimmedUrl, autoConnect: true, - isDefault: true, }); } @@ -813,7 +805,6 @@ export default function SettingsScreen() { connectionStatus={connectionStatus} lastError={lastConnectionError} testState={testState} - onSetDefault={handleSetDefaultDaemon} onTestConnection={handleTestDaemonConnection} onEdit={handleOpenDaemonForm} onRemove={handleRemoveDaemon} @@ -991,7 +982,6 @@ interface DaemonCardProps { connectionStatus: ConnectionStatus; lastError: string | null; testState?: DaemonTestState; - onSetDefault: (daemon: DaemonProfile) => void; onTestConnection: (daemon: DaemonProfile) => void; onEdit: (daemon: DaemonProfile) => void; onRemove: (daemon: DaemonProfile) => void; @@ -1006,7 +996,6 @@ function DaemonCard({ connectionStatus, lastError, testState, - onSetDefault, onTestConnection, onEdit, onRemove, @@ -1172,9 +1161,6 @@ function DaemonCard({ ) : null} - onSetDefault(daemon)}> - {daemon.isDefault ? "Default" : "Make Default"} - daemon.isDefault) ?? daemons[0]; - setActiveDaemonId(fallback.id, { source: "auto_fallback" }); + const fallback = daemons[0]; + if (fallback) { + setActiveDaemonId(fallback.id, { source: "auto_fallback" }); + } }, [daemons, activeDaemonId, activeDaemonPreference.isPending, persistActiveDaemonId, setActiveDaemonId]); const activeDaemon = useMemo(() => { diff --git a/packages/app/src/contexts/daemon-registry-context.tsx b/packages/app/src/contexts/daemon-registry-context.tsx index eee728dbe..db1e156b0 100644 --- a/packages/app/src/contexts/daemon-registry-context.tsx +++ b/packages/app/src/contexts/daemon-registry-context.tsx @@ -1,4 +1,4 @@ -import { createContext, useCallback, useContext, useMemo } from "react"; +import { createContext, useCallback, useContext } from "react"; import type { ReactNode } from "react"; import AsyncStorage from "@react-native-async-storage/async-storage"; import { useQuery, useQueryClient } from "@tanstack/react-query"; @@ -14,7 +14,6 @@ export type DaemonProfile = { wsUrl: string; restUrl?: string | null; autoConnect: boolean; - isDefault: boolean; createdAt: string; updatedAt: string; metadata?: Record | null; @@ -25,7 +24,6 @@ type CreateDaemonInput = { wsUrl: string; restUrl?: string | null; autoConnect?: boolean; - isDefault?: boolean; }; type UpdateDaemonInput = Partial>; @@ -34,11 +32,9 @@ interface DaemonRegistryContextValue { daemons: DaemonProfile[]; isLoading: boolean; error: unknown | null; - defaultDaemon: DaemonProfile | null; addDaemon: (input: CreateDaemonInput) => Promise; updateDaemon: (id: string, updates: UpdateDaemonInput) => Promise; removeDaemon: (id: string) => Promise; - setDefaultDaemon: (id: string) => Promise; } const DaemonRegistryContext = createContext(null); @@ -81,13 +77,12 @@ export function DaemonRegistryProvider({ children }: { children: ReactNode }) { wsUrl: input.wsUrl, restUrl: input.restUrl ?? null, autoConnect: input.autoConnect ?? true, - isDefault: input.isDefault ?? existing.length === 0, createdAt: timestamp, updatedAt: timestamp, metadata: null, }; - const next = normalizeDefaults([...existing, profile]); + const next = [...existing, profile]; await persist(next); return profile; }, [persist, readDaemons]); @@ -107,36 +102,17 @@ export function DaemonRegistryProvider({ children }: { children: ReactNode }) { const removeDaemon = useCallback(async (id: string) => { const remaining = readDaemons().filter((daemon) => daemon.id !== id); - const normalized = normalizeDefaults(remaining); - await persist(normalized.length > 0 ? normalized : [createProfile("Local Host", FALLBACK_DAEMON_URL, true)]); - }, [persist, readDaemons]); - - const setDefaultDaemon = useCallback(async (id: string) => { - const next = readDaemons().map((daemon) => ({ - ...daemon, - isDefault: daemon.id === id, - updatedAt: daemon.id === id ? new Date().toISOString() : daemon.updatedAt, - })); + const next = remaining.length > 0 ? remaining : [createProfile("Local Host", FALLBACK_DAEMON_URL)]; await persist(next); }, [persist, readDaemons]); - const defaultDaemon = useMemo(() => { - if (daemons.length === 0) { - return null; - } - const explicit = daemons.find((daemon) => daemon.isDefault); - return explicit ?? daemons[0]; - }, [daemons]); - const value: DaemonRegistryContextValue = { daemons, isLoading: isPending, error: error ?? null, - defaultDaemon, addDaemon, updateDaemon, removeDaemon, - setDefaultDaemon, }; return ( @@ -160,7 +136,7 @@ function deriveLabelFromUrl(url: string): string { } } -function createProfile(label: string, wsUrl: string, isDefault: boolean): DaemonProfile { +function createProfile(label: string, wsUrl: string): DaemonProfile { const timestamp = new Date().toISOString(); return { id: generateDaemonId(), @@ -168,28 +144,12 @@ function createProfile(label: string, wsUrl: string, isDefault: boolean): Daemon wsUrl, restUrl: null, autoConnect: true, - isDefault, createdAt: timestamp, updatedAt: timestamp, metadata: null, }; } -function normalizeDefaults(profiles: DaemonProfile[]): DaemonProfile[] { - if (profiles.length === 0) { - return profiles; - } - const hasDefault = profiles.some((daemon) => daemon.isDefault); - if (hasDefault) { - return profiles; - } - const [first, ...rest] = profiles; - return [ - { ...first, isDefault: true }, - ...rest, - ]; -} - async function loadDaemonRegistryFromStorage(): Promise { try { const stored = await AsyncStorage.getItem(REGISTRY_STORAGE_KEY); @@ -202,13 +162,13 @@ async function loadDaemonRegistryFromStorage(): Promise { const legacyParsed = JSON.parse(legacy) as Record; const legacyUrl = typeof legacyParsed.serverUrl === "string" ? legacyParsed.serverUrl : null; if (legacyUrl) { - const migrated = [createProfile("Primary Host", legacyUrl, true)]; + const migrated = [createProfile("Primary Host", legacyUrl)]; await AsyncStorage.setItem(REGISTRY_STORAGE_KEY, JSON.stringify(migrated)); return migrated; } } - const fallback = [createProfile("Local Host", FALLBACK_DAEMON_URL, true)]; + const fallback = [createProfile("Local Host", FALLBACK_DAEMON_URL)]; await AsyncStorage.setItem(REGISTRY_STORAGE_KEY, JSON.stringify(fallback)); return fallback; } catch (error) { diff --git a/plan.md b/plan.md index 0c3fc5505..e05009198 100644 --- a/plan.md +++ b/plan.md @@ -23,7 +23,8 @@ The multi-daemon infrastructure is in place: session directory with daemon-scope ### 2. Remove Active/Primary/Auto-Connect Concepts - [x] Remove the concept of "active daemon" from the UI and simplify to just "hosts". - Removed the Settings "Set Active" controls/labels, scrubbed the copy that mentioned an active host (including git diff fallback text), and left the per-host cards focused on status/default/test actions; no automated tests were run. -- [ ] Remove the concept of "primary daemon"—no default host for actions. +- [x] Remove the concept of "primary daemon"—no default host for actions. + - Removed the Default host toggle/state in the registry and settings UI, updated host docs, and kept connection fallback logic simple; tests not run (not requested). - [ ] Remove the "auto-connect" toggle from host settings—hosts always auto-connect when added. - [ ] Clean up any related state/UI that exposes these concepts to users.