Skip to content

Commit 379ce89

Browse files
Merge branch 'main' into brendan/fix-SOU-1960
2 parents 2cd2edf + 8aae78d commit 379ce89

46 files changed

Lines changed: 2977 additions & 107 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Added
1111
- Added a manually triggered cloud image release workflow for isolated internal deployments. [#1566](https://github.com/sourcebot-dev/sourcebot/pull/1566)
1212
- Added Prometheus metrics for the web process, served on `WEB_METRICS_PORT` (default `3070`). [#1570](https://github.com/sourcebot-dev/sourcebot/pull/1570)
13+
- Added an `http_request_duration_seconds` metric recording web request latency by route, method, and status. [#1571](https://github.com/sourcebot-dev/sourcebot/pull/1571)
14+
- [EE] Added one-hour repository-scoped access tokens with public mint and revoke APIs. [#1549](https://github.com/sourcebot-dev/sourcebot/pull/1549)
15+
- Added public connection listing and connection-based repository filtering APIs. [#1550](https://github.com/sourcebot-dev/sourcebot/pull/1550)
1316

1417
### Fixed
1518
- Fixed the web process being capped at a ~4GiB heap regardless of how much memory the container has, which caused multi-second garbage collection pauses on larger deployments. [#1569](https://github.com/sourcebot-dev/sourcebot/pull/1569)
1619
- Upgraded `@sentry/*` to `^10.70.0`, fixing memory leaks where spans retained request data indefinitely. [#1572](https://github.com/sourcebot-dev/sourcebot/pull/1572)
20+
- Fixed code search result links occasionally getting stuck during navigation and restored Cmd/Ctrl-click to open matches in preview. [#1574](https://github.com/sourcebot-dev/sourcebot/pull/1574)
21+
- Fixed a server-side memory leak where a single shared react-query cache retained state from every server render; the cache is now created per-request. [#1575](https://github.com/sourcebot-dev/sourcebot/pull/1575)
22+
- Fixed code host retry warnings to include the HTTP response status. [#1576](https://github.com/sourcebot-dev/sourcebot/pull/1576)
23+
- Fixed streamed code search updates silently cancelling in-flight result navigation. [#1577](https://github.com/sourcebot-dev/sourcebot/pull/1577)
1724
- Fixed the `grep` and `glob` agent tools mis-parsing structured search inputs containing spaces, commas, or quotes. [#1573](https://github.com/sourcebot-dev/sourcebot/pull/1573)
1825

1926
## [5.1.6] - 2026-08-10

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

Lines changed: 306 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
"name": "Search & Navigation",
1111
"description": "Code search and symbol navigation endpoints."
1212
},
13+
{
14+
"name": "Connections",
15+
"description": "Code host connection metadata."
16+
},
1317
{
1418
"name": "Repositories",
1519
"description": "Repository listing and metadata endpoints."
@@ -18,6 +22,10 @@
1822
"name": "Git",
1923
"description": "Git history, diff, and file content endpoints."
2024
},
25+
{
26+
"name": "Scoped Access Tokens",
27+
"description": "Mint and revoke short-lived credentials restricted to specific repositories."
28+
},
2129
{
2230
"name": "System",
2331
"description": "System health and version endpoints."
@@ -512,6 +520,37 @@
512520
]
513521
}
514522
},
523+
"PublicListConnectionsResponse": {
524+
"type": "array",
525+
"items": {
526+
"type": "object",
527+
"properties": {
528+
"id": {
529+
"type": "integer"
530+
},
531+
"name": {
532+
"type": "string"
533+
},
534+
"connectionType": {
535+
"type": "string",
536+
"enum": [
537+
"github",
538+
"gitlab",
539+
"gitea",
540+
"gerrit",
541+
"bitbucket",
542+
"azuredevops",
543+
"git"
544+
]
545+
}
546+
},
547+
"required": [
548+
"id",
549+
"name",
550+
"connectionType"
551+
]
552+
}
553+
},
515554
"PublicVersionResponse": {
516555
"type": "object",
517556
"properties": {
@@ -1090,6 +1129,63 @@
10901129
"$ref": "#/components/schemas/PublicCommitAuthor"
10911130
}
10921131
},
1132+
"PublicCreateScopedAccessTokenResponse": {
1133+
"type": "object",
1134+
"properties": {
1135+
"id": {
1136+
"type": "string",
1137+
"description": "Identifier used to revoke the token."
1138+
},
1139+
"token": {
1140+
"type": "string",
1141+
"pattern": "^sbst_",
1142+
"description": "Opaque bearer token. This value is returned only when the token is created."
1143+
},
1144+
"createdAt": {
1145+
"type": "string",
1146+
"format": "date-time"
1147+
},
1148+
"expiresAt": {
1149+
"type": "string",
1150+
"format": "date-time"
1151+
},
1152+
"repoIds": {
1153+
"type": "array",
1154+
"items": {
1155+
"type": "integer",
1156+
"minimum": 0,
1157+
"exclusiveMinimum": true
1158+
},
1159+
"minItems": 1
1160+
}
1161+
},
1162+
"required": [
1163+
"id",
1164+
"token",
1165+
"createdAt",
1166+
"expiresAt",
1167+
"repoIds"
1168+
]
1169+
},
1170+
"PublicCreateScopedAccessTokenRequest": {
1171+
"type": "object",
1172+
"properties": {
1173+
"repoIds": {
1174+
"type": "array",
1175+
"items": {
1176+
"type": "integer",
1177+
"minimum": 0,
1178+
"exclusiveMinimum": true
1179+
},
1180+
"minItems": 1,
1181+
"description": "Repository IDs to bind to the token. Every ID must identify a repository accessible to the API-key owner."
1182+
}
1183+
},
1184+
"required": [
1185+
"repoIds"
1186+
],
1187+
"additionalProperties": false
1188+
},
10931189
"PublicEeUser": {
10941190
"type": "object",
10951191
"properties": {
@@ -1253,7 +1349,7 @@
12531349
"bearerToken": {
12541350
"type": "http",
12551351
"scheme": "bearer",
1256-
"description": "Bearer authentication header of the form `Bearer <token>`, where `<token>` is your API key."
1352+
"description": "Bearer authentication header of the form `Bearer <token>`. The token may be a Sourcebot API key, OAuth access token, or scoped access token, subject to endpoint requirements."
12571353
},
12581354
"apiKeyHeader": {
12591355
"type": "apiKey",
@@ -1384,6 +1480,18 @@
13841480
"required": false,
13851481
"name": "query",
13861482
"in": "query"
1483+
},
1484+
{
1485+
"schema": {
1486+
"type": "integer",
1487+
"minimum": 0,
1488+
"exclusiveMinimum": true,
1489+
"description": "Filter repositories to those associated with this connection ID. IDs are returned by GET /api/connections."
1490+
},
1491+
"required": false,
1492+
"description": "Filter repositories to those associated with this connection ID. IDs are returned by GET /api/connections.",
1493+
"name": "connectionId",
1494+
"in": "query"
13871495
}
13881496
],
13891497
"responses": {
@@ -1436,6 +1544,48 @@
14361544
}
14371545
}
14381546
},
1547+
"/api/connections": {
1548+
"get": {
1549+
"operationId": "listConnections",
1550+
"tags": [
1551+
"Connections"
1552+
],
1553+
"summary": "List connections",
1554+
"description": "Returns unique code host connections associated with at least one repository visible to the caller. Connection configuration and credentials are never included.",
1555+
"responses": {
1556+
"200": {
1557+
"description": "Connections associated with visible repositories.",
1558+
"content": {
1559+
"application/json": {
1560+
"schema": {
1561+
"$ref": "#/components/schemas/PublicListConnectionsResponse"
1562+
}
1563+
}
1564+
}
1565+
},
1566+
"401": {
1567+
"description": "Authentication is required when anonymous access is disabled.",
1568+
"content": {
1569+
"application/json": {
1570+
"schema": {
1571+
"$ref": "#/components/schemas/PublicApiServiceError"
1572+
}
1573+
}
1574+
}
1575+
},
1576+
"500": {
1577+
"description": "Unexpected connection listing failure.",
1578+
"content": {
1579+
"application/json": {
1580+
"schema": {
1581+
"$ref": "#/components/schemas/PublicApiServiceError"
1582+
}
1583+
}
1584+
}
1585+
}
1586+
}
1587+
}
1588+
},
14391589
"/api/version": {
14401590
"get": {
14411591
"operationId": "getVersion",
@@ -2266,6 +2416,161 @@
22662416
}
22672417
}
22682418
},
2419+
"/api/ee/scoped_access_token": {
2420+
"post": {
2421+
"operationId": "createScopedAccessToken",
2422+
"tags": [
2423+
"Scoped Access Tokens"
2424+
],
2425+
"summary": "Create a scoped access token",
2426+
"description": "Creates an opaque bearer token that expires exactly one hour after issuance and is restricted to the requested repositories. Repository IDs are validated atomically against the API-key owner's current access; the request fails if any ID is missing or inaccessible. Repository IDs are returned by GET /api/repos.\n\nThis endpoint requires a Sourcebot API key. Scoped access tokens, OAuth tokens, and browser sessions cannot mint another scoped access token. The returned token is independent of the API key after issuance and cannot be refreshed.",
2427+
"security": [
2428+
{
2429+
"bearerToken": []
2430+
},
2431+
{
2432+
"apiKeyHeader": []
2433+
}
2434+
],
2435+
"requestBody": {
2436+
"required": true,
2437+
"content": {
2438+
"application/json": {
2439+
"schema": {
2440+
"$ref": "#/components/schemas/PublicCreateScopedAccessTokenRequest"
2441+
}
2442+
}
2443+
}
2444+
},
2445+
"responses": {
2446+
"201": {
2447+
"description": "Scoped access token created. The opaque token value is returned only in this response.",
2448+
"content": {
2449+
"application/json": {
2450+
"schema": {
2451+
"$ref": "#/components/schemas/PublicCreateScopedAccessTokenResponse"
2452+
}
2453+
}
2454+
}
2455+
},
2456+
"400": {
2457+
"description": "Invalid request body or repository scope.",
2458+
"content": {
2459+
"application/json": {
2460+
"schema": {
2461+
"$ref": "#/components/schemas/PublicApiServiceError"
2462+
}
2463+
}
2464+
}
2465+
},
2466+
"401": {
2467+
"description": "Missing or invalid authentication.",
2468+
"content": {
2469+
"application/json": {
2470+
"schema": {
2471+
"$ref": "#/components/schemas/PublicApiServiceError"
2472+
}
2473+
}
2474+
}
2475+
},
2476+
"403": {
2477+
"description": "The current authentication method is not an API key, or the API-key owner is not permitted to perform this operation.",
2478+
"content": {
2479+
"application/json": {
2480+
"schema": {
2481+
"$ref": "#/components/schemas/PublicApiServiceError"
2482+
}
2483+
}
2484+
}
2485+
},
2486+
"500": {
2487+
"description": "Unexpected token creation failure.",
2488+
"content": {
2489+
"application/json": {
2490+
"schema": {
2491+
"$ref": "#/components/schemas/PublicApiServiceError"
2492+
}
2493+
}
2494+
}
2495+
}
2496+
}
2497+
}
2498+
},
2499+
"/api/ee/scoped_access_token/{id}": {
2500+
"delete": {
2501+
"operationId": "revokeScopedAccessToken",
2502+
"tags": [
2503+
"Scoped Access Tokens"
2504+
],
2505+
"summary": "Revoke a scoped access token",
2506+
"description": "Immediately revokes a scoped access token created by the authenticated API-key owner. This endpoint requires a Sourcebot API key.",
2507+
"security": [
2508+
{
2509+
"bearerToken": []
2510+
},
2511+
{
2512+
"apiKeyHeader": []
2513+
}
2514+
],
2515+
"parameters": [
2516+
{
2517+
"schema": {
2518+
"type": "string",
2519+
"description": "Identifier returned when the scoped access token was created."
2520+
},
2521+
"required": true,
2522+
"description": "Identifier returned when the scoped access token was created.",
2523+
"name": "id",
2524+
"in": "path"
2525+
}
2526+
],
2527+
"responses": {
2528+
"204": {
2529+
"description": "Scoped access token revoked."
2530+
},
2531+
"401": {
2532+
"description": "Missing or invalid authentication.",
2533+
"content": {
2534+
"application/json": {
2535+
"schema": {
2536+
"$ref": "#/components/schemas/PublicApiServiceError"
2537+
}
2538+
}
2539+
}
2540+
},
2541+
"403": {
2542+
"description": "The current authentication method is not an API key, or the API-key owner is not permitted to perform this operation.",
2543+
"content": {
2544+
"application/json": {
2545+
"schema": {
2546+
"$ref": "#/components/schemas/PublicApiServiceError"
2547+
}
2548+
}
2549+
}
2550+
},
2551+
"404": {
2552+
"description": "Scoped access token not found.",
2553+
"content": {
2554+
"application/json": {
2555+
"schema": {
2556+
"$ref": "#/components/schemas/PublicApiServiceError"
2557+
}
2558+
}
2559+
}
2560+
},
2561+
"500": {
2562+
"description": "Unexpected token revocation failure.",
2563+
"content": {
2564+
"application/json": {
2565+
"schema": {
2566+
"$ref": "#/components/schemas/PublicApiServiceError"
2567+
}
2568+
}
2569+
}
2570+
}
2571+
}
2572+
}
2573+
},
22692574
"/api/ee/user": {
22702575
"get": {
22712576
"operationId": "getUser",

0 commit comments

Comments
 (0)