fix(app): skip legacy config reads for v2 (#40211)
This commit is contained in:
parent
1882c33827
commit
d4b85f8d83
3 changed files with 103 additions and 6 deletions
|
|
@ -8,6 +8,7 @@ import {
|
||||||
bootstrapDirectory,
|
bootstrapDirectory,
|
||||||
loadAgentsQuery,
|
loadAgentsQuery,
|
||||||
loadCommands,
|
loadCommands,
|
||||||
|
loadGlobalConfigQuery,
|
||||||
loadPathQuery,
|
loadPathQuery,
|
||||||
loadProjectsQuery,
|
loadProjectsQuery,
|
||||||
loadProvidersQuery,
|
loadProvidersQuery,
|
||||||
|
|
@ -76,6 +77,7 @@ function directoryState() {
|
||||||
|
|
||||||
describe("bootstrapDirectory", () => {
|
describe("bootstrapDirectory", () => {
|
||||||
test("uses legacy MCP endpoints while refreshing a v1 directory", async () => {
|
test("uses legacy MCP endpoints while refreshing a v1 directory", async () => {
|
||||||
|
const legacyConfigReads: string[] = []
|
||||||
const mcpReads: string[] = []
|
const mcpReads: string[] = []
|
||||||
const [store, setStore] = directoryState()
|
const [store, setStore] = directoryState()
|
||||||
|
|
||||||
|
|
@ -91,7 +93,12 @@ describe("bootstrapDirectory", () => {
|
||||||
},
|
},
|
||||||
sdk: {
|
sdk: {
|
||||||
app: { agents: async () => ({ data: [{ name: "build", mode: "primary" }] }) },
|
app: { agents: async () => ({ data: [{ name: "build", mode: "primary" }] }) },
|
||||||
config: { get: async () => ({ data: {} }) },
|
config: {
|
||||||
|
get: async () => {
|
||||||
|
legacyConfigReads.push("directory")
|
||||||
|
return { data: {} }
|
||||||
|
},
|
||||||
|
},
|
||||||
session: { status: async () => ({ data: {} }) },
|
session: { status: async () => ({ data: {} }) },
|
||||||
vcs: { get: async () => ({ data: undefined }) },
|
vcs: { get: async () => ({ data: undefined }) },
|
||||||
command: {
|
command: {
|
||||||
|
|
@ -134,8 +141,88 @@ describe("bootstrapDirectory", () => {
|
||||||
await new Promise((resolve) => setTimeout(resolve, 80))
|
await new Promise((resolve) => setTimeout(resolve, 80))
|
||||||
|
|
||||||
expect(store.status).toBe("complete")
|
expect(store.status).toBe("complete")
|
||||||
|
expect(legacyConfigReads).toEqual(["directory"])
|
||||||
expect(mcpReads.sort()).toEqual(["command", "resource", "status"])
|
expect(mcpReads.sort()).toEqual(["command", "resource", "status"])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("skips legacy config while refreshing a v2 directory", async () => {
|
||||||
|
const [store, setStore] = directoryState()
|
||||||
|
|
||||||
|
await bootstrapDirectory({
|
||||||
|
directory: "/project",
|
||||||
|
scope: ServerScope.local,
|
||||||
|
mcp: false,
|
||||||
|
global: {
|
||||||
|
config: {} satisfies Config,
|
||||||
|
path: { state: "", config: "", worktree: "/project", directory: "/project", home: "/home" },
|
||||||
|
project: [{ id: "project", worktree: "/project" } as Project],
|
||||||
|
provider,
|
||||||
|
},
|
||||||
|
sdk: {
|
||||||
|
config: {
|
||||||
|
get: async () => {
|
||||||
|
throw new Error("legacy directory config should not be called")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as unknown as OpencodeClient,
|
||||||
|
api,
|
||||||
|
store,
|
||||||
|
setStore,
|
||||||
|
vcsCache: { setStore() {} } as unknown as VcsCache,
|
||||||
|
loadSessions() {},
|
||||||
|
translate: (key) => key,
|
||||||
|
queryClient: new QueryClient(),
|
||||||
|
protocol: Promise.resolve("v2"),
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(store.status).toBe("partial")
|
||||||
|
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 80))
|
||||||
|
|
||||||
|
expect(store.status).toBe("complete")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("config queries", () => {
|
||||||
|
test("skips legacy global config for v2 servers", async () => {
|
||||||
|
const sdk = {
|
||||||
|
global: {
|
||||||
|
config: {
|
||||||
|
get: async () => {
|
||||||
|
throw new Error("legacy global config should not be called")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as unknown as OpencodeClient
|
||||||
|
|
||||||
|
const result = await new QueryClient().fetchQuery(
|
||||||
|
loadGlobalConfigQuery(ServerScope.local, sdk, Promise.resolve("v2")),
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(result).toEqual({})
|
||||||
|
})
|
||||||
|
|
||||||
|
test("loads legacy global config for v1 servers", async () => {
|
||||||
|
const calls: string[] = []
|
||||||
|
const config = { shell: "zsh" } satisfies Config
|
||||||
|
const sdk = {
|
||||||
|
global: {
|
||||||
|
config: {
|
||||||
|
get: async () => {
|
||||||
|
calls.push("global")
|
||||||
|
return { data: config }
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as unknown as OpencodeClient
|
||||||
|
|
||||||
|
const result = await new QueryClient().fetchQuery(
|
||||||
|
loadGlobalConfigQuery(ServerScope.local, sdk, Promise.resolve("v1")),
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(result).toEqual(config)
|
||||||
|
expect(calls).toEqual(["global"])
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("query keys", () => {
|
describe("query keys", () => {
|
||||||
|
|
|
||||||
|
|
@ -105,10 +105,17 @@ function showErrors(input: {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const loadGlobalConfigQuery = (scope: ServerScope, sdk: OpencodeClient) =>
|
export const loadGlobalConfigQuery = (
|
||||||
|
scope: ServerScope,
|
||||||
|
sdk: OpencodeClient,
|
||||||
|
protocol?: Promise<ServerProtocol>,
|
||||||
|
) =>
|
||||||
queryOptions({
|
queryOptions({
|
||||||
queryKey: [scope, "config"],
|
queryKey: [scope, "config"],
|
||||||
queryFn: () => retry(() => sdk.global.config.get().then((x) => x.data!)),
|
queryFn: async () => {
|
||||||
|
if ((await protocol) !== "v1") return {}
|
||||||
|
return retry(() => sdk.global.config.get().then((x) => x.data!))
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
type ProjectApi = {
|
type ProjectApi = {
|
||||||
|
|
@ -149,7 +156,7 @@ export async function bootstrapGlobal(input: {
|
||||||
queryClient: QueryClient
|
queryClient: QueryClient
|
||||||
}) {
|
}) {
|
||||||
const slow = [
|
const slow = [
|
||||||
() => input.queryClient.fetchQuery(loadGlobalConfigQuery(input.scope, input.serverSDK)),
|
() => input.queryClient.fetchQuery(loadGlobalConfigQuery(input.scope, input.serverSDK, input.protocol)),
|
||||||
() =>
|
() =>
|
||||||
input.queryClient.fetchQuery(
|
input.queryClient.fetchQuery(
|
||||||
loadProvidersQuery(input.scope, null, input.serverAPI, input.serverSDK, input.protocol),
|
loadProvidersQuery(input.scope, null, input.serverAPI, input.serverSDK, input.protocol),
|
||||||
|
|
@ -376,7 +383,10 @@ export async function bootstrapDirectory(input: {
|
||||||
.ensureQueryData(loadAgentsQuery(input.scope, input.directory, input.api.agent, input.sdk, input.protocol))
|
.ensureQueryData(loadAgentsQuery(input.scope, input.directory, input.api.agent, input.sdk, input.protocol))
|
||||||
.then((data) => input.setStore("agent", data)),
|
.then((data) => input.setStore("agent", data)),
|
||||||
() =>
|
() =>
|
||||||
retry(() => input.sdk.config.get().then((x) => input.setStore("config", reconcile(x.data!, { merge: false })))),
|
retry(async () => {
|
||||||
|
if ((await input.protocol) !== "v1") return
|
||||||
|
return input.sdk.config.get().then((x) => input.setStore("config", reconcile(x.data!, { merge: false })))
|
||||||
|
}),
|
||||||
() =>
|
() =>
|
||||||
retry(() =>
|
retry(() =>
|
||||||
(async () => {
|
(async () => {
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,7 @@ function makeQueryOptionsApi(
|
||||||
protocol: Promise<"v1" | "v2">,
|
protocol: Promise<"v1" | "v2">,
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
globalConfig: () => loadGlobalConfigQuery(scope, serverSDK()),
|
globalConfig: () => loadGlobalConfigQuery(scope, serverSDK(), protocol),
|
||||||
projects: () => loadProjectsQuery(scope, serverAPI.project),
|
projects: () => loadProjectsQuery(scope, serverAPI.project),
|
||||||
providers: (directory: PathKey | null) =>
|
providers: (directory: PathKey | null) =>
|
||||||
loadProvidersQuery(scope, directory, serverAPI, directory ? sdkFor(directory) : serverSDK(), protocol),
|
loadProvidersQuery(scope, directory, serverAPI, directory ? sdkFor(directory) : serverSDK(), protocol),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue