summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAkshar Patel <[email protected]>2026-01-14 02:35:59 -0500
committerGitHub <[email protected]>2026-01-14 01:35:59 -0600
commita57c8669b6f3a5247f6f6f57279d7146d095de67 (patch)
tree5d3a48e7bb9be89c0ed2a9a17ad28b382cb89738
parentf9fcdead552d8b8550c55fda3806aeafed107849 (diff)
downloadopencode-a57c8669b6f3a5247f6f6f57279d7146d095de67.tar.gz
opencode-a57c8669b6f3a5247f6f6f57279d7146d095de67.zip
feat: show connected providers in /connect dialog (#8351)
-rw-r--r--packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx115
1 files changed, 60 insertions, 55 deletions
diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx
index cb33c6301..74195c8f9 100644
--- a/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx
+++ b/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx
@@ -26,67 +26,72 @@ export function createDialogProviderOptions() {
const sync = useSync()
const dialog = useDialog()
const sdk = useSDK()
+ const connected = createMemo(() => new Set(sync.data.provider_next.connected))
const options = createMemo(() => {
return pipe(
sync.data.provider_next.all,
sortBy((x) => PROVIDER_PRIORITY[x.id] ?? 99),
- map((provider) => ({
- title: provider.name,
- value: provider.id,
- description: {
- opencode: "(Recommended)",
- anthropic: "(Claude Max or API key)",
- openai: "(ChatGPT Plus/Pro or API key)",
- }[provider.id],
- category: provider.id in PROVIDER_PRIORITY ? "Popular" : "Other",
- async onSelect() {
- const methods = sync.data.provider_auth[provider.id] ?? [
- {
- type: "api",
- label: "API key",
- },
- ]
- let index: number | null = 0
- if (methods.length > 1) {
- index = await new Promise<number | null>((resolve) => {
- dialog.replace(
- () => (
- <DialogSelect
- title="Select auth method"
- options={methods.map((x, index) => ({
- title: x.label,
- value: index,
- }))}
- onSelect={(option) => resolve(option.value)}
- />
- ),
- () => resolve(null),
- )
- })
- }
- if (index == null) return
- const method = methods[index]
- if (method.type === "oauth") {
- const result = await sdk.client.provider.oauth.authorize({
- providerID: provider.id,
- method: index,
- })
- if (result.data?.method === "code") {
- dialog.replace(() => (
- <CodeMethod providerID={provider.id} title={method.label} index={index} authorization={result.data!} />
- ))
+ map((provider) => {
+ const isConnected = connected().has(provider.id)
+ return {
+ title: provider.name,
+ value: provider.id,
+ description: {
+ opencode: "(Recommended)",
+ anthropic: "(Claude Max or API key)",
+ openai: "(ChatGPT Plus/Pro or API key)",
+ }[provider.id],
+ category: provider.id in PROVIDER_PRIORITY ? "Popular" : "Other",
+ footer: isConnected ? "Connected" : undefined,
+ async onSelect() {
+ const methods = sync.data.provider_auth[provider.id] ?? [
+ {
+ type: "api",
+ label: "API key",
+ },
+ ]
+ let index: number | null = 0
+ if (methods.length > 1) {
+ index = await new Promise<number | null>((resolve) => {
+ dialog.replace(
+ () => (
+ <DialogSelect
+ title="Select auth method"
+ options={methods.map((x, index) => ({
+ title: x.label,
+ value: index,
+ }))}
+ onSelect={(option) => resolve(option.value)}
+ />
+ ),
+ () => resolve(null),
+ )
+ })
}
- if (result.data?.method === "auto") {
- dialog.replace(() => (
- <AutoMethod providerID={provider.id} title={method.label} index={index} authorization={result.data!} />
- ))
+ if (index == null) return
+ const method = methods[index]
+ if (method.type === "oauth") {
+ const result = await sdk.client.provider.oauth.authorize({
+ providerID: provider.id,
+ method: index,
+ })
+ if (result.data?.method === "code") {
+ dialog.replace(() => (
+ <CodeMethod providerID={provider.id} title={method.label} index={index} authorization={result.data!} />
+ ))
+ }
+ if (result.data?.method === "auto") {
+ dialog.replace(() => (
+ <AutoMethod providerID={provider.id} title={method.label} index={index} authorization={result.data!} />
+ ))
+ }
}
- }
- if (method.type === "api") {
- return dialog.replace(() => <ApiMethod providerID={provider.id} title={method.label} />)
- }
- },
- })),
+ if (method.type === "api") {
+ return dialog.replace(() => <ApiMethod providerID={provider.id} title={method.label} />)
+ }
+ },
+ }
+ }),
)
})
return options