Compare commits

..

2 commits

Author SHA1 Message Date
Wayne Sun
3a60c5530d
Merge 4304edd6c9 into 7fc068f8b2 2025-12-03 18:59:47 -05:00
Wayne Sun
4304edd6c9 feat: add temporal filtering to search and repository APIs
Add temporal filtering capabilities for searches by git branch/revision
and repository index dates (since/until). Integrates with the refactored
QueryIR-based search architecture.

- Add gitRevision, since, until parameters to SearchOptions
- Implement temporal repo filtering by indexedAt field
- Add branch filtering via QueryIR wrapper
- Add search_commits MCP tool for commit-based searches
- Update list_repos with activeAfter/activeBefore filtering
- Add 88 new tests (all passing)

Signed-off-by: Wayne Sun <gsun@redhat.com>
2025-12-01 11:29:45 -05:00
22 changed files with 74 additions and 265 deletions

View file

@ -21,7 +21,7 @@ AUTH_URL="http://localhost:3000"
DATA_CACHE_DIR=${PWD}/.sourcebot # Path to the sourcebot cache dir (ex. ~/sourcebot/.sourcebot)
SOURCEBOT_PUBLIC_KEY_PATH=${PWD}/public.pem
CONFIG_PATH=${PWD}/config.json # Path to the sourcebot config file (if one exists)
# CONFIG_PATH=${PWD}/config.json # Path to the sourcebot config file (if one exists)
# Email
# EMAIL_FROM_ADDRESS="" # The from address for transactional emails.

View file

@ -7,26 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Fixed
- Fixed review agent so that it works with GHES instances [#611](https://github.com/sourcebot-dev/sourcebot/pull/611)
### Added
- Added support for arbitrary user IDs required for OpenShift. [#658](https://github.com/sourcebot-dev/sourcebot/pull/658)
### Updated
- Improved error messages in file source api. [#665](https://github.com/sourcebot-dev/sourcebot/pull/665)
## [4.10.2] - 2025-12-04
### Fixed
- Fixed issue where the disable telemetry flag was not being respected for web server telemetry. [#657](https://github.com/sourcebot-dev/sourcebot/pull/657)
## [4.10.1] - 2025-12-03
### Added
- Added `ALWAYS_INDEX_FILE_PATTERNS` environment variable to allow specifying a comma seperated list of glob patterns matching file paths that should always be indexed, regardless of size or # of trigrams. [#631](https://github.com/sourcebot-dev/sourcebot/pull/631)
- Added button to explore menu to toggle cross-repository search. [#647](https://github.com/sourcebot-dev/sourcebot/pull/647)
- Added server side telemetry for search metrics. [#652](https://github.com/sourcebot-dev/sourcebot/pull/652)
### Fixed
- Fixed issue where single quotes could not be used in search queries. [#629](https://github.com/sourcebot-dev/sourcebot/pull/629)

View file

@ -195,7 +195,6 @@ RUN addgroup -g $GID sourcebot && \
adduser -D -u $UID -h /app -S sourcebot && \
adduser sourcebot postgres && \
adduser sourcebot redis && \
chown -R sourcebot /app && \
adduser sourcebot node && \
mkdir /var/log/sourcebot && \
chown sourcebot /var/log/sourcebot
@ -245,12 +244,7 @@ RUN mkdir -p /run/postgresql && \
chown -R postgres:postgres /run/postgresql && \
chmod 775 /run/postgresql
# Make app directory accessible to both root and sourcebot user
RUN chown -R sourcebot /app \
&& chgrp -R 0 /app \
&& chmod -R g=u /app
# Make data directory accessible to both root and sourcebot user
RUN chown -R sourcebot /data
RUN chown -R sourcebot:sourcebot /data
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY prefix-output.sh ./prefix-output.sh

View file

@ -23,11 +23,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added integration tests for temporal parameter validation
- Added unit tests for repository identifier resolution (both string and number types)
## [1.0.11] - 2025-12-03
### Changed
- Updated API client to match the latest Sourcebot release. [#652](https://github.com/sourcebot-dev/sourcebot/pull/652)
## [1.0.10] - 2025-11-24
### Changed

View file

@ -1,6 +1,6 @@
{
"name": "@sourcebot/mcp",
"version": "1.0.11",
"version": "1.0.10",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",

View file

@ -8,6 +8,7 @@ export const search = async (request: SearchRequest): Promise<SearchResponse | S
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Org-Domain': '~',
...(env.SOURCEBOT_API_KEY ? { 'X-Sourcebot-Api-Key': env.SOURCEBOT_API_KEY } : {})
},
body: JSON.stringify(request)
@ -33,6 +34,7 @@ export const listRepos = async (params?: { activeAfter?: string, activeBefore?:
method: 'GET',
headers: {
'Content-Type': 'application/json',
'X-Org-Domain': '~',
...(env.SOURCEBOT_API_KEY ? { 'X-Sourcebot-Api-Key': env.SOURCEBOT_API_KEY } : {})
},
}).then(response => response.json());
@ -49,6 +51,7 @@ export const getFileSource = async (request: FileSourceRequest): Promise<FileSou
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Org-Domain': '~',
...(env.SOURCEBOT_API_KEY ? { 'X-Sourcebot-Api-Key': env.SOURCEBOT_API_KEY } : {})
},
body: JSON.stringify(request)

View file

@ -91,7 +91,6 @@ server.tool(
contextLines: env.DEFAULT_CONTEXT_LINES,
isRegexEnabled: true,
isCaseSensitivityEnabled: caseSensitive,
source: 'mcp',
gitRevision,
since,
until,

View file

@ -34,7 +34,6 @@ export const searchOptionsSchema = z.object({
export const searchRequestSchema = z.object({
query: z.string(), // The zoekt query to execute.
source: z.string().optional(), // The source of the search request.
...searchOptionsSchema.shape,
});

View file

@ -147,7 +147,7 @@
"langfuse-vercel": "^3.38.4",
"lucide-react": "^0.517.0",
"micromatch": "^4.0.8",
"next": "^15.5.7",
"next": "^16.0.7",
"next-auth": "^5.0.0-beta.30",
"next-navigation-guard": "^0.2.0",
"next-themes": "^0.3.0",
@ -156,7 +156,6 @@
"openai": "^4.98.0",
"parse-diff": "^0.11.1",
"posthog-js": "^1.161.5",
"posthog-node": "^5.15.0",
"pretty-bytes": "^6.1.1",
"psl": "^1.15.0",
"react": "^19.2.1",

View file

@ -38,8 +38,8 @@ const auditService = getAuditService();
/**
* "Service Error Wrapper".
*
* Captures any thrown exceptions, logs them to the console and Sentry,
* and returns a generic unexpected service error.
* Captures any thrown exceptions and converts them to a unexpected
* service error. Also logs them with Sentry.
*/
export const sew = async <T>(fn: () => Promise<T>): Promise<T | ServiceError> => {
try {
@ -52,6 +52,10 @@ export const sew = async <T>(fn: () => Promise<T>): Promise<T | ServiceError> =>
return e.serviceError;
}
if (e instanceof Error) {
return unexpectedError(e.message);
}
return unexpectedError(`An unexpected error occurred. Please try again later.`);
}
}

View file

@ -22,12 +22,8 @@ export const CodePreviewPanel = async ({ path, repoName, revisionName }: CodePre
getRepoInfoByName(repoName),
]);
if (isServiceError(fileSourceResponse)) {
return <div>Error loading file source: {fileSourceResponse.message}</div>
}
if (isServiceError(repoInfoResponse)) {
return <div>Error loading repo info: {repoInfoResponse.message}</div>
if (isServiceError(fileSourceResponse) || isServiceError(repoInfoResponse)) {
return <div>Error loading file source</div>
}
const codeHostInfo = getCodeHostInfoForRepo({

View file

@ -55,7 +55,6 @@ export const useSuggestionsData = ({
query: `file:${suggestionQuery}`,
matches: 15,
contextLines: 1,
source: 'search-bar-file-suggestions'
}),
select: (data): Suggestion[] => {
if (isServiceError(data)) {
@ -76,7 +75,6 @@ export const useSuggestionsData = ({
query: `sym:${suggestionQuery.length > 0 ? suggestionQuery : ".*"}`,
matches: 15,
contextLines: 1,
source: 'search-bar-symbol-suggestions'
}),
select: (data): Suggestion[] => {
if (isServiceError(data)) {

View file

@ -129,8 +129,7 @@ export const useStreamedSearch = ({ query, matches, contextLines, whole, isRegex
whole,
isRegexEnabled,
isCaseSensitivityEnabled,
source: 'sourcebot-web-client'
} satisfies SearchRequest),
}),
signal: abortControllerRef.current.signal,
});

View file

@ -4,7 +4,6 @@ import { search, searchRequestSchema } from "@/features/search";
import { isServiceError } from "@/lib/utils";
import { NextRequest } from "next/server";
import { schemaValidationError, serviceErrorResponse } from "@/lib/serviceError";
import { captureEvent } from "@/lib/posthog";
export const POST = async (request: NextRequest) => {
const body = await request.json();
@ -17,14 +16,8 @@ export const POST = async (request: NextRequest) => {
const {
query,
source,
...options
} = parsed.data;
await captureEvent('api_code_search_request', {
source: source ?? 'unknown',
type: 'blocking',
});
const response = await search({
queryType: 'string',
@ -35,6 +28,5 @@ export const POST = async (request: NextRequest) => {
if (isServiceError(response)) {
return serviceErrorResponse(response);
}
return Response.json(response);
}

View file

@ -1,7 +1,6 @@
'use server';
import { streamSearch, searchRequestSchema } from '@/features/search';
import { captureEvent } from '@/lib/posthog';
import { schemaValidationError, serviceErrorResponse } from '@/lib/serviceError';
import { isServiceError } from '@/lib/utils';
import { NextRequest } from 'next/server';
@ -16,15 +15,9 @@ export const POST = async (request: NextRequest) => {
const {
query,
source,
...options
} = parsed.data;
await captureEvent('api_code_search_request', {
source: source ?? 'unknown',
type: 'streamed',
});
const stream = await streamSearch({
queryType: 'string',
query,

View file

@ -6,32 +6,28 @@ import { WebhookEventDefinition} from "@octokit/webhooks/types";
import { EndpointDefaults } from "@octokit/types";
import { env } from "@sourcebot/shared";
import { processGitHubPullRequest } from "@/features/agents/review-agent/app";
import { throttling, type ThrottlingOptions } from "@octokit/plugin-throttling";
import { throttling } from "@octokit/plugin-throttling";
import fs from "fs";
import { GitHubPullRequest } from "@/features/agents/review-agent/types";
import { createLogger } from "@sourcebot/shared";
const logger = createLogger('github-webhook');
const DEFAULT_GITHUB_API_BASE_URL = "https://api.github.com";
type GitHubAppBaseOptions = Omit<ConstructorParameters<typeof App>[0], "Octokit"> & { throttle: ThrottlingOptions };
let githubAppBaseOptions: GitHubAppBaseOptions | undefined;
const githubAppCache = new Map<string, App>();
let githubApp: App | undefined;
if (env.GITHUB_REVIEW_AGENT_APP_ID && env.GITHUB_REVIEW_AGENT_APP_WEBHOOK_SECRET && env.GITHUB_REVIEW_AGENT_APP_PRIVATE_KEY_PATH) {
try {
const privateKey = fs.readFileSync(env.GITHUB_REVIEW_AGENT_APP_PRIVATE_KEY_PATH, "utf8");
githubAppBaseOptions = {
const throttledOctokit = Octokit.plugin(throttling);
githubApp = new App({
appId: env.GITHUB_REVIEW_AGENT_APP_ID,
privateKey,
privateKey: privateKey,
webhooks: {
secret: env.GITHUB_REVIEW_AGENT_APP_WEBHOOK_SECRET,
},
Octokit: throttledOctokit,
throttle: {
enabled: true,
onRateLimit: (retryAfter, _options, _octokit, retryCount) => {
onRateLimit: (retryAfter: number, options: Required<EndpointDefaults>, octokit: Octokit, retryCount: number) => {
if (retryCount > 3) {
logger.warn(`Rate limit exceeded: ${retryAfter} seconds`);
return false;
@ -39,55 +35,13 @@ if (env.GITHUB_REVIEW_AGENT_APP_ID && env.GITHUB_REVIEW_AGENT_APP_WEBHOOK_SECRET
return true;
},
onSecondaryRateLimit: (_retryAfter, options) => {
// no retries on secondary rate limits
logger.warn(`SecondaryRateLimit detected for ${options.method} ${options.url}`);
}
},
};
}
});
} catch (error) {
logger.error(`Error initializing GitHub app: ${error}`);
}
}
const normalizeGithubApiBaseUrl = (baseUrl?: string) => {
if (!baseUrl) {
return DEFAULT_GITHUB_API_BASE_URL;
}
return baseUrl.replace(/\/+$/, "");
};
const resolveGithubApiBaseUrl = (headers: Record<string, string>) => {
const enterpriseHost = headers["x-github-enterprise-host"];
if (enterpriseHost) {
return normalizeGithubApiBaseUrl(`https://${enterpriseHost}/api/v3`);
}
return DEFAULT_GITHUB_API_BASE_URL;
};
const getGithubAppForBaseUrl = (baseUrl: string) => {
if (!githubAppBaseOptions) {
return undefined;
}
const normalizedBaseUrl = normalizeGithubApiBaseUrl(baseUrl);
const cachedApp = githubAppCache.get(normalizedBaseUrl);
if (cachedApp) {
return cachedApp;
}
const OctokitWithBaseUrl = Octokit.plugin(throttling).defaults({ baseUrl: normalizedBaseUrl });
const app = new App({
...githubAppBaseOptions,
Octokit: OctokitWithBaseUrl,
});
githubAppCache.set(normalizedBaseUrl, app);
return app;
};
function isPullRequestEvent(eventHeader: string, payload: unknown): payload is WebhookEventDefinition<"pull-request-opened"> | WebhookEventDefinition<"pull-request-synchronize"> {
return eventHeader === "pull_request" && typeof payload === "object" && payload !== null && "action" in payload && typeof payload.action === "string" && (payload.action === "opened" || payload.action === "synchronize");
}
@ -98,16 +52,12 @@ function isIssueCommentEvent(eventHeader: string, payload: unknown): payload is
export const POST = async (request: NextRequest) => {
const body = await request.json();
const headers = Object.fromEntries(Array.from(request.headers.entries(), ([key, value]) => [key.toLowerCase(), value]));
const headers = Object.fromEntries(request.headers.entries());
const githubEvent = headers['x-github-event'];
const githubEvent = headers['x-github-event'] || headers['X-GitHub-Event'];
if (githubEvent) {
logger.info('GitHub event received:', githubEvent);
const githubApiBaseUrl = resolveGithubApiBaseUrl(headers);
logger.debug('Using GitHub API base URL for event', { githubApiBaseUrl });
const githubApp = getGithubAppForBaseUrl(githubApiBaseUrl);
if (!githubApp) {
logger.warn('Received GitHub webhook event but GitHub app env vars are not set');
return Response.json({ status: 'ok' });
@ -163,4 +113,4 @@ export const POST = async (request: NextRequest) => {
}
return Response.json({ status: 'ok' });
}
}

View file

@ -47,7 +47,6 @@ export const useSuggestionsData = ({
query: query.join(' '),
matches: 10,
contextLines: 1,
source: 'chat-file-suggestions'
}))
},
select: (data): FileSuggestion[] => {

View file

@ -97,7 +97,6 @@ export type SearchOptions = z.infer<typeof searchOptionsSchema>;
export const searchRequestSchema = z.object({
query: z.string(), // The zoekt query to execute.
source: z.string().optional(), // The source of the search request.
...searchOptionsSchema.shape,
});
export type SearchRequest = z.infer<typeof searchRequestSchema>;

View file

@ -1,69 +0,0 @@
import { PostHog } from 'posthog-node'
import { env } from '@sourcebot/shared'
import { RequestCookies } from 'next/dist/compiled/@edge-runtime/cookies';
import * as Sentry from "@sentry/nextjs";
import { PosthogEvent, PosthogEventMap } from './posthogEvents';
import { cookies } from 'next/headers';
/**
* @note: This is a subset of the properties stored in the
* ph_phc_<id>_posthog cookie.
*/
export type PostHogCookie = {
distinct_id: string;
}
const isPostHogCookie = (cookie: unknown): cookie is PostHogCookie => {
return typeof cookie === 'object' &&
cookie !== null &&
'distinct_id' in cookie;
}
/**
* Attempts to retrieve the PostHog cookie from the given cookie store, returning
* undefined if the cookie is not found or is invalid.
*/
const getPostHogCookie = (cookieStore: Pick<RequestCookies, 'get'>): PostHogCookie | undefined => {
const phCookieKey = `ph_${env.POSTHOG_PAPIK}_posthog`;
const cookie = cookieStore.get(phCookieKey);
if (!cookie) {
return undefined;
}
const parsedCookie = (() => {
try {
return JSON.parse(cookie.value);
} catch (e) {
Sentry.captureException(e);
return null;
}
})();
if (isPostHogCookie(parsedCookie)) {
return parsedCookie;
}
return undefined;
}
export async function captureEvent<E extends PosthogEvent>(event: E, properties: PosthogEventMap[E]) {
if (env.SOURCEBOT_TELEMETRY_DISABLED === 'true') {
return;
}
const cookieStore = await cookies();
const cookie = getPostHogCookie(cookieStore);
const posthog = new PostHog(env.POSTHOG_PAPIK, {
host: 'https://us.i.posthog.com',
flushAt: 1,
flushInterval: 0
})
posthog.capture({
event,
properties,
distinctId: cookie?.distinct_id ?? '',
});
}

View file

@ -313,11 +313,6 @@ export type PosthogEventMap = {
durationMs: number,
// Whether or not the user is searching all repositories.
isGlobalSearchEnabled: boolean,
},
//////////////////////////////////////////////////////////////////
api_code_search_request: {
source: string;
type: 'streamed' | 'blocking';
},
}
}
export type PosthogEvent = keyof PosthogEventMap;

View file

@ -14,7 +14,7 @@
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"jsx": "react-jsx",
"incremental": true,
"plugins": [
{

107
yarn.lock
View file

@ -3294,10 +3294,10 @@ __metadata:
languageName: node
linkType: hard
"@next/env@npm:15.5.7":
version: 15.5.7
resolution: "@next/env@npm:15.5.7"
checksum: 10c0/f92d99e5fa3516c6b7699abafd9bd813f5c1889dd257ab098f1b71f93137f5e4f49792e22f6dddf8a59efcb134e8e84277c983ff88607b2a42aac651bfde78ea
"@next/env@npm:16.0.7":
version: 16.0.7
resolution: "@next/env@npm:16.0.7"
checksum: 10c0/5bbb4360ae6b0753de83f70700295c09427f5414f6765c7371fee0894de2a614364a2e9b4ec7b7e3451d56334026bafec6d28a21222a2fa7ecaa27f0a9421cc7
languageName: node
linkType: hard
@ -3317,9 +3317,9 @@ __metadata:
languageName: node
linkType: hard
"@next/swc-darwin-arm64@npm:15.5.7":
version: 15.5.7
resolution: "@next/swc-darwin-arm64@npm:15.5.7"
"@next/swc-darwin-arm64@npm:16.0.7":
version: 16.0.7
resolution: "@next/swc-darwin-arm64@npm:16.0.7"
conditions: os=darwin & cpu=arm64
languageName: node
linkType: hard
@ -3331,9 +3331,9 @@ __metadata:
languageName: node
linkType: hard
"@next/swc-darwin-x64@npm:15.5.7":
version: 15.5.7
resolution: "@next/swc-darwin-x64@npm:15.5.7"
"@next/swc-darwin-x64@npm:16.0.7":
version: 16.0.7
resolution: "@next/swc-darwin-x64@npm:16.0.7"
conditions: os=darwin & cpu=x64
languageName: node
linkType: hard
@ -3345,9 +3345,9 @@ __metadata:
languageName: node
linkType: hard
"@next/swc-linux-arm64-gnu@npm:15.5.7":
version: 15.5.7
resolution: "@next/swc-linux-arm64-gnu@npm:15.5.7"
"@next/swc-linux-arm64-gnu@npm:16.0.7":
version: 16.0.7
resolution: "@next/swc-linux-arm64-gnu@npm:16.0.7"
conditions: os=linux & cpu=arm64 & libc=glibc
languageName: node
linkType: hard
@ -3359,9 +3359,9 @@ __metadata:
languageName: node
linkType: hard
"@next/swc-linux-arm64-musl@npm:15.5.7":
version: 15.5.7
resolution: "@next/swc-linux-arm64-musl@npm:15.5.7"
"@next/swc-linux-arm64-musl@npm:16.0.7":
version: 16.0.7
resolution: "@next/swc-linux-arm64-musl@npm:16.0.7"
conditions: os=linux & cpu=arm64 & libc=musl
languageName: node
linkType: hard
@ -3373,9 +3373,9 @@ __metadata:
languageName: node
linkType: hard
"@next/swc-linux-x64-gnu@npm:15.5.7":
version: 15.5.7
resolution: "@next/swc-linux-x64-gnu@npm:15.5.7"
"@next/swc-linux-x64-gnu@npm:16.0.7":
version: 16.0.7
resolution: "@next/swc-linux-x64-gnu@npm:16.0.7"
conditions: os=linux & cpu=x64 & libc=glibc
languageName: node
linkType: hard
@ -3387,9 +3387,9 @@ __metadata:
languageName: node
linkType: hard
"@next/swc-linux-x64-musl@npm:15.5.7":
version: 15.5.7
resolution: "@next/swc-linux-x64-musl@npm:15.5.7"
"@next/swc-linux-x64-musl@npm:16.0.7":
version: 16.0.7
resolution: "@next/swc-linux-x64-musl@npm:16.0.7"
conditions: os=linux & cpu=x64 & libc=musl
languageName: node
linkType: hard
@ -3401,9 +3401,9 @@ __metadata:
languageName: node
linkType: hard
"@next/swc-win32-arm64-msvc@npm:15.5.7":
version: 15.5.7
resolution: "@next/swc-win32-arm64-msvc@npm:15.5.7"
"@next/swc-win32-arm64-msvc@npm:16.0.7":
version: 16.0.7
resolution: "@next/swc-win32-arm64-msvc@npm:16.0.7"
conditions: os=win32 & cpu=arm64
languageName: node
linkType: hard
@ -3422,9 +3422,9 @@ __metadata:
languageName: node
linkType: hard
"@next/swc-win32-x64-msvc@npm:15.5.7":
version: 15.5.7
resolution: "@next/swc-win32-x64-msvc@npm:15.5.7"
"@next/swc-win32-x64-msvc@npm:16.0.7":
version: 16.0.7
resolution: "@next/swc-win32-x64-msvc@npm:16.0.7"
conditions: os=win32 & cpu=x64
languageName: node
linkType: hard
@ -4599,15 +4599,6 @@ __metadata:
languageName: node
linkType: hard
"@posthog/core@npm:1.6.0":
version: 1.6.0
resolution: "@posthog/core@npm:1.6.0"
dependencies:
cross-spawn: "npm:^7.0.6"
checksum: 10c0/28aa907bb21b18587bc5f47c44349ebc834b37d9a4cedb1a18d7b673d4d7cdad2120dda80deceaee707b2f52333e9a08a8e591e1fc4066521ce05e820b76309f
languageName: node
linkType: hard
"@prisma/client@npm:6.2.1":
version: 6.2.1
resolution: "@prisma/client@npm:6.2.1"
@ -8243,7 +8234,7 @@ __metadata:
langfuse-vercel: "npm:^3.38.4"
lucide-react: "npm:^0.517.0"
micromatch: "npm:^4.0.8"
next: "npm:^15.5.7"
next: "npm:^16.0.7"
next-auth: "npm:^5.0.0-beta.30"
next-navigation-guard: "npm:^0.2.0"
next-themes: "npm:^0.3.0"
@ -8254,7 +8245,6 @@ __metadata:
parse-diff: "npm:^0.11.1"
postcss: "npm:^8"
posthog-js: "npm:^1.161.5"
posthog-node: "npm:^5.15.0"
pretty-bytes: "npm:^6.1.1"
psl: "npm:^1.15.0"
react: "npm:^19.2.1"
@ -16178,23 +16168,23 @@ __metadata:
languageName: node
linkType: hard
"next@npm:^15.5.7":
version: 15.5.7
resolution: "next@npm:15.5.7"
"next@npm:^16.0.7":
version: 16.0.7
resolution: "next@npm:16.0.7"
dependencies:
"@next/env": "npm:15.5.7"
"@next/swc-darwin-arm64": "npm:15.5.7"
"@next/swc-darwin-x64": "npm:15.5.7"
"@next/swc-linux-arm64-gnu": "npm:15.5.7"
"@next/swc-linux-arm64-musl": "npm:15.5.7"
"@next/swc-linux-x64-gnu": "npm:15.5.7"
"@next/swc-linux-x64-musl": "npm:15.5.7"
"@next/swc-win32-arm64-msvc": "npm:15.5.7"
"@next/swc-win32-x64-msvc": "npm:15.5.7"
"@next/env": "npm:16.0.7"
"@next/swc-darwin-arm64": "npm:16.0.7"
"@next/swc-darwin-x64": "npm:16.0.7"
"@next/swc-linux-arm64-gnu": "npm:16.0.7"
"@next/swc-linux-arm64-musl": "npm:16.0.7"
"@next/swc-linux-x64-gnu": "npm:16.0.7"
"@next/swc-linux-x64-musl": "npm:16.0.7"
"@next/swc-win32-arm64-msvc": "npm:16.0.7"
"@next/swc-win32-x64-msvc": "npm:16.0.7"
"@swc/helpers": "npm:0.5.15"
caniuse-lite: "npm:^1.0.30001579"
postcss: "npm:8.4.31"
sharp: "npm:^0.34.3"
sharp: "npm:^0.34.4"
styled-jsx: "npm:5.1.6"
peerDependencies:
"@opentelemetry/api": ^1.1.0
@ -16233,7 +16223,7 @@ __metadata:
optional: true
bin:
next: dist/bin/next
checksum: 10c0/baf5b9f42416c478702b3894479b3d7862bc4abf18afe0e43b7fc7ed35567b8dc6cb76cd94906505bab9013cb8d0f3370cdc0451c01ec15ae5a638d37b5ba7c7
checksum: 10c0/72003fed0f5b690c91ae1a0cc59317691ca1976b46809557a93e00a43e55d4158a256b1a46da6cd7506e699d74aa0cf4e973ec5a35ceabbdd9a1955b507ec85d
languageName: node
linkType: hard
@ -17245,15 +17235,6 @@ __metadata:
languageName: node
linkType: hard
"posthog-node@npm:^5.15.0":
version: 5.15.0
resolution: "posthog-node@npm:5.15.0"
dependencies:
"@posthog/core": "npm:1.6.0"
checksum: 10c0/7db929453cefc9b2d0017e1f7c9ffe7e6ecd2a495ee9861bd5e8f3873f72fa29a318dd7bccf10eb15639e1860aab396d4be502af88afba96ed15ac8b46d57e9d
languageName: node
linkType: hard
"preact-render-to-string@npm:6.5.11":
version: 6.5.11
resolution: "preact-render-to-string@npm:6.5.11"
@ -18789,7 +18770,7 @@ __metadata:
languageName: node
linkType: hard
"sharp@npm:^0.34.3":
"sharp@npm:^0.34.4":
version: 0.34.5
resolution: "sharp@npm:0.34.5"
dependencies: