Skip to content

listen emits OSC-8 hyperlinks only when stdout is NOT a terminal, and --color off does not suppress them #403

Description

@leggetter

Summary

hookdeck listen emits OSC-8 terminal hyperlink escape sequences only when stdout is not a terminal — exactly backwards — and neither --color off nor NO_COLOR=1 suppresses them.

Reproduce

Redirected or piped:

💡 Open dashboard …: \x1b]8;;https://dashboard.hookdeck.com/events/cli?team_id=tm_…\x1b\https://…/events/cli\x1b]8;;\x1b\

Measured escape counts:

run OSC-8 sequences
stdout redirected to a file / piped 2
real TTY 0 (plain URL)

--color off and NO_COLOR=1 both correctly strip SGR colour in the non-TTY case (0 SGR sequences) but leave the OSC-8 bytes intact.

Why it matters

  1. It is inverted. A terminal can render OSC-8; a log file and a grep pipeline cannot. The escapes land precisely where they are useless and are withheld where they would work.
  2. It corrupts logs. CI logs, Docker logs and agent transcripts get raw escape bytes in the middle of a URL.
  3. It loses information. The team_id query parameter is hidden inside the escape, so the redirected output shows only the bare URL — making the non-TTY output less informative than the TTY output, on top of being harder to read.
  4. --color off not suppressing it defeats the documented escape hatch for exactly this situation.

Suggested fix

Gate OSC-8 on the same terminal check the colour output already uses, and have --color off / NO_COLOR suppress it. When not emitting the hyperlink, print the full URL including its query parameters.

Testing

Unit: assert the rendered string contains no \x1b]8;; when the writer is not a terminal, and none when colour is disabled. The renderer is already exercised by pkg/listen tests.

Related


Filed by Claude on Phil's behalf, from release-candidate testing.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions