Skip to content

Commit bfa6f98

Browse files
further wip
1 parent 8e0e737 commit bfa6f98

12 files changed

Lines changed: 550 additions & 69 deletions

File tree

packages/queryLanguage/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ type Tree = ReturnType<typeof parser.parse>;
44
type SyntaxNode = Tree['topNode'];
55
export type { Tree, SyntaxNode };
66
export * from "./parser";
7-
export * from "./parser.terms";
7+
export * from "./parser.terms";
8+
export { SEARCH_SYNTAX_DESCRIPTION } from "./syntaxDescription";
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
/**
2+
* Human-readable description of the Sourcebot search query syntax.
3+
* Keep this in sync with query.grammar and tokens.ts when the syntax changes.
4+
*/
5+
export const SEARCH_SYNTAX_DESCRIPTION = `
6+
# Sourcebot Search Query Syntax
7+
8+
Sourcebot uses a structured query language for searching code across repositories.
9+
10+
## Full-text search
11+
12+
Bare words and quoted strings search across file content:
13+
authentication — matches files containing "authentication"
14+
"password reset" — exact phrase match
15+
16+
Words can contain almost any character including slashes, dots, @-signs, and dashes.
17+
For example, @aws-sdk/credential-providers and v1.2.3 are each treated as single terms.
18+
A dash within a word (e.g. hello-world) is part of the word, not negation.
19+
20+
## Prefix filters
21+
22+
Narrow the search using prefix:value syntax. Values can be plain words or quoted strings.
23+
24+
content:<value> (alias: c:) Match within file content
25+
file:<value> (alias: f:) Match file path
26+
lang:<value> Match programming language (see language names below)
27+
repo:<value> (alias: r:) Match repository name
28+
sym:<value> Match symbol or identifier name
29+
rev:<value> Match git revision or branch name
30+
context:<value> Match context
31+
reposet:<value> Match a named repository set
32+
archived:yes|no|only Filter by archived status
33+
fork:yes|no|only Filter by fork status
34+
visibility:public|private|any Filter by repository visibility
35+
36+
## Language names
37+
38+
Language names for lang: come from GitHub Linguist and are case-sensitive.
39+
Common values:
40+
41+
TypeScript — .ts files
42+
TSX — .tsx files (TypeScript + React/JSX)
43+
JavaScript — .js and .jsx files
44+
Python
45+
Go
46+
Rust
47+
Java
48+
C
49+
C++
50+
Ruby
51+
Swift
52+
Kotlin
53+
CSS
54+
HTML
55+
JSON
56+
YAML
57+
Markdown
58+
Shell
59+
Scala
60+
Haskell
61+
Elixir
62+
Elm
63+
PHP
64+
Dart
65+
R
66+
Vue
67+
Svelte
68+
69+
When unsure of the exact language name, prefer using file: with a regex to match
70+
file extensions instead (e.g. file:\\.tsx$ instead of lang:TSX).
71+
72+
## Quoting and spaces
73+
74+
Any term or filter value that contains spaces must be wrapped in double quotes.
75+
Any double-quote characters within the quoted value must be escaped with a backslash (\").
76+
This applies to bare search terms AND to filter values like content:, file:, repo:, etc.
77+
78+
"password reset" — bare term: phrase with a space
79+
content:"error handler" — filter value with a space, no internal quotes
80+
81+
When the pattern itself contains double quotes (e.g. matching JSON or source code), escape
82+
each internal quote with a backslash. Build it up in steps:
83+
84+
Step 1 — raw pattern you want to match: "next": "15.
85+
Step 2 — escape the internal quotes: \"next\": \"15.
86+
Step 3 — wrap in outer double quotes: "\"next\": \"15."
87+
Step 4 — full filter: content:"\"next\": \"15\\.\\d"
88+
89+
WRONG: content:""next": "15\.\d ← unescaped internal quotes break the value boundary
90+
RIGHT: content:"\"next\": \"15\\.\\d"
91+
92+
Every " inside a quoted value MUST become \". Missing even one will produce incorrect results.
93+
94+
## Filter value matching
95+
96+
file:, repo:, sym:, and rev: always treat their value as a regular expression.
97+
A simple word matches as a case-sensitive substring; a full regex pattern can use
98+
anchors, alternation, etc. No forward slashes are used:
99+
file:chat — matches any path containing "chat"
100+
file:test — matches any path containing "test"
101+
file:\\.tsx$ — matches paths ending in .tsx
102+
file:(test|spec) — matches paths containing "test" or "spec"
103+
repo:myorg — matches any repo name containing "myorg"
104+
sym:useState — matches symbols containing "useState"
105+
106+
content: also treats its value as a regular expression:
107+
content:useState — matches files containing "useState"
108+
content:error.*handler — matches files where "error" appears before "handler"
109+
content:"\"next\": \"15\\.\\d" — matches the literal text: "next": "15.<digit>
110+
111+
IMPORTANT: Regex flags (such as /i for case-insensitive) are NOT supported.
112+
All matching is case-sensitive. Do not wrap values in forward slashes for
113+
file:, repo:, sym:, or rev: — the value itself is the pattern.
114+
115+
## Boolean logic
116+
117+
Space (AND): Terms separated by spaces are ANDed — all must match.
118+
119+
or keyword: Use or between terms or filter expressions (must be lowercase).
120+
NOTE: or must not appear at the start or end of a query, and must
121+
be followed by at least one more term.
122+
Correct: auth or login
123+
Incorrect: auth OR login / or login / auth or
124+
125+
Negation (-): Prefix a filter or parenthesized group with - to exclude it.
126+
NOTE: - only negates a prefix filter (e.g. -file:test) or a
127+
parenthesized group (-(...)). A dash inside a word like hello-world
128+
is NOT negation.
129+
Correct: -file:test -(file:test or file:spec)
130+
Incorrect: -hello -"some phrase"
131+
132+
## Grouping
133+
134+
Use parentheses to group expressions:
135+
(auth or login) lang:TypeScript
136+
-(file:test or file:spec)
137+
138+
NOTE: Parentheses must be balanced to be treated as grouping. An unbalanced (
139+
is treated as part of the adjacent word.
140+
141+
## Examples
142+
143+
authentication lang:TypeScript
144+
→ .ts files containing "authentication"
145+
146+
content:useState lang:TSX
147+
→ .tsx (React) files using useState
148+
149+
content:"password reset" -file:test
150+
→ Files with the phrase "password reset", excluding test files
151+
152+
sym:useState lang:TypeScript
153+
→ TypeScript files using the useState symbol
154+
155+
repo:myorg/frontend file:package.json content:@aws-sdk
156+
→ package.json files in the myorg/frontend repo mentioning @aws-sdk
157+
158+
(content:authenticate or content:login) -lang:Markdown
159+
→ Non-markdown files with authentication or login code
160+
161+
content:@aws-sdk/credential-providers file:package.json content:["']3\\.\\d
162+
→ package.json files referencing @aws-sdk/credential-providers at a 3.x version
163+
164+
file:package\\.json content:"\"next\": \"15\\.\\d"
165+
→ package.json files with next pinned to a 15.x version (note escaped inner quotes)
166+
167+
file:package\\.json content:"\"next-auth\": \"\\^?5\\."
168+
→ package.json files with next-auth at a 5.x version
169+
170+
file:package\\.json content:"\"react\": \""
171+
→ package.json files that have a react dependency (any version)
172+
173+
file:package\\.json content:"\"(stripe|openai)\": \""
174+
→ package.json files with stripe or openai as a dependency
175+
176+
file:package\\.json content:"\"[a-z-]+\": \"\\^?(0\\.|[1-9]\\d*\\.)"
177+
→ package.json files with any dependency at a semver version
178+
179+
file:package\\.json content:"\"next\": \"\\^?(1[0-5]|[1-9])\\."
180+
→ package.json files with next at version 15 or lower
181+
182+
lang:TypeScript content:"from \"react\""
183+
→ TypeScript files that import from react
184+
185+
lang:TypeScript content:"from \"(react|react-dom)\""
186+
→ TypeScript files that import from react or react-dom
187+
`.trim();

packages/web/src/app/[domain]/browse/layout.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { auth } from "@/auth";
22
import { LayoutClient } from "./layoutClient";
3+
import { getConfiguredLanguageModelsInfo } from "@/features/chat/actions";
34

45
interface LayoutProps {
56
children: React.ReactNode;
@@ -9,8 +10,9 @@ export default async function Layout({
910
children,
1011
}: LayoutProps) {
1112
const session = await auth();
13+
const languageModels = await getConfiguredLanguageModelsInfo();
1214
return (
13-
<LayoutClient session={session}>
15+
<LayoutClient session={session} isSearchAssistSupported={languageModels.length > 0}>
1416
{children}
1517
</LayoutClient>
1618
)

packages/web/src/app/[domain]/browse/layoutClient.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ import { Session } from "next-auth";
1616
interface LayoutProps {
1717
children: React.ReactNode;
1818
session: Session | null;
19+
isSearchAssistSupported: boolean;
1920
}
2021

2122
export function LayoutClient({
2223
children,
2324
session,
25+
isSearchAssistSupported,
2426
}: LayoutProps) {
2527
const { repoName, revisionName } = useBrowseParams();
2628
const domain = useDomain();
@@ -38,6 +40,7 @@ export function LayoutClient({
3840
query: `repo:^${escapeStringRegexp(repoName)}$${revisionName ? ` rev:${revisionName}` : ''} `,
3941
}}
4042
className="w-full"
43+
isSearchAssistSupported={isSearchAssistSupported}
4144
/>
4245
</TopBar>
4346
<ResizablePanelGroup

0 commit comments

Comments
 (0)