Kaynağa Gözat

fix(tui): make auth URLs clickable regardless of line wrapping (#6317)

Co-authored-by: brettheap <[email protected]>
Co-authored-by: Claude Opus 4.5 <[email protected]>
Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Brett Heap 1 ay önce
ebeveyn
işleme
82b8d8fa5d

+ 3 - 2
packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx

@@ -5,6 +5,7 @@ import { DialogSelect } from "@tui/ui/dialog-select"
 import { useDialog } from "@tui/ui/dialog"
 import { useSDK } from "../context/sdk"
 import { DialogPrompt } from "../ui/dialog-prompt"
+import { Link } from "../ui/link"
 import { useTheme } from "../context/theme"
 import { TextAttributes } from "@opentui/core"
 import type { ProviderAuthAuthorization } from "@opencode-ai/sdk/v2"
@@ -128,7 +129,7 @@ function AutoMethod(props: AutoMethodProps) {
         <text fg={theme.textMuted}>esc</text>
       </box>
       <box gap={1}>
-        <text fg={theme.primary}>{props.authorization.url}</text>
+        <Link href={props.authorization.url} fg={theme.primary} />
         <text fg={theme.textMuted}>{props.authorization.instructions}</text>
       </box>
       <text fg={theme.textMuted}>Waiting for authorization...</text>
@@ -170,7 +171,7 @@ function CodeMethod(props: CodeMethodProps) {
       description={() => (
         <box gap={1}>
           <text fg={theme.textMuted}>{props.authorization.instructions}</text>
-          <text fg={theme.primary}>{props.authorization.url}</text>
+          <Link href={props.authorization.url} fg={theme.primary} />
           <Show when={error()}>
             <text fg={theme.error}>Invalid code</text>
           </Show>

+ 29 - 0
packages/opencode/src/cli/cmd/tui/ui/link.tsx

@@ -0,0 +1,29 @@
+import type { JSX } from "solid-js"
+import type { RGBA } from "@opentui/core"
+import open from "open"
+
+export interface LinkProps {
+  href: string
+  children?: JSX.Element | string
+  fg?: RGBA
+}
+
+/**
+ * Link component that renders clickable hyperlinks.
+ * Clicking anywhere on the link text opens the URL in the default browser.
+ */
+export function Link(props: LinkProps) {
+  const displayText = props.children ?? props.href
+
+  return (
+    <text
+      fg={props.fg}
+      underline={true}
+      onMouseUp={() => {
+        open(props.href).catch(() => {})
+      }}
+    >
+      {displayText}
+    </text>
+  )
+}