Skip to content

Improve markdown file link UX#1956

Merged
juliusmarminge merged 4 commits intopingdotgg:mainfrom
justsomelegs:feat/markdown-file-link-chips
Apr 15, 2026
Merged

Improve markdown file link UX#1956
juliusmarminge merged 4 commits intopingdotgg:mainfrom
justsomelegs:feat/markdown-file-link-chips

Conversation

@justsomelegs
Copy link
Copy Markdown
Contributor

@justsomelegs justsomelegs commented Apr 12, 2026

What Changed

This tightens the UX for markdown-rendered local file links and keeps file-path presentation more consistent across assistant surfaces.

  • Render local markdown file links as dedicated inline file chips instead of plain links
  • Add file icons, hover tooltip paths, right-click actions, and line/column labels when present
  • Disambiguate duplicate basenames inline within the same markdown message
  • Format displayed file paths from the workspace/repo root instead of absolute machine paths where possible
  • Reuse that repo-relative formatting in timeline changed-file previews/badges
  • Split markdown chip styling away from composer chips and restyle it to match markdown inline code more closely
  • Memoize markdown file chips so identical links do less work during streaming
  • Stabilize the touched timeline test under full-suite load

Why

Assistant messages were hard to scan when they referenced the same filename multiple times, especially when the visible markdown text was just menu.tsx or MessagesTimeline.tsx repeatedly. The useful context existed in the href, but the UI was not surfacing it well.

This approach keeps the change small and local to existing rendering paths:

  • improves readability without changing message semantics
  • keeps normal web links untouched
  • preserves editor-open behavior
  • avoids duplicating path-formatting logic by extracting a shared formatter
  • makes markdown file refs feel like part of prose rather than composer UI

UI Changes

Before:

  • local file refs looked like normal links
  • repeated basenames were hard to distinguish
  • tooltips showed machine-absolute paths
  • markdown file refs visually felt disconnected from nearby inline code

After:

  • local file refs render as inline file chips
  • duplicate basenames gain inline suffix disambiguation when needed
  • tooltips show workspace-relative paths
  • chip styling now sits closer to markdown inline code

Screenshots:
CHIPS
Screenshot 2026-04-12 133217
CONTEXT MENU
Screenshot 2026-04-12 131112
HOVER TOOLTIP
Screenshot 2026-04-12 130612

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

Improve file link rendering in chat markdown with icon, line/column, and context menu

  • File links in chat markdown now render as styled inline elements with a VSCode icon, a label that includes line/column info (e.g. filename · L1:C7), and parent path segments to disambiguate duplicate basenames.
  • Clicking a file link opens it in the preferred editor at the specified line/column; a context menu offers options to copy the relative or full path, with toast feedback.
  • Adds resolveMarkdownFileLinkMeta in markdown-links.ts and formatWorkspaceRelativePath in filePathDisplay.ts to support structured metadata and workspace-relative display paths.
  • File paths in MessagesTimeline work entry rows and previews are now formatted relative to the workspace root.
  • Non-file HTTP(S) links continue to open in a new tab unchanged.

Macroscope summarized b85c801.


Note

Medium Risk
Mostly UI/UX changes, but it touches link handling and editor-opening/context-menu behavior; mistakes could break navigation or open/copy actions for file links across chat surfaces.

Overview
Improves local markdown file-link UX by replacing plain anchors with memoized inline file chips that show VS Code-style icons, tooltips, and context-menu actions (open in editor, copy relative/full path), while keeping normal external links unchanged.

Adds resolveMarkdownFileLinkMeta + formatWorkspaceRelativePath to compute workspace-relative display paths and parse line/column info, uses that metadata to label links as basename · parentSuffix · Lx(:Cy) (disambiguating duplicate basenames), and reuses the same path formatting for MessagesTimeline changed-file previews/badges.

Updates CSS for the new chip styling and expands/adjusts tests to cover line/column labels, basename disambiguation, web-link passthrough, and timeline path formatting.

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

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 12, 2026

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

Run ID: 614b202f-11f3-4883-b5ad-d5e2e9f986b5

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
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actions github-actions bot added size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Apr 12, 2026
@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp bot commented Apr 12, 2026

Approvability

Verdict: Needs human review

Introduces a new interactive file link UX with styled chips, tooltips, context menus, and path disambiguation logic. While self-contained to the UI layer with good test coverage, the volume of new user-facing behavior (~800 lines of new components and utilities) represents a meaningful new feature that benefits from human review.

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

Co-authored-by: codex <codex@users.noreply.github.com>

# Conflicts:
#	apps/web/src/components/chat/MessagesTimeline.test.tsx
#	apps/web/src/components/chat/MessagesTimeline.tsx
Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

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 and found 1 potential issue.

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 b85c801. Configure here.

function basenameOfPath(path: string): string {
const separatorIndex = Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\"));
return separatorIndex >= 0 ? path.slice(separatorIndex + 1) : path;
}
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.

Duplicate basenameOfPath in two new files

Low Severity

Two identical private basenameOfPath functions are introduced in markdown-links.ts and filePathDisplay.ts. Both compute the basename by finding the last / or \\ separator. A single shared utility (or reuse/extension of the existing basenameOfPath export in vscode-icons.ts) would avoid the duplication.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b85c801. Configure here.

@juliusmarminge juliusmarminge merged commit 68061af into pingdotgg:main Apr 15, 2026
12 checks passed
smraikai pushed a commit to smraikai/t3code that referenced this pull request Apr 16, 2026
Co-authored-by: Julius Marminge <julius0216@outlook.com>
aaditagrawal added a commit to aaditagrawal/t3code that referenced this pull request Apr 16, 2026
Integrates upstream/main (d22c6f5) into the fork while preserving all
multi-provider support (codex, claudeAgent, copilot, cursor, opencode,
geminiCli, amp, kilo) and fork UI/UX additions.

Highlights adopted from upstream:
- Nightly release channel + update channel selector (pingdotgg#2012, pingdotgg#2049, pingdotgg#1969)
- Filesystem browse API + command palette project picker (pingdotgg#2024)
- Launch Args setting for Claude provider (pingdotgg#1971)
- Kiro editor support in open picker (pingdotgg#1974)
- Claude plan events for TodoWrite during input streaming (pingdotgg#1541)
- Lost provider session recovery (pingdotgg#1938)
- Cache provider status and gate desktop startup (pingdotgg#1962)
- LegendList migration for chat scrolling and branch lists (pingdotgg#1953)
- Shell snapshot queries + backfill migration (pingdotgg#1973, pingdotgg#2004)
- PATH hydration + fallback detection (pingdotgg#1799)
- Warm sidebar thread subscriptions (pingdotgg#2001)
- Full thread title tooltip (pingdotgg#1994)
- Markdown file link UX (pingdotgg#1956), composer polish (pingdotgg#1944, pingdotgg#1992, pingdotgg#1985)
- Worktree/branch state + draft reuse fixes (pingdotgg#2005, pingdotgg#2003, pingdotgg#1995, pingdotgg#1936)
- Window controls overlay for Windows/Linux (pingdotgg#1969)
- Backend readiness timeout 10s→30s (pingdotgg#1979)
- Clear tracked RPCs on reconnect, live stream subscriptions (pingdotgg#2000, pingdotgg#1972)
- Various misc fixes (pingdotgg#2051, pingdotgg#2052, pingdotgg#2025, pingdotgg#2027, pingdotgg#2049, pingdotgg#1997, pingdotgg#1975)

Fork features preserved and reconciled:
- All 8 provider adapters + conformance tests
- Extended ProviderKind union across contracts/model/settings/provider
- appearance/accentColor/themeConfig/ProviderLogo UI system
- customModels + gitTextGeneration + providerModelOptions
- Migration IDs 23 (NormalizeLegacyProviderKinds) and 24
  (RepairProjectionThreadProposedPlanImplementationColumns) kept; new
  upstream migrations registered at IDs 25-26 to avoid breaking deployed
  fork databases
- DesktopBridge: log directory channels (LOG_DIR/LIST/READ/OPEN_DIR)
  retained; getWsUrl replaced by upstream's getAppBranding
- PROVIDER_CACHE_IDS extended to all 8 providers
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.

2 participants