fix(client): singularize generated api groups (#34534)

This commit is contained in:
Kit Langton 2026-06-29 21:07:01 -04:00 committed by GitHub
commit 6846542115
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 1913 additions and 557 deletions

View file

@ -1,5 +1,5 @@
import { TextAttributes } from "@opentui/core"
import type { IntegrationsConnectOauthOutput } from "@opencode-ai/client"
import type { IntegrationConnectOauthOutput } from "@opencode-ai/client"
import type { ConnectionInfo, IntegrationInfo, IntegrationOAuthMethod } from "@opencode-ai/sdk/v2"
import { createMemo, createSignal, onCleanup, onMount, Show } from "solid-js"
import { useClipboard } from "../context/clipboard"
@ -23,7 +23,7 @@ const INTEGRATION_PRIORITY: Record<string, number> = {
}
type ConnectMethod = Exclude<IntegrationInfo["methods"][number], { type: "env" }>
type IntegrationAttempt = IntegrationsConnectOauthOutput["data"]
type IntegrationAttempt = IntegrationConnectOauthOutput["data"]
export function integrationOptions(list: IntegrationInfo[]) {
return list.toSorted(
@ -111,7 +111,7 @@ function manageConnections(
title: `Disconnect ${connection.label}`,
value: connection.id,
onSelect: () => {
void sdk.api.credentials
void sdk.api.credential
.remove({ credentialID: connection.id, location: location(data) })
.then(() => disconnected(integration.name, data, dialog, toast))
.catch(toast.error)
@ -159,7 +159,7 @@ function KeyMethod(props: { integration: IntegrationInfo; method: Extract<Connec
placeholder="API key"
onConfirm={(key) => {
if (!key) return
void sdk.api.integrations
void sdk.api.integration
.connectKey({
integrationID: props.integration.id,
location: location(data),
@ -194,7 +194,7 @@ function OAuthStarting(props: {
const toast = useToast()
onMount(() => {
void sdk.api.integrations
void sdk.api.integration
.connectOauth({
integrationID: props.integration.id,
location: location(data),
@ -248,7 +248,7 @@ function OAuthAuto(props: { integration: IntegrationInfo; title: string; attempt
}))
const poll = () => {
void sdk.api.integrations
void sdk.api.integration
.attemptStatus({ attemptID: props.attempt.attemptID, location: location(data) })
.then((result) => {
const status = result.data
@ -275,7 +275,7 @@ function OAuthAuto(props: { integration: IntegrationInfo; title: string; attempt
onCleanup(() => {
if (timer) clearTimeout(timer)
if (settled) return
void sdk.api.integrations.attemptCancel({ attemptID: props.attempt.attemptID, location: location(data) })
void sdk.api.integration.attemptCancel({ attemptID: props.attempt.attemptID, location: location(data) })
})
return (
@ -300,7 +300,7 @@ function OAuthCode(props: { integration: IntegrationInfo; title: string; attempt
onCleanup(() => {
if (settled) return
void sdk.api.integrations.attemptCancel({ attemptID: props.attempt.attemptID, location: location(data) })
void sdk.api.integration.attemptCancel({ attemptID: props.attempt.attemptID, location: location(data) })
})
return (
@ -309,7 +309,7 @@ function OAuthCode(props: { integration: IntegrationInfo; title: string; attempt
placeholder="Authorization code"
onConfirm={(code) => {
if (!code) return
void sdk.api.integrations
void sdk.api.integration
.attemptComplete({ attemptID: props.attempt.attemptID, location: location(data), code })
.then(() => {
settled = true

View file

@ -77,7 +77,7 @@ export function DialogMoveSession(props: DialogMoveSessionProps) {
async (projectID, info): Promise<ReadonlyArray<ProjectDirectory> | undefined> => {
try {
const location = { directory: projectContext.instance.directory() || paths.cwd }
await sdk.api.projectCopies.refresh({
await sdk.api.projectCopy.refresh({
projectID,
location,
})
@ -227,7 +227,7 @@ export function DialogMoveSession(props: DialogMoveSessionProps) {
setToDelete(undefined)
setRemoving(selected.directory)
setWorking(true)
const error = await sdk.api.projectCopies
const error = await sdk.api.projectCopy
.remove({
projectID: props.projectID,
location: { directory: projectContext.instance.directory() || paths.cwd },
@ -252,7 +252,7 @@ export function DialogMoveSession(props: DialogMoveSessionProps) {
return
}
reopen(selected.directory)
const forcedError = await sdk.api.projectCopies
const forcedError = await sdk.api.projectCopy
.remove({
projectID: props.projectID,
location: { directory: projectContext.instance.directory() || paths.cwd },

View file

@ -32,7 +32,7 @@ export function DialogSessionList() {
const [searchResults] = createResource(search, async (query) => {
if (!query) return
const location = data.location.default()
const response = await sdk.api.sessions.list({
const response = await sdk.api.session.list({
search: query,
limit: 50,
order: "desc",

View file

@ -17,7 +17,7 @@ export function DialogSessionRename(props: { sessionID: string; currentTitle?: s
onConfirm={(value) => {
const title = value.trim()
if (!title) return
void sdk.api.sessions
void sdk.api.session
.rename({ sessionID: props.sessionID, title })
.then(() => dialog.clear())
.catch((error) =>

View file

@ -17,7 +17,7 @@ export function DialogTag(props: { onSelect?: (value: string) => void }) {
const [files] = createResource(
() => [store.filter],
async () => {
const result = await sdk.api.files
const result = await sdk.api.file
.find({
query: store.filter,
type: "file",

View file

@ -320,7 +320,7 @@ export function Autocomplete(props: {
if (referenceMatch()) return []
const { lineRange, baseQuery } = extractLineRange(input.query ?? "")
const result = await sdk.api.files
const result = await sdk.api.file
.find({
query: baseQuery,
limit: 20,

View file

@ -425,7 +425,7 @@ export function Prompt(props: PromptProps) {
}, 5000)
if (store.interrupt >= 2) {
void sdk.api.sessions.interrupt({
void sdk.api.session.interrupt({
sessionID: props.sessionID,
})
setStore("interrupt", 0)
@ -1012,7 +1012,7 @@ export function Prompt(props: PromptProps) {
finishMoveProgress = Boolean(move.progress())
const location = data.location.default()
const created = await sdk.api.sessions
const created = await sdk.api.session
.create({
location: directory
? { directory, workspaceID }
@ -1114,20 +1114,20 @@ export function Prompt(props: PromptProps) {
session = data.session.get(sessionID)
}
if (session?.agent !== agent.id) {
await sdk.api.sessions.switchAgent({ sessionID, agent: agent.id })
await sdk.api.session.switchAgent({ sessionID, agent: agent.id })
}
if (
session?.model?.providerID !== selectedModel.providerID ||
session.model.id !== selectedModel.modelID ||
session.model.variant !== variant
) {
await sdk.api.sessions.switchModel({
await sdk.api.session.switchModel({
sessionID,
model: { providerID: selectedModel.providerID, id: selectedModel.modelID, variant },
})
}
if (session?.revert) {
const error = await sdk.api.sessions.commit({ sessionID }).then(
const error = await sdk.api.session.commit({ sessionID }).then(
() => undefined,
(error) => error,
)
@ -1136,7 +1136,7 @@ export function Prompt(props: PromptProps) {
return false
}
}
const error = await sdk.api.sessions
const error = await sdk.api.session
.prompt({
sessionID,
prompt: {

View file

@ -37,7 +37,7 @@ export function usePromptMove(input: { projectID: () => string | undefined; sess
{ projectID, context },
{ throwOnError: true },
)
const result = await sdk.api.projectCopies.create({
const result = await sdk.api.projectCopy.create({
projectID,
location: { directory: project.instance.directory() || paths.cwd },
strategy: "git_worktree",

View file

@ -554,7 +554,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
return store.session.status[sessionID] ?? "idle"
},
async refresh(sessionID: string) {
setStore("session", "info", sessionID, mutable(await sdk.api.sessions.get({ sessionID })))
setStore("session", "info", sessionID, mutable(await sdk.api.session.get({ sessionID })))
},
message: {
ids(sessionID: string) {
@ -572,7 +572,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
setStore("session", "message", sessionID, [])
messageIndex.set(sessionID, new Map())
const loaded = mutable(
(await sdk.api.messages.list({ sessionID, limit: 200, order: "desc" })).data,
(await sdk.api.message.list({ sessionID, limit: 200, order: "desc" })).data,
).toReversed()
const live = store.session.message[sessionID] ?? []
const liveByID = new Map(live.map((message) => [message.id, message]))
@ -588,7 +588,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
return store.session.permission[sessionID]
},
async refresh(sessionID: string) {
setStore("session", "permission", sessionID, mutable(await sdk.api.permissions.list({ sessionID })))
setStore("session", "permission", sessionID, mutable(await sdk.api.permission.list({ sessionID })))
},
},
question: {
@ -596,7 +596,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
return store.session.question[sessionID]
},
async refresh(sessionID: string) {
setStore("session", "question", sessionID, mutable(await sdk.api.questions.list({ sessionID })))
setStore("session", "question", sessionID, mutable(await sdk.api.question.list({ sessionID })))
},
},
},
@ -606,7 +606,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
return store.project.permission[projectID]
},
async refresh(projectID: string) {
setStore("project", "permission", projectID, mutable(await sdk.api.permissions.listSaved({ projectID })))
setStore("project", "permission", projectID, mutable(await sdk.api.permission.listSaved({ projectID })))
},
},
},
@ -618,16 +618,16 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
return store.shell[id]
},
async refresh(ref?: LocationRef) {
const result = await sdk.client.v2.shell.list({ location: locationQuery(ref) }, { throwOnError: true })
const result = await sdk.api.shell.list({ location: locationQuery(ref) })
setStore(
"shell",
produce((draft) => {
for (const info of result.data.data) draft[info.id] = info
for (const info of mutable(result.data)) draft[info.id] = info
}),
)
},
async remove(id: string) {
await sdk.client.v2.shell.remove({ id }, { throwOnError: true })
await sdk.api.shell.remove({ id })
setStore("shell", id, undefined!)
},
},
@ -646,7 +646,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
return store.location[locationKey(location ?? defaultLocation())]?.agent
},
async refresh(ref?: LocationRef) {
const result = await sdk.api.agents.list({ location: locationQuery(ref ?? defaultLocation()) })
const result = await sdk.api.agent.list({ location: locationQuery(ref ?? defaultLocation()) })
const key = locationKey(result.location)
setStore("location", key, { ...store.location[key], agent: mutable(result.data) })
},
@ -656,7 +656,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
return store.location[locationKey(location ?? defaultLocation())]?.command
},
async refresh(ref?: LocationRef) {
const result = await sdk.api.commands.list({ location: locationQuery(ref ?? defaultLocation()) })
const result = await sdk.api.command.list({ location: locationQuery(ref ?? defaultLocation()) })
const key = locationKey(result.location)
setStore("location", key, { ...store.location[key], command: mutable(result.data) })
},
@ -666,7 +666,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
return store.location[locationKey(location ?? defaultLocation())]?.integration
},
async refresh(ref?: LocationRef) {
const result = await sdk.api.integrations.list({ location: locationQuery(ref ?? defaultLocation()) })
const result = await sdk.api.integration.list({ location: locationQuery(ref ?? defaultLocation()) })
const key = locationKey(result.location)
setStore("location", key, { ...store.location[key], integration: mutable(result.data) })
},
@ -676,7 +676,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
return store.location[locationKey(location ?? defaultLocation())]?.model
},
async refresh(ref?: LocationRef) {
const result = await sdk.api.models.list({ location: locationQuery(ref ?? defaultLocation()) })
const result = await sdk.api.model.list({ location: locationQuery(ref ?? defaultLocation()) })
const key = locationKey(result.location)
setStore("location", key, { ...store.location[key], model: mutable(result.data) })
},
@ -686,7 +686,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
return store.location[locationKey(location ?? defaultLocation())]?.provider
},
async refresh(ref?: LocationRef) {
const result = await sdk.api.providers.list({ location: locationQuery(ref ?? defaultLocation()) })
const result = await sdk.api.provider.list({ location: locationQuery(ref ?? defaultLocation()) })
const key = locationKey(result.location)
setStore("location", key, { ...store.location[key], provider: mutable(result.data) })
},
@ -696,7 +696,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
return store.location[locationKey(location ?? defaultLocation())]?.reference
},
async refresh(ref?: LocationRef) {
const result = await sdk.api.references.list({ location: locationQuery(ref ?? defaultLocation()) })
const result = await sdk.api.reference.list({ location: locationQuery(ref ?? defaultLocation()) })
const key = locationKey(result.location)
setStore("location", key, { ...store.location[key], reference: mutable(result.data) })
},
@ -706,7 +706,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
return store.location[locationKey(location ?? defaultLocation())]?.skill
},
async refresh(ref?: LocationRef) {
const result = await sdk.api.skills.list({ location: locationQuery(ref ?? defaultLocation()) })
const result = await sdk.api.skill.list({ location: locationQuery(ref ?? defaultLocation()) })
const key = locationKey(result.location)
setStore("location", key, { ...store.location[key], skill: mutable(result.data) })
},
@ -716,7 +716,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
async function bootstrap() {
const settled = await Promise.allSettled([
sdk.api.sessions
sdk.api.session
.list({
limit: 50,
order: "desc",
@ -732,7 +732,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
}),
),
),
sdk.api.sessions
sdk.api.session
.active()
.then((active) =>
setStore(

View file

@ -22,7 +22,7 @@ export function DialogMessage(props: { messageID: string; sessionID: string; set
value: "session.revert",
description: "undo messages and file changes",
onSelect: async (dialog) => {
await sdk.api.sessions
await sdk.api.session
.stage({ sessionID: props.sessionID, messageID: props.messageID })
.catch((error) => toast.show({ message: errorMessage(error), variant: "error", duration: 5000 }))
dialog.clear()

View file

@ -369,7 +369,7 @@ export function Session() {
aliases: ["summarize"],
},
run: () => {
void sdk.api.sessions.compact({ sessionID: route.sessionID })
void sdk.api.session.compact({ sessionID: route.sessionID })
dialog.clear()
},
},
@ -403,7 +403,7 @@ export function Session() {
dialog.clear()
return
}
const error = await sdk.api.sessions.stage({ sessionID: route.sessionID, messageID: target }).then(
const error = await sdk.api.session.stage({ sessionID: route.sessionID, messageID: target }).then(
() => undefined,
(error) => error,
)
@ -420,7 +420,7 @@ export function Session() {
slash: { name: "redo" },
run: () => {
void (async () => {
const error = await sdk.api.sessions.clear({ sessionID: route.sessionID }).then(
const error = await sdk.api.session.clear({ sessionID: route.sessionID }).then(
() => undefined,
(error) => error,
)
@ -843,7 +843,12 @@ export function Session() {
// snap to bottom when session changes
createEffect(on(() => route.sessionID, toBottom))
createEffect(on(() => route.sessionID, () => setComposer("open", false)))
createEffect(
on(
() => route.sessionID,
() => setComposer("open", false),
),
)
return (
<LocationProvider location={location()}>
@ -913,9 +918,7 @@ export function Session() {
onClose={() => setComposer("open", false)}
/>
<Switch>
<Match when={composer.open || !!session()?.parentID}>
{null}
</Match>
<Match when={composer.open || !!session()?.parentID}>{null}</Match>
<Match when={permissions().length > 0}>
<PermissionPrompt request={permissions()[0]} directory={session()?.location.directory} />
</Match>
@ -1230,7 +1233,7 @@ function RevertMessage(props: {
onMouseUp={() => {
if (renderer.getSelection()?.getSelectedText()) return
void (async () => {
const error = await sdk.api.sessions.clear({ sessionID: route.sessionID }).then(
const error = await sdk.api.session.clear({ sessionID: route.sessionID }).then(
() => undefined,
(error) => error,
)

View file

@ -186,7 +186,7 @@ export function PermissionPrompt(props: { request: PermissionV2Request; director
onSelect={(option) => {
setStore("stage", "permission")
if (option === "cancel") return
void sdk.api.permissions.reply({
void sdk.api.permission.reply({
sessionID: props.request.sessionID,
reply: "always",
requestID: props.request.id,
@ -197,7 +197,7 @@ export function PermissionPrompt(props: { request: PermissionV2Request; director
<Match when={store.stage === "reject"}>
<RejectPrompt
onConfirm={(message) => {
void sdk.api.permissions.reply({
void sdk.api.permission.reply({
sessionID: props.request.sessionID,
reply: "reject",
requestID: props.request.id,
@ -443,14 +443,14 @@ export function PermissionPrompt(props: { request: PermissionV2Request; director
setStore("stage", "reject")
return
}
void sdk.api.permissions.reply({
void sdk.api.permission.reply({
sessionID: props.request.sessionID,
reply: "reject",
requestID: props.request.id,
})
return
}
void sdk.api.permissions.reply({
void sdk.api.permission.reply({
sessionID: props.request.sessionID,
reply: "once",
requestID: props.request.id,

View file

@ -47,7 +47,7 @@ export function QuestionPrompt(props: { request: QuestionV2Request; directory?:
function submit() {
const answers = questions().map((_, i) => store.answers[i] ?? [])
void sdk.api.questions.reply({
void sdk.api.question.reply({
sessionID: props.request.sessionID,
requestID: props.request.id,
answers,
@ -55,7 +55,7 @@ export function QuestionPrompt(props: { request: QuestionV2Request; directory?:
}
function reject() {
void sdk.api.questions.reject({
void sdk.api.question.reject({
sessionID: props.request.sessionID,
requestID: props.request.id,
})
@ -71,7 +71,7 @@ export function QuestionPrompt(props: { request: QuestionV2Request; directory?:
setStore("custom", inputs)
}
if (single()) {
void sdk.api.questions.reply({
void sdk.api.question.reply({
sessionID: props.request.sessionID,
requestID: props.request.id,
answers: [[answer]],