diff --git a/packages/tui/src/component/dialog-integration.tsx b/packages/tui/src/component/dialog-integration.tsx
index 6511a14036b..12d0b401b52 100644
--- a/packages/tui/src/component/dialog-integration.tsx
+++ b/packages/tui/src/component/dialog-integration.tsx
@@ -6,6 +6,7 @@ import type {
IntegrationOauthConnectOutput,
IntegrationOAuthMethod,
} from "@opencode-ai/client"
+import open from "open"
import { createMemo, createSignal, onCleanup, onMount, Show } from "solid-js"
import { useClipboard } from "../context/clipboard"
import { useData } from "../context/data"
@@ -445,6 +446,19 @@ function OAuthAuto(props: {
Keymap.createLayer(() => ({
mode: "modal",
commands: [
+ {
+ bind: "o",
+ title: "Open authorization URL",
+ group: "Dialog",
+ run: () => {
+ open(props.attempt.url).catch(() =>
+ toast.show({
+ message: "Could not open the browser. Copy the URL and continue manually.",
+ variant: "error",
+ }),
+ )
+ },
+ },
{
bind: "c",
title: "Copy authorization details",
@@ -502,6 +516,7 @@ function OAuthAuto(props: {
instructions={props.attempt.instructions}
message="Waiting for authorization..."
copy
+ open
/>
)
}
@@ -559,7 +574,14 @@ function OAuthCode(props: {
)
}
-function OAuthView(props: { title: string; url?: string; instructions?: string; message: string; copy?: boolean }) {
+function OAuthView(props: {
+ title: string
+ url?: string
+ instructions?: string
+ message: string
+ copy?: boolean
+ open?: boolean
+}) {
const dialog = useDialog()
const theme = useTheme("elevated")
return (
@@ -583,11 +605,18 @@ function OAuthView(props: { title: string; url?: string; instructions?: string;
)}
{props.message}
-
-
- c copy
-
-
+
+
+
+ o open
+
+
+
+
+ c copy
+
+
+
)
}
diff --git a/packages/tui/src/ui/link.tsx b/packages/tui/src/ui/link.tsx
index cfd78bc3335..98c57d6f1d7 100644
--- a/packages/tui/src/ui/link.tsx
+++ b/packages/tui/src/ui/link.tsx
@@ -28,7 +28,7 @@ export function Link(props: LinkProps) {
open(props.href).catch(() => {})
}}
>
- {displayText}
+ {displayText}
)
}