/ utils / hyperlink.ts
hyperlink.ts
 1  import chalk from 'chalk'
 2  import { supportsHyperlinks } from '../ink/supports-hyperlinks.js'
 3  
 4  // OSC 8 hyperlink escape sequences
 5  // Format: \e]8;;URL\e\\TEXT\e]8;;\e\\
 6  // Using \x07 (BEL) as terminator which is more widely supported
 7  export const OSC8_START = '\x1b]8;;'
 8  export const OSC8_END = '\x07'
 9  
10  type HyperlinkOptions = {
11    supportsHyperlinks?: boolean
12  }
13  
14  /**
15   * Create a clickable hyperlink using OSC 8 escape sequences.
16   * Falls back to plain text if the terminal doesn't support hyperlinks.
17   *
18   * @param url - The URL to link to
19   * @param content - Optional content to display as the link text (only when hyperlinks are supported).
20   *                  If provided and hyperlinks are supported, this text is shown as a clickable link.
21   *                  If hyperlinks are not supported, content is ignored and only the URL is shown.
22   * @param options - Optional overrides for testing (supportsHyperlinks)
23   */
24  export function createHyperlink(
25    url: string,
26    content?: string,
27    options?: HyperlinkOptions,
28  ): string {
29    const hasSupport = options?.supportsHyperlinks ?? supportsHyperlinks()
30    if (!hasSupport) {
31      return url
32    }
33  
34    // Apply basic ANSI blue color - wrap-ansi preserves this across line breaks
35    // RGB colors (like theme colors) are NOT preserved by wrap-ansi with OSC 8
36    const displayText = content ?? url
37    const coloredText = chalk.blue(displayText)
38    return `${OSC8_START}${url}${OSC8_END}${coloredText}${OSC8_START}${OSC8_END}`
39  }