diff --git a/packages/app/src/components/dialog-select-server.tsx b/packages/app/src/components/dialog-select-server.tsx
index a684a350e9..4762dddc41 100644
--- a/packages/app/src/components/dialog-select-server.tsx
+++ b/packages/app/src/components/dialog-select-server.tsx
@@ -12,7 +12,6 @@ import { batch, createEffect, createMemo, onCleanup, Show, startTransition, untr
import { createStore, reconcile } from "solid-js/store"
import { DialogWslServer } from "@/components/dialog-wsl-server"
import { ServerHealthIndicator, ServerRow } from "@/components/server/server-row"
-import { useDefaultServer } from "@/context/default-server"
import { useLanguage } from "@/context/language"
import { usePlatform } from "@/context/platform"
import { normalizeServerUrl, ServerConnection, useServer } from "@/context/server"
@@ -147,7 +146,6 @@ export function DialogSelectServer(props: DialogSelectServerProps = {}) {
const server = useServer()
const platform = usePlatform()
const language = useLanguage()
- const { defaultKey, canDefault, setDefault } = useDefaultServer()
const wslServers = useWslServers()
const checkServerHealth = useCheckServerHealth()
let disposed = false
@@ -274,7 +272,7 @@ export function DialogSelectServer(props: DialogSelectServerProps = {}) {
},
onSuccess: async (key) => {
server.remove(key)
- if (defaultKey() === key) await setDefault(null)
+ if (server.defaultKey() === key) await server.setDefault(null)
},
onError: (err) => showRequestError(language, err),
}))
@@ -549,7 +547,7 @@ export function DialogSelectServer(props: DialogSelectServerProps = {}) {
async function handleRemove(key: ServerConnection.Key) {
server.remove(key)
- if (defaultKey() === key) await setDefault(null)
+ if (server.defaultKey() === key) await server.setDefault(null)
}
function handleRemoveWsl(conn: ServerConnection.Any) {
@@ -621,7 +619,7 @@ export function DialogSelectServer(props: DialogSelectServerProps = {}) {
const wsl = isWslSidecar(i)
const wslDistro = wsl ? i.distro : undefined
const blocked = () => health(key)?.healthy === false
- const canChangeDefault = () => canDefault() && i.type !== "ssh"
+ const canChangeDefault = () => server.canDefault() && i.type !== "ssh"
const canRemove = () => i.type === "http" || wsl
const hasMenuActionsBeforeDelete = () => canRemove() && (i.type === "http" || canChangeDefault() || canRetryWsl(i))
const outdated = () => {
@@ -651,7 +649,7 @@ export function DialogSelectServer(props: DialogSelectServerProps = {}) {
version={wslCheck(i)?.version ?? undefined}
class="flex items-center gap-3 min-w-0 flex-1"
badge={
-
+
{language.t("dialog.server.status.default")}
@@ -708,15 +706,15 @@ export function DialogSelectServer(props: DialogSelectServerProps = {}) {
Retry start
-
- void setDefault(key)}>
+
+ void server.setDefault(key)}>
{language.t("dialog.server.menu.default")}
-
- void setDefault(null)}>
+
+ void server.setDefault(null)}>
{language.t("dialog.server.menu.defaultRemove")}
diff --git a/packages/app/src/components/status-popover-body.tsx b/packages/app/src/components/status-popover-body.tsx
index b290f7b5d5..3c7dbad1d9 100644
--- a/packages/app/src/components/status-popover-body.tsx
+++ b/packages/app/src/components/status-popover-body.tsx
@@ -6,17 +6,13 @@ import { Tabs } from "@opencode-ai/ui/tabs"
import { useMutation } from "@tanstack/solid-query"
import { showToast } from "@opencode-ai/ui/toast"
import { useNavigate } from "@solidjs/router"
-import { type Accessor, batch, createEffect, createMemo, For, type JSXElement, onCleanup, Show, startTransition, untrack } from "solid-js"
-import { createStore, reconcile } from "solid-js/store"
-import { ServerHealthIndicator, ServerRow } from "@/components/server/server-row"
-import { useDefaultServer } from "@/context/default-server"
+import { type Accessor, batch, createEffect, createMemo, For, type JSXElement, onCleanup, Show, startTransition } from "solid-js"
+import { createStore } from "solid-js/store"
+import { ServerRow } from "@/components/server/server-row"
import { useLanguage } from "@/context/language"
import { useSDK } from "@/context/sdk"
import { ServerConnection, useServer } from "@/context/server"
import { useSync } from "@/context/sync"
-import { useCheckServerHealth, type ServerHealth } from "@/utils/server-health"
-
-const pollMs = 10_000
const pluginEmptyMessage = (value: string, file: string): JSXElement => {
const parts = value.split(file)
@@ -30,72 +26,6 @@ const pluginEmptyMessage = (value: string, file: string): JSXElement => {
)
}
-const listServersByHealth = (
- list: ServerConnection.Any[],
- active: ServerConnection.Key | undefined,
- status: Record,
-) => {
- if (!list.length) return list
- const order = new Map(list.map((url, index) => [url, index] as const))
- const rank = (value?: ServerHealth) => {
- if (value?.healthy === true) return 0
- if (value?.healthy === false) return 2
- return 1
- }
-
- return list.slice().sort((a, b) => {
- if (ServerConnection.key(a) === active) return -1
- if (ServerConnection.key(b) === active) return 1
- const diff = rank(status[ServerConnection.key(a)]) - rank(status[ServerConnection.key(b)])
- if (diff !== 0) return diff
- return (order.get(a) ?? 0) - (order.get(b) ?? 0)
- })
-}
-
-const useServerHealth = (servers: Accessor, enabled: Accessor) => {
- const checkServerHealth = useCheckServerHealth()
- const [status, setStatus] = createStore({} as Record)
- const pollKey = createMemo(() =>
- enabled()
- ? servers()
- .map((conn) =>
- [ServerConnection.key(conn), conn.http.url, conn.http.username ?? "", conn.http.password ?? ""].join("\n"),
- )
- .join("\n\n")
- : "",
- )
-
- createEffect(() => {
- if (!enabled()) {
- setStatus(reconcile({}))
- return
- }
- pollKey()
- const list = untrack(servers)
- let dead = false
-
- const refresh = async () => {
- const results: Record = {}
- await Promise.all(
- list.map(async (conn) => {
- results[ServerConnection.key(conn)] = await checkServerHealth(conn.http)
- }),
- )
- if (dead) return
- setStatus(reconcile(results))
- }
-
- void refresh()
- const id = setInterval(() => void refresh(), pollMs)
- onCleanup(() => {
- dead = true
- clearInterval(id)
- })
- })
-
- return status
-}
-
const useMcpToggleMutation = () => {
const sync = useSync()
const sdk = useSDK()
@@ -125,7 +55,6 @@ export function StatusPopoverBody(props: { shown: Accessor }) {
const language = useLanguage()
const navigate = useNavigate()
const sdk = useSDK()
- const defaultServer = useDefaultServer()
const [load, setLoad] = createStore({
lspDone: false,
@@ -193,8 +122,6 @@ export function StatusPopoverBody(props: { shown: Accessor }) {
if (list.every((item) => ServerConnection.key(item) !== ServerConnection.key(current))) return [current, ...list]
return [current, ...list.filter((item) => ServerConnection.key(item) !== ServerConnection.key(current))]
})
- const health = useServerHealth(servers, props.shown)
- const sortedServers = createMemo(() => listServersByHealth(servers(), server.key, health))
const toggleMcp = useMcpToggleMutation()
const mcpNames = createMemo(() => Object.keys(sync.data.mcp ?? {}).sort((a, b) => a.localeCompare(b)))
const mcpStatus = (name: string) => sync.data.mcp?.[name]?.status
@@ -219,7 +146,7 @@ export function StatusPopoverBody(props: { shown: Accessor }) {
>
- {sortedServers().length > 0 ? `${sortedServers().length} ` : ""}
+ {servers().length > 0 ? `${servers().length} ` : ""}
{language.t("status.popover.tab.servers")}
@@ -239,45 +166,35 @@ export function StatusPopoverBody(props: { shown: Accessor }) {
-
+
{(s) => {
const key = ServerConnection.key(s)
- const blocked = () => health[key]?.healthy === false
return (