fix(tui): refresh MCP status for active location (#36882)
This commit is contained in:
parent
634386fe0f
commit
a6b5cf94b0
2 changed files with 86 additions and 3 deletions
|
|
@ -841,7 +841,6 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
|
|||
// Authenticating an MCP integration reconnects its server, which emits mcp.status.changed,
|
||||
// so the mcp list refreshes here rather than off integration.updated.
|
||||
case "mcp.status.changed":
|
||||
if (bootstrapping) break
|
||||
void result.location.mcp.server.refresh(event.location)
|
||||
break
|
||||
case "mcp.resources.changed":
|
||||
|
|
@ -1044,7 +1043,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
|
|||
return store.location[locationKey(location ?? defaultLocation())]?.mcp?.server
|
||||
},
|
||||
async refresh(ref?: LocationRef) {
|
||||
const result = await client.api.mcp.list({ location: locationQuery(ref) })
|
||||
const result = await client.api.mcp.list({ location: locationQuery(ref ?? defaultLocation()) })
|
||||
const key = locationKey(result.location)
|
||||
setStore("location", key, {
|
||||
...store.location[key],
|
||||
|
|
@ -1057,7 +1056,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
|
|||
return store.location[locationKey(location ?? defaultLocation())]?.mcp?.resource
|
||||
},
|
||||
async refresh(ref?: LocationRef) {
|
||||
const result = await client.api.mcp.resource.catalog({ location: locationQuery(ref) })
|
||||
const result = await client.api.mcp.resource.catalog({ location: locationQuery(ref ?? defaultLocation()) })
|
||||
const key = locationKey(result.location)
|
||||
setStore("location", key, {
|
||||
...store.location[key],
|
||||
|
|
|
|||
|
|
@ -42,6 +42,90 @@ function durable(sessionID: string, seq = 0, version = 1) {
|
|||
return { aggregateID: sessionID, seq, version }
|
||||
}
|
||||
|
||||
test("bootstraps MCP data for the TUI location", async () => {
|
||||
const events = createEventStream()
|
||||
const requests: URL[] = []
|
||||
const calls = createFetch((url) => {
|
||||
if (url.pathname === "/api/mcp" || url.pathname === "/api/mcp/resource") requests.push(url)
|
||||
return undefined
|
||||
}, events)
|
||||
|
||||
const app = await testRender(() => (
|
||||
<TestTuiContexts>
|
||||
<ClientProvider api={createApi(calls.fetch)}>
|
||||
<ProjectProvider>
|
||||
<DataProvider>
|
||||
<box />
|
||||
</DataProvider>
|
||||
</ProjectProvider>
|
||||
</ClientProvider>
|
||||
</TestTuiContexts>
|
||||
))
|
||||
|
||||
try {
|
||||
await wait(() => requests.length === 2)
|
||||
expect(requests.map((url) => url.searchParams.get("location[directory]"))).toEqual([
|
||||
process.cwd(),
|
||||
process.cwd(),
|
||||
])
|
||||
} finally {
|
||||
app.renderer.destroy()
|
||||
}
|
||||
})
|
||||
|
||||
test("refreshes MCP status when a connection settles during bootstrap", async () => {
|
||||
const events = createEventStream()
|
||||
let mcpRequests = 0
|
||||
let resolveModels!: (response: Response) => void
|
||||
const calls = createFetch((url) => {
|
||||
if (url.pathname === "/api/mcp") {
|
||||
mcpRequests++
|
||||
return json({
|
||||
location: { directory, project: { id: "proj_test", directory } },
|
||||
data: [{ name: "context7", status: { status: mcpRequests === 1 ? "pending" : "connected" } }],
|
||||
})
|
||||
}
|
||||
if (url.pathname === "/api/model")
|
||||
return new Promise<Response>((resolve) => {
|
||||
resolveModels = resolve
|
||||
})
|
||||
return undefined
|
||||
}, events)
|
||||
let data!: ReturnType<typeof useData>
|
||||
|
||||
function Probe() {
|
||||
data = useData()
|
||||
return <box />
|
||||
}
|
||||
|
||||
const app = await testRender(() => (
|
||||
<TestTuiContexts>
|
||||
<ClientProvider api={createApi(calls.fetch)}>
|
||||
<ProjectProvider>
|
||||
<DataProvider>
|
||||
<Probe />
|
||||
</DataProvider>
|
||||
</ProjectProvider>
|
||||
</ClientProvider>
|
||||
</TestTuiContexts>
|
||||
))
|
||||
|
||||
try {
|
||||
await wait(() => data.location.mcp.server.list()?.[0]?.status.status === "pending")
|
||||
emitEvent(events, {
|
||||
id: "evt_mcp_connected",
|
||||
created: 1,
|
||||
type: "mcp.status.changed",
|
||||
data: { server: "context7" },
|
||||
})
|
||||
await wait(() => data.location.mcp.server.list()?.[0]?.status.status === "connected")
|
||||
expect(mcpRequests).toBe(2)
|
||||
resolveModels(json({ location: { directory, project: { id: "proj_test", directory } }, data: [] }))
|
||||
} finally {
|
||||
app.renderer.destroy()
|
||||
}
|
||||
})
|
||||
|
||||
test("refreshes resources into reactive getters", async () => {
|
||||
const events = createEventStream()
|
||||
const location = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue