Skip to content

fix(web): recognize markdown file links with angle brackets and parentheses - #5222

Open
yashranaway wants to merge 3 commits into
pingdotgg:mainfrom
yashranaway:fix/markdown-file-link-destinations
Open

fix(web): recognize markdown file links with angle brackets and parentheses#5222
yashranaway wants to merge 3 commits into
pingdotgg:mainfrom
yashranaway:fix/markdown-file-link-destinations

Conversation

@yashranaway

@yashranaway yashranaway commented Aug 2, 2026

Copy link
Copy Markdown

What Changed

File-link classification in ChatMarkdown scanned message text with a single
regex that recognized fewer CommonMark link destinations than react-markdown
renders. Angle-bracket destinations ([x](</a b/c.tsv>)) matched nothing and
bare destinations containing balanced parentheses ([x](/tmp/a(1).txt)) were
truncated at the first ), so both rendered as dead plain anchors.

  • Replaced the regex with extractMarkdownLinkHrefs, a small CommonMark-aware
    scanner handling both the angle-bracket and bare (balanced-paren) forms.
  • Added normalizeMarkdownLinkHrefKey, decoding percent-encoding so a rendered
    href (a space becomes %20) matches the unencoded destination scanned from
    source text; file URIs keep single-decode semantics.
  • Moved both helpers into markdown-links.ts with focused unit tests.

Why

Paths agents emit routinely contain spaces, and duplicate downloads produce
names like report (1).pdf. Those links previously did nothing when clicked.
Fixes #5158.

UI Changes

Sending the exact repro from the issue

markdown_file_link_chips_fix_demo.mp4

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Note

Fix markdown file link detection to support angle-bracket and parenthesized destinations

  • Replaces local link-extraction helpers in ChatMarkdown.tsx with extractMarkdownLinkHrefs and normalizeMarkdownLinkHrefKey from markdown-links.ts
  • extractMarkdownLinkHrefs now parses CommonMark inline link destinations, including angle-bracket form (with spaces) and bare destinations with balanced parentheses, and skips destinations embedded in link titles
  • normalizeMarkdownLinkHrefKey produces stable lookup keys that align raw markdown destinations with react-markdown-rendered hrefs, including file:// URIs
  • File link meta is now resolved from the original href (single decode) while lookups use the normalized key, preventing double-decoding mismatches

Macroscope summarized c9550c9.


Note

Low Risk
Localized markdown link parsing and lookup-key normalization in the web chat UI, with broad unit tests and no auth or data-layer changes.

Overview
Chat markdown file links now work for paths with spaces and balanced parentheses in link destinations—cases that previously rendered as plain anchors because pre-scan used a regex that didn’t match CommonMark-style destinations.

extractMarkdownLinkHrefs in markdown-links.ts replaces that regex with a small CommonMark-aware scanner (angle-bracket destinations, bare destinations with balanced (), escaped/nested label brackets, optional titles). normalizeMarkdownLinkHrefKey aligns pre-scan keys with react-markdown’s rendered href (e.g. %20 vs literal space) and with rewritten file:// paths, while ChatMarkdown still resolves file paths from the original href to avoid double-decoding.

File link chips use the render-time href in copy markdown when available. Unit tests cover extraction and key normalization.

Reviewed by Cursor Bugbot for commit c9550c9. Bugbot is set up for automated code reviews on this repo. Configure here.

…theses

The file-link classifier scanned message text with a single regex that
captured fewer CommonMark link destination forms than react-markdown
renders. Angle-bracket destinations ([x](</a b/c.tsv>)) captured nothing
and bare destinations with balanced parentheses ([x](/tmp/a(1).txt)) were
truncated at the first ')', so those links rendered as plain anchors that
did nothing when clicked.

Replace the regex with extractMarkdownLinkHrefs, a small CommonMark-aware
scanner that understands both destination forms, and add
normalizeMarkdownLinkHrefKey which decodes percent-encoding so a rendered
href (spaces become %20) matches the unencoded destination scanned from
the source text. File URIs keep their single-decode semantics.

Both helpers move to markdown-links.ts with focused unit tests.

Fixes pingdotgg#5158
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f159b0dd-4587-4c38-8932-bdb8e182ae9a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 2, 2026
Comment thread apps/web/src/markdown-links.ts
Resolve conflicts in apps/web with upstream inline-code file-link work:
keep the shared extractMarkdownLinkHrefs/normalizeMarkdownLinkHrefKey
helpers (now imported from markdown-links.ts) alongside upstream's
extractInlineCodeSpans and resolveInlineCodeFileLinkMeta.
@yashranaway
yashranaway marked this pull request as ready for review August 2, 2026 08:24
Comment thread apps/web/src/markdown-links.ts
Comment thread apps/web/src/markdown-links.ts Outdated
@macroscopeapp

macroscopeapp Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces substantial new markdown link parsing logic. There is an unresolved medium-severity comment identifying that unclosed brackets stop the entire link scan, potentially missing valid links that appear later in text. This correctness concern warrants human review.

You can customize Macroscope's approvability policy. Learn more.

Address review findings on the file-link scanner:

- Resolve the link label end across escaped (\]) and balanced nested
  ([foo [bar]]) brackets instead of stopping at the first ], so those
  CommonMark links are classified correctly.
- Skip the optional link title and closing paren after the destination so
  a [label](url) sequence embedded inside a title is no longer extracted
  as a real link.
- Decode file:// keys consistently in normalizeMarkdownLinkHrefKey so the
  pre-scan key (from the raw file:// href) matches the render-time key
  (from the already-rewritten path). The file path is now resolved from
  the original href to keep single-decode semantics and avoid double
  decoding percent-encoded octets.

Extend markdown-links tests to cover escaped/nested labels, titles that
contain link-looking text, and file:// key matching.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c9550c9. Configure here.

const labelStart = text.indexOf("[", index);
if (labelStart === -1) break;

const labelEnd = findMarkdownLinkLabelEnd(text, labelStart);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Unclosed label stops link scan

Medium Severity

When findMarkdownLinkLabelEnd can't find a balanced closing bracket for an opening [, extractMarkdownLinkHrefs stops scanning the entire text. This means any valid inline links appearing later in the message are missed, preventing them from being recognized as file links and causing them to render incorrectly, even if react-markdown parses them fine.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c9550c9. Configure here.

}

if (text[pos] === ")") pos += 1;
return pos;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Parenthesized title breaks on first paren

Low Severity

skipMarkdownLinkTitleAndClose treats a parenthesized link title by scanning until the first ), without balancing nested parentheses. Destinations or nested [text](url) inside a (title) stop the scan early, so the scanner can treat title content as later links or advance the index incorrectly compared to quoted-title handling.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c9550c9. Configure here.

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

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Markdown file links break when the destination uses angle brackets or contains parentheses

1 participant