Hive Hive
Sign in

fix(forage): render inline markdown in GitHub issue titles and excerpts

GitHub issue · Closed

Metadata
Source
tuist/hive #31
Updated
Jun 24, 2026
Domains
Hive
Details

Summary

  • HiveWeb.Markdown.inline/1 renders a single line through MDEx with the same options + sanitize policy as render/1, then strips the wrapping <p> so the result can sit inside an existing block element (issue title link, excerpt paragraph).
  • The GitHub issues forage list now routes issue.title and the body excerpt through Markdown.inline/1, so backticks become real <code> spans instead of raw characters.
  • issue_excerpt/1 skips lines that match ^#+\s+, so GitHub issue templates that start with ### What happened? don’t surface that heading as the description.
  • Styled inline <code> inside [data-part="issue-copy"] using Noora tokens (--noora-spacing-1, --noora-radius-1, --noora-surface-background-secondary, --noora-font-family-mono), following the project’s anchor + data-part CSS convention.

Motivation

Synced GitHub issues were displayed in the forage list with raw markdown leaking through. Titles like Static framework with \.metal` produces `default.metallib`showed the backticks verbatim, and the body excerpt picked the first non-blank line of the body which, for any issue using GitHub's standard issue template, is### What happened?`. Both made the list look unfinished.

Approach considered

A regex-only solution for backticks would have matched GitHub’s own issue-title rendering (which only renders inline code), but the project already standardizes on MDEx in HiveWeb.Markdown with a configured sanitize policy. Reusing that surface was preferred over introducing a one-off regex so escapes, autolinks, and HTML safety stay consistent and future markdown additions don’t need new plumbing. The catch is that MDEx wraps output in <p>; inline/1 parses with the existing options and strips the leading/trailing <p> via a tight regex so the caller decides the surrounding element.

For the excerpt, walking the MDEx AST to find the first paragraph node was considered but felt heavy for a one-line summary. The line-based filter (skip heading-marker lines, then route through Markdown.inline/1) is small, readable, and handles the actual failure mode in the screenshot.

Verification

  • mix test test/hive_web/markdown_test.exs test/hive_web/components/forage_components_test.exs test/hive_web/live/forage_live/github_issues_test.exs — 25 tests, 0 failures.
  • New tests lock in: inline rendering produces no wrapping <p>, raw HTML stays escaped, nil returns an empty safe string, the issue title renders <code> spans, and heading-only excerpt lines are skipped.
  • mix format + mix credo --strict clean (only pre-existing repo-wide warnings remained).
Flights

Investigate, reproduce, or fix this item in an isolated repository. Each Flight preserves its outcome and agent session.

New Flights are paused Configure model inference, GitHub, and a sandbox provider to start another Flight. Existing results remain available below.
No Flights yet

Start a Flight and preserve its objective, outcome, and session here.

Comments

No GitHub comments yet.