Skip to content

feat(web): render GitHub PR links as chips in RichMarkdown#274

Merged
pedroscosta merged 2 commits into
mainfrom
feat/pr-link-chips
May 18, 2026
Merged

feat(web): render GitHub PR links as chips in RichMarkdown#274
pedroscosta merged 2 commits into
mainfrom
feat/pr-link-chips

Conversation

@pedroscosta
Copy link
Copy Markdown
Collaborator

@pedroscosta pedroscosta commented May 16, 2026

Summary

  • Detect canonical GitHub pull request URLs in RichMarkdown link rendering and show them as inline PrChip controls (owner/repo, PR icon, number) instead of plain anchors.
  • Add PrChip in chips.tsx and a playground variant that exercises /pull/, /pulls/, www, anchors, and trailing paths so non-PR GitHub links stay normal links.
  • Wrap thread mention chips in a contents span and adjust adjacent text spacing so inline chips align cleanly next to markdown text.

Test plan

  • Open the app playground Rich Markdown route and select PR link example; confirm PR URLs render as chips and repo/issue links stay as links.
  • Confirm Thread mention variant still shows the thread chip and spacing looks acceptable beside surrounding text.
  • Smoke-test a real message or surface that uses RichMarkdown with a GitHub PR link and a thread mention.

Made with Cursor


Summary by cubic

Render GitHub PR links as inline chips in RichMarkdown with schema validation and cleaner inline spacing; non-PR GitHub links remain unchanged.

  • New Features
    • Added PrChip and detection + Zod validation for GitHub PR URLs in RichMarkdown; supports /pull/, /pulls/, www, anchors, and trailing paths.
    • Wrapped PR and thread chips in contents spans with whitespace-aware margins for clean inline alignment.
    • Added a playground variant to demo PR link rendering and edge cases.

Written for commit 385b516. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

  • New Features

    • GitHub pull request links now render as interactive PR chips showing owner, repo and PR number.
    • Markdown-rendered GitHub PR links automatically display inline as styled PR chips instead of regular links.
  • Style

    • Improved inline spacing and alignment for chips adjacent to surrounding text for better typography.

Review Change Stack

Detect GitHub PR URLs in markdown links and render them as a styled
`PrChip` (icon + owner/repo + #number), matching the existing thread
mention chip pattern. The matcher accepts canonical, `/pulls/`, `www.`,
trailing-path and anchor/query shapes.

Also adds a JS-based adjacent-whitespace detector so both PR and thread
chips pick up a tiny inline margin only when surrounding text actually
has spaces, keeping flush placements (e.g. punctuation) tight.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 16, 2026

📝 Walkthrough

Walkthrough

Adds a PrChip component and GitHub PR URL parsing; rich-markdown now renders matching PR links as inline PR chips and adjusts surrounding whitespace; playground adds a PR-mention sample variant.

Changes

GitHub PR Chip System

Layer / File(s) Summary
PR Chip Component
apps/web/src/components/chips.tsx
Adds PrChip component rendering owner/repo and #number as an external-link chip using BaseButton and threadChipVariants; imports GitPullRequest; minor formatting change to ThreadSummaryCard.
GitHub PR Detection & Inline Rendering
apps/web/src/components/markdown/rich-markdown.tsx
Adds PR URL parsing (regex + GithubPrSchema), parseGithubPrUrl, and PrChipInline which wraps PrChip and uses useLayoutEffect to detect adjacent text-node whitespace; updates ThreadMention spacing logic and markdown a renderer to render PR URLs as PrChipInline when matched.
Playground Examples and Variants
apps/web/src/routes/app/_workspace/_main/playground/rich-markdown.tsx
Adds PR_MENTION_CONTENT markdown sample, a pr-mention variant, and selects the PR sample for that variant in the playground UI.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • FrontDeskHQ/front-desk#269: Both PRs modify the link-normalization path in rich-markdown.tsx that produces thread chips; main PR extends it to also handle GitHub PR URLs.
  • FrontDeskHQ/front-desk#267: Both PRs touch chips.tsx; main PR adds GitHub PR chip components built on threadChipVariants, while the retrieved PR refactors the underlying chip styling.
  • FrontDeskHQ/front-desk#271: Both PRs modify chips.tsx and the ThreadMention/ThreadChipWithSummary usage in rich-markdown.tsx, indicating coupled refactoring of thread chip infrastructure.

Suggested reviewers

  • cubic-dev-ai
  • danielmoural

Poem

🐰 I found a link and gave it flair,
A tiny chip with PR care.
I measure gaps with patient eyes,
Tuck whitespace in so text complies.
Now pull requests hop into place—✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately describes the primary change: adding functionality to render GitHub PR links as chips in RichMarkdown. It is specific, concise, and directly related to the main feature implemented across the modified files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/pr-link-chips

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/web/src/components/markdown/rich-markdown.tsx (1)

13-27: ⚡ Quick win

Use Zod to validate parsed GitHub PR data before rendering.

The parseGithubPrUrl function (lines 16-25) validates the URL pattern with regex but lacks explicit schema validation for the returned data shape. Per coding guidelines, add a small Zod schema to validate the parsed object before returning it, ensuring the owner, repo, and number fields meet expected types and constraints.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/components/markdown/rich-markdown.tsx` around lines 13 - 27, Add
Zod validation to parseGithubPrUrl: define a small Zod schema (e.g.,
GithubPrSchema) that requires owner and repo as non-empty strings and number as
a positive integer, then run safeParse/parse against the object you build from
the regex match inside parseGithubPrUrl; if validation fails return null,
otherwise return the validated object (owner, repo, number, url). Ensure you
import z from "zod" and use the schema name (GithubPrSchema) when validating
before returning.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/web/src/components/markdown/rich-markdown.tsx`:
- Around line 13-27: Add Zod validation to parseGithubPrUrl: define a small Zod
schema (e.g., GithubPrSchema) that requires owner and repo as non-empty strings
and number as a positive integer, then run safeParse/parse against the object
you build from the regex match inside parseGithubPrUrl; if validation fails
return null, otherwise return the validated object (owner, repo, number, url).
Ensure you import z from "zod" and use the schema name (GithubPrSchema) when
validating before returning.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0009aee8-87e6-4129-87f5-57296122cc07

📥 Commits

Reviewing files that changed from the base of the PR and between 13387fe and e019e07.

📒 Files selected for processing (3)
  • apps/web/src/components/chips.tsx
  • apps/web/src/components/markdown/rich-markdown.tsx
  • apps/web/src/routes/app/_workspace/_main/playground/rich-markdown.tsx

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 3 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Auto-approved: This PR adds a PrChip component and regex-based detection to render GitHub pull request URLs as inline chips in RichMarkdown, with careful handling of edge cases and spacing; the changes are isolated to UI rendering, do not affect business logic or critical paths, and the AI review found no issues.
Re-trigger cubic

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/web/src/components/markdown/rich-markdown.tsx (1)

151-164: ⚡ Quick win

Extract duplicated sibling-whitespace logic into a shared hook.

PrChipInline and ThreadMention currently duplicate the same ref/state/layout-effect block. A small shared hook (e.g. useAdjacentTextWhitespace) will prevent behavior drift and reduce maintenance overhead.

Proposed refactor
+function useAdjacentTextWhitespace() {
+  const ref = useRef<HTMLSpanElement>(null);
+  const [hasLeadingSpace, setHasLeadingSpace] = useState(false);
+  const [hasTrailingSpace, setHasTrailingSpace] = useState(false);
+
+  useLayoutEffect(() => {
+    const prev = ref.current?.previousSibling;
+    const next = ref.current?.nextSibling;
+    setHasLeadingSpace(
+      prev?.nodeType === Node.TEXT_NODE && /\s$/.test(prev.textContent ?? ""),
+    );
+    setHasTrailingSpace(
+      next?.nodeType === Node.TEXT_NODE && /^\s/.test(next.textContent ?? ""),
+    );
+  });
+
+  return { ref, hasLeadingSpace, hasTrailingSpace };
+}

Also applies to: 192-205

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/components/markdown/rich-markdown.tsx` around lines 151 - 164,
Duplicate logic that inspects adjacent text-node whitespace (the
useRef/useLayoutEffect block that sets hasLeadingSpace and hasTrailingSpace)
appears in PrChipInline and ThreadMention; extract it into a small reusable hook
(e.g., useAdjacentTextWhitespace) that accepts no args and returns { ref,
hasLeadingSpace, hasTrailingSpace } or returns a ref plus the two booleans, move
the current DOM checks (/\s$/ and /^\s/) and Node.TEXT_NODE checks into that
hook, and replace the duplicated blocks in PrChipInline and ThreadMention with
calls to the new hook to centralize behavior and avoid drift.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/web/src/components/markdown/rich-markdown.tsx`:
- Around line 151-164: Duplicate logic that inspects adjacent text-node
whitespace (the useRef/useLayoutEffect block that sets hasLeadingSpace and
hasTrailingSpace) appears in PrChipInline and ThreadMention; extract it into a
small reusable hook (e.g., useAdjacentTextWhitespace) that accepts no args and
returns { ref, hasLeadingSpace, hasTrailingSpace } or returns a ref plus the two
booleans, move the current DOM checks (/\s$/ and /^\s/) and Node.TEXT_NODE
checks into that hook, and replace the duplicated blocks in PrChipInline and
ThreadMention with calls to the new hook to centralize behavior and avoid drift.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e26c1e5e-8758-4181-9a0a-09cd0e6bef6d

📥 Commits

Reviewing files that changed from the base of the PR and between e019e07 and 385b516.

📒 Files selected for processing (1)
  • apps/web/src/components/markdown/rich-markdown.tsx

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 1 file (changes from recent commits).

Auto-approved: The change adds a new feature to render GitHub PR links as inline chips in RichMarkdown with careful regex and Zod validation, and the only modifications to existing code are minor spacing adjustments to thread chips, all within a single frontend component that poses low risk to business logic...
Re-trigger cubic

@pedroscosta pedroscosta merged commit 6af3c92 into main May 18, 2026
4 checks passed
@pedroscosta pedroscosta deleted the feat/pr-link-chips branch May 18, 2026 23:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant