fix(app): restore deferred MCP status updates (#30220)

This commit is contained in:
Luke Parker
2026-06-02 12:11:11 +10:00
committed by GitHub
parent 1cae8f89c5
commit 4e70eabbcc
2 changed files with 28 additions and 25 deletions

View File

@@ -6,7 +6,7 @@ import type { State } from "./types"
import type { QueryOptionsApi } from "../server-sync" import type { QueryOptionsApi } from "../server-sync"
let createChildStoreManager: typeof import("./child-store").createChildStoreManager let createChildStoreManager: typeof import("./child-store").createChildStoreManager
const queryGroups: Array<() => { queries: Array<{ enabled?: boolean }> }> = [] const querySingles: Array<() => { queryKey?: unknown[]; enabled?: boolean }> = []
const child = () => createStore({} as State) const child = () => createStore({} as State)
const provider = { all: new Map(), connected: [], default: {} } satisfies NormalizedProviderListResponse const provider = { all: new Map(), connected: [], default: {} } satisfies NormalizedProviderListResponse
@@ -49,14 +49,19 @@ beforeAll(async () => {
persisted: (_target: string, store: unknown[]) => [store[0], store[1], null, () => true], persisted: (_target: string, store: unknown[]) => [store[0], store[1], null, () => true],
})) }))
mock.module("@tanstack/solid-query", () => ({ mock.module("@tanstack/solid-query", () => ({
useQueries: (options: () => { queries: Array<{ enabled?: boolean }> }) => { useQuery: (options: () => { queryKey?: unknown[]; enabled?: boolean }) => {
queryGroups.push(options) querySingles.push(options)
return [ return {
{ isLoading: true, data: undefined }, get isLoading() {
{ isLoading: false, data: {} }, return options().queryKey?.[1] === "path"
{ isLoading: false, data: [] }, },
{ isLoading: false, data: provider }, get data() {
] if (options().queryKey?.[1] === "mcp") return options().enabled ? { demo: { status: "disabled" } } : undefined
if (options().queryKey?.[1] === "lsp") return []
if (options().queryKey?.[1] === "providers") return provider
return undefined
},
}
}, },
})) }))
@@ -159,7 +164,7 @@ describe("createChildStoreManager", () => {
test("enables MCP only when requested for the directory", () => { test("enables MCP only when requested for the directory", () => {
let manager: ReturnType<typeof createChildStoreManager> | undefined let manager: ReturnType<typeof createChildStoreManager> | undefined
const offset = queryGroups.length const offset = querySingles.length
const mcpLoads: string[] = [] const mcpLoads: string[] = []
const dispose = createOwner((owner) => { const dispose = createOwner((owner) => {
@@ -180,18 +185,20 @@ describe("createChildStoreManager", () => {
try { try {
if (!manager) throw new Error("manager required") if (!manager) throw new Error("manager required")
const [, setStore] = manager.child("/project", { bootstrap: false }) const [store, setStore] = manager.child("/project", { bootstrap: false })
const queries = queryGroups[offset] expect(querySingles.length - offset).toBe(4)
if (!queries) throw new Error("queries required") const query = querySingles[offset + 1]
expect(queries().queries[1]?.enabled).toBe(false) if (!query) throw new Error("query required")
expect(query().enabled).toBe(false)
setStore("status", "complete") setStore("status", "complete")
manager.child("/project", { bootstrap: false, mcp: true }) manager.child("/project", { bootstrap: false, mcp: true })
expect(queries().queries[1]?.enabled).toBe(true) expect(query().enabled).toBe(true)
expect(store.mcp).toEqual({ demo: { status: "disabled" } })
expect(mcpLoads).toEqual(["/project"]) expect(mcpLoads).toEqual(["/project"])
manager.disableMcp("/project") manager.disableMcp("/project")
expect(queries().queries[1]?.enabled).toBe(false) expect(query().enabled).toBe(false)
expect(manager.mcp("/project")).toBe(false) expect(manager.mcp("/project")).toBe(false)
} finally { } finally {
dispose() dispose()

View File

@@ -14,7 +14,7 @@ import {
type VcsCache, type VcsCache,
} from "./types" } from "./types"
import { canDisposeDirectory, pickDirectoriesToEvict } from "./eviction" import { canDisposeDirectory, pickDirectoriesToEvict } from "./eviction"
import { useQueries } from "@tanstack/solid-query" import { useQuery } from "@tanstack/solid-query"
import { QueryOptionsApi } from "../server-sync" import { QueryOptionsApi } from "../server-sync"
import { directoryKey, type DirectoryKey } from "./utils" import { directoryKey, type DirectoryKey } from "./utils"
import { NormalizedProviderListResponse } from "@opencode-ai/ui/context" import { NormalizedProviderListResponse } from "@opencode-ai/ui/context"
@@ -180,14 +180,10 @@ export function createChildStoreManager(input: {
const initialIcon = icon[0].value const initialIcon = icon[0].value
const [mcpEnabled, setMcpEnabled] = createSignal(false) const [mcpEnabled, setMcpEnabled] = createSignal(false)
const [pathQuery, mcpQuery, lspQuery, providerQuery] = useQueries(() => ({ const pathQuery = useQuery(() => input.queryOptions.path(key))
queries: [ const mcpQuery = useQuery(() => ({ ...input.queryOptions.mcp(key), enabled: mcpEnabled() }))
input.queryOptions.path(key), const lspQuery = useQuery(() => input.queryOptions.lsp(key))
{ ...input.queryOptions.mcp(key), enabled: mcpEnabled() }, const providerQuery = useQuery(() => input.queryOptions.providers(key))
input.queryOptions.lsp(key),
input.queryOptions.providers(key),
],
}))
const child = createStore<State>({ const child = createStore<State>({
project: "", project: "",