diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx index 288504a72fc..b76151ad692 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx @@ -12,6 +12,7 @@ import { type Component, } from "solid-js" import { Dynamic } from "solid-js/web" +import open from "open" import path from "path" import { useRoute, useRouteData } from "@tui/context/route" import { useSync } from "@tui/context/sync" @@ -70,6 +71,14 @@ import { DialogSubagent } from "./dialog-subagent.tsx" addDefaultParsers(parsers.parsers) +/** + * Handle alt+click or ctrl+click on links in markdown content + * Opens URLs in the default browser + */ +function handleLinkClick(url: string) { + open(url).catch(() => {}) +} + class CustomSpeedScroll implements ScrollAcceleration { constructor(private speed: number) {} @@ -1240,6 +1249,7 @@ function ReasoningPart(props: { last: boolean; part: ReasoningPart; message: Ass content={"_Thinking:_ " + content()} conceal={ctx.conceal()} fg={theme.textMuted} + onLinkClick={handleLinkClick} /> @@ -1260,6 +1270,7 @@ function TextPart(props: { last: boolean; part: TextPart; message: AssistantMess content={props.part.text.trim()} conceal={ctx.conceal()} fg={theme.text} + onLinkClick={handleLinkClick} /> @@ -1493,6 +1504,7 @@ ToolRegistry.register({ filetype={filetype(props.input.filePath!)} syntaxStyle={syntax()} content={code()} + onLinkClick={handleLinkClick} />