Skip to content

Commit 8ae6e84

Browse files
committed
Merge remote-tracking branch 'origin/main' into cursor/SOU-822-7df0
# Conflicts: # CHANGELOG.md
2 parents 1427d39 + cfaea87 commit 8ae6e84

File tree

9 files changed

+819
-654
lines changed

9 files changed

+819
-654
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,22 @@ 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+
1013
### Changed
1114
- 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)
1215

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+
1326
## [4.16.5] - 2026-04-02
1427

1528
### Added

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.5",
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.5";
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: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@ 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 { SINGLE_TENANT_ORG_DOMAIN } from '@/lib/constants';
2324
import isEqual from "fast-deep-equal/react";
2425

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

2730
const annotateCodeBlocks: Plugin<[], Root> = () => {
@@ -243,6 +246,19 @@ const MarkdownRendererComponent = forwardRef<HTMLDivElement, MarkdownRendererPro
243246

244247
}, [router]);
245248

249+
const renderAnchor = useCallback(({ href, children, ...rest }: React.JSX.IntrinsicElements['a']) => {
250+
if (href) {
251+
const match = LINEAR_ISSUE_URL_REGEX.exec(href);
252+
if (match) {
253+
const identifier = match[1];
254+
const titleSlug = match[2];
255+
const title = titleSlug.replace(/-/g, ' ');
256+
return <LinearIssueCard identifier={identifier} title={title} href={href} />;
257+
}
258+
}
259+
return <a href={href} target="_blank" rel="noopener noreferrer" {...rest}>{children}</a>;
260+
}, []);
261+
246262
return (
247263
<div
248264
ref={ref}

0 commit comments

Comments
 (0)