Skip to content

Commit 3c617de

Browse files
committed
wrap url under OSC 8
1 parent 9fe244b commit 3c617de

3 files changed

Lines changed: 22 additions & 1 deletion

File tree

cmd/lk/agent_run.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,14 @@ func runAgentDev(ctx context.Context, cmd *cli.Command) error {
295295
// Delay briefly so the link prints after the agent's own startup
296296
// logs rather than getting buried in them.
297297
time.AfterFunc(time.Second, func() {
298+
// Accent-colored, and a clickable OSC 8 hyperlink on terminals
299+
// that support it (gated so the escape never leaks into pipes).
300+
label := util.Accented(link)
301+
if out.Interactive() {
302+
label = util.Hyperlink(link, label)
303+
}
298304
out.Status("")
299-
out.Statusf("Agent console: %s", link)
305+
out.Statusf("Agent console: %s", label)
300306
})
301307
})
302308
}

pkg/util/printer.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ func NewPrinter(out, err io.Writer, quiet bool) *Printer {
5555
return &Printer{Out: out, Err: err, Quiet: quiet, interactive: isTerminal(err)}
5656
}
5757

58+
// Interactive reports whether status output is going to a real terminal, so
59+
// callers can gate terminal-only escapes (e.g. OSC 8 hyperlinks) and avoid
60+
// leaking them into piped or redirected output.
61+
func (p *Printer) Interactive() bool {
62+
return p != nil && p.interactive
63+
}
64+
5865
// isTerminal reports whether w is a terminal-backed *os.File. Non-file writers
5966
// (bytes.Buffer in tests, pipes) are never terminals.
6067
func isTerminal(w io.Writer) bool {

pkg/util/theme.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,14 @@ func Dimmed(text string) string {
167167
return Theme.Focused.Description.Render(text)
168168
}
169169

170+
// Hyperlink wraps label in an OSC 8 terminal hyperlink pointing at url. Terminals
171+
// that support OSC 8 render label as a clickable link; others ignore the escape
172+
// and show label unchanged. Gate calls on an interactive terminal (see
173+
// Printer.Interactive) so the escape never leaks into piped/redirected output.
174+
func Hyperlink(url, label string) string {
175+
return "\x1b]8;;" + url + "\x1b\\" + label + "\x1b]8;;\x1b\\"
176+
}
177+
170178
// Confirm is a yes/no select styled by the active theme.
171179
func Confirm() *huh.Select[bool] {
172180
return huh.NewSelect[bool]().

0 commit comments

Comments
 (0)