chore(web): Add telemetry for all api requests - #835

Merged
brendan-kellam merged 4 commits into
mainfrom
bkellam/api-events
Feb 1, 2026
Merged

chore(web): Add telemetry for all api requests#835
brendan-kellam merged 4 commits into
mainfrom
bkellam/api-events

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

This PR adds a api_request event that is fired for any api route that uses the apiHandler factory. The event includes a path and source. The source is sourced from the X-Sourcebot-Client-Source header

Summary by CodeRabbit

  • New Features

    • Centralized API handler wrapper that can emit lightweight API-request tracking events.
  • Improvements

    • Requests now include a client-source header for clearer client identification.
    • Removed redundant in-body source fields from search and suggestion requests to streamline payloads.
    • Added a new analytics event for API requests to improve usage insights.

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions

This comment has been minimized.

@coderabbitai

coderabbitaiBot commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@brendan-kellam has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 16 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

Migrates source identification from request bodies to the X-Sourcebot-Client-Source header across clients and routes, and introduces an apiHandler wrapper on many server routes that optionally emits api_request PostHog events.

Changes

Cohort / File(s)Summary
API handler & events
packages/web/src/lib/apiHandler.ts, packages/web/src/lib/posthogEvents.ts
Adds apiHandler wrapper that optionally tracks requests to PostHog and a new api_request event type.
MCP client & schemas
packages/mcp/src/client.ts, packages/mcp/src/schemas.ts, packages/mcp/src/index.ts
Adds X-Sourcebot-Client-Source: mcp header to MCP client requests and removes optional source from MCP search schema/index usage.
Web client headers & schemas
packages/web/src/app/api/(client)/client.ts, packages/web/src/app/[domain]/search/useStreamedSearch.ts, packages/web/src/features/search/types.ts, packages/web/src/app/[domain]/components/searchBar/useSuggestionsData.ts, packages/web/src/features/chat/components/chatBox/useSuggestionsData.ts
Adds X-Sourcebot-Client-Source: sourcebot-web-client header to client calls/streaming; removes source fields from request bodies/schemas.
Server routes (wrapped)
packages/web/src/app/api/(server)/**, packages/web/src/app/api/[domain]/repos/[repoId]/image/route.ts
Replaces many exported route handlers with apiHandler(...) wrapped handlers; several routes now read source from X-Sourcebot-Client-Source header (default 'unknown') and use centralized tracking/error plumbing.
Client-side API calls (web)
packages/web/src/app/api/(client)/client.ts
Adds X-Sourcebot-Client-Source header to multiple client-side API functions (search, getFileSource, listRepos, getVersion, findSearchBasedSymbolReferences/Definitions, getTree, getFiles).

Sequence Diagram(s)

sequenceDiagram
participant Client
participant ServerRoute
participant apiHandler as apiHandler (wrapper)
participant PostHog
Client->>ServerRoute: HTTP request (includes X-Sourcebot-Client-Source)
ServerRoute->>apiHandler: invoked (wrapper receives req)
apiHandler-->>PostHog: async emit api_request { path, source } rgba(100,150,250,0.5)
apiHandler->>ServerRoute: forward to original handler
ServerRoute-->>Client: HTTP response (JSON / stream / file)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

sourcebot-team

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main objective of adding telemetry/api request tracking across all API routes via the apiHandler wrapper.
Docstring Coverage✅ PassedDocstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bkellam/api-events

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment threadpackages/mcp/src/client.ts Outdated

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@packages/mcp/src/client.ts`:
- Around line 110-133: Resolve the merge conflict markers around the askCodebase
implementation by removing the <<<<<<<, =======, and >>>>>>> lines and keeping
the correct askCodebase function body; ensure the file exports/defines the async
function askCodebase(request: AskCodebaseRequest): Promise<AskCodebaseResponse>
exactly as in the new block and call parseResponse(response,
askCodebaseResponseSchema). Also add or restore the necessary imports for
AskCodebaseRequest, AskCodebaseResponse, askCodebaseResponseSchema (and
parseResponse/env if missing) at the top of the file so the TypeScript compiles
without errors.
In `@packages/web/src/app/api/`(server)/repos/route.ts:
- Around line 1-13: The file contains Git conflict markers and duplicated
imports; remove the conflict markers (<<<<<<<, =======, >>>>>>>) and consolidate
imports into one block so each symbol is imported exactly once — keep required
symbols like apiHandler, buildLinkHeader, listReposQueryParamsSchema,
repositoryQuerySchema, queryParamsSchemaValidationError, serviceErrorResponse,
and isServiceError, and drop unused/old imports such as NextRequest, sew, or
withOptionalAuthV2 if they are not referenced elsewhere in this module; ensure
the final import block imports each identifier only once and re-run lint/type
checks.
🧹 Nitpick comments (1)
packages/web/src/app/[domain]/search/useStreamedSearch.ts (1)

120-125: Extract the source header name/value into a shared constant/helper.

Hard-coded literals here can drift from other API calls; centralizing the header name/value makes future updates safer and more consistent.

♻️ Example refactor
+const SOURCEBOT_CLIENT_SOURCE_HEADER = 'X-Sourcebot-Client-Source';+const SOURCEBOT_WEB_CLIENT_SOURCE = 'sourcebot-web-client';+
// ...
const response = await fetch('/api/stream_search', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
- 'X-Sourcebot-Client-Source': 'sourcebot-web-client',+ [SOURCEBOT_CLIENT_SOURCE_HEADER]: SOURCEBOT_WEB_CLIENT_SOURCE,
},

Comment threadpackages/mcp/src/client.ts Outdated
Comment threadpackages/web/src/app/api/(server)/repos/route.ts Outdated
@claude

claudeBot commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Code review

This PR contains 2 critical issues - unresolved git merge conflicts that will prevent the code from compiling:

Issue 1: Merge conflict in packages/mcp/src/client.ts

Location: Lines 110-133
Link:https://github.com/sourcebot-dev/sourcebot/blob/891737e89ce9ccf251b6397d766687a94678e80c/packages/mcp/src/client.ts#L109-L134

The file contains unresolved merge conflict markers:

<<<<<<< Updated upstream
=======
... askCodebase function ...
>>>>>>> Stashed changes

This will cause a syntax error. The conflict needs to be resolved by deciding whether to keep, remove, or merge the askCodebase function.

Issue 2: Merge conflict in packages/web/src/app/api/(server)/repos/route.ts

Location: Lines 1-9 (imports section)
Link:

<<<<<<<Updatedupstream
import{NextRequest}from "next/server";
import{sew}from "@/actions";
import{withOptionalAuthV2}from "@/withAuthV2";
=======
import{apiHandler}from"@/lib/apiHandler";
import{buildLinkHeader}from"@/lib/pagination";
import{listReposQueryParamsSchema}from"@/lib/schemas";
>>>>>>>Stashedchanges
import{queryParamsSchemaValidationError,serviceErrorResponse}from"@/lib/serviceError";
import{isServiceError}from"@/lib/utils";
import{listReposQueryParamsSchema,repositoryQuerySchema}from"@/lib/schemas";
import{buildLinkHeader}from"@/lib/pagination";
import{getBrowsePath}from"@/app/[domain]/browse/hooks/utils";

The import section contains unresolved merge conflict markers:

<<<<<<< Updated upstream
import { NextRequest } from "next/server";
import { sew } from "@/actions";
import { withOptionalAuthV2 } from "@/withAuthV2";
=======
import { apiHandler } from "@/lib/apiHandler";
import { buildLinkHeader } from "@/lib/pagination";
import { listReposQueryParamsSchema } from "@/lib/schemas";
>>>>>>> Stashed changes

This will cause a syntax error. After the conflict markers, there are also duplicate imports that should be cleaned up once the conflict is resolved.


Action required: Please resolve these merge conflicts before the PR can be merged.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/web/src/app/api/(server)/repos/route.ts (1)

42-44: ⚠️ Potential issue | 🟠 Major

Count query is missing the query filter, causing incorrect pagination.

The findMany query applies the query filter (line 34-36), but the count query only filters by orgId. This means totalCount will be the total repos for the org, not the filtered count, resulting in incorrect X-Total-Count and Link pagination headers when a search query is provided.

🐛 Proposed fix to include the query filter in count
 prisma.repo.count({
- where: { orgId: org.id },+ where: {+ orgId: org.id,+ ...(query ? {+ name: { contains: query, mode: 'insensitive' },+ } : {}),+ },
}),

@brendan-kellam
brendan-kellam merged commit 6b79cbf into mainFeb 1, 2026
9 checks passed
@brendan-kellam
brendan-kellam deleted the bkellam/api-events branch February 1, 2026 05:18
@github-actionsgithub-actionsBot mentioned this pull request Feb 1, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 1, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 13, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content

chore(web): Add telemetry for all api requests - #835

Merged
brendan-kellam merged 4 commits into
mainfrom
bkellam/api-events
Feb 1, 2026
Merged

chore(web): Add telemetry for all api requests#835
brendan-kellam merged 4 commits into
mainfrom
bkellam/api-events

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

This PR adds a api_request event that is fired for any api route that uses the apiHandler factory. The event includes a path and source. The source is sourced from the X-Sourcebot-Client-Source header

Summary by CodeRabbit

  • New Features

    • Centralized API handler wrapper that can emit lightweight API-request tracking events.
  • Improvements

    • Requests now include a client-source header for clearer client identification.
    • Removed redundant in-body source fields from search and suggestion requests to streamline payloads.
    • Added a new analytics event for API requests to improve usage insights.

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions

This comment has been minimized.

@coderabbitai

coderabbitaiBot commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@brendan-kellam has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 16 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

Migrates source identification from request bodies to the X-Sourcebot-Client-Source header across clients and routes, and introduces an apiHandler wrapper on many server routes that optionally emits api_request PostHog events.

Changes

Cohort / File(s)Summary
API handler & events
packages/web/src/lib/apiHandler.ts, packages/web/src/lib/posthogEvents.ts
Adds apiHandler wrapper that optionally tracks requests to PostHog and a new api_request event type.
MCP client & schemas
packages/mcp/src/client.ts, packages/mcp/src/schemas.ts, packages/mcp/src/index.ts
Adds X-Sourcebot-Client-Source: mcp header to MCP client requests and removes optional source from MCP search schema/index usage.
Web client headers & schemas
packages/web/src/app/api/(client)/client.ts, packages/web/src/app/[domain]/search/useStreamedSearch.ts, packages/web/src/features/search/types.ts, packages/web/src/app/[domain]/components/searchBar/useSuggestionsData.ts, packages/web/src/features/chat/components/chatBox/useSuggestionsData.ts
Adds X-Sourcebot-Client-Source: sourcebot-web-client header to client calls/streaming; removes source fields from request bodies/schemas.
Server routes (wrapped)
packages/web/src/app/api/(server)/**, packages/web/src/app/api/[domain]/repos/[repoId]/image/route.ts
Replaces many exported route handlers with apiHandler(...) wrapped handlers; several routes now read source from X-Sourcebot-Client-Source header (default 'unknown') and use centralized tracking/error plumbing.
Client-side API calls (web)
packages/web/src/app/api/(client)/client.ts
Adds X-Sourcebot-Client-Source header to multiple client-side API functions (search, getFileSource, listRepos, getVersion, findSearchBasedSymbolReferences/Definitions, getTree, getFiles).

Sequence Diagram(s)

sequenceDiagram
participant Client
participant ServerRoute
participant apiHandler as apiHandler (wrapper)
participant PostHog
Client->>ServerRoute: HTTP request (includes X-Sourcebot-Client-Source)
ServerRoute->>apiHandler: invoked (wrapper receives req)
apiHandler-->>PostHog: async emit api_request { path, source } rgba(100,150,250,0.5)
apiHandler->>ServerRoute: forward to original handler
ServerRoute-->>Client: HTTP response (JSON / stream / file)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

sourcebot-team

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main objective of adding telemetry/api request tracking across all API routes via the apiHandler wrapper.
Docstring Coverage✅ PassedDocstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bkellam/api-events

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment threadpackages/mcp/src/client.ts Outdated

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@packages/mcp/src/client.ts`:
- Around line 110-133: Resolve the merge conflict markers around the askCodebase
implementation by removing the <<<<<<<, =======, and >>>>>>> lines and keeping
the correct askCodebase function body; ensure the file exports/defines the async
function askCodebase(request: AskCodebaseRequest): Promise<AskCodebaseResponse>
exactly as in the new block and call parseResponse(response,
askCodebaseResponseSchema). Also add or restore the necessary imports for
AskCodebaseRequest, AskCodebaseResponse, askCodebaseResponseSchema (and
parseResponse/env if missing) at the top of the file so the TypeScript compiles
without errors.
In `@packages/web/src/app/api/`(server)/repos/route.ts:
- Around line 1-13: The file contains Git conflict markers and duplicated
imports; remove the conflict markers (<<<<<<<, =======, >>>>>>>) and consolidate
imports into one block so each symbol is imported exactly once — keep required
symbols like apiHandler, buildLinkHeader, listReposQueryParamsSchema,
repositoryQuerySchema, queryParamsSchemaValidationError, serviceErrorResponse,
and isServiceError, and drop unused/old imports such as NextRequest, sew, or
withOptionalAuthV2 if they are not referenced elsewhere in this module; ensure
the final import block imports each identifier only once and re-run lint/type
checks.
🧹 Nitpick comments (1)
packages/web/src/app/[domain]/search/useStreamedSearch.ts (1)

120-125: Extract the source header name/value into a shared constant/helper.

Hard-coded literals here can drift from other API calls; centralizing the header name/value makes future updates safer and more consistent.

♻️ Example refactor
+const SOURCEBOT_CLIENT_SOURCE_HEADER = 'X-Sourcebot-Client-Source';+const SOURCEBOT_WEB_CLIENT_SOURCE = 'sourcebot-web-client';+
// ...
const response = await fetch('/api/stream_search', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
- 'X-Sourcebot-Client-Source': 'sourcebot-web-client',+ [SOURCEBOT_CLIENT_SOURCE_HEADER]: SOURCEBOT_WEB_CLIENT_SOURCE,
},

Comment threadpackages/mcp/src/client.ts Outdated
Comment threadpackages/web/src/app/api/(server)/repos/route.ts Outdated
@claude

claudeBot commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Code review

This PR contains 2 critical issues - unresolved git merge conflicts that will prevent the code from compiling:

Issue 1: Merge conflict in packages/mcp/src/client.ts

Location: Lines 110-133
Link:https://github.com/sourcebot-dev/sourcebot/blob/891737e89ce9ccf251b6397d766687a94678e80c/packages/mcp/src/client.ts#L109-L134

The file contains unresolved merge conflict markers:

<<<<<<< Updated upstream
=======
... askCodebase function ...
>>>>>>> Stashed changes

This will cause a syntax error. The conflict needs to be resolved by deciding whether to keep, remove, or merge the askCodebase function.

Issue 2: Merge conflict in packages/web/src/app/api/(server)/repos/route.ts

Location: Lines 1-9 (imports section)
Link:

<<<<<<<Updatedupstream
import{NextRequest}from "next/server";
import{sew}from "@/actions";
import{withOptionalAuthV2}from "@/withAuthV2";
=======
import{apiHandler}from"@/lib/apiHandler";
import{buildLinkHeader}from"@/lib/pagination";
import{listReposQueryParamsSchema}from"@/lib/schemas";
>>>>>>>Stashedchanges
import{queryParamsSchemaValidationError,serviceErrorResponse}from"@/lib/serviceError";
import{isServiceError}from"@/lib/utils";
import{listReposQueryParamsSchema,repositoryQuerySchema}from"@/lib/schemas";
import{buildLinkHeader}from"@/lib/pagination";
import{getBrowsePath}from"@/app/[domain]/browse/hooks/utils";

The import section contains unresolved merge conflict markers:

<<<<<<< Updated upstream
import { NextRequest } from "next/server";
import { sew } from "@/actions";
import { withOptionalAuthV2 } from "@/withAuthV2";
=======
import { apiHandler } from "@/lib/apiHandler";
import { buildLinkHeader } from "@/lib/pagination";
import { listReposQueryParamsSchema } from "@/lib/schemas";
>>>>>>> Stashed changes

This will cause a syntax error. After the conflict markers, there are also duplicate imports that should be cleaned up once the conflict is resolved.


Action required: Please resolve these merge conflicts before the PR can be merged.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/web/src/app/api/(server)/repos/route.ts (1)

42-44: ⚠️ Potential issue | 🟠 Major

Count query is missing the query filter, causing incorrect pagination.

The findMany query applies the query filter (line 34-36), but the count query only filters by orgId. This means totalCount will be the total repos for the org, not the filtered count, resulting in incorrect X-Total-Count and Link pagination headers when a search query is provided.

🐛 Proposed fix to include the query filter in count
 prisma.repo.count({
- where: { orgId: org.id },+ where: {+ orgId: org.id,+ ...(query ? {+ name: { contains: query, mode: 'insensitive' },+ } : {}),+ },
}),

@brendan-kellam
brendan-kellam merged commit 6b79cbf into mainFeb 1, 2026
9 checks passed
@brendan-kellam
brendan-kellam deleted the bkellam/api-events branch February 1, 2026 05:18
@github-actionsgithub-actionsBot mentioned this pull request Feb 1, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 1, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 13, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(web): Add telemetry for all api requests - #835

Merged
brendan-kellam merged 4 commits into
mainfrom
bkellam/api-events
Feb 1, 2026
Merged

chore(web): Add telemetry for all api requests#835
brendan-kellam merged 4 commits into
mainfrom
bkellam/api-events

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

This PR adds a api_request event that is fired for any api route that uses the apiHandler factory. The event includes a path and source. The source is sourced from the X-Sourcebot-Client-Source header

Summary by CodeRabbit

  • New Features

    • Centralized API handler wrapper that can emit lightweight API-request tracking events.
  • Improvements

    • Requests now include a client-source header for clearer client identification.
    • Removed redundant in-body source fields from search and suggestion requests to streamline payloads.
    • Added a new analytics event for API requests to improve usage insights.

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions

This comment has been minimized.

@coderabbitai

coderabbitaiBot commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@brendan-kellam has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 16 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

Migrates source identification from request bodies to the X-Sourcebot-Client-Source header across clients and routes, and introduces an apiHandler wrapper on many server routes that optionally emits api_request PostHog events.

Changes

Cohort / File(s)Summary
API handler & events
packages/web/src/lib/apiHandler.ts, packages/web/src/lib/posthogEvents.ts
Adds apiHandler wrapper that optionally tracks requests to PostHog and a new api_request event type.
MCP client & schemas
packages/mcp/src/client.ts, packages/mcp/src/schemas.ts, packages/mcp/src/index.ts
Adds X-Sourcebot-Client-Source: mcp header to MCP client requests and removes optional source from MCP search schema/index usage.
Web client headers & schemas
packages/web/src/app/api/(client)/client.ts, packages/web/src/app/[domain]/search/useStreamedSearch.ts, packages/web/src/features/search/types.ts, packages/web/src/app/[domain]/components/searchBar/useSuggestionsData.ts, packages/web/src/features/chat/components/chatBox/useSuggestionsData.ts
Adds X-Sourcebot-Client-Source: sourcebot-web-client header to client calls/streaming; removes source fields from request bodies/schemas.
Server routes (wrapped)
packages/web/src/app/api/(server)/**, packages/web/src/app/api/[domain]/repos/[repoId]/image/route.ts
Replaces many exported route handlers with apiHandler(...) wrapped handlers; several routes now read source from X-Sourcebot-Client-Source header (default 'unknown') and use centralized tracking/error plumbing.
Client-side API calls (web)
packages/web/src/app/api/(client)/client.ts
Adds X-Sourcebot-Client-Source header to multiple client-side API functions (search, getFileSource, listRepos, getVersion, findSearchBasedSymbolReferences/Definitions, getTree, getFiles).

Sequence Diagram(s)

sequenceDiagram
participant Client
participant ServerRoute
participant apiHandler as apiHandler (wrapper)
participant PostHog
Client->>ServerRoute: HTTP request (includes X-Sourcebot-Client-Source)
ServerRoute->>apiHandler: invoked (wrapper receives req)
apiHandler-->>PostHog: async emit api_request { path, source } rgba(100,150,250,0.5)
apiHandler->>ServerRoute: forward to original handler
ServerRoute-->>Client: HTTP response (JSON / stream / file)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

sourcebot-team

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main objective of adding telemetry/api request tracking across all API routes via the apiHandler wrapper.
Docstring Coverage✅ PassedDocstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bkellam/api-events

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment threadpackages/mcp/src/client.ts Outdated

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@packages/mcp/src/client.ts`:
- Around line 110-133: Resolve the merge conflict markers around the askCodebase
implementation by removing the <<<<<<<, =======, and >>>>>>> lines and keeping
the correct askCodebase function body; ensure the file exports/defines the async
function askCodebase(request: AskCodebaseRequest): Promise<AskCodebaseResponse>
exactly as in the new block and call parseResponse(response,
askCodebaseResponseSchema). Also add or restore the necessary imports for
AskCodebaseRequest, AskCodebaseResponse, askCodebaseResponseSchema (and
parseResponse/env if missing) at the top of the file so the TypeScript compiles
without errors.
In `@packages/web/src/app/api/`(server)/repos/route.ts:
- Around line 1-13: The file contains Git conflict markers and duplicated
imports; remove the conflict markers (<<<<<<<, =======, >>>>>>>) and consolidate
imports into one block so each symbol is imported exactly once — keep required
symbols like apiHandler, buildLinkHeader, listReposQueryParamsSchema,
repositoryQuerySchema, queryParamsSchemaValidationError, serviceErrorResponse,
and isServiceError, and drop unused/old imports such as NextRequest, sew, or
withOptionalAuthV2 if they are not referenced elsewhere in this module; ensure
the final import block imports each identifier only once and re-run lint/type
checks.
🧹 Nitpick comments (1)
packages/web/src/app/[domain]/search/useStreamedSearch.ts (1)

120-125: Extract the source header name/value into a shared constant/helper.

Hard-coded literals here can drift from other API calls; centralizing the header name/value makes future updates safer and more consistent.

♻️ Example refactor
+const SOURCEBOT_CLIENT_SOURCE_HEADER = 'X-Sourcebot-Client-Source';+const SOURCEBOT_WEB_CLIENT_SOURCE = 'sourcebot-web-client';+
// ...
const response = await fetch('/api/stream_search', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
- 'X-Sourcebot-Client-Source': 'sourcebot-web-client',+ [SOURCEBOT_CLIENT_SOURCE_HEADER]: SOURCEBOT_WEB_CLIENT_SOURCE,
},

Comment threadpackages/mcp/src/client.ts Outdated
Comment threadpackages/web/src/app/api/(server)/repos/route.ts Outdated
@claude

claudeBot commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Code review

This PR contains 2 critical issues - unresolved git merge conflicts that will prevent the code from compiling:

Issue 1: Merge conflict in packages/mcp/src/client.ts

Location: Lines 110-133
Link:https://github.com/sourcebot-dev/sourcebot/blob/891737e89ce9ccf251b6397d766687a94678e80c/packages/mcp/src/client.ts#L109-L134

The file contains unresolved merge conflict markers:

<<<<<<< Updated upstream
=======
... askCodebase function ...
>>>>>>> Stashed changes

This will cause a syntax error. The conflict needs to be resolved by deciding whether to keep, remove, or merge the askCodebase function.

Issue 2: Merge conflict in packages/web/src/app/api/(server)/repos/route.ts

Location: Lines 1-9 (imports section)
Link:

<<<<<<<Updatedupstream
import{NextRequest}from "next/server";
import{sew}from "@/actions";
import{withOptionalAuthV2}from "@/withAuthV2";
=======
import{apiHandler}from"@/lib/apiHandler";
import{buildLinkHeader}from"@/lib/pagination";
import{listReposQueryParamsSchema}from"@/lib/schemas";
>>>>>>>Stashedchanges
import{queryParamsSchemaValidationError,serviceErrorResponse}from"@/lib/serviceError";
import{isServiceError}from"@/lib/utils";
import{listReposQueryParamsSchema,repositoryQuerySchema}from"@/lib/schemas";
import{buildLinkHeader}from"@/lib/pagination";
import{getBrowsePath}from"@/app/[domain]/browse/hooks/utils";

The import section contains unresolved merge conflict markers:

<<<<<<< Updated upstream
import { NextRequest } from "next/server";
import { sew } from "@/actions";
import { withOptionalAuthV2 } from "@/withAuthV2";
=======
import { apiHandler } from "@/lib/apiHandler";
import { buildLinkHeader } from "@/lib/pagination";
import { listReposQueryParamsSchema } from "@/lib/schemas";
>>>>>>> Stashed changes

This will cause a syntax error. After the conflict markers, there are also duplicate imports that should be cleaned up once the conflict is resolved.


Action required: Please resolve these merge conflicts before the PR can be merged.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/web/src/app/api/(server)/repos/route.ts (1)

42-44: ⚠️ Potential issue | 🟠 Major

Count query is missing the query filter, causing incorrect pagination.

The findMany query applies the query filter (line 34-36), but the count query only filters by orgId. This means totalCount will be the total repos for the org, not the filtered count, resulting in incorrect X-Total-Count and Link pagination headers when a search query is provided.

🐛 Proposed fix to include the query filter in count
 prisma.repo.count({
- where: { orgId: org.id },+ where: {+ orgId: org.id,+ ...(query ? {+ name: { contains: query, mode: 'insensitive' },+ } : {}),+ },
}),

@brendan-kellam
brendan-kellam merged commit 6b79cbf into mainFeb 1, 2026
9 checks passed
@brendan-kellam
brendan-kellam deleted the bkellam/api-events branch February 1, 2026 05:18
@github-actionsgithub-actionsBot mentioned this pull request Feb 1, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 1, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 13, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(web): Add telemetry for all api requests - #835

Merged
brendan-kellam merged 4 commits into
mainfrom
bkellam/api-events
Feb 1, 2026
Merged

chore(web): Add telemetry for all api requests#835
brendan-kellam merged 4 commits into
mainfrom
bkellam/api-events

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

This PR adds a api_request event that is fired for any api route that uses the apiHandler factory. The event includes a path and source. The source is sourced from the X-Sourcebot-Client-Source header

Summary by CodeRabbit

  • New Features

    • Centralized API handler wrapper that can emit lightweight API-request tracking events.
  • Improvements

    • Requests now include a client-source header for clearer client identification.
    • Removed redundant in-body source fields from search and suggestion requests to streamline payloads.
    • Added a new analytics event for API requests to improve usage insights.

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions

This comment has been minimized.

@coderabbitai

coderabbitaiBot commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@brendan-kellam has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 16 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

Migrates source identification from request bodies to the X-Sourcebot-Client-Source header across clients and routes, and introduces an apiHandler wrapper on many server routes that optionally emits api_request PostHog events.

Changes

Cohort / File(s)Summary
API handler & events
packages/web/src/lib/apiHandler.ts, packages/web/src/lib/posthogEvents.ts
Adds apiHandler wrapper that optionally tracks requests to PostHog and a new api_request event type.
MCP client & schemas
packages/mcp/src/client.ts, packages/mcp/src/schemas.ts, packages/mcp/src/index.ts
Adds X-Sourcebot-Client-Source: mcp header to MCP client requests and removes optional source from MCP search schema/index usage.
Web client headers & schemas
packages/web/src/app/api/(client)/client.ts, packages/web/src/app/[domain]/search/useStreamedSearch.ts, packages/web/src/features/search/types.ts, packages/web/src/app/[domain]/components/searchBar/useSuggestionsData.ts, packages/web/src/features/chat/components/chatBox/useSuggestionsData.ts
Adds X-Sourcebot-Client-Source: sourcebot-web-client header to client calls/streaming; removes source fields from request bodies/schemas.
Server routes (wrapped)
packages/web/src/app/api/(server)/**, packages/web/src/app/api/[domain]/repos/[repoId]/image/route.ts
Replaces many exported route handlers with apiHandler(...) wrapped handlers; several routes now read source from X-Sourcebot-Client-Source header (default 'unknown') and use centralized tracking/error plumbing.
Client-side API calls (web)
packages/web/src/app/api/(client)/client.ts
Adds X-Sourcebot-Client-Source header to multiple client-side API functions (search, getFileSource, listRepos, getVersion, findSearchBasedSymbolReferences/Definitions, getTree, getFiles).

Sequence Diagram(s)

sequenceDiagram
participant Client
participant ServerRoute
participant apiHandler as apiHandler (wrapper)
participant PostHog
Client->>ServerRoute: HTTP request (includes X-Sourcebot-Client-Source)
ServerRoute->>apiHandler: invoked (wrapper receives req)
apiHandler-->>PostHog: async emit api_request { path, source } rgba(100,150,250,0.5)
apiHandler->>ServerRoute: forward to original handler
ServerRoute-->>Client: HTTP response (JSON / stream / file)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

sourcebot-team

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main objective of adding telemetry/api request tracking across all API routes via the apiHandler wrapper.
Docstring Coverage✅ PassedDocstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bkellam/api-events

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment threadpackages/mcp/src/client.ts Outdated

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@packages/mcp/src/client.ts`:
- Around line 110-133: Resolve the merge conflict markers around the askCodebase
implementation by removing the <<<<<<<, =======, and >>>>>>> lines and keeping
the correct askCodebase function body; ensure the file exports/defines the async
function askCodebase(request: AskCodebaseRequest): Promise<AskCodebaseResponse>
exactly as in the new block and call parseResponse(response,
askCodebaseResponseSchema). Also add or restore the necessary imports for
AskCodebaseRequest, AskCodebaseResponse, askCodebaseResponseSchema (and
parseResponse/env if missing) at the top of the file so the TypeScript compiles
without errors.
In `@packages/web/src/app/api/`(server)/repos/route.ts:
- Around line 1-13: The file contains Git conflict markers and duplicated
imports; remove the conflict markers (<<<<<<<, =======, >>>>>>>) and consolidate
imports into one block so each symbol is imported exactly once — keep required
symbols like apiHandler, buildLinkHeader, listReposQueryParamsSchema,
repositoryQuerySchema, queryParamsSchemaValidationError, serviceErrorResponse,
and isServiceError, and drop unused/old imports such as NextRequest, sew, or
withOptionalAuthV2 if they are not referenced elsewhere in this module; ensure
the final import block imports each identifier only once and re-run lint/type
checks.
🧹 Nitpick comments (1)
packages/web/src/app/[domain]/search/useStreamedSearch.ts (1)

120-125: Extract the source header name/value into a shared constant/helper.

Hard-coded literals here can drift from other API calls; centralizing the header name/value makes future updates safer and more consistent.

♻️ Example refactor
+const SOURCEBOT_CLIENT_SOURCE_HEADER = 'X-Sourcebot-Client-Source';+const SOURCEBOT_WEB_CLIENT_SOURCE = 'sourcebot-web-client';+
// ...
const response = await fetch('/api/stream_search', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
- 'X-Sourcebot-Client-Source': 'sourcebot-web-client',+ [SOURCEBOT_CLIENT_SOURCE_HEADER]: SOURCEBOT_WEB_CLIENT_SOURCE,
},

Comment threadpackages/mcp/src/client.ts Outdated
Comment threadpackages/web/src/app/api/(server)/repos/route.ts Outdated
@claude

claudeBot commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Code review

This PR contains 2 critical issues - unresolved git merge conflicts that will prevent the code from compiling:

Issue 1: Merge conflict in packages/mcp/src/client.ts

Location: Lines 110-133
Link:https://github.com/sourcebot-dev/sourcebot/blob/891737e89ce9ccf251b6397d766687a94678e80c/packages/mcp/src/client.ts#L109-L134

The file contains unresolved merge conflict markers:

<<<<<<< Updated upstream
=======
... askCodebase function ...
>>>>>>> Stashed changes

This will cause a syntax error. The conflict needs to be resolved by deciding whether to keep, remove, or merge the askCodebase function.

Issue 2: Merge conflict in packages/web/src/app/api/(server)/repos/route.ts

Location: Lines 1-9 (imports section)
Link:

<<<<<<<Updatedupstream
import{NextRequest}from "next/server";
import{sew}from "@/actions";
import{withOptionalAuthV2}from "@/withAuthV2";
=======
import{apiHandler}from"@/lib/apiHandler";
import{buildLinkHeader}from"@/lib/pagination";
import{listReposQueryParamsSchema}from"@/lib/schemas";
>>>>>>>Stashedchanges
import{queryParamsSchemaValidationError,serviceErrorResponse}from"@/lib/serviceError";
import{isServiceError}from"@/lib/utils";
import{listReposQueryParamsSchema,repositoryQuerySchema}from"@/lib/schemas";
import{buildLinkHeader}from"@/lib/pagination";
import{getBrowsePath}from"@/app/[domain]/browse/hooks/utils";

The import section contains unresolved merge conflict markers:

<<<<<<< Updated upstream
import { NextRequest } from "next/server";
import { sew } from "@/actions";
import { withOptionalAuthV2 } from "@/withAuthV2";
=======
import { apiHandler } from "@/lib/apiHandler";
import { buildLinkHeader } from "@/lib/pagination";
import { listReposQueryParamsSchema } from "@/lib/schemas";
>>>>>>> Stashed changes

This will cause a syntax error. After the conflict markers, there are also duplicate imports that should be cleaned up once the conflict is resolved.


Action required: Please resolve these merge conflicts before the PR can be merged.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/web/src/app/api/(server)/repos/route.ts (1)

42-44: ⚠️ Potential issue | 🟠 Major

Count query is missing the query filter, causing incorrect pagination.

The findMany query applies the query filter (line 34-36), but the count query only filters by orgId. This means totalCount will be the total repos for the org, not the filtered count, resulting in incorrect X-Total-Count and Link pagination headers when a search query is provided.

🐛 Proposed fix to include the query filter in count
 prisma.repo.count({
- where: { orgId: org.id },+ where: {+ orgId: org.id,+ ...(query ? {+ name: { contains: query, mode: 'insensitive' },+ } : {}),+ },
}),

@brendan-kellam
brendan-kellam merged commit 6b79cbf into mainFeb 1, 2026
9 checks passed
@brendan-kellam
brendan-kellam deleted the bkellam/api-events branch February 1, 2026 05:18
@github-actionsgithub-actionsBot mentioned this pull request Feb 1, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 1, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 13, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

chore(web): Add telemetry for all api requests - #835

Merged
brendan-kellam merged 4 commits into
mainfrom
bkellam/api-events
Feb 1, 2026
Merged

chore(web): Add telemetry for all api requests#835
brendan-kellam merged 4 commits into
mainfrom
bkellam/api-events

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

This PR adds a api_request event that is fired for any api route that uses the apiHandler factory. The event includes a path and source. The source is sourced from the X-Sourcebot-Client-Source header

Summary by CodeRabbit

  • New Features

    • Centralized API handler wrapper that can emit lightweight API-request tracking events.
  • Improvements

    • Requests now include a client-source header for clearer client identification.
    • Removed redundant in-body source fields from search and suggestion requests to streamline payloads.
    • Added a new analytics event for API requests to improve usage insights.

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions

This comment has been minimized.

@coderabbitai

coderabbitaiBot commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@brendan-kellam has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 16 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

Migrates source identification from request bodies to the X-Sourcebot-Client-Source header across clients and routes, and introduces an apiHandler wrapper on many server routes that optionally emits api_request PostHog events.

Changes

Cohort / File(s)Summary
API handler & events
packages/web/src/lib/apiHandler.ts, packages/web/src/lib/posthogEvents.ts
Adds apiHandler wrapper that optionally tracks requests to PostHog and a new api_request event type.
MCP client & schemas
packages/mcp/src/client.ts, packages/mcp/src/schemas.ts, packages/mcp/src/index.ts
Adds X-Sourcebot-Client-Source: mcp header to MCP client requests and removes optional source from MCP search schema/index usage.
Web client headers & schemas
packages/web/src/app/api/(client)/client.ts, packages/web/src/app/[domain]/search/useStreamedSearch.ts, packages/web/src/features/search/types.ts, packages/web/src/app/[domain]/components/searchBar/useSuggestionsData.ts, packages/web/src/features/chat/components/chatBox/useSuggestionsData.ts
Adds X-Sourcebot-Client-Source: sourcebot-web-client header to client calls/streaming; removes source fields from request bodies/schemas.
Server routes (wrapped)
packages/web/src/app/api/(server)/**, packages/web/src/app/api/[domain]/repos/[repoId]/image/route.ts
Replaces many exported route handlers with apiHandler(...) wrapped handlers; several routes now read source from X-Sourcebot-Client-Source header (default 'unknown') and use centralized tracking/error plumbing.
Client-side API calls (web)
packages/web/src/app/api/(client)/client.ts
Adds X-Sourcebot-Client-Source header to multiple client-side API functions (search, getFileSource, listRepos, getVersion, findSearchBasedSymbolReferences/Definitions, getTree, getFiles).

Sequence Diagram(s)

sequenceDiagram
participant Client
participant ServerRoute
participant apiHandler as apiHandler (wrapper)
participant PostHog
Client->>ServerRoute: HTTP request (includes X-Sourcebot-Client-Source)
ServerRoute->>apiHandler: invoked (wrapper receives req)
apiHandler-->>PostHog: async emit api_request { path, source } rgba(100,150,250,0.5)
apiHandler->>ServerRoute: forward to original handler
ServerRoute-->>Client: HTTP response (JSON / stream / file)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

sourcebot-team

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main objective of adding telemetry/api request tracking across all API routes via the apiHandler wrapper.
Docstring Coverage✅ PassedDocstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bkellam/api-events

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment threadpackages/mcp/src/client.ts Outdated

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@packages/mcp/src/client.ts`:
- Around line 110-133: Resolve the merge conflict markers around the askCodebase
implementation by removing the <<<<<<<, =======, and >>>>>>> lines and keeping
the correct askCodebase function body; ensure the file exports/defines the async
function askCodebase(request: AskCodebaseRequest): Promise<AskCodebaseResponse>
exactly as in the new block and call parseResponse(response,
askCodebaseResponseSchema). Also add or restore the necessary imports for
AskCodebaseRequest, AskCodebaseResponse, askCodebaseResponseSchema (and
parseResponse/env if missing) at the top of the file so the TypeScript compiles
without errors.
In `@packages/web/src/app/api/`(server)/repos/route.ts:
- Around line 1-13: The file contains Git conflict markers and duplicated
imports; remove the conflict markers (<<<<<<<, =======, >>>>>>>) and consolidate
imports into one block so each symbol is imported exactly once — keep required
symbols like apiHandler, buildLinkHeader, listReposQueryParamsSchema,
repositoryQuerySchema, queryParamsSchemaValidationError, serviceErrorResponse,
and isServiceError, and drop unused/old imports such as NextRequest, sew, or
withOptionalAuthV2 if they are not referenced elsewhere in this module; ensure
the final import block imports each identifier only once and re-run lint/type
checks.
🧹 Nitpick comments (1)
packages/web/src/app/[domain]/search/useStreamedSearch.ts (1)

120-125: Extract the source header name/value into a shared constant/helper.

Hard-coded literals here can drift from other API calls; centralizing the header name/value makes future updates safer and more consistent.

♻️ Example refactor
+const SOURCEBOT_CLIENT_SOURCE_HEADER = 'X-Sourcebot-Client-Source';+const SOURCEBOT_WEB_CLIENT_SOURCE = 'sourcebot-web-client';+
// ...
const response = await fetch('/api/stream_search', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
- 'X-Sourcebot-Client-Source': 'sourcebot-web-client',+ [SOURCEBOT_CLIENT_SOURCE_HEADER]: SOURCEBOT_WEB_CLIENT_SOURCE,
},

Comment threadpackages/mcp/src/client.ts Outdated
Comment threadpackages/web/src/app/api/(server)/repos/route.ts Outdated
@claude

claudeBot commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Code review

This PR contains 2 critical issues - unresolved git merge conflicts that will prevent the code from compiling:

Issue 1: Merge conflict in packages/mcp/src/client.ts

Location: Lines 110-133
Link:https://github.com/sourcebot-dev/sourcebot/blob/891737e89ce9ccf251b6397d766687a94678e80c/packages/mcp/src/client.ts#L109-L134

The file contains unresolved merge conflict markers:

<<<<<<< Updated upstream
=======
... askCodebase function ...
>>>>>>> Stashed changes

This will cause a syntax error. The conflict needs to be resolved by deciding whether to keep, remove, or merge the askCodebase function.

Issue 2: Merge conflict in packages/web/src/app/api/(server)/repos/route.ts

Location: Lines 1-9 (imports section)
Link:

<<<<<<<Updatedupstream
import{NextRequest}from "next/server";
import{sew}from "@/actions";
import{withOptionalAuthV2}from "@/withAuthV2";
=======
import{apiHandler}from"@/lib/apiHandler";
import{buildLinkHeader}from"@/lib/pagination";
import{listReposQueryParamsSchema}from"@/lib/schemas";
>>>>>>>Stashedchanges
import{queryParamsSchemaValidationError,serviceErrorResponse}from"@/lib/serviceError";
import{isServiceError}from"@/lib/utils";
import{listReposQueryParamsSchema,repositoryQuerySchema}from"@/lib/schemas";
import{buildLinkHeader}from"@/lib/pagination";
import{getBrowsePath}from"@/app/[domain]/browse/hooks/utils";

The import section contains unresolved merge conflict markers:

<<<<<<< Updated upstream
import { NextRequest } from "next/server";
import { sew } from "@/actions";
import { withOptionalAuthV2 } from "@/withAuthV2";
=======
import { apiHandler } from "@/lib/apiHandler";
import { buildLinkHeader } from "@/lib/pagination";
import { listReposQueryParamsSchema } from "@/lib/schemas";
>>>>>>> Stashed changes

This will cause a syntax error. After the conflict markers, there are also duplicate imports that should be cleaned up once the conflict is resolved.


Action required: Please resolve these merge conflicts before the PR can be merged.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/web/src/app/api/(server)/repos/route.ts (1)

42-44: ⚠️ Potential issue | 🟠 Major

Count query is missing the query filter, causing incorrect pagination.

The findMany query applies the query filter (line 34-36), but the count query only filters by orgId. This means totalCount will be the total repos for the org, not the filtered count, resulting in incorrect X-Total-Count and Link pagination headers when a search query is provided.

🐛 Proposed fix to include the query filter in count
 prisma.repo.count({
- where: { orgId: org.id },+ where: {+ orgId: org.id,+ ...(query ? {+ name: { contains: query, mode: 'insensitive' },+ } : {}),+ },
}),

@brendan-kellam
brendan-kellam merged commit 6b79cbf into mainFeb 1, 2026
9 checks passed
@brendan-kellam
brendan-kellam deleted the bkellam/api-events branch February 1, 2026 05:18
@github-actionsgithub-actionsBot mentioned this pull request Feb 1, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 1, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 13, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(web): Add telemetry for all api requests - #835

Merged
brendan-kellam merged 4 commits into
mainfrom
bkellam/api-events
Feb 1, 2026
Merged

chore(web): Add telemetry for all api requests#835
brendan-kellam merged 4 commits into
mainfrom
bkellam/api-events

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

This PR adds a api_request event that is fired for any api route that uses the apiHandler factory. The event includes a path and source. The source is sourced from the X-Sourcebot-Client-Source header

Summary by CodeRabbit

  • New Features

    • Centralized API handler wrapper that can emit lightweight API-request tracking events.
  • Improvements

    • Requests now include a client-source header for clearer client identification.
    • Removed redundant in-body source fields from search and suggestion requests to streamline payloads.
    • Added a new analytics event for API requests to improve usage insights.

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions

This comment has been minimized.

@coderabbitai

coderabbitaiBot commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@brendan-kellam has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 16 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

Migrates source identification from request bodies to the X-Sourcebot-Client-Source header across clients and routes, and introduces an apiHandler wrapper on many server routes that optionally emits api_request PostHog events.

Changes

Cohort / File(s)Summary
API handler & events
packages/web/src/lib/apiHandler.ts, packages/web/src/lib/posthogEvents.ts
Adds apiHandler wrapper that optionally tracks requests to PostHog and a new api_request event type.
MCP client & schemas
packages/mcp/src/client.ts, packages/mcp/src/schemas.ts, packages/mcp/src/index.ts
Adds X-Sourcebot-Client-Source: mcp header to MCP client requests and removes optional source from MCP search schema/index usage.
Web client headers & schemas
packages/web/src/app/api/(client)/client.ts, packages/web/src/app/[domain]/search/useStreamedSearch.ts, packages/web/src/features/search/types.ts, packages/web/src/app/[domain]/components/searchBar/useSuggestionsData.ts, packages/web/src/features/chat/components/chatBox/useSuggestionsData.ts
Adds X-Sourcebot-Client-Source: sourcebot-web-client header to client calls/streaming; removes source fields from request bodies/schemas.
Server routes (wrapped)
packages/web/src/app/api/(server)/**, packages/web/src/app/api/[domain]/repos/[repoId]/image/route.ts
Replaces many exported route handlers with apiHandler(...) wrapped handlers; several routes now read source from X-Sourcebot-Client-Source header (default 'unknown') and use centralized tracking/error plumbing.
Client-side API calls (web)
packages/web/src/app/api/(client)/client.ts
Adds X-Sourcebot-Client-Source header to multiple client-side API functions (search, getFileSource, listRepos, getVersion, findSearchBasedSymbolReferences/Definitions, getTree, getFiles).

Sequence Diagram(s)

sequenceDiagram
participant Client
participant ServerRoute
participant apiHandler as apiHandler (wrapper)
participant PostHog
Client->>ServerRoute: HTTP request (includes X-Sourcebot-Client-Source)
ServerRoute->>apiHandler: invoked (wrapper receives req)
apiHandler-->>PostHog: async emit api_request { path, source } rgba(100,150,250,0.5)
apiHandler->>ServerRoute: forward to original handler
ServerRoute-->>Client: HTTP response (JSON / stream / file)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

sourcebot-team

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main objective of adding telemetry/api request tracking across all API routes via the apiHandler wrapper.
Docstring Coverage✅ PassedDocstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bkellam/api-events

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment threadpackages/mcp/src/client.ts Outdated

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@packages/mcp/src/client.ts`:
- Around line 110-133: Resolve the merge conflict markers around the askCodebase
implementation by removing the <<<<<<<, =======, and >>>>>>> lines and keeping
the correct askCodebase function body; ensure the file exports/defines the async
function askCodebase(request: AskCodebaseRequest): Promise<AskCodebaseResponse>
exactly as in the new block and call parseResponse(response,
askCodebaseResponseSchema). Also add or restore the necessary imports for
AskCodebaseRequest, AskCodebaseResponse, askCodebaseResponseSchema (and
parseResponse/env if missing) at the top of the file so the TypeScript compiles
without errors.
In `@packages/web/src/app/api/`(server)/repos/route.ts:
- Around line 1-13: The file contains Git conflict markers and duplicated
imports; remove the conflict markers (<<<<<<<, =======, >>>>>>>) and consolidate
imports into one block so each symbol is imported exactly once — keep required
symbols like apiHandler, buildLinkHeader, listReposQueryParamsSchema,
repositoryQuerySchema, queryParamsSchemaValidationError, serviceErrorResponse,
and isServiceError, and drop unused/old imports such as NextRequest, sew, or
withOptionalAuthV2 if they are not referenced elsewhere in this module; ensure
the final import block imports each identifier only once and re-run lint/type
checks.
🧹 Nitpick comments (1)
packages/web/src/app/[domain]/search/useStreamedSearch.ts (1)

120-125: Extract the source header name/value into a shared constant/helper.

Hard-coded literals here can drift from other API calls; centralizing the header name/value makes future updates safer and more consistent.

♻️ Example refactor
+const SOURCEBOT_CLIENT_SOURCE_HEADER = 'X-Sourcebot-Client-Source';+const SOURCEBOT_WEB_CLIENT_SOURCE = 'sourcebot-web-client';+
// ...
const response = await fetch('/api/stream_search', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
- 'X-Sourcebot-Client-Source': 'sourcebot-web-client',+ [SOURCEBOT_CLIENT_SOURCE_HEADER]: SOURCEBOT_WEB_CLIENT_SOURCE,
},

Comment threadpackages/mcp/src/client.ts Outdated
Comment threadpackages/web/src/app/api/(server)/repos/route.ts Outdated
@claude

claudeBot commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Code review

This PR contains 2 critical issues - unresolved git merge conflicts that will prevent the code from compiling:

Issue 1: Merge conflict in packages/mcp/src/client.ts

Location: Lines 110-133
Link:https://github.com/sourcebot-dev/sourcebot/blob/891737e89ce9ccf251b6397d766687a94678e80c/packages/mcp/src/client.ts#L109-L134

The file contains unresolved merge conflict markers:

<<<<<<< Updated upstream
=======
... askCodebase function ...
>>>>>>> Stashed changes

This will cause a syntax error. The conflict needs to be resolved by deciding whether to keep, remove, or merge the askCodebase function.

Issue 2: Merge conflict in packages/web/src/app/api/(server)/repos/route.ts

Location: Lines 1-9 (imports section)
Link:

<<<<<<<Updatedupstream
import{NextRequest}from "next/server";
import{sew}from "@/actions";
import{withOptionalAuthV2}from "@/withAuthV2";
=======
import{apiHandler}from"@/lib/apiHandler";
import{buildLinkHeader}from"@/lib/pagination";
import{listReposQueryParamsSchema}from"@/lib/schemas";
>>>>>>>Stashedchanges
import{queryParamsSchemaValidationError,serviceErrorResponse}from"@/lib/serviceError";
import{isServiceError}from"@/lib/utils";
import{listReposQueryParamsSchema,repositoryQuerySchema}from"@/lib/schemas";
import{buildLinkHeader}from"@/lib/pagination";
import{getBrowsePath}from"@/app/[domain]/browse/hooks/utils";

The import section contains unresolved merge conflict markers:

<<<<<<< Updated upstream
import { NextRequest } from "next/server";
import { sew } from "@/actions";
import { withOptionalAuthV2 } from "@/withAuthV2";
=======
import { apiHandler } from "@/lib/apiHandler";
import { buildLinkHeader } from "@/lib/pagination";
import { listReposQueryParamsSchema } from "@/lib/schemas";
>>>>>>> Stashed changes

This will cause a syntax error. After the conflict markers, there are also duplicate imports that should be cleaned up once the conflict is resolved.


Action required: Please resolve these merge conflicts before the PR can be merged.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/web/src/app/api/(server)/repos/route.ts (1)

42-44: ⚠️ Potential issue | 🟠 Major

Count query is missing the query filter, causing incorrect pagination.

The findMany query applies the query filter (line 34-36), but the count query only filters by orgId. This means totalCount will be the total repos for the org, not the filtered count, resulting in incorrect X-Total-Count and Link pagination headers when a search query is provided.

🐛 Proposed fix to include the query filter in count
 prisma.repo.count({
- where: { orgId: org.id },+ where: {+ orgId: org.id,+ ...(query ? {+ name: { contains: query, mode: 'insensitive' },+ } : {}),+ },
}),

@brendan-kellam
brendan-kellam merged commit 6b79cbf into mainFeb 1, 2026
9 checks passed
@brendan-kellam
brendan-kellam deleted the bkellam/api-events branch February 1, 2026 05:18
@github-actionsgithub-actionsBot mentioned this pull request Feb 1, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 1, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 13, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(web): Add telemetry for all api requests - #835

Merged
brendan-kellam merged 4 commits into
mainfrom
bkellam/api-events
Feb 1, 2026
Merged

chore(web): Add telemetry for all api requests#835
brendan-kellam merged 4 commits into
mainfrom
bkellam/api-events

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

This PR adds a api_request event that is fired for any api route that uses the apiHandler factory. The event includes a path and source. The source is sourced from the X-Sourcebot-Client-Source header

Summary by CodeRabbit

  • New Features

    • Centralized API handler wrapper that can emit lightweight API-request tracking events.
  • Improvements

    • Requests now include a client-source header for clearer client identification.
    • Removed redundant in-body source fields from search and suggestion requests to streamline payloads.
    • Added a new analytics event for API requests to improve usage insights.

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions

This comment has been minimized.

@coderabbitai

coderabbitaiBot commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@brendan-kellam has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 16 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

Migrates source identification from request bodies to the X-Sourcebot-Client-Source header across clients and routes, and introduces an apiHandler wrapper on many server routes that optionally emits api_request PostHog events.

Changes

Cohort / File(s)Summary
API handler & events
packages/web/src/lib/apiHandler.ts, packages/web/src/lib/posthogEvents.ts
Adds apiHandler wrapper that optionally tracks requests to PostHog and a new api_request event type.
MCP client & schemas
packages/mcp/src/client.ts, packages/mcp/src/schemas.ts, packages/mcp/src/index.ts
Adds X-Sourcebot-Client-Source: mcp header to MCP client requests and removes optional source from MCP search schema/index usage.
Web client headers & schemas
packages/web/src/app/api/(client)/client.ts, packages/web/src/app/[domain]/search/useStreamedSearch.ts, packages/web/src/features/search/types.ts, packages/web/src/app/[domain]/components/searchBar/useSuggestionsData.ts, packages/web/src/features/chat/components/chatBox/useSuggestionsData.ts
Adds X-Sourcebot-Client-Source: sourcebot-web-client header to client calls/streaming; removes source fields from request bodies/schemas.
Server routes (wrapped)
packages/web/src/app/api/(server)/**, packages/web/src/app/api/[domain]/repos/[repoId]/image/route.ts
Replaces many exported route handlers with apiHandler(...) wrapped handlers; several routes now read source from X-Sourcebot-Client-Source header (default 'unknown') and use centralized tracking/error plumbing.
Client-side API calls (web)
packages/web/src/app/api/(client)/client.ts
Adds X-Sourcebot-Client-Source header to multiple client-side API functions (search, getFileSource, listRepos, getVersion, findSearchBasedSymbolReferences/Definitions, getTree, getFiles).

Sequence Diagram(s)

sequenceDiagram
participant Client
participant ServerRoute
participant apiHandler as apiHandler (wrapper)
participant PostHog
Client->>ServerRoute: HTTP request (includes X-Sourcebot-Client-Source)
ServerRoute->>apiHandler: invoked (wrapper receives req)
apiHandler-->>PostHog: async emit api_request { path, source } rgba(100,150,250,0.5)
apiHandler->>ServerRoute: forward to original handler
ServerRoute-->>Client: HTTP response (JSON / stream / file)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

sourcebot-team

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main objective of adding telemetry/api request tracking across all API routes via the apiHandler wrapper.
Docstring Coverage✅ PassedDocstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bkellam/api-events

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment threadpackages/mcp/src/client.ts Outdated

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@packages/mcp/src/client.ts`:
- Around line 110-133: Resolve the merge conflict markers around the askCodebase
implementation by removing the <<<<<<<, =======, and >>>>>>> lines and keeping
the correct askCodebase function body; ensure the file exports/defines the async
function askCodebase(request: AskCodebaseRequest): Promise<AskCodebaseResponse>
exactly as in the new block and call parseResponse(response,
askCodebaseResponseSchema). Also add or restore the necessary imports for
AskCodebaseRequest, AskCodebaseResponse, askCodebaseResponseSchema (and
parseResponse/env if missing) at the top of the file so the TypeScript compiles
without errors.
In `@packages/web/src/app/api/`(server)/repos/route.ts:
- Around line 1-13: The file contains Git conflict markers and duplicated
imports; remove the conflict markers (<<<<<<<, =======, >>>>>>>) and consolidate
imports into one block so each symbol is imported exactly once — keep required
symbols like apiHandler, buildLinkHeader, listReposQueryParamsSchema,
repositoryQuerySchema, queryParamsSchemaValidationError, serviceErrorResponse,
and isServiceError, and drop unused/old imports such as NextRequest, sew, or
withOptionalAuthV2 if they are not referenced elsewhere in this module; ensure
the final import block imports each identifier only once and re-run lint/type
checks.
🧹 Nitpick comments (1)
packages/web/src/app/[domain]/search/useStreamedSearch.ts (1)

120-125: Extract the source header name/value into a shared constant/helper.

Hard-coded literals here can drift from other API calls; centralizing the header name/value makes future updates safer and more consistent.

♻️ Example refactor
+const SOURCEBOT_CLIENT_SOURCE_HEADER = 'X-Sourcebot-Client-Source';+const SOURCEBOT_WEB_CLIENT_SOURCE = 'sourcebot-web-client';+
// ...
const response = await fetch('/api/stream_search', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
- 'X-Sourcebot-Client-Source': 'sourcebot-web-client',+ [SOURCEBOT_CLIENT_SOURCE_HEADER]: SOURCEBOT_WEB_CLIENT_SOURCE,
},

Comment threadpackages/mcp/src/client.ts Outdated
Comment threadpackages/web/src/app/api/(server)/repos/route.ts Outdated
@claude

claudeBot commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Code review

This PR contains 2 critical issues - unresolved git merge conflicts that will prevent the code from compiling:

Issue 1: Merge conflict in packages/mcp/src/client.ts

Location: Lines 110-133
Link:https://github.com/sourcebot-dev/sourcebot/blob/891737e89ce9ccf251b6397d766687a94678e80c/packages/mcp/src/client.ts#L109-L134

The file contains unresolved merge conflict markers:

<<<<<<< Updated upstream
=======
... askCodebase function ...
>>>>>>> Stashed changes

This will cause a syntax error. The conflict needs to be resolved by deciding whether to keep, remove, or merge the askCodebase function.

Issue 2: Merge conflict in packages/web/src/app/api/(server)/repos/route.ts

Location: Lines 1-9 (imports section)
Link:

<<<<<<<Updatedupstream
import{NextRequest}from "next/server";
import{sew}from "@/actions";
import{withOptionalAuthV2}from "@/withAuthV2";
=======
import{apiHandler}from"@/lib/apiHandler";
import{buildLinkHeader}from"@/lib/pagination";
import{listReposQueryParamsSchema}from"@/lib/schemas";
>>>>>>>Stashedchanges
import{queryParamsSchemaValidationError,serviceErrorResponse}from"@/lib/serviceError";
import{isServiceError}from"@/lib/utils";
import{listReposQueryParamsSchema,repositoryQuerySchema}from"@/lib/schemas";
import{buildLinkHeader}from"@/lib/pagination";
import{getBrowsePath}from"@/app/[domain]/browse/hooks/utils";

The import section contains unresolved merge conflict markers:

<<<<<<< Updated upstream
import { NextRequest } from "next/server";
import { sew } from "@/actions";
import { withOptionalAuthV2 } from "@/withAuthV2";
=======
import { apiHandler } from "@/lib/apiHandler";
import { buildLinkHeader } from "@/lib/pagination";
import { listReposQueryParamsSchema } from "@/lib/schemas";
>>>>>>> Stashed changes

This will cause a syntax error. After the conflict markers, there are also duplicate imports that should be cleaned up once the conflict is resolved.


Action required: Please resolve these merge conflicts before the PR can be merged.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/web/src/app/api/(server)/repos/route.ts (1)

42-44: ⚠️ Potential issue | 🟠 Major

Count query is missing the query filter, causing incorrect pagination.

The findMany query applies the query filter (line 34-36), but the count query only filters by orgId. This means totalCount will be the total repos for the org, not the filtered count, resulting in incorrect X-Total-Count and Link pagination headers when a search query is provided.

🐛 Proposed fix to include the query filter in count
 prisma.repo.count({
- where: { orgId: org.id },+ where: {+ orgId: org.id,+ ...(query ? {+ name: { contains: query, mode: 'insensitive' },+ } : {}),+ },
}),

@brendan-kellam
brendan-kellam merged commit 6b79cbf into mainFeb 1, 2026
9 checks passed
@brendan-kellam
brendan-kellam deleted the bkellam/api-events branch February 1, 2026 05:18
@github-actionsgithub-actionsBot mentioned this pull request Feb 1, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 1, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 13, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

chore(web): Add telemetry for all api requests - #835

Merged
brendan-kellam merged 4 commits into
mainfrom
bkellam/api-events
Feb 1, 2026
Merged

chore(web): Add telemetry for all api requests#835
brendan-kellam merged 4 commits into
mainfrom
bkellam/api-events

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

This PR adds a api_request event that is fired for any api route that uses the apiHandler factory. The event includes a path and source. The source is sourced from the X-Sourcebot-Client-Source header

Summary by CodeRabbit

  • New Features

    • Centralized API handler wrapper that can emit lightweight API-request tracking events.
  • Improvements

    • Requests now include a client-source header for clearer client identification.
    • Removed redundant in-body source fields from search and suggestion requests to streamline payloads.
    • Added a new analytics event for API requests to improve usage insights.

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions

This comment has been minimized.

@coderabbitai

coderabbitaiBot commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@brendan-kellam has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 16 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

Migrates source identification from request bodies to the X-Sourcebot-Client-Source header across clients and routes, and introduces an apiHandler wrapper on many server routes that optionally emits api_request PostHog events.

Changes

Cohort / File(s)Summary
API handler & events
packages/web/src/lib/apiHandler.ts, packages/web/src/lib/posthogEvents.ts
Adds apiHandler wrapper that optionally tracks requests to PostHog and a new api_request event type.
MCP client & schemas
packages/mcp/src/client.ts, packages/mcp/src/schemas.ts, packages/mcp/src/index.ts
Adds X-Sourcebot-Client-Source: mcp header to MCP client requests and removes optional source from MCP search schema/index usage.
Web client headers & schemas
packages/web/src/app/api/(client)/client.ts, packages/web/src/app/[domain]/search/useStreamedSearch.ts, packages/web/src/features/search/types.ts, packages/web/src/app/[domain]/components/searchBar/useSuggestionsData.ts, packages/web/src/features/chat/components/chatBox/useSuggestionsData.ts
Adds X-Sourcebot-Client-Source: sourcebot-web-client header to client calls/streaming; removes source fields from request bodies/schemas.
Server routes (wrapped)
packages/web/src/app/api/(server)/**, packages/web/src/app/api/[domain]/repos/[repoId]/image/route.ts
Replaces many exported route handlers with apiHandler(...) wrapped handlers; several routes now read source from X-Sourcebot-Client-Source header (default 'unknown') and use centralized tracking/error plumbing.
Client-side API calls (web)
packages/web/src/app/api/(client)/client.ts
Adds X-Sourcebot-Client-Source header to multiple client-side API functions (search, getFileSource, listRepos, getVersion, findSearchBasedSymbolReferences/Definitions, getTree, getFiles).

Sequence Diagram(s)

sequenceDiagram
participant Client
participant ServerRoute
participant apiHandler as apiHandler (wrapper)
participant PostHog
Client->>ServerRoute: HTTP request (includes X-Sourcebot-Client-Source)
ServerRoute->>apiHandler: invoked (wrapper receives req)
apiHandler-->>PostHog: async emit api_request { path, source } rgba(100,150,250,0.5)
apiHandler->>ServerRoute: forward to original handler
ServerRoute-->>Client: HTTP response (JSON / stream / file)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

sourcebot-team

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main objective of adding telemetry/api request tracking across all API routes via the apiHandler wrapper.
Docstring Coverage✅ PassedDocstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bkellam/api-events

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment threadpackages/mcp/src/client.ts Outdated

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@packages/mcp/src/client.ts`:
- Around line 110-133: Resolve the merge conflict markers around the askCodebase
implementation by removing the <<<<<<<, =======, and >>>>>>> lines and keeping
the correct askCodebase function body; ensure the file exports/defines the async
function askCodebase(request: AskCodebaseRequest): Promise<AskCodebaseResponse>
exactly as in the new block and call parseResponse(response,
askCodebaseResponseSchema). Also add or restore the necessary imports for
AskCodebaseRequest, AskCodebaseResponse, askCodebaseResponseSchema (and
parseResponse/env if missing) at the top of the file so the TypeScript compiles
without errors.
In `@packages/web/src/app/api/`(server)/repos/route.ts:
- Around line 1-13: The file contains Git conflict markers and duplicated
imports; remove the conflict markers (<<<<<<<, =======, >>>>>>>) and consolidate
imports into one block so each symbol is imported exactly once — keep required
symbols like apiHandler, buildLinkHeader, listReposQueryParamsSchema,
repositoryQuerySchema, queryParamsSchemaValidationError, serviceErrorResponse,
and isServiceError, and drop unused/old imports such as NextRequest, sew, or
withOptionalAuthV2 if they are not referenced elsewhere in this module; ensure
the final import block imports each identifier only once and re-run lint/type
checks.
🧹 Nitpick comments (1)
packages/web/src/app/[domain]/search/useStreamedSearch.ts (1)

120-125: Extract the source header name/value into a shared constant/helper.

Hard-coded literals here can drift from other API calls; centralizing the header name/value makes future updates safer and more consistent.

♻️ Example refactor
+const SOURCEBOT_CLIENT_SOURCE_HEADER = 'X-Sourcebot-Client-Source';+const SOURCEBOT_WEB_CLIENT_SOURCE = 'sourcebot-web-client';+
// ...
const response = await fetch('/api/stream_search', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
- 'X-Sourcebot-Client-Source': 'sourcebot-web-client',+ [SOURCEBOT_CLIENT_SOURCE_HEADER]: SOURCEBOT_WEB_CLIENT_SOURCE,
},

Comment threadpackages/mcp/src/client.ts Outdated
Comment threadpackages/web/src/app/api/(server)/repos/route.ts Outdated
@claude

claudeBot commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Code review

This PR contains 2 critical issues - unresolved git merge conflicts that will prevent the code from compiling:

Issue 1: Merge conflict in packages/mcp/src/client.ts

Location: Lines 110-133
Link:https://github.com/sourcebot-dev/sourcebot/blob/891737e89ce9ccf251b6397d766687a94678e80c/packages/mcp/src/client.ts#L109-L134

The file contains unresolved merge conflict markers:

<<<<<<< Updated upstream
=======
... askCodebase function ...
>>>>>>> Stashed changes

This will cause a syntax error. The conflict needs to be resolved by deciding whether to keep, remove, or merge the askCodebase function.

Issue 2: Merge conflict in packages/web/src/app/api/(server)/repos/route.ts

Location: Lines 1-9 (imports section)
Link:

<<<<<<<Updatedupstream
import{NextRequest}from "next/server";
import{sew}from "@/actions";
import{withOptionalAuthV2}from "@/withAuthV2";
=======
import{apiHandler}from"@/lib/apiHandler";
import{buildLinkHeader}from"@/lib/pagination";
import{listReposQueryParamsSchema}from"@/lib/schemas";
>>>>>>>Stashedchanges
import{queryParamsSchemaValidationError,serviceErrorResponse}from"@/lib/serviceError";
import{isServiceError}from"@/lib/utils";
import{listReposQueryParamsSchema,repositoryQuerySchema}from"@/lib/schemas";
import{buildLinkHeader}from"@/lib/pagination";
import{getBrowsePath}from"@/app/[domain]/browse/hooks/utils";

The import section contains unresolved merge conflict markers:

<<<<<<< Updated upstream
import { NextRequest } from "next/server";
import { sew } from "@/actions";
import { withOptionalAuthV2 } from "@/withAuthV2";
=======
import { apiHandler } from "@/lib/apiHandler";
import { buildLinkHeader } from "@/lib/pagination";
import { listReposQueryParamsSchema } from "@/lib/schemas";
>>>>>>> Stashed changes

This will cause a syntax error. After the conflict markers, there are also duplicate imports that should be cleaned up once the conflict is resolved.


Action required: Please resolve these merge conflicts before the PR can be merged.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/web/src/app/api/(server)/repos/route.ts (1)

42-44: ⚠️ Potential issue | 🟠 Major

Count query is missing the query filter, causing incorrect pagination.

The findMany query applies the query filter (line 34-36), but the count query only filters by orgId. This means totalCount will be the total repos for the org, not the filtered count, resulting in incorrect X-Total-Count and Link pagination headers when a search query is provided.

🐛 Proposed fix to include the query filter in count
 prisma.repo.count({
- where: { orgId: org.id },+ where: {+ orgId: org.id,+ ...(query ? {+ name: { contains: query, mode: 'insensitive' },+ } : {}),+ },
}),

@brendan-kellam
brendan-kellam merged commit 6b79cbf into mainFeb 1, 2026
9 checks passed
@brendan-kellam
brendan-kellam deleted the bkellam/api-events branch February 1, 2026 05:18
@github-actionsgithub-actionsBot mentioned this pull request Feb 1, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 1, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 13, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@brendan-kellam