diff --git a/package.json b/package.json index dadf042bc..79df4e380 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "overrides": { "@babel/helpers@<7.26.10": ">=7.29.7", "@babel/runtime@<7.26.10": ">=7.29.7", - "axios@>=1.0.0 <1.8.2": ">=1.16.1", + "axios@>=1.0.0 <1.8.2": ">=1.17.0", "brace-expansion@>=2.0.0 <=2.0.1": ">=5.0.6", "brace-expansion@>=1.0.0 <=1.1.11": ">=5.0.6", "esbuild@<=0.24.2": ">=0.28.0", @@ -88,13 +88,13 @@ "nanoid@>=4.0.0 <5.0.9": ">=5.1.11", "prismjs@<1.30.0": ">=1.30.0", "proxmox-api>undici": "7.24.6", - "react-is": "^19.2.6", - "rollup@>=4.0.0 <4.22.4": ">=4.60.4", + "react-is": "^19.2.7", + "rollup@>=4.0.0 <4.22.4": ">=4.61.0", "sha.js@<=2.4.11": ">=2.4.12", "tar-fs@>=3.0.0 <3.0.9": ">=3.1.2", "tar-fs@>=2.0.0 <2.1.3": ">=3.1.2", "tmp@<=0.2.3": ">=0.2.7", - "vite@>=5.0.0 <=5.4.18": ">=8.0.15" + "vite@>=5.0.0 <=5.4.18": ">=8.0.16" }, "patchedDependencies": { "@types/node-unifi": "patches/@types__node-unifi.patch", diff --git a/packages/definitions/src/integration.ts b/packages/definitions/src/integration.ts index f43d821bf..2984a2519 100644 --- a/packages/definitions/src/integration.ts +++ b/packages/definitions/src/integration.ts @@ -364,7 +364,7 @@ export const integrationDefs = { }, truenas: { name: "TrueNAS", - secretKinds: [["username", "password"]], + secretKinds: [["username", "password"], ["apiKey"]], iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/truenas.svg", category: ["healthMonitoring"], documentationUrl: createDocumentationLink("/docs/integrations/truenas"), diff --git a/packages/integrations/package.json b/packages/integrations/package.json index 88ea6892a..6e0c81039 100644 --- a/packages/integrations/package.json +++ b/packages/integrations/package.json @@ -47,12 +47,14 @@ "timezones-ical-library": "catalog:", "tsdav": "catalog:", "undici": "catalog:", + "ws": "catalog:", "xml2js": "catalog:", "zod": "catalog:" }, "devDependencies": { "@homarr/tsconfig": "workspace:^0.1.0", "@types/node-unifi": "catalog:", + "@types/ws": "catalog:", "@types/xml2js": "catalog:", "typescript": "catalog:" } diff --git a/packages/integrations/src/base/integration.ts b/packages/integrations/src/base/integration.ts index 22ad8b1ea..e129ca283 100644 --- a/packages/integrations/src/base/integration.ts +++ b/packages/integrations/src/base/integration.ts @@ -85,6 +85,16 @@ export abstract class Integration { return this.createUrl(this.integration.externalUrl ?? this.integration.url, path, queryParams); } + protected webSocketUrl( + path: `/${string}`, + queryParams?: Record, + ) { + const url = this.url(path, queryParams); + // http -> ws, https -> wss + url.protocol = url.protocol.replace("http", "ws"); + return url; + } + public async testConnectionAsync(): Promise { try { const url = new URL(this.integration.url); diff --git a/packages/integrations/src/truenas/test/truenas-api.spec.ts b/packages/integrations/src/truenas/test/truenas-api.spec.ts new file mode 100644 index 000000000..cc75bcc07 --- /dev/null +++ b/packages/integrations/src/truenas/test/truenas-api.spec.ts @@ -0,0 +1,79 @@ +import { describe, expect, test } from "vitest"; + +import { trueNasApis } from "../truenas-api"; + +describe("trueNasApis descriptors", () => { + test("expose the expected endpoints and handshake requirements", () => { + expect(trueNasApis.jsonRpc).toMatchObject({ + kind: "jsonRpc", + path: "/api/current", + requiresSessionHandshake: false, + }); + expect(trueNasApis.legacy).toMatchObject({ + kind: "legacy", + path: "/websocket", + requiresSessionHandshake: true, + }); + }); +}); + +describe("jsonRpc api", () => { + const { buildRequest, matchResponse } = trueNasApis.jsonRpc; + + test("builds a JSON-RPC 2.0 envelope", () => { + expect(buildRequest("id-1", "system.info", [])).toStrictEqual({ + jsonrpc: "2.0", + id: "id-1", + method: "system.info", + params: [], + }); + }); + + test("matches a result for the requested id", () => { + const result = matchResponse({ jsonrpc: "2.0", id: "id-1", result: true }, "id-1"); + expect(result).toStrictEqual({ result: true }); + }); + + test("returns the error when the response carries one", () => { + const error = { code: -32001, message: "Not authenticated" }; + expect(matchResponse({ jsonrpc: "2.0", id: "id-1", error }, "id-1")).toStrictEqual({ error }); + }); + + test("ignores responses for a different id", () => { + expect(matchResponse({ jsonrpc: "2.0", id: "other", result: true }, "id-1")).toBeUndefined(); + }); + + test("ignores non JSON-RPC messages", () => { + expect(matchResponse({ msg: "result", id: "id-1", result: true }, "id-1")).toBeUndefined(); + }); +}); + +describe("legacy api", () => { + const { buildRequest, matchResponse } = trueNasApis.legacy; + + test("builds a DDP method envelope", () => { + expect(buildRequest("id-1", "auth.login", ["user", "pass"])).toStrictEqual({ + id: "id-1", + msg: "method", + method: "auth.login", + params: ["user", "pass"], + }); + }); + + test("matches a result message for the requested id", () => { + expect(matchResponse({ msg: "result", id: "id-1", result: false }, "id-1")).toStrictEqual({ result: false }); + }); + + test("returns the error when the result message carries one", () => { + const error = { error: 13, reason: "boom" }; + expect(matchResponse({ msg: "result", id: "id-1", error }, "id-1")).toStrictEqual({ error }); + }); + + test("ignores responses for a different id", () => { + expect(matchResponse({ msg: "result", id: "other", result: true }, "id-1")).toBeUndefined(); + }); + + test("ignores non-result messages such as the session handshake", () => { + expect(matchResponse({ msg: "connected", session: "abc" }, "id-1")).toBeUndefined(); + }); +}); diff --git a/packages/integrations/src/truenas/test/truenas-integration.spec.ts b/packages/integrations/src/truenas/test/truenas-integration.spec.ts new file mode 100644 index 000000000..28ff3b8d1 --- /dev/null +++ b/packages/integrations/src/truenas/test/truenas-integration.spec.ts @@ -0,0 +1,264 @@ +import { beforeEach, describe, expect, test, vi } from "vitest"; + +import { IntegrationRequestError } from "../../base/errors/http/integration-request-error"; +import type { IntegrationSecret } from "../../base/types"; + +const ws = vi.hoisted(() => { + const sentPayloads: Record[] = []; + const constructedUrls: string[] = []; + // A failure with a `code` emits a coded TLS-style error; without one it mimics a missing endpoint (HTTP 404). + const failures: { path: string; code?: string }[] = []; + let responder: (method: string, params: unknown[]) => unknown = () => undefined; + + type Listener = (...args: unknown[]) => void; + + class FakeWebSocket { + static readonly OPEN = 1; + public readyState = FakeWebSocket.OPEN; + private readonly listeners: Record = {}; + + constructor(url: URL | string) { + constructedUrls.push(url.toString()); + setTimeout(() => { + const failure = failures.find((candidate) => url.toString().includes(candidate.path)); + if (failure) { + const error: Error & { code?: string } = new Error(failure.code ?? "Unexpected server response: 404"); + if (failure.code) error.code = failure.code; + this.dispatch("error", error); + } else { + this.dispatch("open"); + } + }, 0); + } + + on(event: string, listener: Listener) { + (this.listeners[event] ??= []).push(listener); + return this; + } + + once(event: string, listener: Listener) { + const wrapper: Listener = (...args) => { + this.off(event, wrapper); + listener(...args); + }; + return this.on(event, wrapper); + } + + off(event: string, listener: Listener) { + this.listeners[event] = (this.listeners[event] ?? []).filter((candidate) => candidate !== listener); + return this; + } + + send(raw: string) { + const payload = JSON.parse(raw) as Record; + sentPayloads.push(payload); + + if (payload.msg === "connect") { + this.respond(JSON.stringify({ msg: "connected", session: "test-session" })); + return; + } + + const result = responder(payload.method as string, (payload.params as unknown[] | undefined) ?? []); + const envelope = + payload.jsonrpc === "2.0" + ? { jsonrpc: "2.0", id: payload.id, result } + : { msg: "result", id: payload.id, result }; + this.respond(JSON.stringify(envelope)); + } + + close() { + this.readyState = 3; + } + + private respond(message: string) { + setTimeout(() => this.dispatch("message", message), 0); + } + + private dispatch(event: string, ...args: unknown[]) { + // `off` replaces the array rather than mutating it, so iterating it directly is safe. + for (const listener of this.listeners[event] ?? []) listener(...args); + } + } + + return { + FakeWebSocket, + sentPayloads, + constructedUrls, + failures, + setResponder: (fn: (method: string, params: unknown[]) => unknown) => { + responder = fn; + }, + }; +}); + +vi.mock("ws", () => ({ WebSocket: ws.FakeWebSocket })); +vi.mock("@homarr/core/infrastructure/certificates", () => ({ + getAllTrustedCertificatesAsync: vi.fn().mockResolvedValue([]), + getTrustedCertificateHostnamesAsync: vi.fn().mockResolvedValue([]), +})); +vi.mock("@homarr/core/infrastructure/http", () => ({ + createCustomCheckServerIdentity: () => () => undefined, +})); + +import { TrueNasIntegration } from "../truenas-integration"; + +const happyResponder = (method: string) => { + switch (method) { + case "auth.login": + case "auth.login_with_api_key": + return true; + case "system.info": + return { + version: "TrueNAS-SCALE-24.10", + hostname: "nas", + physmem: 16_000_000_000, + model: "Intel Xeon", + uptime_seconds: 3600, + }; + case "reporting.get_data": + return [ + { + name: "cpu", + identifier: "cpu", + aggregations: emptyAggregations(), + start: 0, + end: 1, + legend: [], + data: [[1000, 12]], + }, + { + name: "memory", + identifier: "memory", + aggregations: emptyAggregations(), + start: 0, + end: 1, + legend: [], + data: [[1000, 8_000_000_000]], + }, + { + name: "cputemp", + identifier: "cputemp", + aggregations: emptyAggregations(), + start: 0, + end: 1, + legend: [], + data: [[1000, 45]], + }, + ]; + case "pool.query": + return [{ name: "tank", status: "ONLINE", healthy: true, free: 500, size: 1000, allocated: 500 }]; + case "interface.query": + return [{ id: "eth0", name: "eth0" }]; + case "reporting.netdata_get_data": + return [{ name: "interface", identifier: "eth0", data: [[1000, 100, 200]] }]; + default: + return null; + } +}; + +const emptyAggregations = () => ({ min: {}, mean: {}, max: {} }); + +let integrationCounter = 0; +const createIntegration = (decryptedSecrets: IntegrationSecret[]) => + new TrueNasIntegration({ + id: `truenas-${(integrationCounter += 1)}`, + name: "TrueNAS Test", + url: "https://truenas.local", + externalUrl: null, + decryptedSecrets, + }); + +const credentials: IntegrationSecret[] = [ + { kind: "username", value: "root" }, + { kind: "password", value: "secret" }, +]; + +describe("TrueNasIntegration", () => { + beforeEach(() => { + ws.sentPayloads.length = 0; + ws.constructedUrls.length = 0; + ws.failures.length = 0; + ws.setResponder(happyResponder); + }); + + test("fetches and maps system info over the JSON-RPC API", async () => { + const integration = createIntegration(credentials); + + const result = await integration.getSystemInfoAsync(); + + expect(ws.constructedUrls).toContain("wss://truenas.local/api/current"); + // JSON-RPC does not use the legacy "connect" session handshake. + expect(ws.sentPayloads.some((payload) => payload.msg === "connect")).toBe(false); + + expect(result).toMatchObject({ + version: "TrueNAS-SCALE-24.10", + cpuModelName: "Intel Xeon", + cpuTemp: 45, + memAvailableInBytes: 16_000_000_000, + memUsedInBytes: 8_000_000_000, + uptime: 3600, + rebootRequired: false, + availablePkgUpdates: 0, + loadAverage: null, + gpu: [], + network: { up: 20_000, down: 10_000 }, + fileSystem: [{ deviceName: "tank", available: "1000", used: "500", percentage: 50 }], + smart: [{ deviceName: "tank", healthy: true, overallStatus: "ONLINE", temperature: null }], + }); + }); + + test("authenticates with an API key when one is configured", async () => { + const integration = createIntegration([{ kind: "apiKey", value: "api-key-123" }]); + + await integration.getSystemInfoAsync(); + + const authPayload = ws.sentPayloads.find((payload) => String(payload.method).startsWith("auth.")); + expect(authPayload).toMatchObject({ method: "auth.login_with_api_key", params: ["api-key-123"] }); + }); + + test("authenticates with username and password when no API key is configured", async () => { + const integration = createIntegration(credentials); + + await integration.getSystemInfoAsync(); + + const authPayload = ws.sentPayloads.find((payload) => String(payload.method).startsWith("auth.")); + expect(authPayload).toMatchObject({ method: "auth.login", params: ["root", "secret"] }); + }); + + test("falls back to the legacy websocket API when the JSON-RPC endpoint is unavailable", async () => { + ws.failures.push({ path: "/api/current" }); + const integration = createIntegration(credentials); + + const result = await integration.getSystemInfoAsync(); + + expect(ws.constructedUrls).toContain("wss://truenas.local/api/current"); + expect(ws.constructedUrls).toContain("wss://truenas.local/websocket"); + // The legacy API requires the "connect" session handshake before authenticating. + expect(ws.sentPayloads[0]).toMatchObject({ msg: "connect" }); + expect(ws.sentPayloads.find((payload) => String(payload.method).startsWith("auth."))).toMatchObject({ + msg: "method", + method: "auth.login", + }); + expect(result.version).toBe("TrueNAS-SCALE-24.10"); + }); + + test("rejects when authentication is not successful", async () => { + ws.setResponder((method) => (method.startsWith("auth.") ? false : happyResponder(method))); + const integration = createIntegration(credentials); + + await expect(integration.getSystemInfoAsync()).rejects.toThrow(); + }); + + test("surfaces a self-signed certificate as a certificate request error without falling back", async () => { + ws.failures.push({ path: "/api/current", code: "DEPTH_ZERO_SELF_SIGNED_CERT" }); + ws.failures.push({ path: "/websocket", code: "DEPTH_ZERO_SELF_SIGNED_CERT" }); + const integration = createIntegration(credentials); + + const error = await integration.getSystemInfoAsync().catch((caught: unknown) => caught); + + expect(error).toBeInstanceOf(IntegrationRequestError); + expect((error as IntegrationRequestError).cause).toMatchObject({ type: "certificate", reason: "untrusted" }); + // A certificate failure is endpoint-independent, so the legacy API must not be tried. + expect(ws.constructedUrls).not.toContain("wss://truenas.local/websocket"); + }); +}); diff --git a/packages/integrations/src/truenas/truenas-api.ts b/packages/integrations/src/truenas/truenas-api.ts new file mode 100644 index 000000000..322c3e856 --- /dev/null +++ b/packages/integrations/src/truenas/truenas-api.ts @@ -0,0 +1,50 @@ +export type TrueNasApiKind = "jsonRpc" | "legacy"; + +export type TrueNasResponse = { result: unknown } | { error: unknown }; + +export interface TrueNasApi { + kind: TrueNasApiKind; + /** Websocket path appended to the integration URL. */ + path: `/${string}`; + /** The legacy DDP API requires a "connect" handshake before authentication, the JSON-RPC API does not. */ + requiresSessionHandshake: boolean; + /** Builds the request envelope for a method call. */ + buildRequest: (id: string, method: string, params: unknown[]) => Record; + /** + * Returns the response payload when `message` is the reply to `id`, + * otherwise `undefined` so the caller keeps waiting for a later message. + */ + matchResponse: (message: Record, id: string) => TrueNasResponse | undefined; +} + +/** + * JSON-RPC 2.0 API introduced in TrueNAS SCALE 24.10 (Electric Eel) and the + * legacy DDP-style websocket API used before it. Both expose the same + * middleware methods, so only the transport envelope differs. + * @see https://www.truenas.com/docs/api/scale_rest_api.html + * @see https://www.truenas.com/docs/api/scale_websocket_api.html#websocket_protocol + */ +export const trueNasApis = { + jsonRpc: { + kind: "jsonRpc", + path: "/api/current", + requiresSessionHandshake: false, + buildRequest: (id: string, method: string, params: unknown[]) => ({ jsonrpc: "2.0", id, method, params }), + matchResponse: (message: Record, id: string) => { + if (message.id !== id || message.jsonrpc !== "2.0") return undefined; + if (message.error != null) return { error: message.error }; + return { result: message.result }; + }, + }, + legacy: { + kind: "legacy", + path: "/websocket", + requiresSessionHandshake: true, + buildRequest: (id: string, method: string, params: unknown[]) => ({ id, msg: "method", method, params }), + matchResponse: (message: Record, id: string) => { + if (message.id !== id || message.msg !== "result") return undefined; + if (message.error != null) return { error: message.error }; + return { result: message.result }; + }, + }, +} satisfies Record; diff --git a/packages/integrations/src/truenas/truenas-client.ts b/packages/integrations/src/truenas/truenas-client.ts new file mode 100644 index 000000000..e0f04f447 --- /dev/null +++ b/packages/integrations/src/truenas/truenas-client.ts @@ -0,0 +1,315 @@ +import type { RawData } from "ws"; +import { WebSocket } from "ws"; +import z from "zod"; + +import { createId } from "@homarr/common"; +import { matchErrorCode, RequestError, ResponseError } from "@homarr/common/server"; +import { + getAllTrustedCertificatesAsync, + getTrustedCertificateHostnamesAsync, +} from "@homarr/core/infrastructure/certificates"; +import { createCustomCheckServerIdentity } from "@homarr/core/infrastructure/http"; +import { createLogger } from "@homarr/core/infrastructure/logs"; + +import type { IntegrationTestingInput } from "../base/integration"; +import type { TrueNasApi } from "./truenas-api"; +import { trueNasApis } from "./truenas-api"; + +const logger = createLogger({ module: "trueNasClient" }); + +const REQUEST_TIMEOUT_MS = 5000; + +type CertificateOptions = IntegrationTestingInput["options"]; + +export type TrueNasCredentials = { apiKey: string } | { username: string; password: string }; + +/** + * Handles talking to a TrueNAS server: opening a websocket with Homarr's + * trusted certificates, negotiating the API variant, authenticating, and + * sending method requests. Connections are reused across the per-request + * integration instances and reconnected transparently when the server drops + * an idle socket. + */ +export class TrueNasClient { + // Keyed by integration id. The value is the in-flight connection promise so concurrent + // callers reuse a single socket instead of racing to open duplicates. + private static readonly connectionMap = new Map>(); + private static readonly apiMap = new Map(); + + constructor( + private readonly id: string, + private readonly webSocketUrl: (path: `/${string}`) => URL, + private readonly credentials: TrueNasCredentials, + ) {} + + /** Sends an authenticated request, reusing the cached connection while it is open. */ + public async requestAsync(method: string, params: unknown[] = []): Promise { + const socket = await this.getSocketAsync(); + return socket.requestAsync(method, params); + } + + /** + * Opens a connection with the provided certificate options, authenticates, + * and closes it. Used by the connection test, which may run with updated + * credentials, so any cached connection is dropped and the API re-detected. + */ + public async testAsync(certificate: CertificateOptions): Promise { + this.evictConnection(); + TrueNasClient.apiMap.delete(this.id); + + const socket = await this.openSocketAsync(certificate); + try { + await this.authenticateAsync(socket); + } finally { + socket.close(); + } + } + + private getSocketAsync(): Promise { + let connection = TrueNasClient.connectionMap.get(this.id); + if (!connection) { + connection = this.connectAndAuthenticateAsync(); + TrueNasClient.connectionMap.set(this.id, connection); + + const evict = () => { + if (TrueNasClient.connectionMap.get(this.id) === connection) { + TrueNasClient.connectionMap.delete(this.id); + } + }; + // Reconnect on the next request once this attempt fails or the server drops the socket. + connection.then((socket) => socket.onClose(evict), evict); + } + + return connection; + } + + private async connectAndAuthenticateAsync(): Promise { + const socket = await this.openSocketAsync(await resolveCertificateOptionsAsync()); + try { + await this.authenticateAsync(socket); + } catch (error) { + // Never keep an unauthenticated socket, it would be reused without re-authenticating. + socket.close(); + throw error; + } + return socket; + } + + private evictConnection() { + const connection = TrueNasClient.connectionMap.get(this.id); + if (!connection) return; + + TrueNasClient.connectionMap.delete(this.id); + connection.then((socket) => socket.close()).catch(() => undefined); + } + + /** + * Connects using the JSON-RPC API (TrueNAS 24.10+) when available and falls + * back to the legacy websocket API otherwise. A missing JSON-RPC endpoint + * surfaces as a plain protocol error; certificate, connection, DNS and + * timeout errors are endpoint-independent and are never retried. + */ + private async openSocketAsync(certificate: CertificateOptions): Promise { + const cachedApi = TrueNasClient.apiMap.get(this.id); + if (cachedApi) { + return openTrueNasSocketAsync(this.webSocketUrl(cachedApi.path), cachedApi, certificate); + } + + try { + const socket = await openTrueNasSocketAsync( + this.webSocketUrl(trueNasApis.jsonRpc.path), + trueNasApis.jsonRpc, + certificate, + ); + TrueNasClient.apiMap.set(this.id, trueNasApis.jsonRpc); + return socket; + } catch (error) { + if (error instanceof RequestError) throw error; + + logger.debug("JSON-RPC API unavailable, falling back to the legacy websocket API", { + error: error instanceof Error ? error.message : undefined, + }); + const socket = await openTrueNasSocketAsync( + this.webSocketUrl(trueNasApis.legacy.path), + trueNasApis.legacy, + certificate, + ); + TrueNasClient.apiMap.set(this.id, trueNasApis.legacy); + return socket; + } + } + + /** + * Authenticates with an API key when one is configured, otherwise with the + * username and password. Both methods work on either API. + * @see https://www.truenas.com/docs/api/scale_websocket_api.html#websocket_protocol + */ + private async authenticateAsync(socket: TrueNasSocket): Promise { + const response = + "apiKey" in this.credentials + ? await socket.requestAsync("auth.login_with_api_key", [this.credentials.apiKey]) + : await socket.requestAsync("auth.login", [this.credentials.username, this.credentials.password]); + + const success = await z.boolean().parseAsync(response); + if (!success) throw new ResponseError({ status: 401 }); + } +} + +/** + * Wraps a single websocket connection and speaks whichever TrueNAS API + * ({@link trueNasApis}) was negotiated when it was opened. + */ +class TrueNasSocket { + constructor( + private readonly webSocket: WebSocket, + private readonly api: TrueNasApi, + ) {} + + public close() { + this.webSocket.close(); + } + + public onClose(listener: () => void) { + this.webSocket.once("close", listener); + } + + /** + * The legacy DDP API requires a "connect" handshake to obtain a session + * before any method can be called. + * @see https://www.truenas.com/docs/api/scale_websocket_api.html#websocket_protocol + */ + public registerSessionAsync(): Promise { + return new Promise((resolve, reject) => { + const handler = (raw: RawData) => { + const message = parseMessage(raw); + if (message?.msg === "connected") { + this.webSocket.off("message", handler); + resolve(); + } else if (message?.msg === "failed") { + this.webSocket.off("message", handler); + reject(new Error("Unable to establish TrueNAS session")); + } + }; + + this.webSocket.on("message", handler); + this.webSocket.send(JSON.stringify({ msg: "connect", version: "1", support: ["1"] })); + }); + } + + /** + * Sends a method request and resolves with its result. Rejects after + * {@link REQUEST_TIMEOUT_MS} when no matching response was received. + */ + public requestAsync(method: string, params: unknown[] = []): Promise { + return new Promise((resolve, reject) => { + const id = createId(); + + const cleanup = () => { + clearTimeout(timeoutId); + this.webSocket.off("message", handler); + this.webSocket.off("close", onClose); + this.webSocket.off("error", onError); + }; + + const handler = (raw: RawData) => { + const message = parseMessage(raw); + if (!message) return; + + const response = this.api.matchResponse(message, id); + if (!response) return; + + cleanup(); + if ("error" in response) { + reject(new Error(`TrueNAS method "${method}" failed: ${JSON.stringify(response.error)}`)); + return; + } + logger.debug("Received method response", { id, method, api: this.api.kind }); + resolve(response.result); + }; + + // A dropped connection would otherwise leave the request hanging until the timeout below. + const onClose = () => { + cleanup(); + reject( + new RequestError( + { type: "connection", reason: "reset", code: "ECONNRESET" }, + { cause: new Error("Connection closed before a response was received") }, + ), + ); + }; + const onError = (error: Error) => { + cleanup(); + reject(error); + }; + + const timeoutId = setTimeout(() => { + cleanup(); + reject( + new RequestError( + { + type: "timeout", + reason: "aborted", + code: "ECONNABORTED", + }, + { cause: new Error("Canceled request after 5 seconds") }, + ), + ); + }, REQUEST_TIMEOUT_MS); + + this.webSocket.on("message", handler); + this.webSocket.once("close", onClose); + this.webSocket.once("error", onError); + logger.debug("Sending method request", { id, method, api: this.api.kind }); + this.webSocket.send(JSON.stringify(this.api.buildRequest(id, method, params))); + }); + } +} + +/** + * Opens a websocket using Homarr's trusted certificates and performs the + * session handshake when the API requires it. TLS, connection, DNS and timeout + * failures are translated into {@link RequestError}s so the connection test can + * offer to trust a self-signed certificate, exactly like the HTTP integrations. + */ +const openTrueNasSocketAsync = async ( + url: URL, + api: TrueNasApi, + certificate: CertificateOptions, +): Promise => { + logger.debug("Connecting to TrueNAS websocket", { url: url.toString(), api: api.kind }); + + const webSocket = await new Promise((resolve, reject) => { + const socket = new WebSocket(url, { + ca: certificate.ca, + // The @types/ws contract types this as returning a boolean, but ws forwards it to + // tls.connect which uses Node's `Error | undefined` contract that our helper follows. + checkServerIdentity: certificate.checkServerIdentity as never, + }); + + socket.once("open", () => resolve(socket)); + socket.once("error", (error: Error & { code?: string }) => { + const matched = error.code ? matchErrorCode(error.code) : undefined; + reject(matched ? new RequestError(matched, { cause: error }) : error); + }); + }); + + const socket = new TrueNasSocket(webSocket, api); + if (api.requiresSessionHandshake) await socket.registerSessionAsync(); + return socket; +}; + +const resolveCertificateOptionsAsync = async (): Promise => ({ + ca: await getAllTrustedCertificatesAsync(), + checkServerIdentity: createCustomCheckServerIdentity(await getTrustedCertificateHostnamesAsync()), +}); + +const parseMessage = (raw: RawData): Record | undefined => { + try { + const parsed: unknown = JSON.parse(raw.toString()); + return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) + ? (parsed as Record) + : undefined; + } catch { + return undefined; + } +}; diff --git a/packages/integrations/src/truenas/truenas-integration.ts b/packages/integrations/src/truenas/truenas-integration.ts index 8d64f848c..adbe32b3b 100644 --- a/packages/integrations/src/truenas/truenas-integration.ts +++ b/packages/integrations/src/truenas/truenas-integration.ts @@ -1,8 +1,6 @@ import dayjs from "dayjs"; import z from "zod"; -import { createId } from "@homarr/common"; -import { RequestError, ResponseError } from "@homarr/common/server"; import { createLogger } from "@homarr/core/infrastructure/logs"; import type { IntegrationTestingInput } from "../base/integration"; @@ -10,252 +8,21 @@ import { Integration } from "../base/integration"; import type { TestingResult } from "../base/test-connection/test-connection-service"; import type { ISystemHealthMonitoringIntegration } from "../interfaces/health-monitoring/health-monitoring-integration"; import type { SystemHealthMonitoring } from "../interfaces/health-monitoring/health-monitoring-types"; +import type { TrueNasCredentials } from "./truenas-client"; +import { TrueNasClient } from "./truenas-client"; const logger = createLogger({ module: "trueNasIntegration" }); const NETWORK_MULTIPLIER = 100; export class TrueNasIntegration extends Integration implements ISystemHealthMonitoringIntegration { - private static webSocketMap = new Map(); - - private wsUrl() { - const url = super.url("/websocket"); - url.protocol = url.protocol.replace("http", "ws"); - return url; - } - - private get webSocket() { - return TrueNasIntegration.webSocketMap.get(this.integration.id) ?? null; - } - - protected async testingAsync(_input: IntegrationTestingInput): Promise { - const webSocket = await this.connectWebSocketAsync(); - await this.registerSessionAsync(webSocket); - await this.authenticateWebSocketAsync(webSocket); - - // Remove current socket connection so we can authenticate with updated credentials - TrueNasIntegration.webSocketMap.delete(this.integration.id); + private client?: TrueNasClient; + protected async testingAsync(input: IntegrationTestingInput): Promise { + await this.getClient().testAsync(input.options); return { success: true }; } - /** - * TrueNAS API uses WebSocket. This function connects to the socket - * and resolves the promise if the connection was successful. - * @see https://www.truenas.com/docs/api/scale_websocket_api.html - */ - private async connectWebSocketAsync(): Promise { - logger.debug("Connecting to websocket server", { - url: this.wsUrl(), - }); - const webSocket = new WebSocket(this.wsUrl()); - - return new Promise((resolve, reject) => { - webSocket.onopen = () => { - logger.debug("Connected to websocket server", { - url: this.wsUrl(), - }); - resolve(webSocket); - }; - - webSocket.onerror = () => { - reject(new Error("Failed to connect")); - }; - }); - } - - /** - * Before authentication, a session must be obtained from the server using the "connect" event. - * @see https://www.truenas.com/docs/api/scale_websocket_api.html#websocket_protocol - */ - private async registerSessionAsync(webSocket: WebSocket): Promise { - return new Promise((resolve, reject) => { - const subscribe = (event: MessageEvent) => { - const data = JSON.parse(event.data) as { msg: string }; - if (data.msg === "connected") { - webSocket.removeEventListener("message", subscribe); - resolve(); - } else if (data.msg === "failed") { - webSocket.removeEventListener("message", subscribe); - reject(new Error("Unable to establish connection")); - } - }; - - webSocket.addEventListener("message", subscribe); - webSocket.send( - JSON.stringify({ - msg: "connect", - version: "1", // this must be number, not string - support: ["1"], // this must be number, not string - }), - ); - }); - } - - /** - * After a session was obtained, the session can be authenticated. - * @see https://www.truenas.com/docs/api/scale_websocket_api.html#websocket_protocol - */ - private async authenticateWebSocketAsync(webSocket?: WebSocket): Promise { - logger.debug("Authenticating with username and password", { - url: this.wsUrl(), - }); - const response = await this.requestAsync( - "auth.login", - [this.getSecretValue("username"), this.getSecretValue("password")], - webSocket, - ); - const result = await z.boolean().parseAsync(response); - if (!result) throw new ResponseError({ status: 401 }); - logger.debug("Authenticated successfully with username and password", { - url: this.wsUrl(), - }); - } - - private async getPoolsAsync() { - logger.debug("Retrieving pools", { - url: this.wsUrl(), - }); - - const response = await this.requestAsync("pool.query", [ - [], - { - extra: { - is_upgraded: true, - }, - }, - ]); - const result = await poolSchema.parseAsync(response); - // Offline / exported pools have null values for allocated, size and free, so we filter them out - // See https://github.com/homarr-labs/homarr/issues/5194 - const activePools = result - .map((pool) => { - if (pool.allocated !== null && pool.size !== null && pool.free !== null) { - return { - ...pool, - allocated: pool.allocated, - size: pool.size, - free: pool.free, - }; - } - - return null; - }) - .filter((pool) => pool !== null); - logger.debug("Retrieved pools", { - url: this.wsUrl(), - totalCount: result.length, - activeCount: activePools.length, - }); - return activePools; - } - - /** - * Retrieves data using the reporting method - * @see https://www.truenas.com/docs/api/scale_websocket_api.html#reporting - */ - private async getReportingAsync(): Promise { - logger.debug("Retrieving reporting data", { - url: this.wsUrl(), - }); - - const response = await this.requestAsync("reporting.get_data", [ - [ - { - name: "cpu", - }, - { - name: "memory", - }, - { - name: "cputemp", - }, - ], - { - aggregate: true, - start: dayjs().add(-5, "minutes").unix(), - end: dayjs().unix(), - }, - ]); - const result = await z.array(reportingItemSchema).parseAsync(response); - - logger.debug("Retrieved reporting data", { - url: this.wsUrl(), - count: result.length, - }); - return result; - } - - /** - * Retrieves a list of all available network interfaces - * @see https://www.truenas.com/docs/core/13.0/api/core_websocket_api.html#interface - */ - private async getNetworkInterfacesAsync(): Promise> { - logger.debug("Retrieving available network-interfaces", { - url: this.wsUrl(), - }); - - const response = await this.requestAsync("interface.query", [ - [], // no filters - {}, - ]); - const result = await networkInterfaceSchema.parseAsync(response); - - logger.debug("Retrieved available network-interfaces", { - url: this.wsUrl(), - count: result.length, - }); - return result; - } - - /** - * Retrieves reporting network data of the last 5 minutes - * @see https://www.truenas.com/docs/api/scale_websocket_api.html#reporting - */ - private async getReportingNetdataAsync(): Promise> { - const networkInterfaces = await this.getNetworkInterfacesAsync(); - - logger.debug("Retrieving reporting network data", { - url: this.wsUrl(), - }); - - const response = await this.requestAsync("reporting.netdata_get_data", [ - networkInterfaces.map((networkInterface) => ({ - name: "interface", - identifier: networkInterface.id, - })), - { - start: dayjs().add(-5, "minutes").unix(), - end: dayjs().unix(), - }, - ]); - const result = await reportingNetDataSchema.parseAsync(response); - - logger.debug("Retrieved reporting-network-data", { - url: this.wsUrl(), - count: result.length, - }); - return result; - } - - /** - * Retrieves information about the system - * @see https://www.truenas.com/docs/api/scale_websocket_api.html#system - */ - private async getSystemInformationAsync(): Promise> { - logger.debug("Retrieving system-information", { - url: this.wsUrl(), - }); - - const response = await this.requestAsync("system.info"); - const result = await systemInfoSchema.parseAsync(response); - - logger.debug("Retrieved system-information", { - url: this.wsUrl(), - }); - return result; - } - public async getSystemInfoAsync(): Promise { const systemInformation = await this.getSystemInformationAsync(); const reporting = await this.getReportingAsync(); @@ -272,7 +39,7 @@ export class TrueNasIntegration extends Integration implements ISystemHealthMoni return { cpuUtilization: cpuData.reduce((acc, item) => acc + (item > 100 ? 0 : item), 0) / cpuData.length, - cpuTemp: Math.max(...cpuTempData.filter((_item, i) => i > 0)), + cpuTemp: Math.max(...cpuTempData.filter((_item, index) => index > 0)), memAvailableInBytes: systemInformation.physmem, memUsedInBytes: memoryData[1] ?? 0, // Index 0 is UNIX timestamp, Index 1 is free space in bytes fileSystem: datasets.map((dataset) => ({ @@ -301,87 +68,164 @@ export class TrueNasIntegration extends Integration implements ISystemHealthMoni }; } - /** - * Send a request through websocket and return response - * Times out after 5 seconds when no response was received. - * @param method json-rpc method to call - * @param params array of parameters - * @param webSocketOverride override of webSocket, helpful for not storing the connection - * @returns result of json-rpc call - */ - private async requestAsync(method: string, params: unknown[] = [], webSocketOverride?: WebSocket) { - let webSocket = webSocketOverride ?? this.webSocket; - if (webSocket?.readyState !== WebSocket.OPEN) { - logger.debug("Connecting to websocket", { - url: this.wsUrl(), - }); - // We can only land here with static webSocket - webSocket = await this.connectWebSocketAsync(); - await this.registerSessionAsync(webSocket); - - TrueNasIntegration.webSocketMap.set(this.integration.id, webSocket); - await this.authenticateWebSocketAsync(); - } - - return await new Promise((resolve, reject) => { - const id = createId(); - const handler = (event: MessageEvent) => { - const data = JSON.parse(event.data) as Record; - if (data.msg !== "result") return; - if (data.id !== id) return; - - clearTimeout(timeoutId); - webSocket.removeEventListener("message", handler); - logger.debug("Received method response", { - id, - method, - url: this.wsUrl(), - }); - resolve(data.result); - }; - const timeoutId = setTimeout(() => { - webSocket.removeEventListener("message", handler); - reject( - new RequestError( - { - type: "timeout", - reason: "aborted", - code: "ECONNABORTED", - }, - { cause: new Error("Canceled request after 5 seconds") }, - ), - ); - }, 5000); - - webSocket.addEventListener("message", handler); - - logger.debug("Sending method request", { - id, - method, - url: this.wsUrl(), - }); - - webSocket.send( - JSON.stringify({ - id, - msg: "method", - method, - params, - }), - ); - }); + private getClient(): TrueNasClient { + return (this.client ??= this.createClient()); } - private extractNetworkTrafficData = (data: z.infer, index = 1 | 2) => { + private createClient(): TrueNasClient { + const credentials: TrueNasCredentials = this.hasSecretValue("apiKey") + ? { apiKey: this.getSecretValue("apiKey") } + : { username: this.getSecretValue("username"), password: this.getSecretValue("password") }; + + return new TrueNasClient(this.integration.id, (path) => this.webSocketUrl(path), credentials); + } + + private async requestAsync(method: string, params: unknown[] = []): Promise { + return this.getClient().requestAsync(method, params); + } + + private async getPoolsAsync() { + logger.debug("Retrieving pools", { url: this.integration.url }); + + const response = await this.requestAsync("pool.query", [ + [], + { + extra: { + is_upgraded: true, + }, + }, + ]); + const result = await poolSchema.parseAsync(response); + // Offline / exported pools have null values for allocated, size and free, so we filter them out + // See https://github.com/homarr-labs/homarr/issues/5194 + const activePools = result + .map((pool) => { + if (pool.allocated !== null && pool.size !== null && pool.free !== null) { + return { + ...pool, + allocated: pool.allocated, + size: pool.size, + free: pool.free, + }; + } + + return null; + }) + .filter((pool) => pool !== null); + logger.debug("Retrieved pools", { + url: this.integration.url, + totalCount: result.length, + activeCount: activePools.length, + }); + return activePools; + } + + /** + * Retrieves data using the reporting method + * @see https://www.truenas.com/docs/api/scale_websocket_api.html#reporting + */ + private async getReportingAsync(): Promise { + logger.debug("Retrieving reporting data", { url: this.integration.url }); + + const response = await this.requestAsync("reporting.get_data", [ + [ + { + name: "cpu", + }, + { + name: "memory", + }, + { + name: "cputemp", + }, + ], + { + aggregate: true, + start: dayjs().add(-5, "minutes").unix(), + end: dayjs().unix(), + }, + ]); + const result = await z.array(reportingItemSchema).parseAsync(response); + + logger.debug("Retrieved reporting data", { + url: this.integration.url, + count: result.length, + }); + return result; + } + + /** + * Retrieves a list of all available network interfaces + * @see https://www.truenas.com/docs/core/13.0/api/core_websocket_api.html#interface + */ + private async getNetworkInterfacesAsync(): Promise> { + logger.debug("Retrieving available network-interfaces", { url: this.integration.url }); + + const response = await this.requestAsync("interface.query", [ + [], // no filters + {}, + ]); + const result = await networkInterfaceSchema.parseAsync(response); + + logger.debug("Retrieved available network-interfaces", { + url: this.integration.url, + count: result.length, + }); + return result; + } + + /** + * Retrieves reporting network data of the last 5 minutes + * @see https://www.truenas.com/docs/api/scale_websocket_api.html#reporting + */ + private async getReportingNetdataAsync(): Promise> { + const networkInterfaces = await this.getNetworkInterfacesAsync(); + + logger.debug("Retrieving reporting network data", { url: this.integration.url }); + + const response = await this.requestAsync("reporting.netdata_get_data", [ + networkInterfaces.map((networkInterface) => ({ + name: "interface", + identifier: networkInterface.id, + })), + { + start: dayjs().add(-5, "minutes").unix(), + end: dayjs().unix(), + }, + ]); + const result = await reportingNetDataSchema.parseAsync(response); + + logger.debug("Retrieved reporting-network-data", { + url: this.integration.url, + count: result.length, + }); + return result; + } + + /** + * Retrieves information about the system + * @see https://www.truenas.com/docs/api/scale_websocket_api.html#system + */ + private async getSystemInformationAsync(): Promise> { + logger.debug("Retrieving system-information", { url: this.integration.url }); + + const response = await this.requestAsync("system.info"); + const result = await systemInfoSchema.parseAsync(response); + + logger.debug("Retrieved system-information", { url: this.integration.url }); + return result; + } + + private extractNetworkTrafficData = (data: z.infer, index: 1 | 2) => { return data.reduce((acc, current) => acc + (current.data.at(-1)?.at(index) ?? 0), 0); }; - private extractLatestReportingData(data: ReportingItem[], key: ReportingItem["identifier"]) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const dataObject = data.find((item) => item.identifier === key)!; - // TODO: check why the below sorting is done, because right now it compares number[] with number[]? - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - return dataObject.data.sort((item1, item2) => (item1 > item2 ? -1 : 1))[0]!; + private extractLatestReportingData(data: ReportingItem[], identifier: ReportingItem["identifier"]) { + const item = data.find((reportingItem) => reportingItem.identifier === identifier); + // Reporting rows are [timestamp, ...values] in ascending time order, so the last row is the most recent reading. + const latest = item?.data.at(-1); + if (!latest) throw new Error(`TrueNAS returned no "${identifier}" reporting data`); + return latest; } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b6613db27..e976840e2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -40,8 +40,8 @@ catalogs: specifier: 7.2.1 version: 7.2.1 '@gfazioli/mantine-onboarding-tour': - specifier: ^4.0.3 - version: 4.0.3 + specifier: ^4.0.4 + version: 4.0.4 '@gitbeaker/rest': specifier: ^43.8.0 version: 43.8.0 @@ -253,8 +253,8 @@ catalogs: specifier: ^1.26.6 version: 1.26.6 '@types/react': - specifier: 19.2.15 - version: 19.2.15 + specifier: 19.2.16 + version: 19.2.16 '@types/react-dom': specifier: 19.2.3 version: 19.2.3 @@ -406,8 +406,8 @@ catalogs: specifier: 3.22.4 version: 3.22.4 next: - specifier: 16.2.6 - version: 16.2.6 + specifier: 16.2.7 + version: 16.2.7 next-auth: specifier: 5.0.0-beta.31 version: 5.0.0-beta.31 @@ -421,8 +421,8 @@ catalogs: specifier: ^5.0.5 version: 5.0.5 oxfmt: - specifier: ^0.52.0 - version: 0.52.0 + specifier: ^0.53.0 + version: 0.53.0 oxlint: specifier: ^1.67.0 version: 1.67.0 @@ -439,11 +439,11 @@ catalogs: specifier: 1.1.1 version: 1.1.1 react: - specifier: 19.2.6 - version: 19.2.6 + specifier: 19.2.7 + version: 19.2.7 react-dom: - specifier: 19.2.6 - version: 19.2.6 + specifier: 19.2.7 + version: 19.2.7 react-error-boundary: specifier: ^6.1.2 version: 6.1.2 @@ -538,7 +538,7 @@ catalogs: overrides: '@babel/helpers@<7.26.10': '>=7.29.7' '@babel/runtime@<7.26.10': '>=7.29.7' - axios@>=1.0.0 <1.8.2: '>=1.16.1' + axios@>=1.0.0 <1.8.2: '>=1.17.0' brace-expansion@>=2.0.0 <=2.0.1: '>=5.0.6' brace-expansion@>=1.0.0 <=1.1.11: '>=5.0.6' esbuild@<=0.24.2: '>=0.28.0' @@ -548,13 +548,13 @@ overrides: nanoid@>=4.0.0 <5.0.9: '>=5.1.11' prismjs@<1.30.0: '>=1.30.0' proxmox-api>undici: 7.24.6 - react-is: ^19.2.6 - rollup@>=4.0.0 <4.22.4: '>=4.60.4' + react-is: ^19.2.7 + rollup@>=4.0.0 <4.22.4: '>=4.61.0' sha.js@<=2.4.11: '>=2.4.12' tar-fs@>=3.0.0 <3.0.9: '>=3.1.2' tar-fs@>=2.0.0 <2.1.3: '>=3.1.2' tmp@<=0.2.3: '>=0.2.7' - vite@>=5.0.0 <=5.4.18: '>=8.0.15' + vite@>=5.0.0 <=5.4.18: '>=8.0.16' patchedDependencies: '@types/node-unifi': @@ -618,7 +618,7 @@ importers: version: 2.2.3 oxfmt: specifier: 'catalog:' - version: 0.52.0 + version: 0.53.0 oxlint: specifier: 'catalog:' version: 1.67.0 @@ -645,19 +645,19 @@ importers: dependencies: '@dnd-kit/core': specifier: 'catalog:' - version: 6.3.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 6.3.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@dnd-kit/modifiers': specifier: 'catalog:' - version: 9.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 9.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7) '@dnd-kit/sortable': specifier: 'catalog:' - version: 10.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 10.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7) '@dnd-kit/utilities': specifier: 'catalog:' - version: 3.2.2(react@19.2.6) + version: 3.2.2(react@19.2.7) '@gfazioli/mantine-onboarding-tour': specifier: 'catalog:' - version: 4.0.3(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 4.0.4(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(@tabler/icons-react@3.44.0(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@homarr/analytics': specifier: workspace:^0.1.0 version: link:../../packages/analytics @@ -756,46 +756,46 @@ importers: version: 9.2.2(chroma-js@3.2.0) '@mantine/core': specifier: 'catalog:' - version: 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@mantine/dropzone': specifier: 'catalog:' - version: 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@mantine/hooks': specifier: 'catalog:' - version: 9.2.2(react@19.2.6) + version: 9.2.2(react@19.2.7) '@mantine/modals': specifier: 'catalog:' - version: 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@mantine/tiptap': specifier: 'catalog:' - version: 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tiptap/extension-link@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))(@tiptap/react@3.24.0(@floating-ui/dom@1.7.6)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(@tiptap/extension-link@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))(@tiptap/react@3.24.0(@floating-ui/dom@1.7.6)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@modelcontextprotocol/sdk': specifier: 'catalog:' version: 1.26.0(zod@4.4.3) '@scalar/api-reference-react': specifier: 'catalog:' - version: 0.9.42(react@19.2.6)(tailwindcss@4.3.0)(typescript@5.9.3)(zod@4.4.3) + version: 0.9.42(react@19.2.7)(tailwindcss@4.3.0)(typescript@5.9.3)(zod@4.4.3) '@tabler/icons-react': specifier: 'catalog:' - version: 3.44.0(react@19.2.6) + version: 3.44.0(react@19.2.7) '@tanstack/react-query': specifier: 'catalog:' - version: 5.100.14(react@19.2.6) + version: 5.100.14(react@19.2.7) '@tanstack/react-query-devtools': specifier: 'catalog:' - version: 5.100.14(@tanstack/react-query@5.100.14(react@19.2.6))(react@19.2.6) + version: 5.100.14(@tanstack/react-query@5.100.14(react@19.2.7))(react@19.2.7) '@tanstack/react-query-next-experimental': specifier: 'catalog:' - version: 5.100.14(@tanstack/react-query@5.100.14(react@19.2.6))(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(react@19.2.6) + version: 5.100.14(@tanstack/react-query@5.100.14(react@19.2.7))(next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0))(react@19.2.7) '@trpc/client': specifier: 'catalog:' version: 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3) '@trpc/next': specifier: 'catalog:' - version: 11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/react-query@11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@5.9.3) + version: 11.17.0(@tanstack/react-query@5.100.14(react@19.2.7))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/react-query@11.17.0(@tanstack/react-query@5.100.14(react@19.2.7))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.7)(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.9.3) '@trpc/react-query': specifier: 'catalog:' - version: 11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3) + version: 11.17.0(@tanstack/react-query@5.100.14(react@19.2.7))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.7)(typescript@5.9.3) '@trpc/server': specifier: 'catalog:' version: 11.17.0(typescript@5.9.3) @@ -834,16 +834,16 @@ importers: version: 3.15.0(@noble/hashes@2.0.1) jotai: specifier: 'catalog:' - version: 2.20.0(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@19.2.15)(react@19.2.6) + version: 2.20.0(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@19.2.16)(react@19.2.7) mantine-react-table: specifier: 'catalog:' - version: mantine-react-table-open@9.0.3(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: mantine-react-table-open@9.0.3(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(@tabler/icons-react@3.44.0(react@19.2.7))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) mcp-handler: specifier: 'catalog:' - version: 1.1.0(@modelcontextprotocol/sdk@1.26.0(zod@4.4.3))(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0)) + version: 1.1.0(@modelcontextprotocol/sdk@1.26.0(zod@4.4.3))(next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0)) next: specifier: 'catalog:' - version: 16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0) + version: 16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0) postcss-preset-mantine: specifier: 'catalog:' version: 1.18.0(postcss@8.5.15) @@ -852,16 +852,16 @@ importers: version: 1.30.0 react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.7 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.7(react@19.2.7) react-error-boundary: specifier: 'catalog:' - version: 6.1.2(react@19.2.6) + version: 6.1.2(react@19.2.7) react-simple-code-editor: specifier: 'catalog:' - version: 0.14.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 0.14.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) sass: specifier: 'catalog:' version: 1.100.0 @@ -870,10 +870,10 @@ importers: version: 2.2.6 trpc-to-mcp: specifier: 'catalog:' - version: 1.3.2(@trpc/server@11.17.0(typescript@5.9.3))(better-auth@1.6.14(@opentelemetry/api@1.9.0)(better-sqlite3@12.10.0)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@libsql/client-wasm@0.14.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.10.0)(gel@2.0.0)(kysely@0.29.2)(mysql2@3.22.4(@types/node@24.12.4))(pg@8.21.0))(mysql2@3.22.4(@types/node@24.12.4))(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.8)(vue@3.5.35(typescript@5.9.3)))(mcp-handler@1.1.0(@modelcontextprotocol/sdk@1.26.0(zod@4.4.3))(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0)))(zod@4.4.3) + version: 1.3.2(@trpc/server@11.17.0(typescript@5.9.3))(better-auth@1.6.14(@opentelemetry/api@1.9.0)(better-sqlite3@12.10.0)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@libsql/client-wasm@0.14.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.10.0)(gel@2.0.0)(kysely@0.29.2)(mysql2@3.22.4(@types/node@24.12.4))(pg@8.21.0))(mysql2@3.22.4(@types/node@24.12.4))(next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0))(pg@8.21.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vitest@4.1.8)(vue@3.5.35(typescript@5.9.3)))(mcp-handler@1.1.0(@modelcontextprotocol/sdk@1.26.0(zod@4.4.3))(next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0)))(zod@4.4.3) use-deep-compare-effect: specifier: 'catalog:' - version: 1.8.1(react@19.2.6) + version: 1.8.1(react@19.2.7) yaml: specifier: 'catalog:' version: 2.9.0 @@ -895,10 +895,10 @@ importers: version: 1.26.6 '@types/react': specifier: 'catalog:' - version: 19.2.15 + version: 19.2.16 '@types/react-dom': specifier: 'catalog:' - version: 19.2.3(@types/react@19.2.15) + version: 19.2.3(@types/react@19.2.16) concurrently: specifier: 'catalog:' version: 9.2.1 @@ -1141,37 +1141,37 @@ importers: version: 1.4.0 '@tanstack/react-query': specifier: 'catalog:' - version: 5.100.14(react@19.2.6) + version: 5.100.14(react@19.2.7) '@trpc/client': specifier: 'catalog:' version: 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3) '@trpc/react-query': specifier: 'catalog:' - version: 11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3) + version: 11.17.0(@tanstack/react-query@5.100.14(react@19.2.7))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.7)(typescript@5.9.3) '@trpc/server': specifier: 'catalog:' version: 11.17.0(typescript@5.9.3) '@trpc/tanstack-react-query': specifier: 'catalog:' - version: 11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3) + version: 11.17.0(@tanstack/react-query@5.100.14(react@19.2.7))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.7)(typescript@5.9.3) lodash.clonedeep: specifier: 'catalog:' version: 4.5.0 next: specifier: 'catalog:' - version: 16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0) + version: 16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0) react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.7 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.7(react@19.2.7) superjson: specifier: 'catalog:' version: 2.2.6 trpc-to-mcp: specifier: 'catalog:' - version: 1.3.2(@trpc/server@11.17.0(typescript@5.9.3))(better-auth@1.6.14(@opentelemetry/api@1.9.0)(better-sqlite3@12.10.0)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@libsql/client-wasm@0.14.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.10.0)(gel@2.0.0)(kysely@0.29.2)(mysql2@3.22.4(@types/node@24.12.4))(pg@8.21.0))(mysql2@3.22.4(@types/node@24.12.4))(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.8)(vue@3.5.35(typescript@5.9.3)))(mcp-handler@1.1.0(@modelcontextprotocol/sdk@1.26.0(zod@4.4.3))(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0)))(zod@4.4.3) + version: 1.3.2(@trpc/server@11.17.0(typescript@5.9.3))(better-auth@1.6.14(@opentelemetry/api@1.9.0)(better-sqlite3@12.10.0)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@libsql/client-wasm@0.14.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.10.0)(gel@2.0.0)(kysely@0.29.2)(mysql2@3.22.4(@types/node@24.12.4))(pg@8.21.0))(mysql2@3.22.4(@types/node@24.12.4))(next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0))(pg@8.21.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vitest@4.1.8)(vue@3.5.35(typescript@5.9.3)))(mcp-handler@1.1.0(@modelcontextprotocol/sdk@1.26.0(zod@4.4.3))(next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0)))(zod@4.4.3) trpc-to-openapi: specifier: 'catalog:' version: 3.3.0(patch_hash=2ca3c16af0fcca0c736697ad4fe553a14f794524fa9ce0d5c3e8ee4aea76090c)(@trpc/server@11.17.0(typescript@5.9.3))(zod-openapi@5.3.0(zod@4.4.3))(zod@4.4.3) @@ -1220,16 +1220,16 @@ importers: version: 8.1.8 next: specifier: 'catalog:' - version: 16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0) + version: 16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0) next-auth: specifier: 'catalog:' - version: 5.0.0-beta.31(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(react@19.2.6) + version: 5.0.0-beta.31(next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0))(react@19.2.7) react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.7 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.7(react@19.2.7) zod: specifier: 'catalog:' version: 4.4.3 @@ -1254,10 +1254,10 @@ importers: version: link:../api react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.7 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.7(react@19.2.7) devDependencies: '@homarr/tsconfig': specifier: workspace:^0.1.0 @@ -1313,16 +1313,16 @@ importers: version: 1.11.21 next: specifier: 'catalog:' - version: 16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0) + version: 16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0) octokit: specifier: 'catalog:' version: 5.0.5 react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.7 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.7(react@19.2.7) undici: specifier: 'catalog:' version: 7.24.6 @@ -1504,7 +1504,7 @@ importers: version: link:../server-settings '@mantine/core': specifier: 'catalog:' - version: 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@paralleldrive/cuid2': specifier: 'catalog:' version: 3.3.0 @@ -1618,7 +1618,7 @@ importers: version: link:../validation '@mantine/form': specifier: 'catalog:' - version: 9.2.2(react@19.2.6) + version: 9.2.2(react@19.2.7) zod: specifier: 'catalog:' version: 4.4.3 @@ -1658,10 +1658,10 @@ importers: version: link:../validation '@mantine/core': specifier: 'catalog:' - version: 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.7 zod: specifier: 'catalog:' version: 4.4.3 @@ -1788,6 +1788,9 @@ importers: undici: specifier: 'catalog:' version: 7.24.6 + ws: + specifier: 'catalog:' + version: 8.21.0 xml2js: specifier: 'catalog:' version: 0.6.2 @@ -1801,6 +1804,9 @@ importers: '@types/node-unifi': specifier: 'catalog:' version: 2.5.1(patch_hash=5e6ae51e2a17a7f9729bfa30b0eb3d0842a5810ac6db47603ab4a6efa1ed84c5) + '@types/ws': + specifier: 'catalog:' + version: 8.18.1 '@types/xml2js': specifier: 'catalog:' version: 0.4.14 @@ -1818,13 +1824,13 @@ importers: version: link:../ui '@mantine/core': specifier: 'catalog:' - version: 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@mantine/hooks': specifier: 'catalog:' - version: 9.2.2(react@19.2.6) + version: 9.2.2(react@19.2.7) react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.7 devDependencies: '@homarr/tsconfig': specifier: workspace:^0.1.0 @@ -1870,22 +1876,22 @@ importers: version: link:../validation '@mantine/core': specifier: 'catalog:' - version: 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@tabler/icons-react': specifier: 'catalog:' - version: 3.44.0(react@19.2.6) + version: 3.44.0(react@19.2.7) dayjs: specifier: 'catalog:' version: 1.11.21 next: specifier: 'catalog:' - version: 16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0) + version: 16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0) react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.7 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.7(react@19.2.7) zod: specifier: 'catalog:' version: 4.4.3 @@ -1904,10 +1910,10 @@ importers: version: link:../ui '@mantine/notifications': specifier: 'catalog:' - version: 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@tabler/icons-react': specifier: 'catalog:' - version: 3.44.0(react@19.2.6) + version: 3.44.0(react@19.2.7) devDependencies: '@homarr/tsconfig': specifier: workspace:^0.1.0 @@ -1953,22 +1959,22 @@ importers: version: link:../validation '@mantine/core': specifier: 'catalog:' - version: 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@mantine/hooks': specifier: 'catalog:' - version: 9.2.2(react@19.2.6) + version: 9.2.2(react@19.2.7) adm-zip: specifier: 'catalog:' version: 0.5.17 next: specifier: 'catalog:' - version: 16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0) + version: 16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0) react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.7 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.7(react@19.2.7) superjson: specifier: 'catalog:' version: 2.2.6 @@ -2124,16 +2130,16 @@ importers: version: link:../server-settings '@mantine/dates': specifier: 'catalog:' - version: 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) next: specifier: 'catalog:' - version: 16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0) + version: 16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0) react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.7 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.7(react@19.2.7) devDependencies: '@homarr/tsconfig': specifier: workspace:^0.1.0 @@ -2179,31 +2185,31 @@ importers: version: link:../ui '@mantine/core': specifier: 'catalog:' - version: 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@mantine/hooks': specifier: 'catalog:' - version: 9.2.2(react@19.2.6) + version: 9.2.2(react@19.2.7) '@mantine/spotlight': specifier: 'catalog:' - version: 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@tabler/icons-react': specifier: 'catalog:' - version: 3.44.0(react@19.2.6) + version: 3.44.0(react@19.2.7) jotai: specifier: 'catalog:' - version: 2.20.0(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@19.2.15)(react@19.2.6) + version: 2.20.0(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@19.2.16)(react@19.2.7) next: specifier: 'catalog:' - version: 16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0) + version: 16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0) react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.7 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.7(react@19.2.7) use-deep-compare-effect: specifier: 'catalog:' - version: 1.8.1(react@19.2.6) + version: 1.8.1(react@19.2.7) devDependencies: '@homarr/tsconfig': specifier: workspace:^0.1.0 @@ -2228,19 +2234,19 @@ importers: version: 4.3.1 mantine-react-table: specifier: 'catalog:' - version: mantine-react-table-open@9.0.3(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: mantine-react-table-open@9.0.3(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(@tabler/icons-react@3.44.0(react@19.2.7))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) next: specifier: 'catalog:' - version: 16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0) + version: 16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0) next-intl: specifier: 'catalog:' - version: 4.13.0(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(react@19.2.6)(typescript@5.9.3) + version: 4.13.0(next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0))(react@19.2.7)(typescript@5.9.3) react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.7 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.7(react@19.2.7) devDependencies: '@homarr/tsconfig': specifier: workspace:^0.1.0 @@ -2268,31 +2274,31 @@ importers: version: link:../validation '@mantine/core': specifier: 'catalog:' - version: 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@mantine/dates': specifier: 'catalog:' - version: 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@mantine/hooks': specifier: 'catalog:' - version: 9.2.2(react@19.2.6) + version: 9.2.2(react@19.2.7) '@tabler/icons-react': specifier: 'catalog:' - version: 3.44.0(react@19.2.6) + version: 3.44.0(react@19.2.7) crypto-js: specifier: 'catalog:' version: 4.2.0 mantine-react-table: specifier: 'catalog:' - version: mantine-react-table-open@9.0.3(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: mantine-react-table-open@9.0.3(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(@tabler/icons-react@3.44.0(react@19.2.7))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) next: specifier: 'catalog:' - version: 16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0) + version: 16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0) react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.7 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.7(react@19.2.7) svgson: specifier: 'catalog:' version: 5.3.1 @@ -2336,10 +2342,10 @@ importers: dependencies: '@dnd-kit/core': specifier: 'catalog:' - version: 6.3.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 6.3.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@dnd-kit/sortable': specifier: 'catalog:' - version: 10.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 10.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7) '@homarr/api': specifier: workspace:^0.1.0 version: link:../api @@ -2405,19 +2411,19 @@ importers: version: link:../validation '@mantine/charts': specifier: 'catalog:' - version: 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(recharts@3.8.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react-is@19.2.6)(react@19.2.6)(redux@5.0.1)) + version: 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(recharts@3.8.1(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react-is@19.2.7)(react@19.2.7)(redux@5.0.1)) '@mantine/core': specifier: 'catalog:' - version: 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@mantine/form': specifier: 'catalog:' - version: 9.2.2(react@19.2.6) + version: 9.2.2(react@19.2.7) '@mantine/hooks': specifier: 'catalog:' - version: 9.2.2(react@19.2.6) + version: 9.2.2(react@19.2.7) '@tabler/icons-react': specifier: 'catalog:' - version: 3.44.0(react@19.2.6) + version: 3.44.0(react@19.2.7) '@tiptap/extension-color': specifier: 'catalog:' version: 3.24.0(@tiptap/extension-text-style@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))) @@ -2462,7 +2468,7 @@ importers: version: 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0)) '@tiptap/react': specifier: 'catalog:' - version: 3.24.0(@floating-ui/dom@1.7.6)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 3.24.0(@floating-ui/dom@1.7.6)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@tiptap/starter-kit': specifier: 'catalog:' version: 3.24.0 @@ -2474,25 +2480,25 @@ importers: version: 1.11.21 mantine-react-table: specifier: 'catalog:' - version: mantine-react-table-open@9.0.3(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: mantine-react-table-open@9.0.3(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(@tabler/icons-react@3.44.0(react@19.2.7))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) next: specifier: 'catalog:' - version: 16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0) + version: 16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0) react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.7 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.7(react@19.2.7) react-markdown: specifier: 'catalog:' - version: 10.1.0(@types/react@19.2.15)(react@19.2.6) + version: 10.1.0(@types/react@19.2.16)(react@19.2.7) react-quill-new: specifier: 'catalog:' - version: 3.8.3(quill-delta@5.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 3.8.3(quill-delta@5.1.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) recharts: specifier: 'catalog:' - version: 3.8.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react-is@19.2.6)(react@19.2.6)(redux@5.0.1) + version: 3.8.1(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react-is@19.2.7)(react@19.2.7)(redux@5.0.1) video.js: specifier: 'catalog:' version: 8.23.7 @@ -2786,8 +2792,8 @@ packages: resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==} hasBin: true - '@codemirror/autocomplete@6.20.2': - resolution: {integrity: sha512-G5FPkgIiLjOgZMjqVjvuKQ1rGPtHogLldJr33eFJdVLtmwY+giGrlv/ewljLz6b9BSQLkjxuwBc6g6omDM+YxQ==} + '@codemirror/autocomplete@6.20.3': + resolution: {integrity: sha512-tlosUqb+3BbxCxZdu4tKeRghPFC+QM7q4X5YhKV2eCmPG+1r2F3f4AaSz5sCrFqUtX4Jh20VFTKecl16MgiV9g==} '@codemirror/commands@6.10.3': resolution: {integrity: sha512-JFRiqhKu+bvSkDLI+rUhJwSxQxYb759W5GBezE8Uc8mHLqC9aV/9aTC7yJSqCtB3F00pylrLCwnyS91Ap5ej4Q==} @@ -3487,8 +3493,8 @@ packages: '@formatjs/intl-localematcher@0.8.1': resolution: {integrity: sha512-xwEuwQFdtSq1UKtQnyTZWC+eHdv7Uygoa+H2k/9uzBVQjDyp9r20LNDNKedWXll7FssT3GRHvqsdJGYSUWqYFA==} - '@gfazioli/mantine-onboarding-tour@4.0.3': - resolution: {integrity: sha512-krYmZoGSV9qpvtztK+QChhfwv1l6LsP/n0u+ih2/A0mV0Osn5avmlj+UBAKoIvwzA4xS50NSoPHj3B53QLzs/Q==} + '@gfazioli/mantine-onboarding-tour@4.0.4': + resolution: {integrity: sha512-8O70elJVFSJJCB/Ie4TDxAKuDgE1BRU8o7O7ArFWzPYGx4Sa4jWW8OC0QyjxZul5aFaFJFl55lG263oh7IMkHg==} peerDependencies: '@mantine/core': '>=9.0.0' '@mantine/hooks': '>=9.0.0' @@ -4067,71 +4073,61 @@ packages: '@cfworker/json-schema': optional: true - '@modelcontextprotocol/sdk@1.29.0': - resolution: {integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==} - engines: {node: '>=18'} - peerDependencies: - '@cfworker/json-schema': ^4.1.1 - zod: ^3.25 || ^4.0 - peerDependenciesMeta: - '@cfworker/json-schema': - optional: true - '@mswjs/interceptors@0.41.9': resolution: {integrity: sha512-VVPPgHyQ6ShqnrmDWuxjmUIsO9gWyOZFmuOfLd9LfBGQJwZfy0gvv9pbHSJuoFNIYC7ZDX9aoFwowjcdSC4E8w==} engines: {node: '>=18'} - '@next/env@16.2.6': - resolution: {integrity: sha512-gd8HoHN4ufj73WmR3JmVolrpJR47ILK6LouP5xElPglaVxir6e1a7VzvTvDWkOoPXT9rkkTzyCxBu4yeZfZwcw==} + '@next/env@16.2.7': + resolution: {integrity: sha512-tMJizPlj6ZYpBMMdK8S0LJufrP4QTdR6pcv9KQ/bVETPAmg0j1mlHE9G2c38UyGHxoBapgwuj7XjbGJ2RcDFOg==} - '@next/swc-darwin-arm64@16.2.6': - resolution: {integrity: sha512-ZJGkkcNfYgrrMkqOdZ7zoLa1TOy0qpcMfk/z4Mh/FKUz40gVO+HNQWqmLxf67Z5WB64DRp0dhEbyHfel+6sJUg==} + '@next/swc-darwin-arm64@16.2.7': + resolution: {integrity: sha512-vm1EDI/pVaBNNiychmxk3fft+OhQPVD9cIM/tReLZIQ3TfQ4kqI9DwKk00dzuS1ulC7icbrzCFrmRRlk9PfNdw==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@16.2.6': - resolution: {integrity: sha512-v/YLBHIY132Ced3puBJ7YJKw1lqsCrgcNo2aRJlCEyQrrCeRJlvGlnmxhPxNQI3KE3N1DN5r9TPNPvka3nq5RQ==} + '@next/swc-darwin-x64@16.2.7': + resolution: {integrity: sha512-O3IRSv1ZBL1zs0WrIgefTEcTKFVn+ryxBNe54erJ6KsD+2f/Mmt7g2jOYh8PSBdUwPtKQJuCsTMlZ7tIu2AcsQ==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@16.2.6': - resolution: {integrity: sha512-RPOvqlYBbcQjkz9VQQDZ2T2bARIjXZV1KFlt+V2Mr6SW/e4I9fcKsaA0hdyf2FHoTlsV2xnBd5Y912rP/1Ce6w==} + '@next/swc-linux-arm64-gnu@16.2.7': + resolution: {integrity: sha512-Re6PZtjBDd0aMU+VcZcC/PrIvj4WhrjDYtMhhCVQamWN4L90EVP0pcEOBQD25prSlw7OzNw5QpHLWMilRLsRNw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] libc: [glibc] - '@next/swc-linux-arm64-musl@16.2.6': - resolution: {integrity: sha512-URUTu1+dMkxJsPFgm+OeEvq9wf5sujw0EvgYy80TDGHTSLTnIHeqb0Eu8A3sC95IRgjejQL+kC4mw+4yPxiAXA==} + '@next/swc-linux-arm64-musl@16.2.7': + resolution: {integrity: sha512-qyogG9QtBzWxgJfeGBvOEHI3851gTfCF3wLZ5RDLTBJGAmE9p1qDwKCOdrBrvBzRvYDT+gUDp72pzlSEfAXgNA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] libc: [musl] - '@next/swc-linux-x64-gnu@16.2.6': - resolution: {integrity: sha512-DOj182mPV8G3UkrayLoREM5YEYI+Dk5wv7Ox9xl1fFibAELEsFD0lDPfHIeILlutMMfdyhlzYPELG3peuKaurw==} + '@next/swc-linux-x64-gnu@16.2.7': + resolution: {integrity: sha512-Vhe4ZDuBpmMogrGi5D4R2Kq4JAQlj6+wvgaFYy31zfES0zPmt6TLA+cuYpM/OLrPZjo2MYQTHVqNUSCR6+fDZQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] libc: [glibc] - '@next/swc-linux-x64-musl@16.2.6': - resolution: {integrity: sha512-HKQ5SP/V/ub73UvF7n/zeJlxk2kLmtL7Wzrg4WfmkjmNos5onJ2tKu7yZOPdL18A6Svfn3max29ym+ry7NkK4g==} + '@next/swc-linux-x64-musl@16.2.7': + resolution: {integrity: sha512-srvian89JahFLw1YLBEuhvPJ0DO5lpUeJQMXy4xYo7g628ZlNgXdNkqoxSAv9OYrBfByh6vxISMwW/mRbzCY+g==} engines: {node: '>= 10'} cpu: [x64] os: [linux] libc: [musl] - '@next/swc-win32-arm64-msvc@16.2.6': - resolution: {integrity: sha512-LZXpTlPyS5v7HhSmnvsLGP3iIYgYOBnc8r8ArlT55sGHV89bR2HlDdBjWQ+PY6SJMmk8TuVGFuxalnP3k/0Dwg==} + '@next/swc-win32-arm64-msvc@16.2.7': + resolution: {integrity: sha512-GX3wvLpULFuRFJzwHaKfm7QZJ18F4ZSuxlPJ96BoBglCzBmdSjyeBKF+ZhWhvL/ckxNfLnNa7bsObO2ipYpszw==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-x64-msvc@16.2.6': - resolution: {integrity: sha512-F0+4i0h9J6C4eE3EAPWsoCk7UW/dbzOjyzxY0qnDUOYFu6FFmdZ6l97/XdV3/Nz3VYyO7UWjyEJUXkGqcoXfMA==} + '@next/swc-win32-x64-msvc@16.2.7': + resolution: {integrity: sha512-J4WlM72NMk076Qsg0jTdK3SNXatlSdnjW7L7oNGLst1tAGjHrJh/FYi+pw9wyIjEtGRKDNzD0zuiY16oWYWVaw==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -4277,124 +4273,124 @@ packages: resolution: {integrity: sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==} engines: {node: '>=14'} - '@oxfmt/binding-android-arm-eabi@0.52.0': - resolution: {integrity: sha512-17EMSJnQ9g+upVHrAUYDMfH5lvRKQ9Nvg8WtEoH72oDr1VpWz+7/o3tD97U1EToen2YAQ/68JmtDYkQUi20dfQ==} + '@oxfmt/binding-android-arm-eabi@0.53.0': + resolution: {integrity: sha512-XfVM8AmIovBTKXCt14Op5wbfcoM8418nttd+nhMgM3RAVaJg1MtJc73FyWfUt0oxLyBGVwfniNVUsbV/b3VmPg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxfmt/binding-android-arm64@0.52.0': - resolution: {integrity: sha512-A2G1IdwGEW2lLJkIxcvuirRH1CzSl/e0NX11zTlW1gvxJThfwbI/BEoaKrTNpm7M2FchvIf6guvIQU7d5iz+OQ==} + '@oxfmt/binding-android-arm64@0.53.0': + resolution: {integrity: sha512-btHDfXckwdf9zgyAVznfZkf+GVyB0I1m1hlvaOMRx2xoyz3hphfPX97s89J3wfCN8QBETLtk4lQUaeOkrMuQOg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxfmt/binding-darwin-arm64@0.52.0': - resolution: {integrity: sha512-f9+bLvOYxy7NttCLFTvQ7afmqDOWY4wIP9xdvfj5trQ1qj6f2UFAGwZESlfsMjvJNTyRpXfIlOanCI9FOvoeQA==} + '@oxfmt/binding-darwin-arm64@0.53.0': + resolution: {integrity: sha512-k2RjMcSTkHjoOlsVGbL35JVzXL+oQco3GHPl/5kjebVF4oHNfE24In8F5isqBh9LBJucycWHKDXdGrCchdWcHQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxfmt/binding-darwin-x64@0.52.0': - resolution: {integrity: sha512-YSTB9sJ5nnQd/Q0ddHkgof0ZCHPAnWZT1IW2SJ8omz7CP7KluJhO1fNHrpqdxCtpztJwSs4hY1uAee35wKxxaw==} + '@oxfmt/binding-darwin-x64@0.53.0': + resolution: {integrity: sha512-65jIBE2H1l5SSs16fmv6/7b6sAx/WpvnsgDhVWK9qSjNFDUro7MPQ6q5UhpY7kl46yltfR046iAnxy/Bzqbiew==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxfmt/binding-freebsd-x64@0.52.0': - resolution: {integrity: sha512-NIrRNTTPCs4UbmVs0bxLSCDlLCtIRMJIXklNKaXa5Oj2/K1UIMBvgE8+uPVo01Io3N9HF0+GAX+aAHjUgZS7vA==} + '@oxfmt/binding-freebsd-x64@0.53.0': + resolution: {integrity: sha512-oYe1gkz7U49PCYrS9147d2fJZj8mDI4Di6AvlsU5fu9p+Tq8S7qqOMSZjUiVTLX8bXuSA9Lk/tIxuegVjkNYRA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxfmt/binding-linux-arm-gnueabihf@0.52.0': - resolution: {integrity: sha512-JXUCde8mn3GpgQouz2PXUokgy/uT1QrRJBL2s983VWcSQp62wTFYiNXgTKdeo1Jgbr0IgUnKKvzIk/YBlj/nVQ==} + '@oxfmt/binding-linux-arm-gnueabihf@0.53.0': + resolution: {integrity: sha512-ailB2vLzGi629tymdAb2VYJyEHref7oqGxP+tRBrtRBxQrb6NV55JMT7xtGZ8uTeG2+Y9zojqW4LhJYxQnz9Pg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxfmt/binding-linux-arm-musleabihf@0.52.0': - resolution: {integrity: sha512-psbUXaRZ+V8DaXz10Qf7LSHtdtdKAmC8fxXgeU608jjzrmWK4quamZMOpl6sf+dikoFHA85uE93Q0BqxrCdQrQ==} + '@oxfmt/binding-linux-arm-musleabihf@0.53.0': + resolution: {integrity: sha512-abh4mWBvOvD966sobqF7r103y2yYx7Rb4WGHLOS4+5igGqLbbPxS9aK5+45D6iUY7dWMsk3Muz9a8gUtufvqJA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxfmt/binding-linux-arm64-gnu@0.52.0': - resolution: {integrity: sha512-Jw7MgWUU9lcLCcy82updISP3EthTlfvAwR6gWNxPzqly7+fLvOi2gHQE9xXQjpqaVLm/8P+gOzlv9ODuoVlaaw==} + '@oxfmt/binding-linux-arm64-gnu@0.53.0': + resolution: {integrity: sha512-z73PvuhJ8qA+cDbaiqbtopHglA91U4+y5wn2sTJJrnpB957d5P33FEuyP3DQIFd7ofljmDmfVT4G0CVGHZaJWg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-arm64-musl@0.52.0': - resolution: {integrity: sha512-wZg6bLjDvh2KibyI3QFUYo8GTXneIFsd0JvehtvJiUmQ8WRPERgxd/VM4ctWb86U5FT1FkqgS8/wZKVB+AZScg==} + '@oxfmt/binding-linux-arm64-musl@0.53.0': + resolution: {integrity: sha512-I6bhOTroqc3ThrwZ89l2k3ivKuELhdPLbAcJhRNyjWvlgwb0vjRgEnVL1XLx5Jud04/ypNRZBykAWrSk6l/D+g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxfmt/binding-linux-ppc64-gnu@0.52.0': - resolution: {integrity: sha512-IngE8uxhNvxcMrLjZNDo9xNLY7rEK33AKnaMd2B46he1e/mz2CfcW6If/U1wUjdRZddm1QzQaciqZkuMkdh1FA==} + '@oxfmt/binding-linux-ppc64-gnu@0.53.0': + resolution: {integrity: sha512-w0p3JzB/PkkQjXALMJMqP9YfP3yq4w6zGsu5kezQmUnxRkN3b/Theg2l/nDgBsOcczxS3gL6Gam5XNAVrO6QJQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-riscv64-gnu@0.52.0': - resolution: {integrity: sha512-H3+DdFMv/efN3Efmhsv18jDrpiWWqKG7wsfAlQBqAt6z/E2Bx+TwEj2Nowe51CPOWB8/mFBC2dAMSgVFLvvowA==} + '@oxfmt/binding-linux-riscv64-gnu@0.53.0': + resolution: {integrity: sha512-mzBhF6k1Yq1K/dqDmVe/AAafnlJfEpx7yfUiksyeWXJk5iSzZqBSxcsa02zIytYgQFRZ7h6WPZfwHg/DoOE1Kw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-riscv64-musl@0.52.0': - resolution: {integrity: sha512-zji+1kb7lJKohSDjzC1IsS+K/cKRs1hdVf0ZH0VbdbiakmtLvN9twBoXo/k8VdjFax7kfo+DyPxS7vv52br1aw==} + '@oxfmt/binding-linux-riscv64-musl@0.53.0': + resolution: {integrity: sha512-AlFCpnRQhogQFzZXWbO6xB6/Udy745L+eQNmDPGg7G/OeWsYmJc4jZYfUN5pQg0reOPWSED2mOQqKZOJM1U8cA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@oxfmt/binding-linux-s390x-gnu@0.52.0': - resolution: {integrity: sha512-hcLBYedpCy7ToUvvBidWk7+11Yhg1oAZ4+6hKPic/mQI6NaqXJSXMps5nFlwUuX2ewhtLZZDPg63TI042qGKBg==} + '@oxfmt/binding-linux-s390x-gnu@0.53.0': + resolution: {integrity: sha512-XD4ulY4f1DWbuuZXAqxhVn+gdPmrhnmojWtFN78ctVoupmS845fGhsUrk1HZXKQI+iymbaiz9vAjPsghHNQ7Ag==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-x64-gnu@0.52.0': - resolution: {integrity: sha512-IDO2loXK2OtTOhSPchU9MW25mWL2QCDGdJbjN8MXKZVS80qXe5gMTwQWu/gMJ3juoBHbkuUZNB2N1LHzNT7DoA==} + '@oxfmt/binding-linux-x64-gnu@0.53.0': + resolution: {integrity: sha512-xg8KWX0QnxmYWRe60CgHYWXI0ZOtBbqTsXvWiWrcl2XUHJ3fht2QerOk2iWvylzX3zNT2GpvBRxGoR4d3sxPRQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-x64-musl@0.52.0': - resolution: {integrity: sha512-mAV2Hjn0SatJ+KoAzKUC3eJhdJ8wv+3m1KyuS0dTsbF0c5weq+QrCt/DRZZM+uj/XiKzCDEUKYsBF30e2qkcyw==} + '@oxfmt/binding-linux-x64-musl@0.53.0': + resolution: {integrity: sha512-MWExpYBGvl+pIvVB/gj/CcWlN2al8AizT7rUbtaYaWNoQkhWARM6W3qpgoCr72CYSN9PborzPmM5MIRe2BrNdA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxfmt/binding-openharmony-arm64@0.52.0': - resolution: {integrity: sha512-vd4npaUIwChxp7XzkqmepBWTT9YMcSe/NBApVGPC30/lLyOVaV3dvma1SKo03t8O73BPRAG7EyJzGlN5cJM5hQ==} + '@oxfmt/binding-openharmony-arm64@0.53.0': + resolution: {integrity: sha512-u4sajgO4nxgmJIgc/y2AqPhkdbOkQH8WugXpA1+pW0ESQhvGZ1oGq61Q4xMbJHJU1hFgtO18QNrcFYDPYH0gwQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxfmt/binding-win32-arm64-msvc@0.52.0': - resolution: {integrity: sha512-k2sz6gWQdMfh5HPpIS+Bw/0UEV/kaK2xuqJRrWL233sEHx9WLlsmvlPFM4HUNThkYbSN0U0vPW7LVKZWDS8hPQ==} + '@oxfmt/binding-win32-arm64-msvc@0.53.0': + resolution: {integrity: sha512-Yq9sOZoIOJ5xPjO0qOyHJS4CiPuTkB2en9auxZz7Ar2p5RaC7BzLyVVmAA7zz9/L9YnjjY1DwNxN+ivKXimN/A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxfmt/binding-win32-ia32-msvc@0.52.0': - resolution: {integrity: sha512-rhke69GTcArodLHpjMTfNnvjTEBryDeZcUCKK/VjXDMtfTULl6QRh0ymX5/hbCUv2WjYm9h/QbW++q2vE15gWQ==} + '@oxfmt/binding-win32-ia32-msvc@0.53.0': + resolution: {integrity: sha512-es1fVNZEkBqEcQtBpn19SYFgZF7FawlkCjkT/iImfEAus4gun8fBwB1E9hpV5LcR9B0DBNvRIXhW8BQk3JaE+Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxfmt/binding-win32-x64-msvc@0.52.0': - resolution: {integrity: sha512-q5xL7oeXkZdEtNZWBdvehJcmt+GRu9l2bK40yJs1jJXlqq+r0Hygb1rTjq+FM2o/2xyt4cufH6KRplHp3Jjsvw==} + '@oxfmt/binding-win32-x64-msvc@0.53.0': + resolution: {integrity: sha512-QFmJs2bEu9AO4O6qsmEaZNGi6dFq8N+rT8EHAAnZIq/B9SeJDUbc4DzVxQ48MfDsL7D3sCZzo37zuTuspcURgg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -5671,8 +5667,8 @@ packages: peerDependencies: '@types/react': ^19.2.0 - '@types/react@19.2.15': - resolution: {integrity: sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q==} + '@types/react@19.2.16': + resolution: {integrity: sha512-esJiCAnl0kfpNdE69f3So4WJUXy95dLZydX0KwK46riIHDzHM7O9Vtf9xCHW0PXIqvgqNrswl522kA/5yx+F4w==} '@types/semver@7.5.8': resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} @@ -5768,7 +5764,7 @@ packages: resolution: {integrity: sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: - vite: '>=8.0.15' + vite: '>=8.0.16' '@vitest/coverage-v8@4.1.8': resolution: {integrity: sha512-lt3kovsyHwYe00wq4D1ti0Z974fWj4NLp6siqiyEufUpyFwK9Yhi7rBhac9JL5aA0zoMrJqc4vYPZRUnI7l7nw==} @@ -5854,7 +5850,7 @@ packages: resolution: {integrity: sha512-SDobKBbPIOe0cVL7QxMzGkuUGHvWTdihi9zOrrWaWUgFKe15cwEcwfWmgrcNzjT6kHnNmWuTajPHoIzUjYNYYQ==} peerDependencies: async-validator: ^4 - axios: '>=1.16.1' + axios: '>=1.17.0' change-case: ^5 drauu: ^0.4 focus-trap: ^7 @@ -6189,10 +6185,6 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - baseline-browser-mapping@2.9.19: - resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==} - hasBin: true - bcrypt-pbkdf@1.0.2: resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} @@ -6353,9 +6345,6 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} - caniuse-lite@1.0.30001766: - resolution: {integrity: sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==} - caniuse-lite@1.0.30001793: resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==} @@ -8443,8 +8432,8 @@ packages: typescript: optional: true - next@16.2.6: - resolution: {integrity: sha512-qOVgKJg1+At15NpeUP+eJgCHvTCgXsogweq87Ri/Ix7PkqQHg4sdaXmSFqKlgaIXE4kW0g25LE68W87UANlHtw==} + next@16.2.7: + resolution: {integrity: sha512-eMJxgjRzBaj3olkP4cBamHDXL79A8FC6u1GcsO1D1Tsx8bw/LLXUJCaoajVxtnhD3A1IJqIT8IcRJjgBIPJq4w==} engines: {node: '>=20.9.0'} hasBin: true peerDependencies: @@ -8662,8 +8651,8 @@ packages: outvariant@1.4.3: resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} - oxfmt@0.52.0: - resolution: {integrity: sha512-nJlYM35F64zTDMecCNhoHNkf+D/eHv7xcjj9XDSj+bFAVtN93m7v8DQMdHd6nDG6Akf/kEYYHmDUBs2Dz27Sug==} + oxfmt@0.53.0: + resolution: {integrity: sha512-9cB5glS3Ip6NMuZ+6NYTao9FCWkDhRtPYCtR3QBu/NxHoFbgzzTvi41N4jxz/GqGfuLKspui1qb/LlSu2IbMcw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -9122,10 +9111,10 @@ packages: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true - react-dom@19.2.6: - resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==} + react-dom@19.2.7: + resolution: {integrity: sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==} peerDependencies: - react: ^19.2.6 + react: ^19.2.7 react-dropzone@15.0.0: resolution: {integrity: sha512-lGjYV/EoqEjEWPnmiSvH4v5IoIAwQM2W4Z1C0Q/Pw2xD0eVzKPS359BQTUMum+1fa0kH2nrKjuavmTPOGhpLPg==} @@ -9138,8 +9127,8 @@ packages: peerDependencies: react: ^18.0.0 || ^19.0.0 - react-is@19.2.6: - resolution: {integrity: sha512-XjBR15BhXuylgWGuslhDKqlSayuqvqBX91BP8pauG8kd1zY8kotkNWbXksTCNRarse4kuGbe2kIY05ARtwNIvw==} + react-is@19.2.7: + resolution: {integrity: sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A==} react-markdown@10.1.0: resolution: {integrity: sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==} @@ -9218,8 +9207,8 @@ packages: react: '>=16.6.0' react-dom: '>=16.6.0' - react@19.2.6: - resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==} + react@19.2.7: + resolution: {integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==} engines: {node: '>=0.10.0'} read-package-up@11.0.0: @@ -9266,7 +9255,7 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-is: ^19.2.6 + react-is: ^19.2.7 redis-errors@1.2.0: resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} @@ -10252,7 +10241,7 @@ packages: vite-tsconfig-paths@6.1.1: resolution: {integrity: sha512-2cihq7zliibCCZ8P9cKJrQBkfgdvcFkOOc3Y02o3GWUDLgqjWsZudaoiuOwO/gzTzy17cS5F7ZPo4bsnS4DGkg==} peerDependencies: - vite: '>=8.0.15' + vite: '>=8.0.16' vite@7.1.12: resolution: {integrity: sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==} @@ -10871,7 +10860,7 @@ snapshots: dependencies: css-tree: 3.2.1 - '@codemirror/autocomplete@6.20.2': + '@codemirror/autocomplete@6.20.3': dependencies: '@codemirror/language': 6.12.3 '@codemirror/state': 6.6.0 @@ -10887,7 +10876,7 @@ snapshots: '@codemirror/lang-css@6.3.1': dependencies: - '@codemirror/autocomplete': 6.20.2 + '@codemirror/autocomplete': 6.20.3 '@codemirror/language': 6.12.3 '@codemirror/state': 6.6.0 '@lezer/common': 1.5.2 @@ -10895,7 +10884,7 @@ snapshots: '@codemirror/lang-html@6.4.11': dependencies: - '@codemirror/autocomplete': 6.20.2 + '@codemirror/autocomplete': 6.20.3 '@codemirror/lang-css': 6.3.1 '@codemirror/lang-javascript': 6.2.5 '@codemirror/language': 6.12.3 @@ -10907,7 +10896,7 @@ snapshots: '@codemirror/lang-javascript@6.2.5': dependencies: - '@codemirror/autocomplete': 6.20.2 + '@codemirror/autocomplete': 6.20.3 '@codemirror/language': 6.12.3 '@codemirror/lint': 6.9.6 '@codemirror/state': 6.6.0 @@ -10922,7 +10911,7 @@ snapshots: '@codemirror/lang-xml@6.1.0': dependencies: - '@codemirror/autocomplete': 6.20.2 + '@codemirror/autocomplete': 6.20.3 '@codemirror/language': 6.12.3 '@codemirror/state': 6.6.0 '@codemirror/view': 6.43.0 @@ -10931,7 +10920,7 @@ snapshots: '@codemirror/lang-yaml@6.1.3': dependencies: - '@codemirror/autocomplete': 6.20.2 + '@codemirror/autocomplete': 6.20.3 '@codemirror/language': 6.12.3 '@codemirror/state': 6.6.0 '@lezer/common': 1.5.2 @@ -11043,36 +11032,36 @@ snapshots: enabled: 2.0.0 kuler: 2.0.0 - '@dnd-kit/accessibility@3.1.1(react@19.2.6)': + '@dnd-kit/accessibility@3.1.1(react@19.2.7)': dependencies: - react: 19.2.6 + react: 19.2.7 tslib: 2.8.1 - '@dnd-kit/core@6.3.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@dnd-kit/core@6.3.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@dnd-kit/accessibility': 3.1.1(react@19.2.6) - '@dnd-kit/utilities': 3.2.2(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@dnd-kit/accessibility': 3.1.1(react@19.2.7) + '@dnd-kit/utilities': 3.2.2(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) tslib: 2.8.1 - '@dnd-kit/modifiers@9.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)': + '@dnd-kit/modifiers@9.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7)': dependencies: - '@dnd-kit/core': 6.3.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@dnd-kit/utilities': 3.2.2(react@19.2.6) - react: 19.2.6 + '@dnd-kit/core': 6.3.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@dnd-kit/utilities': 3.2.2(react@19.2.7) + react: 19.2.7 tslib: 2.8.1 - '@dnd-kit/sortable@10.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)': + '@dnd-kit/sortable@10.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7)': dependencies: - '@dnd-kit/core': 6.3.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@dnd-kit/utilities': 3.2.2(react@19.2.6) - react: 19.2.6 + '@dnd-kit/core': 6.3.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@dnd-kit/utilities': 3.2.2(react@19.2.7) + react: 19.2.7 tslib: 2.8.1 - '@dnd-kit/utilities@3.2.2(react@19.2.6)': + '@dnd-kit/utilities@3.2.2(react@19.2.7)': dependencies: - react: 19.2.6 + react: 19.2.7 tslib: 2.8.1 '@drizzle-team/brocli@0.10.2': {} @@ -11372,18 +11361,18 @@ snapshots: '@floating-ui/core': 1.7.5 '@floating-ui/utils': 0.2.11 - '@floating-ui/react-dom@2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@floating-ui/react-dom@2.1.8(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: '@floating-ui/dom': 1.7.6 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - '@floating-ui/react@0.27.19(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@floating-ui/react@0.27.19(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@floating-ui/react-dom': 2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@floating-ui/react-dom': 2.1.8(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@floating-ui/utils': 0.2.11 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) tabbable: 6.2.0 '@floating-ui/utils@0.2.10': {} @@ -11431,13 +11420,13 @@ snapshots: '@formatjs/fast-memoize': 3.1.0 tslib: 2.8.1 - '@gfazioli/mantine-onboarding-tour@4.0.3(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@gfazioli/mantine-onboarding-tour@4.0.4(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(@tabler/icons-react@3.44.0(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 9.2.2(react@19.2.6) - '@tabler/icons-react': 3.44.0(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@mantine/hooks': 9.2.2(react@19.2.7) + '@tabler/icons-react': 3.44.0(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) '@gitbeaker/core@43.8.0': dependencies: @@ -11488,7 +11477,7 @@ snapshots: eventemitter2: 6.4.9 http-cookie-agent: 6.0.8(tough-cookie@5.1.2)(undici@7.24.6) tough-cookie: 5.1.2 - ws: 8.20.1 + ws: 8.21.0 transitivePeerDependencies: - bufferutil - debug @@ -11904,95 +11893,95 @@ snapshots: js-base64: 3.7.8 optional: true - '@mantine/charts@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(recharts@3.8.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react-is@19.2.6)(react@19.2.6)(redux@5.0.1))': + '@mantine/charts@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(recharts@3.8.1(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react-is@19.2.7)(react@19.2.7)(redux@5.0.1))': dependencies: - '@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 9.2.2(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - recharts: 3.8.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react-is@19.2.6)(react@19.2.6)(redux@5.0.1) + '@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@mantine/hooks': 9.2.2(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + recharts: 3.8.1(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react-is@19.2.7)(react@19.2.7)(redux@5.0.1) '@mantine/colors-generator@9.2.2(chroma-js@3.2.0)': dependencies: chroma-js: 3.2.0 - '@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@floating-ui/react': 0.27.19(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 9.2.2(react@19.2.6) + '@floating-ui/react': 0.27.19(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@mantine/hooks': 9.2.2(react@19.2.7) clsx: 2.1.1 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - react-number-format: 5.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react-remove-scroll: 2.7.2(@types/react@19.2.15)(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-number-format: 5.4.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react-remove-scroll: 2.7.2(@types/react@19.2.16)(react@19.2.7) type-fest: 5.6.0 transitivePeerDependencies: - '@types/react' - '@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 9.2.2(react@19.2.6) + '@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@mantine/hooks': 9.2.2(react@19.2.7) clsx: 2.1.1 dayjs: 1.11.21 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - '@mantine/dropzone@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@mantine/dropzone@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 9.2.2(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - react-dropzone: 15.0.0(react@19.2.6) + '@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@mantine/hooks': 9.2.2(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-dropzone: 15.0.0(react@19.2.7) - '@mantine/form@9.2.2(react@19.2.6)': + '@mantine/form@9.2.2(react@19.2.7)': dependencies: '@standard-schema/spec': 1.1.0 fast-deep-equal: 3.1.3 klona: 2.0.6 - react: 19.2.6 + react: 19.2.7 - '@mantine/hooks@9.2.2(react@19.2.6)': + '@mantine/hooks@9.2.2(react@19.2.7)': dependencies: - react: 19.2.6 + react: 19.2.7 - '@mantine/modals@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@mantine/modals@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 9.2.2(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@mantine/hooks': 9.2.2(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - '@mantine/notifications@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@mantine/notifications@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 9.2.2(react@19.2.6) - '@mantine/store': 9.2.2(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - react-transition-group: 4.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@mantine/hooks': 9.2.2(react@19.2.7) + '@mantine/store': 9.2.2(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-transition-group: 4.4.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) - '@mantine/spotlight@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@mantine/spotlight@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 9.2.2(react@19.2.6) - '@mantine/store': 9.2.2(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@mantine/hooks': 9.2.2(react@19.2.7) + '@mantine/store': 9.2.2(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - '@mantine/store@9.2.2(react@19.2.6)': + '@mantine/store@9.2.2(react@19.2.7)': dependencies: - react: 19.2.6 + react: 19.2.7 - '@mantine/tiptap@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tiptap/extension-link@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))(@tiptap/react@3.24.0(@floating-ui/dom@1.7.6)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@mantine/tiptap@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(@tiptap/extension-link@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))(@tiptap/react@3.24.0(@floating-ui/dom@1.7.6)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 9.2.2(react@19.2.6) + '@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@mantine/hooks': 9.2.2(react@19.2.7) '@tiptap/extension-link': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - '@tiptap/react': 3.24.0(@floating-ui/dom@1.7.6)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@tiptap/react': 3.24.0(@floating-ui/dom@1.7.6)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) '@marijn/find-cluster-break@1.0.2': {} @@ -12018,28 +12007,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)': - dependencies: - '@hono/node-server': 1.19.14(hono@4.12.23) - ajv: 8.18.0 - ajv-formats: 3.0.1(ajv@8.18.0) - content-type: 1.0.5 - cors: 2.8.6 - cross-spawn: 7.0.6 - eventsource: 3.0.7 - eventsource-parser: 3.1.0 - express: 5.2.1 - express-rate-limit: 8.5.2(express@5.2.1) - hono: 4.12.23 - jose: 6.2.3 - json-schema-typed: 8.0.2 - pkce-challenge: 5.0.1 - raw-body: 3.0.2 - zod: 4.4.3 - zod-to-json-schema: 3.25.2(zod@4.4.3) - transitivePeerDependencies: - - supports-color - '@mswjs/interceptors@0.41.9': dependencies: '@open-draft/deferred-promise': 2.2.0 @@ -12050,30 +12017,30 @@ snapshots: strict-event-emitter: 0.5.1 optional: true - '@next/env@16.2.6': {} + '@next/env@16.2.7': {} - '@next/swc-darwin-arm64@16.2.6': + '@next/swc-darwin-arm64@16.2.7': optional: true - '@next/swc-darwin-x64@16.2.6': + '@next/swc-darwin-x64@16.2.7': optional: true - '@next/swc-linux-arm64-gnu@16.2.6': + '@next/swc-linux-arm64-gnu@16.2.7': optional: true - '@next/swc-linux-arm64-musl@16.2.6': + '@next/swc-linux-arm64-musl@16.2.7': optional: true - '@next/swc-linux-x64-gnu@16.2.6': + '@next/swc-linux-x64-gnu@16.2.7': optional: true - '@next/swc-linux-x64-musl@16.2.6': + '@next/swc-linux-x64-musl@16.2.7': optional: true - '@next/swc-win32-arm64-msvc@16.2.6': + '@next/swc-win32-arm64-msvc@16.2.7': optional: true - '@next/swc-win32-x64-msvc@16.2.6': + '@next/swc-win32-x64-msvc@16.2.7': optional: true '@noble/ciphers@2.2.0': {} @@ -12250,61 +12217,61 @@ snapshots: '@opentelemetry/semantic-conventions@1.41.1': {} - '@oxfmt/binding-android-arm-eabi@0.52.0': + '@oxfmt/binding-android-arm-eabi@0.53.0': optional: true - '@oxfmt/binding-android-arm64@0.52.0': + '@oxfmt/binding-android-arm64@0.53.0': optional: true - '@oxfmt/binding-darwin-arm64@0.52.0': + '@oxfmt/binding-darwin-arm64@0.53.0': optional: true - '@oxfmt/binding-darwin-x64@0.52.0': + '@oxfmt/binding-darwin-x64@0.53.0': optional: true - '@oxfmt/binding-freebsd-x64@0.52.0': + '@oxfmt/binding-freebsd-x64@0.53.0': optional: true - '@oxfmt/binding-linux-arm-gnueabihf@0.52.0': + '@oxfmt/binding-linux-arm-gnueabihf@0.53.0': optional: true - '@oxfmt/binding-linux-arm-musleabihf@0.52.0': + '@oxfmt/binding-linux-arm-musleabihf@0.53.0': optional: true - '@oxfmt/binding-linux-arm64-gnu@0.52.0': + '@oxfmt/binding-linux-arm64-gnu@0.53.0': optional: true - '@oxfmt/binding-linux-arm64-musl@0.52.0': + '@oxfmt/binding-linux-arm64-musl@0.53.0': optional: true - '@oxfmt/binding-linux-ppc64-gnu@0.52.0': + '@oxfmt/binding-linux-ppc64-gnu@0.53.0': optional: true - '@oxfmt/binding-linux-riscv64-gnu@0.52.0': + '@oxfmt/binding-linux-riscv64-gnu@0.53.0': optional: true - '@oxfmt/binding-linux-riscv64-musl@0.52.0': + '@oxfmt/binding-linux-riscv64-musl@0.53.0': optional: true - '@oxfmt/binding-linux-s390x-gnu@0.52.0': + '@oxfmt/binding-linux-s390x-gnu@0.53.0': optional: true - '@oxfmt/binding-linux-x64-gnu@0.52.0': + '@oxfmt/binding-linux-x64-gnu@0.53.0': optional: true - '@oxfmt/binding-linux-x64-musl@0.52.0': + '@oxfmt/binding-linux-x64-musl@0.53.0': optional: true - '@oxfmt/binding-openharmony-arm64@0.52.0': + '@oxfmt/binding-openharmony-arm64@0.53.0': optional: true - '@oxfmt/binding-win32-arm64-msvc@0.52.0': + '@oxfmt/binding-win32-arm64-msvc@0.53.0': optional: true - '@oxfmt/binding-win32-ia32-msvc@0.52.0': + '@oxfmt/binding-win32-ia32-msvc@0.53.0': optional: true - '@oxfmt/binding-win32-x64-msvc@0.52.0': + '@oxfmt/binding-win32-x64-msvc@0.53.0': optional: true '@oxlint/binding-android-arm-eabi@1.67.0': @@ -12507,7 +12474,7 @@ snapshots: dependencies: '@redis/client': 1.6.1 - '@reduxjs/toolkit@2.11.2(react-redux@9.2.0(@types/react@19.2.15)(react@19.2.6)(redux@5.0.1))(react@19.2.6)': + '@reduxjs/toolkit@2.11.2(react-redux@9.2.0(@types/react@19.2.16)(react@19.2.7)(redux@5.0.1))(react@19.2.7)': dependencies: '@standard-schema/spec': 1.1.0 '@standard-schema/utils': 0.3.0 @@ -12516,8 +12483,8 @@ snapshots: redux-thunk: 3.1.0(redux@5.0.1) reselect: 5.1.1 optionalDependencies: - react: 19.2.6 - react-redux: 9.2.0(@types/react@19.2.15)(react@19.2.6)(redux@5.0.1) + react: 19.2.7 + react-redux: 9.2.0(@types/react@19.2.16)(react@19.2.7)(redux@5.0.1) '@replit/codemirror-css-color-picker@6.3.0(@codemirror/language@6.12.3)(@codemirror/state@6.6.0)(@codemirror/view@6.43.0)': dependencies: @@ -12695,11 +12662,11 @@ snapshots: - typescript - universal-cookie - '@scalar/api-reference-react@0.9.42(react@19.2.6)(tailwindcss@4.3.0)(typescript@5.9.3)(zod@4.4.3)': + '@scalar/api-reference-react@0.9.42(react@19.2.7)(tailwindcss@4.3.0)(typescript@5.9.3)(zod@4.4.3)': dependencies: '@scalar/api-reference': 1.58.0(tailwindcss@4.3.0)(typescript@5.9.3)(zod@4.4.3) '@scalar/types': 0.12.3 - react: 19.2.6 + react: 19.2.7 transitivePeerDependencies: - '@vue/composition-api' - async-validator @@ -12880,7 +12847,7 @@ snapshots: '@scalar/use-codemirror@0.14.11(typescript@5.9.3)': dependencies: - '@codemirror/autocomplete': 6.20.2 + '@codemirror/autocomplete': 6.20.3 '@codemirror/commands': 6.10.3 '@codemirror/lang-css': 6.3.1 '@codemirror/lang-html': 6.4.11 @@ -13118,10 +13085,10 @@ snapshots: typescript: 5.9.3 zod: 4.4.3 - '@tabler/icons-react@3.44.0(react@19.2.6)': + '@tabler/icons-react@3.44.0(react@19.2.7)': dependencies: '@tabler/icons': 3.44.0 - react: 19.2.6 + react: 19.2.7 '@tabler/icons@3.44.0': {} @@ -13133,34 +13100,34 @@ snapshots: '@tanstack/query-devtools@5.100.14': {} - '@tanstack/react-query-devtools@5.100.14(@tanstack/react-query@5.100.14(react@19.2.6))(react@19.2.6)': + '@tanstack/react-query-devtools@5.100.14(@tanstack/react-query@5.100.14(react@19.2.7))(react@19.2.7)': dependencies: '@tanstack/query-devtools': 5.100.14 - '@tanstack/react-query': 5.100.14(react@19.2.6) - react: 19.2.6 + '@tanstack/react-query': 5.100.14(react@19.2.7) + react: 19.2.7 - '@tanstack/react-query-next-experimental@5.100.14(@tanstack/react-query@5.100.14(react@19.2.6))(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(react@19.2.6)': + '@tanstack/react-query-next-experimental@5.100.14(@tanstack/react-query@5.100.14(react@19.2.7))(next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0))(react@19.2.7)': dependencies: - '@tanstack/react-query': 5.100.14(react@19.2.6) - next: 16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0) - react: 19.2.6 + '@tanstack/react-query': 5.100.14(react@19.2.7) + next: 16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0) + react: 19.2.7 - '@tanstack/react-query@5.100.14(react@19.2.6)': + '@tanstack/react-query@5.100.14(react@19.2.7)': dependencies: '@tanstack/query-core': 5.100.14 - react: 19.2.6 + react: 19.2.7 - '@tanstack/react-table@8.20.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@tanstack/react-table@8.20.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: '@tanstack/table-core': 8.20.5 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - '@tanstack/react-virtual@3.11.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@tanstack/react-virtual@3.11.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: '@tanstack/virtual-core': 3.11.2 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) '@tanstack/table-core@8.20.5': {} @@ -13371,17 +13338,17 @@ snapshots: prosemirror-transform: 1.10.2 prosemirror-view: 1.41.4 - '@tiptap/react@3.24.0(@floating-ui/dom@1.7.6)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@tiptap/react@3.24.0(@floating-ui/dom@1.7.6)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) '@tiptap/pm': 3.24.0 - '@types/react': 19.2.15 - '@types/react-dom': 19.2.3(@types/react@19.2.15) + '@types/react': 19.2.16 + '@types/react-dom': 19.2.3(@types/react@19.2.16) '@types/use-sync-external-store': 0.0.6 fast-equals: 5.3.3 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - use-sync-external-store: 1.6.0(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + use-sync-external-store: 1.6.0(react@19.2.7) optionalDependencies: '@tiptap/extension-bubble-menu': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) '@tiptap/extension-floating-menu': 3.24.0(@floating-ui/dom@1.7.6)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) @@ -13420,36 +13387,36 @@ snapshots: '@trpc/server': 11.17.0(typescript@5.9.3) typescript: 5.9.3 - '@trpc/next@11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/react-query@11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@5.9.3)': + '@trpc/next@11.17.0(@tanstack/react-query@5.100.14(react@19.2.7))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/react-query@11.17.0(@tanstack/react-query@5.100.14(react@19.2.7))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.7)(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.9.3)': dependencies: '@trpc/client': 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3) '@trpc/server': 11.17.0(typescript@5.9.3) - next: 16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + next: 16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) typescript: 5.9.3 optionalDependencies: - '@tanstack/react-query': 5.100.14(react@19.2.6) - '@trpc/react-query': 11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3) + '@tanstack/react-query': 5.100.14(react@19.2.7) + '@trpc/react-query': 11.17.0(@tanstack/react-query@5.100.14(react@19.2.7))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.7)(typescript@5.9.3) - '@trpc/react-query@11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3)': + '@trpc/react-query@11.17.0(@tanstack/react-query@5.100.14(react@19.2.7))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.7)(typescript@5.9.3)': dependencies: - '@tanstack/react-query': 5.100.14(react@19.2.6) + '@tanstack/react-query': 5.100.14(react@19.2.7) '@trpc/client': 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3) '@trpc/server': 11.17.0(typescript@5.9.3) - react: 19.2.6 + react: 19.2.7 typescript: 5.9.3 '@trpc/server@11.17.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@trpc/tanstack-react-query@11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3)': + '@trpc/tanstack-react-query@11.17.0(@tanstack/react-query@5.100.14(react@19.2.7))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.7)(typescript@5.9.3)': dependencies: - '@tanstack/react-query': 5.100.14(react@19.2.6) + '@tanstack/react-query': 5.100.14(react@19.2.7) '@trpc/client': 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3) '@trpc/server': 11.17.0(typescript@5.9.3) - react: 19.2.6 + react: 19.2.7 typescript: 5.9.3 '@turbo/darwin-64@2.9.16': @@ -13652,11 +13619,11 @@ snapshots: '@types/range-parser@1.2.7': {} - '@types/react-dom@19.2.3(@types/react@19.2.15)': + '@types/react-dom@19.2.3(@types/react@19.2.16)': dependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.16 - '@types/react@19.2.15': + '@types/react@19.2.16': dependencies: csstype: 3.2.3 @@ -14237,8 +14204,6 @@ snapshots: baseline-browser-mapping@2.10.31: {} - baseline-browser-mapping@2.9.19: {} - bcrypt-pbkdf@1.0.2: dependencies: tweetnacl: 0.14.5 @@ -14250,7 +14215,7 @@ snapshots: before-after-hook@4.0.0: {} - better-auth@1.6.14(@opentelemetry/api@1.9.0)(better-sqlite3@12.10.0)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@libsql/client-wasm@0.14.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.10.0)(gel@2.0.0)(kysely@0.29.2)(mysql2@3.22.4(@types/node@24.12.4))(pg@8.21.0))(mysql2@3.22.4(@types/node@24.12.4))(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.8)(vue@3.5.35(typescript@5.9.3)): + better-auth@1.6.14(@opentelemetry/api@1.9.0)(better-sqlite3@12.10.0)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@libsql/client-wasm@0.14.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.10.0)(gel@2.0.0)(kysely@0.29.2)(mysql2@3.22.4(@types/node@24.12.4))(pg@8.21.0))(mysql2@3.22.4(@types/node@24.12.4))(next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0))(pg@8.21.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vitest@4.1.8)(vue@3.5.35(typescript@5.9.3)): dependencies: '@better-auth/core': 1.6.14(@better-auth/utils@0.4.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.29.2)(nanostores@1.3.0) '@better-auth/drizzle-adapter': 1.6.14(@better-auth/core@1.6.14(@better-auth/utils@0.4.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.29.2)(nanostores@1.3.0))(@better-auth/utils@0.4.1)(drizzle-orm@0.45.2(@libsql/client-wasm@0.14.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.10.0)(gel@2.0.0)(kysely@0.29.2)(mysql2@3.22.4(@types/node@24.12.4))(pg@8.21.0)) @@ -14274,10 +14239,10 @@ snapshots: drizzle-kit: 0.31.10 drizzle-orm: 0.45.2(@libsql/client-wasm@0.14.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.10.0)(gel@2.0.0)(kysely@0.29.2)(mysql2@3.22.4(@types/node@24.12.4))(pg@8.21.0) mysql2: 3.22.4(@types/node@24.12.4) - next: 16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0) + next: 16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0) pg: 8.21.0 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) vitest: 4.1.8(@opentelemetry/api@1.9.0)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.8)(@vitest/ui@4.1.8)(jsdom@29.1.1(@noble/hashes@2.0.1))(msw@2.14.6(@types/node@24.12.4)(typescript@5.9.3))(vite@7.1.12(@types/node@24.12.4)(jiti@1.21.7)(sass@1.100.0)(sugarss@5.0.0(postcss@8.5.15))(terser@5.46.1)(tsx@4.21.0)(yaml@2.9.0)) vue: 3.5.35(typescript@5.9.3) transitivePeerDependencies: @@ -14385,8 +14350,6 @@ snapshots: camelcase-css@2.0.1: {} - caniuse-lite@1.0.30001766: {} - caniuse-lite@1.0.30001793: {} ccount@2.0.1: {} @@ -15921,12 +15884,12 @@ snapshots: jose@6.2.3: {} - jotai@2.20.0(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@19.2.15)(react@19.2.6): + jotai@2.20.0(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@19.2.16)(react@19.2.7): optionalDependencies: '@babel/core': 7.29.0 '@babel/template': 7.28.6 - '@types/react': 19.2.15 - react: 19.2.6 + '@types/react': 19.2.16 + react: 19.2.7 js-base64@3.7.8: {} @@ -16125,19 +16088,19 @@ snapshots: dependencies: semver: 7.7.4 - mantine-react-table-open@9.0.3(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + mantine-react-table-open@9.0.3(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(@tabler/icons-react@3.44.0(react@19.2.7))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: - '@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/dates': 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 9.2.2(react@19.2.6) - '@tabler/icons-react': 3.44.0(react@19.2.6) + '@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@mantine/dates': 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.7))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.2.2(react@19.2.7))(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@mantine/hooks': 9.2.2(react@19.2.7) + '@tabler/icons-react': 3.44.0(react@19.2.7) '@tanstack/match-sorter-utils': 8.19.4 - '@tanstack/react-table': 8.20.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@tanstack/react-virtual': 3.11.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@tanstack/react-table': 8.20.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@tanstack/react-virtual': 3.11.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) clsx: 2.1.1 dayjs: 1.11.21 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) maria2@0.4.1: {} @@ -16158,14 +16121,14 @@ snapshots: math-intrinsics@1.1.0: {} - mcp-handler@1.1.0(@modelcontextprotocol/sdk@1.26.0(zod@4.4.3))(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0)): + mcp-handler@1.1.0(@modelcontextprotocol/sdk@1.26.0(zod@4.4.3))(next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0)): dependencies: '@modelcontextprotocol/sdk': 1.26.0(zod@4.4.3) chalk: 5.4.1 commander: 11.1.0 redis: 4.7.1 optionalDependencies: - next: 16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0) + next: 16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0) mdast-util-find-and-replace@3.0.2: dependencies: @@ -16666,50 +16629,50 @@ snapshots: dependencies: typescript: 5.9.3 - next-auth@5.0.0-beta.31(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(react@19.2.6): + next-auth@5.0.0-beta.31(next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0))(react@19.2.7): dependencies: '@auth/core': 0.41.2 - next: 16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0) - react: 19.2.6 + next: 16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0) + react: 19.2.7 next-intl-swc-plugin-extractor@4.13.0: {} - next-intl@4.13.0(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(react@19.2.6)(typescript@5.9.3): + next-intl@4.13.0(next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0))(react@19.2.7)(typescript@5.9.3): dependencies: '@formatjs/intl-localematcher': 0.8.1 '@parcel/watcher': 2.4.1 '@swc/core': 1.15.3 icu-minify: 4.13.0 negotiator: 1.0.0 - next: 16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0) + next: 16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0) next-intl-swc-plugin-extractor: 4.13.0 po-parser: 2.1.1 - react: 19.2.6 - use-intl: 4.13.0(react@19.2.6) + react: 19.2.7 + use-intl: 4.13.0(react@19.2.7) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - '@swc/helpers' - next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0): + next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0): dependencies: - '@next/env': 16.2.6 + '@next/env': 16.2.7 '@swc/helpers': 0.5.15 - baseline-browser-mapping: 2.9.19 - caniuse-lite: 1.0.30001766 + baseline-browser-mapping: 2.10.31 + caniuse-lite: 1.0.30001793 postcss: 8.4.31 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - styled-jsx: 5.1.6(@babel/core@7.29.0)(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + styled-jsx: 5.1.6(@babel/core@7.29.0)(react@19.2.7) optionalDependencies: - '@next/swc-darwin-arm64': 16.2.6 - '@next/swc-darwin-x64': 16.2.6 - '@next/swc-linux-arm64-gnu': 16.2.6 - '@next/swc-linux-arm64-musl': 16.2.6 - '@next/swc-linux-x64-gnu': 16.2.6 - '@next/swc-linux-x64-musl': 16.2.6 - '@next/swc-win32-arm64-msvc': 16.2.6 - '@next/swc-win32-x64-msvc': 16.2.6 + '@next/swc-darwin-arm64': 16.2.7 + '@next/swc-darwin-x64': 16.2.7 + '@next/swc-linux-arm64-gnu': 16.2.7 + '@next/swc-linux-arm64-musl': 16.2.7 + '@next/swc-linux-x64-gnu': 16.2.7 + '@next/swc-linux-x64-musl': 16.2.7 + '@next/swc-win32-arm64-msvc': 16.2.7 + '@next/swc-win32-x64-msvc': 16.2.7 '@opentelemetry/api': 1.9.0 '@playwright/test': 1.60.0 babel-plugin-react-compiler: 1.0.0 @@ -16846,29 +16809,29 @@ snapshots: outvariant@1.4.3: optional: true - oxfmt@0.52.0: + oxfmt@0.53.0: dependencies: tinypool: 2.1.0 optionalDependencies: - '@oxfmt/binding-android-arm-eabi': 0.52.0 - '@oxfmt/binding-android-arm64': 0.52.0 - '@oxfmt/binding-darwin-arm64': 0.52.0 - '@oxfmt/binding-darwin-x64': 0.52.0 - '@oxfmt/binding-freebsd-x64': 0.52.0 - '@oxfmt/binding-linux-arm-gnueabihf': 0.52.0 - '@oxfmt/binding-linux-arm-musleabihf': 0.52.0 - '@oxfmt/binding-linux-arm64-gnu': 0.52.0 - '@oxfmt/binding-linux-arm64-musl': 0.52.0 - '@oxfmt/binding-linux-ppc64-gnu': 0.52.0 - '@oxfmt/binding-linux-riscv64-gnu': 0.52.0 - '@oxfmt/binding-linux-riscv64-musl': 0.52.0 - '@oxfmt/binding-linux-s390x-gnu': 0.52.0 - '@oxfmt/binding-linux-x64-gnu': 0.52.0 - '@oxfmt/binding-linux-x64-musl': 0.52.0 - '@oxfmt/binding-openharmony-arm64': 0.52.0 - '@oxfmt/binding-win32-arm64-msvc': 0.52.0 - '@oxfmt/binding-win32-ia32-msvc': 0.52.0 - '@oxfmt/binding-win32-x64-msvc': 0.52.0 + '@oxfmt/binding-android-arm-eabi': 0.53.0 + '@oxfmt/binding-android-arm64': 0.53.0 + '@oxfmt/binding-darwin-arm64': 0.53.0 + '@oxfmt/binding-darwin-x64': 0.53.0 + '@oxfmt/binding-freebsd-x64': 0.53.0 + '@oxfmt/binding-linux-arm-gnueabihf': 0.53.0 + '@oxfmt/binding-linux-arm-musleabihf': 0.53.0 + '@oxfmt/binding-linux-arm64-gnu': 0.53.0 + '@oxfmt/binding-linux-arm64-musl': 0.53.0 + '@oxfmt/binding-linux-ppc64-gnu': 0.53.0 + '@oxfmt/binding-linux-riscv64-gnu': 0.53.0 + '@oxfmt/binding-linux-riscv64-musl': 0.53.0 + '@oxfmt/binding-linux-s390x-gnu': 0.53.0 + '@oxfmt/binding-linux-x64-gnu': 0.53.0 + '@oxfmt/binding-linux-x64-musl': 0.53.0 + '@oxfmt/binding-openharmony-arm64': 0.53.0 + '@oxfmt/binding-win32-arm64-msvc': 0.53.0 + '@oxfmt/binding-win32-ia32-msvc': 0.53.0 + '@oxfmt/binding-win32-x64-msvc': 0.53.0 oxlint@1.67.0: optionalDependencies: @@ -17191,7 +17154,7 @@ snapshots: dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 - react-is: 19.2.6 + react-is: 19.2.7 proper-lockfile@4.1.2: dependencies: @@ -17386,34 +17349,34 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 - react-dom@19.2.6(react@19.2.6): + react-dom@19.2.7(react@19.2.7): dependencies: - react: 19.2.6 + react: 19.2.7 scheduler: 0.27.0 - react-dropzone@15.0.0(react@19.2.6): + react-dropzone@15.0.0(react@19.2.7): dependencies: attr-accept: 2.2.5 file-selector: 2.1.2 prop-types: 15.8.1 - react: 19.2.6 + react: 19.2.7 - react-error-boundary@6.1.2(react@19.2.6): + react-error-boundary@6.1.2(react@19.2.7): dependencies: - react: 19.2.6 + react: 19.2.7 - react-is@19.2.6: {} + react-is@19.2.7: {} - react-markdown@10.1.0(@types/react@19.2.15)(react@19.2.6): + react-markdown@10.1.0(@types/react@19.2.16)(react@19.2.7): dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 - '@types/react': 19.2.15 + '@types/react': 19.2.16 devlop: 1.1.0 hast-util-to-jsx-runtime: 2.3.6 html-url-attributes: 3.0.1 mdast-util-to-hast: 13.2.0 - react: 19.2.6 + react: 19.2.7 remark-parse: 11.0.0 remark-rehype: 11.1.1 unified: 11.0.5 @@ -17422,72 +17385,72 @@ snapshots: transitivePeerDependencies: - supports-color - react-number-format@5.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + react-number-format@5.4.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - react-quill-new@3.8.3(quill-delta@5.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + react-quill-new@3.8.3(quill-delta@5.1.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: lodash-es: 4.17.21 quill: 2.0.3 quill-delta: 5.1.0 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - react-redux@9.2.0(@types/react@19.2.15)(react@19.2.6)(redux@5.0.1): + react-redux@9.2.0(@types/react@19.2.16)(react@19.2.7)(redux@5.0.1): dependencies: '@types/use-sync-external-store': 0.0.6 - react: 19.2.6 - use-sync-external-store: 1.6.0(react@19.2.6) + react: 19.2.7 + use-sync-external-store: 1.6.0(react@19.2.7) optionalDependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.16 redux: 5.0.1 react-refresh@0.18.0: {} - react-remove-scroll-bar@2.3.8(@types/react@19.2.15)(react@19.2.6): + react-remove-scroll-bar@2.3.8(@types/react@19.2.16)(react@19.2.7): dependencies: - react: 19.2.6 - react-style-singleton: 2.2.3(@types/react@19.2.15)(react@19.2.6) + react: 19.2.7 + react-style-singleton: 2.2.3(@types/react@19.2.16)(react@19.2.7) tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.16 - react-remove-scroll@2.7.2(@types/react@19.2.15)(react@19.2.6): + react-remove-scroll@2.7.2(@types/react@19.2.16)(react@19.2.7): dependencies: - react: 19.2.6 - react-remove-scroll-bar: 2.3.8(@types/react@19.2.15)(react@19.2.6) - react-style-singleton: 2.2.3(@types/react@19.2.15)(react@19.2.6) + react: 19.2.7 + react-remove-scroll-bar: 2.3.8(@types/react@19.2.16)(react@19.2.7) + react-style-singleton: 2.2.3(@types/react@19.2.16)(react@19.2.7) tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@19.2.15)(react@19.2.6) - use-sidecar: 1.1.3(@types/react@19.2.15)(react@19.2.6) + use-callback-ref: 1.3.3(@types/react@19.2.16)(react@19.2.7) + use-sidecar: 1.1.3(@types/react@19.2.16)(react@19.2.7) optionalDependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.16 - react-simple-code-editor@0.14.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + react-simple-code-editor@0.14.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - react-style-singleton@2.2.3(@types/react@19.2.15)(react@19.2.6): + react-style-singleton@2.2.3(@types/react@19.2.16)(react@19.2.7): dependencies: get-nonce: 1.0.1 - react: 19.2.6 + react: 19.2.7 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.16 - react-transition-group@4.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + react-transition-group@4.4.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: '@babel/runtime': 7.29.7 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - react@19.2.6: {} + react@19.2.7: {} read-package-up@11.0.0: dependencies: @@ -17549,21 +17512,21 @@ snapshots: real-require@0.2.0: {} - recharts@3.8.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react-is@19.2.6)(react@19.2.6)(redux@5.0.1): + recharts@3.8.1(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react-is@19.2.7)(react@19.2.7)(redux@5.0.1): dependencies: - '@reduxjs/toolkit': 2.11.2(react-redux@9.2.0(@types/react@19.2.15)(react@19.2.6)(redux@5.0.1))(react@19.2.6) + '@reduxjs/toolkit': 2.11.2(react-redux@9.2.0(@types/react@19.2.16)(react@19.2.7)(redux@5.0.1))(react@19.2.7) clsx: 2.1.1 decimal.js-light: 2.5.1 es-toolkit: 1.46.1 eventemitter3: 5.0.4 immer: 10.2.0 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - react-is: 19.2.6 - react-redux: 9.2.0(@types/react@19.2.15)(react@19.2.6)(redux@5.0.1) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-is: 19.2.7 + react-redux: 9.2.0(@types/react@19.2.16)(react@19.2.7)(redux@5.0.1) reselect: 5.1.1 tiny-invariant: 1.3.3 - use-sync-external-store: 1.4.0(react@19.2.6) + use-sync-external-store: 1.4.0(react@19.2.7) victory-vendor: 37.3.6 transitivePeerDependencies: - '@types/react' @@ -18135,10 +18098,10 @@ snapshots: dependencies: inline-style-parser: 0.2.4 - styled-jsx@5.1.6(@babel/core@7.29.0)(react@19.2.6): + styled-jsx@5.1.6(@babel/core@7.29.0)(react@19.2.7): dependencies: client-only: 0.0.1 - react: 19.2.6 + react: 19.2.7 optionalDependencies: '@babel/core': 7.29.0 @@ -18365,12 +18328,12 @@ snapshots: trough@2.2.0: {} - trpc-to-mcp@1.3.2(@trpc/server@11.17.0(typescript@5.9.3))(better-auth@1.6.14(@opentelemetry/api@1.9.0)(better-sqlite3@12.10.0)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@libsql/client-wasm@0.14.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.10.0)(gel@2.0.0)(kysely@0.29.2)(mysql2@3.22.4(@types/node@24.12.4))(pg@8.21.0))(mysql2@3.22.4(@types/node@24.12.4))(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.8)(vue@3.5.35(typescript@5.9.3)))(mcp-handler@1.1.0(@modelcontextprotocol/sdk@1.26.0(zod@4.4.3))(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0)))(zod@4.4.3): + trpc-to-mcp@1.3.2(@trpc/server@11.17.0(typescript@5.9.3))(better-auth@1.6.14(@opentelemetry/api@1.9.0)(better-sqlite3@12.10.0)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@libsql/client-wasm@0.14.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.10.0)(gel@2.0.0)(kysely@0.29.2)(mysql2@3.22.4(@types/node@24.12.4))(pg@8.21.0))(mysql2@3.22.4(@types/node@24.12.4))(next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0))(pg@8.21.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vitest@4.1.8)(vue@3.5.35(typescript@5.9.3)))(mcp-handler@1.1.0(@modelcontextprotocol/sdk@1.26.0(zod@4.4.3))(next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0)))(zod@4.4.3): dependencies: - '@modelcontextprotocol/sdk': 1.29.0(zod@4.4.3) + '@modelcontextprotocol/sdk': 1.26.0(zod@4.4.3) '@trpc/server': 11.17.0(typescript@5.9.3) - better-auth: 1.6.14(@opentelemetry/api@1.9.0)(better-sqlite3@12.10.0)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@libsql/client-wasm@0.14.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.10.0)(gel@2.0.0)(kysely@0.29.2)(mysql2@3.22.4(@types/node@24.12.4))(pg@8.21.0))(mysql2@3.22.4(@types/node@24.12.4))(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.8)(vue@3.5.35(typescript@5.9.3)) - mcp-handler: 1.1.0(@modelcontextprotocol/sdk@1.26.0(zod@4.4.3))(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0)) + better-auth: 1.6.14(@opentelemetry/api@1.9.0)(better-sqlite3@12.10.0)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@libsql/client-wasm@0.14.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@12.10.0)(gel@2.0.0)(kysely@0.29.2)(mysql2@3.22.4(@types/node@24.12.4))(pg@8.21.0))(mysql2@3.22.4(@types/node@24.12.4))(next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0))(pg@8.21.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vitest@4.1.8)(vue@3.5.35(typescript@5.9.3)) + mcp-handler: 1.1.0(@modelcontextprotocol/sdk@1.26.0(zod@4.4.3))(next@16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.100.0)) zod: 4.4.3 transitivePeerDependencies: - '@cfworker/json-schema' @@ -18561,42 +18524,42 @@ snapshots: url-toolkit@2.2.5: {} - use-callback-ref@1.3.3(@types/react@19.2.15)(react@19.2.6): + use-callback-ref@1.3.3(@types/react@19.2.16)(react@19.2.7): dependencies: - react: 19.2.6 + react: 19.2.7 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.16 - use-deep-compare-effect@1.8.1(react@19.2.6): + use-deep-compare-effect@1.8.1(react@19.2.7): dependencies: '@babel/runtime': 7.29.7 dequal: 2.0.3 - react: 19.2.6 + react: 19.2.7 - use-intl@4.13.0(react@19.2.6): + use-intl@4.13.0(react@19.2.7): dependencies: '@formatjs/fast-memoize': 3.1.0 '@schummar/icu-type-parser': 1.21.5 icu-minify: 4.13.0 intl-messageformat: 11.1.1 - react: 19.2.6 + react: 19.2.7 - use-sidecar@1.1.3(@types/react@19.2.15)(react@19.2.6): + use-sidecar@1.1.3(@types/react@19.2.16)(react@19.2.7): dependencies: detect-node-es: 1.1.0 - react: 19.2.6 + react: 19.2.7 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.16 - use-sync-external-store@1.4.0(react@19.2.6): + use-sync-external-store@1.4.0(react@19.2.7): dependencies: - react: 19.2.6 + react: 19.2.7 - use-sync-external-store@1.6.0(react@19.2.6): + use-sync-external-store@1.6.0(react@19.2.7): dependencies: - react: 19.2.6 + react: 19.2.7 util-deprecate@1.0.2: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 488154798..0d17339d5 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -14,7 +14,7 @@ catalog: "@dnd-kit/utilities": ^3.2.2 "@drizzle-team/brocli": ^0.12.0 "@extractus/feed-extractor": 7.2.1 - '@gfazioli/mantine-onboarding-tour': ^4.0.3 + '@gfazioli/mantine-onboarding-tour': ^4.0.4 "@gitbeaker/rest": ^43.8.0 "@homarr/gridstack": ^1.12.0 "@homarr/node-unifi": ^2.6.0 @@ -33,7 +33,7 @@ catalog: "@mantine/notifications": ^9.2.2 "@mantine/spotlight": ^9.2.2 "@mantine/tiptap": ^9.2.2 - "@next/eslint-plugin-next": 16.2.6 + "@next/eslint-plugin-next": 16.2.7 "@octokit/auth-app": ^8.2.0 "@paralleldrive/cuid2": ^3.3.0 "@playwright/test": ^1.60.0 @@ -85,7 +85,7 @@ catalog: "@types/node-unifi": ^2.5.1 "@types/pg": ^8.20.0 "@types/prismjs": ^1.26.6 - "@types/react": 19.2.15 + "@types/react": 19.2.16 "@types/react-dom": 19.2.3 "@scalar/api-reference-react": ^0.9.34 "@types/video.js": ^7.3.58 @@ -137,19 +137,19 @@ catalog: mcp-handler: ^1.1.0 maria2: ^0.4.1 mysql2: 3.22.4 - next: 16.2.6 + next: 16.2.7 next-auth: 5.0.0-beta.31 next-intl: 4.13.0 node-loader: ^2.1.0 octokit: ^5.0.5 - oxfmt: ^0.52.0 + oxfmt: ^0.53.0 oxlint: ^1.67.0 pg: ^8.21.0 postcss-preset-mantine: ^1.18.0 prismjs: ^1.30.0 proxmox-api: 1.1.1 - react: 19.2.6 - react-dom: 19.2.6 + react: 19.2.7 + react-dom: 19.2.7 react-error-boundary: ^6.1.2 react-markdown: ^10.1.0 react-quill-new: ^3.8.3