Skip to content

feat: Auto-link GitHub PR/issue references in chat messages#238

Merged
StephaneDelcroix merged 2 commits intomainfrom
fix/i-keep-repeating-that-all-pull-request-a-20260227-0916
Feb 28, 2026
Merged

feat: Auto-link GitHub PR/issue references in chat messages#238
StephaneDelcroix merged 2 commits intomainfrom
fix/i-keep-repeating-that-all-pull-request-a-20260227-0916

Conversation

@StephaneDelcroix
Copy link
Copy Markdown
Collaborator

Summary

Adds built-in linkification for GitHub PR/issue references in chat messages. Plain-text references like #123 and owner/repo#123 are automatically converted to clickable links that open in the browser.

What Changed

  • GitHubReferenceLinker.cs — New static utility that post-processes Markdig HTML output to convert GitHub references to <a> links
    • Handles fully-qualified refs (owner/repo#123) without any repo context
    • Handles bare refs (#123) when the session has a known repo URL
    • Safely skips content inside <a>, <code>, <pre>, <script>, <style> tags
    • Skips HTML entities (&#123;) and URL fragments (/path#123)
  • ChatMessageList.razor — Calls linker in RenderMarkdown, accepts RepoUrl parameter
  • ChatMessageItem.razor — Passes RepoUrl to RenderMarkdown calls
  • ExpandedSessionView.razor / SessionCard.razor / Dashboard.razor — Thread RepoUrl from session context
  • CopilotService.Organization.cs — New GetRepoUrlForSession() method resolves repo URL via WorktreeId or group RepoId

Tests

  • 30 new unit tests covering all patterns and edge cases
  • All 1575 existing tests continue to pass (1 pre-existing flaky test unrelated)

StephaneDelcroix and others added 2 commits February 27, 2026 10:30
Add built-in linkification for GitHub references (#123 and owner/repo#123)
in chat messages. This converts plain-text issue/PR numbers into clickable
links that open in the browser.

- Add GitHubReferenceLinker utility that post-processes HTML after Markdig
  rendering to convert references to <a> links
- Handle fully-qualified refs (owner/repo#123) without any repo context
- Handle bare refs (#123) when session has a known repo URL
- Safely skip content inside <a>, <code>, <pre>, <script>, <style> tags
- Skip HTML entities (&#123;) and URL fragments (/path#123)
- Thread RepoUrl parameter through ChatMessageList → ChatMessageItem
- Add GetRepoUrlForSession() to CopilotService for repo URL resolution
- Add 30 unit tests covering all patterns and edge cases

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reject owner/repo paths containing characters outside
[A-Za-z0-9._-/] to prevent HTML attribute injection via
crafted SSH or HTTPS remote URLs. Add two regression tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@StephaneDelcroix
Copy link
Copy Markdown
Collaborator Author

✅ Multi-Model Review: Ready to Merge

Initial 5-model review found an XSS vulnerability (4/5 models flagged):

🟡 GitHubReferenceLinker.cs:ExtractOwnerRepo — SSH remote URLs returned the path verbatim with no validation. A crafted remote like git@github.com:org/repo" onclick="alert(1).git could break out of the href attribute.

Fix applied in commit ee3202d:

  • Added SafeOwnerRepoRegex (^[A-Za-z0-9._-]+/[A-Za-z0-9._-]+$) validation on both SSH and HTTPS extraction paths
  • 2 regression tests added for malicious URLs
  • All 32 GitHubReferenceLinker tests pass

Post-fix re-review (5 models): All confirmed XSS is fixed. No new consensus issues.

@StephaneDelcroix StephaneDelcroix merged commit 983cfe3 into main Feb 28, 2026
@StephaneDelcroix StephaneDelcroix deleted the fix/i-keep-repeating-that-all-pull-request-a-20260227-0916 branch February 28, 2026 09:44
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