Conversation
Hyperlink(text, url) wraps text in OSC 8 escape sequences, with sanitizeURL stripping C0 control characters and DEL to prevent sequence injection via BEL/ESC in URLs. LinkifyMarkdownLinks converts [text](url) to clickable OSC 8 links for non-glamour rendering paths. LinkifyURLs wraps bare https?:// URLs with double-wrap prevention for post-glamour processing.
Glamour path: RenderMarkdown* post-processes output with LinkifyURLs so bare URLs in rendered markdown become clickable. Campfire: applies LinkifyMarkdownLinks + LinkifyURLs after HTMLToMarkdown, replaces runewidth with ansi.StringWidth for ANSI/OSC-aware width calculation, and avoids rune-by-rune splitting of tokens containing escape sequences to preserve hyperlink state. Presenter: adds Styled flag to Styles, wraps title-role fields in renderListRow and headlines in RenderDetail with OSC 8 hyperlinks keyed off app_url. Covers schema-backed output (todos, cards) not just the generic fallback renderer. CLI table/object: wraps title/name cells in OSC 8 hyperlinks using app_url metadata when styled output is active.
Adds titleURL field and SetTitleURL to Preview widget, wrapping the title in an OSC 8 hyperlink in View(). Detail view captures AppURL from SDK types (todo, message, card, generic) into detailData and passes it to the preview via syncPreview.
Campfire's wrapLine now uses charmbracelet/x/ansi.StringWidth instead of mattn/go-runewidth directly.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c802a18a68
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Pull request overview
Adds OSC 8 terminal hyperlink support so Basecamp URLs become clickable across CLI and TUI rendering paths, with URL sanitization to mitigate terminal escape-sequence injection risks.
Changes:
- Introduces
internal/richtextOSC 8 hyperlink utilities (URL sanitization + linkification for Markdown links and bare URLs) with tests. - Applies hyperlinking in presenter- and generic-rendered CLI output plus TUI preview title; propagates
app_urlinto the detail view preview. - Updates campfire rendering to linkify URLs/Markdown links and to use ANSI-aware width calculations for wrapping.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/richtext/hyperlink.go | New OSC 8 hyperlink + URL sanitization + linkification helpers. |
| internal/richtext/hyperlink_test.go | Unit tests covering OSC 8 output, sanitization, and double-wrap prevention. |
| internal/richtext/richtext.go | Post-process glamour output to linkify bare URLs. |
| internal/tui/workspace/views/campfire.go | Linkify content, switch wrapping to ANSI-aware width, and avoid splitting escape sequences. |
| internal/presenter/render.go | Adds Styles.Styled flag and hyperlinks schema “title” fields/headlines via app_url. |
| internal/presenter/presenter_test.go | Tests for hyperlink behavior in styled vs unstyled presenter rendering. |
| internal/output/render.go | Hyperlinks title/name fields via app_url in styled table/object rendering. |
| internal/tui/workspace/widget/preview.go | Adds SetTitleURL() and wraps the preview title in an OSC 8 hyperlink when present. |
| internal/tui/workspace/views/detail.go | Captures app_url from SDK/generic types and forwards it to the preview title. |
| go.mod | Adjusts dependency directness (runewidth now indirect). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…runcation - reMarkdownLink and reBareURL now handle balanced parentheses in URLs (e.g., Wikipedia links like /wiki/Foo_(bar)) - sanitizeURL strips C1 control characters (U+0080–U+009F) including 8-bit ST which can terminate OSC sequences in some terminals - Campfire wrapLine uses ansi.Truncate for long hyperlinked words instead of writing them whole and overflowing the viewport
Constructs an OSC 8-wrapped URL wider than the wrap width and asserts visible width is capped, the opener is preserved, and the reset sequence is present.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
SetTitle now resets titleURL so callers that set a title without an accompanying URL (e.g. Messages.clearPreview, Messages.updatePreview) don't accidentally inherit a stale URL from a previous detail view.
Summary
Changes
internal/richtext/hyperlink.go—Hyperlink(),sanitizeURL(),LinkifyMarkdownLinks(),LinkifyURLs()with double-wrap prevention.internal/richtext/richtext.go—RenderMarkdown*post-processes withLinkifyURLsfor bare URL clickability.internal/tui/workspace/views/campfire.go— ANSI-awarewrapLineviaansi.StringWidth, escape-safe overflow handling,LinkifyMarkdownLinks+LinkifyURLspipeline.internal/presenter/render.go—Styledflag onStyles,hyperlinkFromDatahelper, hyperlinks onrole: "title"fields in list rows and detail headlines.internal/output/render.go— Title/name cells hyperlinked viaapp_urlin styled table and object renderers.internal/tui/workspace/widget/preview.go—SetTitleURL()wraps preview title in OSC 8.internal/tui/workspace/views/detail.go—appURLcaptured from SDK types, propagated to preview.Test plan
make checkpasses (fmt, vet, lint, test, test-e2e, tidy)basecamp todos listin iTerm2/Kitty — todo content column clickablebasecamp todos show <id>— headline clickablebasecamp tui→ campfire — link text clickable, bare URLs clickablebasecamp tui→ detail view — preview title clickablebasecamp todos list | cat— no visible escape artifacts (OSC 8 only when TTY)Summary by cubic
Make links clickable across the CLI and TUI using OSC 8 hyperlinks. Adds safe URL sanitization (C0/C1/DEL) and balanced-parentheses handling; only applies when styled output is enabled.
New Features
Refactors
Written for commit 2883ae8. Summary will update on new commits.