@@ -179,6 +179,7 @@ interface ChatMarkdownProps {
179179 onUseArtifactTemplate ?: ( ( template : CodexArtifactTemplate ) => void ) | undefined ;
180180 imageBaseDir ?: string | undefined ;
181181 onImageExpand ?: ( ( preview : ExpandedImagePreview ) => void ) | undefined ;
182+ extraRemarkPlugins ?: NonNullable < ReactMarkdownOptions [ "remarkPlugins" ] > ;
182183}
183184
184185export function canUseMarkdownFileShellActions (
@@ -211,6 +212,7 @@ export function shouldUseMarkdownFileBrowserPrimaryAction(input: {
211212}
212213
213214const EMPTY_MARKDOWN_SKILLS : ReadonlyArray < Pick < ServerProviderSkill , "name" | "displayName" > > = [ ] ;
215+ const EMPTY_REMARK_PLUGINS : NonNullable < ReactMarkdownOptions [ "remarkPlugins" ] > = [ ] ;
214216
215217const ARTIFACT_TEMPLATE_ICON_BY_KIND = {
216218 document : FileTextIcon ,
@@ -360,6 +362,7 @@ const CHAT_MARKDOWN_SANITIZE_SCHEMA = {
360362 code : [ ...( defaultSchema . attributes ?. code ?? [ ] ) , "dataCodeMeta" , "dataInlineCode" ] ,
361363 blockquote : [ ...( defaultSchema . attributes ?. blockquote ?? [ ] ) , "dataAlert" ] ,
362364 div : [ ...( defaultSchema . attributes ?. div ?? [ ] ) , ...CODEX_ARTIFACT_TEMPLATE_HAST_PROPERTIES ] ,
365+ a : [ ...( defaultSchema . attributes ?. a ?? [ ] ) , "dataPullRequestAutolink" ] ,
363366 img : [ ...( defaultSchema . attributes ?. img ?? [ ] ) , "dataLocalSrc" , "dataMarkdownTitle" ] ,
364367 } ,
365368 protocols : {
@@ -1812,6 +1815,7 @@ function ChatMarkdown({
18121815 onUseArtifactTemplate,
18131816 imageBaseDir,
18141817 onImageExpand,
1818+ extraRemarkPlugins = EMPTY_REMARK_PLUGINS ,
18151819} : ChatMarkdownProps ) {
18161820 const { resolvedTheme } = useTheme ( ) ;
18171821 const createAssetUrl = useAtomQueryRunner ( assetEnvironment . createUrl , {
@@ -2208,13 +2212,25 @@ function ChatMarkdown({
22082212 : null ;
22092213 if ( ! fileLinkMeta ) {
22102214 const faviconHost = resolveExternalWebLinkHost ( href ) ;
2215+ const pullRequestAutolink = String (
2216+ ( props as Record < string , unknown > ) [ "data-pull-request-autolink" ] ?? "" ,
2217+ ) ;
2218+ const pullRequestCopy =
2219+ pullRequestAutolink === "commit"
2220+ ? / \/ c o m m i t \/ ( [ 0 - 9 a - f ] { 40 } ) $ / iu. exec ( href ?? "" ) ?. [ 1 ]
2221+ : pullRequestAutolink === "reference"
2222+ ? plainHastText ( node )
2223+ : undefined ;
2224+ const isPullRequestAutolink = pullRequestCopy !== undefined ;
22112225 const isSameDocumentLink = href ?. startsWith ( "#" ) ?? false ;
22122226 const onClick = props . onClick ;
22132227 const canOpenInPreview = Boolean ( threadRef ) && isPreviewSupportedInRuntime ( ) ;
22142228 const linkChildren = < MarkdownLinkContext value > { children } </ MarkdownLinkContext > ;
22152229 const link = (
22162230 < a
22172231 { ...props }
2232+ className = { cn ( props . className , pullRequestAutolink === "commit" && "font-mono" ) }
2233+ data-markdown-copy = { pullRequestCopy }
22182234 href = { href }
22192235 target = { isSameDocumentLink ? undefined : "_blank" }
22202236 rel = { isSameDocumentLink ? undefined : "noopener noreferrer" }
@@ -2286,7 +2302,7 @@ function ChatMarkdown({
22862302 } ) ;
22872303 } }
22882304 >
2289- { faviconHost && hastHasText ( node ) ? (
2305+ { faviconHost && hastHasText ( node ) && ! isPullRequestAutolink ? (
22902306 < MarkdownExternalLinkContent host = { faviconHost } plainText = { plainHastText ( node ) } >
22912307 { linkChildren }
22922308 </ MarkdownExternalLinkContent >
@@ -2443,6 +2459,14 @@ function ChatMarkdown({
24432459 ] ) ;
24442460 /* eslint-enable react/no-unstable-nested-components */
24452461
2462+ const remarkPlugins = useMemo (
2463+ ( ) => [
2464+ ...( lineBreaks ? CHAT_MARKDOWN_REMARK_PLUGINS_WITH_BREAKS : CHAT_MARKDOWN_REMARK_PLUGINS ) ,
2465+ ...extraRemarkPlugins ,
2466+ ] ,
2467+ [ extraRemarkPlugins , lineBreaks ] ,
2468+ ) ;
2469+
24462470 // react-markdown converts unparsed HTML nodes to text when skipHtml is false.
24472471 // Keep that behavior explicit because literal mode depends on escaping the
24482472 // complete source token instead of dropping it from the rendered message.
@@ -2455,9 +2479,7 @@ function ChatMarkdown({
24552479 onCopy = { handleCopy }
24562480 >
24572481 < ReactMarkdown
2458- remarkPlugins = {
2459- lineBreaks ? CHAT_MARKDOWN_REMARK_PLUGINS_WITH_BREAKS : CHAT_MARKDOWN_REMARK_PLUGINS
2460- }
2482+ remarkPlugins = { remarkPlugins }
24612483 rehypePlugins = { parseRawHtml ? CHAT_MARKDOWN_REHYPE_PLUGINS : undefined }
24622484 skipHtml = { false }
24632485 components = { markdownComponents }
0 commit comments