Skip to content

Commit d7ab2da

Browse files
Merge branch 'main' into brendan/remove-domain-from-routes
2 parents a7509b5 + b7656c3 commit d7ab2da

File tree

9 files changed

+837
-655
lines changed

9 files changed

+837
-655
lines changed

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
- Linear issue links in chat responses now render as a rich card-style UI showing the Linear logo, issue identifier, and title instead of plain hyperlinks. [#1060](https://github.com/sourcebot-dev/sourcebot/pull/1060)
12+
13+
### Changed
14+
- Links in Ask Sourcebot chat responses now open in a new tab with a subtle external link icon indicator. [#1059](https://github.com/sourcebot-dev/sourcebot/pull/1059)
15+
16+
## [4.16.7] - 2026-04-03
17+
18+
### Fixed
19+
- Fixed "TypeError: pathRegexp is not a function" type error in the worker. [#1093](https://github.com/sourcebot-dev/sourcebot/pull/1093)
20+
21+
## [4.16.6] - 2026-04-03
22+
23+
### Changed
24+
- Bumped dependencies. [#1082](https://github.com/sourcebot-dev/sourcebot/pull/1082) [#1083](https://github.com/sourcebot-dev/sourcebot/pull/1083) [#1084](https://github.com/sourcebot-dev/sourcebot/pull/1084) [#1085](https://github.com/sourcebot-dev/sourcebot/pull/1085) [#1086](https://github.com/sourcebot-dev/sourcebot/pull/1086) [#1087](https://github.com/sourcebot-dev/sourcebot/pull/1087) [#1088](https://github.com/sourcebot-dev/sourcebot/pull/1088) [#1089](https://github.com/sourcebot-dev/sourcebot/pull/1089) [#1090](https://github.com/sourcebot-dev/sourcebot/pull/1090) [#1091](https://github.com/sourcebot-dev/sourcebot/pull/1091) [#1092](https://github.com/sourcebot-dev/sourcebot/pull/1092)
25+
26+
## [4.16.5] - 2026-04-02
27+
1028
### Added
1129
- Added `GET /api/commit` endpoint for retrieving details about a single commit, including parent commit SHAs [#1077](https://github.com/sourcebot-dev/sourcebot/pull/1077)
1230

docs/api-reference/sourcebot-public.openapi.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"openapi": "3.0.3",
33
"info": {
44
"title": "Sourcebot Public API",
5-
"version": "v4.16.4",
5+
"version": "v4.16.7",
66
"description": "OpenAPI description for the public Sourcebot REST endpoints used for search, repository listing, and file browsing. Authentication is instance-dependent: API keys are the standard integration mechanism, OAuth bearer tokens are EE-only, and some instances may allow anonymous access."
77
},
88
"tags": [

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
"node-gyp/glob": "^10.5.0",
3838
"sucrase/glob": "^10.5.0",
3939
"rimraf@npm:5.0.10/glob": "^10.5.0",
40-
"@opentelemetry/resources": "2.5.1"
40+
"@opentelemetry/resources": "2.5.1",
41+
"path-to-regexp@0.1.12": "0.1.13",
42+
"path-to-regexp@^8": "^8.4.0",
43+
"picomatch@^4": "^4.0.4"
4144
}
4245
}

packages/shared/src/version.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
// This file is auto-generated by .github/workflows/release-sourcebot.yml
2-
export const SOURCEBOT_VERSION = "v4.16.4";
2+
export const SOURCEBOT_VERSION = "v4.16.7";

packages/web/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"@ai-sdk/react": "^3.0.107",
2727
"@ai-sdk/xai": "^3.0.60",
2828
"@auth/prisma-adapter": "^2.11.1",
29-
"@aws-sdk/credential-providers": "^3.1000.0",
29+
"@aws-sdk/credential-providers": "^3.1023.0",
3030
"@codemirror/commands": "^6.6.0",
3131
"@codemirror/lang-cpp": "^6.0.2",
3232
"@codemirror/lang-css": "^6.3.0",

packages/web/public/linear.svg

Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
'use client';
2+
3+
import { cn } from '@/lib/utils';
4+
import { ExternalLinkIcon } from 'lucide-react';
5+
import Image from 'next/image';
6+
import linearLogo from '@/public/linear.svg';
7+
8+
interface LinearIssueCardProps {
9+
identifier: string;
10+
title: string;
11+
href: string;
12+
className?: string;
13+
}
14+
15+
export const LinearIssueCard = ({ identifier, title, href, className }: LinearIssueCardProps) => {
16+
return (
17+
<a
18+
href={href}
19+
target="_blank"
20+
rel="noopener noreferrer"
21+
className={cn(
22+
"not-prose inline-flex items-center gap-2 px-2.5 py-1.5 rounded-md border border-border bg-muted hover:bg-accent transition-colors text-sm no-underline",
23+
className
24+
)}
25+
>
26+
<Image
27+
src={linearLogo}
28+
alt="Linear"
29+
className="w-4 h-4 shrink-0 dark:invert"
30+
/>
31+
<span className="font-mono font-semibold text-foreground">{identifier}</span>
32+
<span className="text-muted-foreground truncate max-w-[240px] capitalize">{title}</span>
33+
<ExternalLinkIcon className="w-3 h-3 shrink-0 text-muted-foreground" />
34+
</a>
35+
);
36+
};

packages/web/src/features/chat/components/chatThread/markdownRenderer.tsx

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { SearchQueryParams } from '@/lib/types';
55
import { cn, createPathWithQueryParams } from '@/lib/utils';
66
import type { Element, Root } from "hast";
77
import { Schema as SanitizeSchema } from 'hast-util-sanitize';
8-
import { CopyIcon, SearchIcon } from 'lucide-react';
8+
import { CopyIcon, ExternalLinkIcon, SearchIcon } from 'lucide-react';
99
import type { Heading, Nodes } from "mdast";
1010
import { findAndReplace } from 'mdast-util-find-and-replace';
1111
import { useRouter } from 'next/navigation';
@@ -17,10 +17,13 @@ import remarkGfm from 'remark-gfm';
1717
import type { PluggableList, Plugin } from "unified";
1818
import { visit } from 'unist-util-visit';
1919
import { CodeBlock } from './codeBlock';
20+
import { LinearIssueCard } from './linearIssueCard';
2021
import { FILE_REFERENCE_REGEX } from '@/features/chat/constants';
2122
import { createFileReference } from '@/features/chat/utils';
2223
import isEqual from "fast-deep-equal/react";
2324

25+
const LINEAR_ISSUE_URL_REGEX = /^https:\/\/linear\.app\/[^/]+\/issue\/([A-Z]+-\d+)\/([^/\s"]+)$/;
26+
2427
export const REFERENCE_PAYLOAD_ATTRIBUTE = 'data-reference-payload';
2528

2629
const annotateCodeBlocks: Plugin<[], Root> = () => {
@@ -170,6 +173,30 @@ const MarkdownRendererComponent = forwardRef<HTMLDivElement, MarkdownRendererPro
170173
)
171174
}, []);
172175

176+
const renderAnchor = useCallback(({ href, children, className: incomingClassName, ...rest }: React.JSX.IntrinsicElements['a']) => {
177+
if (href) {
178+
const match = LINEAR_ISSUE_URL_REGEX.exec(href);
179+
if (match) {
180+
const identifier = match[1];
181+
const titleSlug = match[2];
182+
const title = titleSlug.replace(/-/g, ' ');
183+
return <LinearIssueCard identifier={identifier} title={title} href={href} />;
184+
}
185+
}
186+
return (
187+
<a
188+
{...rest}
189+
href={href}
190+
target="_blank"
191+
rel="noopener noreferrer"
192+
className={cn(incomingClassName, "inline-flex items-center gap-0.5")}
193+
>
194+
{children}
195+
<ExternalLinkIcon className="inline w-3 h-3 mb-0.5 opacity-60" />
196+
</a>
197+
);
198+
}, []);
199+
173200
const renderCode = useCallback(({ className, children, node, ...rest }: React.JSX.IntrinsicElements['code'] & { node?: Element }) => {
174201
const text = children?.toString().trimEnd() ?? '';
175202

@@ -238,6 +265,7 @@ const MarkdownRendererComponent = forwardRef<HTMLDivElement, MarkdownRendererPro
238265
components={{
239266
pre: renderPre,
240267
code: renderCode,
268+
a: renderAnchor,
241269
}}
242270
>
243271
{content}

0 commit comments

Comments
 (0)