- Removed the @openclaw/dashboard-next package and its associated files.

- Updated dependencies in `pnpm-lock.yaml` to reflect the new package structure.
- Cleaned up configuration and environment files related to the previous dashboard implementation.
This commit is contained in:
Val Alexander
2026-02-21 09:56:41 -06:00
parent 152dda7108
commit cf45f877ed
18 changed files with 13 additions and 859 deletions

View File

@@ -57,9 +57,9 @@
"check": "pnpm format:check && pnpm tsgo && pnpm lint",
"check:docs": "pnpm format:docs:check && pnpm lint:docs && pnpm docs:check-links",
"check:loc": "node --import tsx scripts/check-ts-max-loc.ts --max 500",
"dashboard-next:build": "pnpm --dir packages/dashboard-next build",
"dashboard-next:dev": "pnpm --dir packages/dashboard-next dev",
"dashboard-next:start": "pnpm --dir packages/dashboard-next start",
"dashboard-lit:build": "pnpm --dir packages/dashboard-lit build",
"dashboard-lit:dev": "pnpm --dir packages/dashboard-lit dev",
"dashboard-lit:preview": "pnpm --dir packages/dashboard-lit preview",
"deadcode:ci": "pnpm deadcode:report:ci:knip && pnpm deadcode:report:ci:ts-prune && pnpm deadcode:report:ci:ts-unused",
"deadcode:knip": "pnpm dlx knip --no-progress",
"deadcode:report": "pnpm deadcode:knip; pnpm deadcode:ts-prune; pnpm deadcode:ts-unused",

View File

@@ -1,5 +0,0 @@
# Default gateway WebSocket target for local development
NEXT_PUBLIC_GATEWAY_URL=ws://127.0.0.1:18789
# Optional: base path if hosted behind a prefix (example: /openclaw)
NEXT_PUBLIC_BASE_PATH=

View File

@@ -1,29 +0,0 @@
# OpenClaw Dashboard (Next preview)
This is a **phase 1, low-lift preview** of a Next.js dashboard that coexists with the current Lit Control UI.
## Security posture (phase 1)
- Gateway remains the source of truth for auth, pairing, scopes, and method authorization.
- This app is a browser client only; it does not introduce privileged Next API routes.
- URL bootstrap behavior:
- `token` may be consumed and persisted locally.
- `password` is scrubbed from URL and never hydrated from URL.
- `gatewayUrl` may be consumed for remote/Tailscale testing and persisted locally.
## Run
```bash
pnpm dashboard-next:dev
```
## Phase 1 Checklist
- [x] App scaffold with App Router + TS
- [x] Shared WS gateway client package
- [x] URL bootstrap + sanitization path
- [x] Overview route (read-only status/snapshot)
- [x] Chat route (minimal send path)
- [ ] Feature flag and integrated gateway-serving route
- [ ] Parity checks vs existing Control UI tabs
- [ ] Security/performance gate review

View File

@@ -1,5 +0,0 @@
import { ChatPanel } from "../../components/chat-panel";
export default function ChatPage() {
return <ChatPanel />;
}

View File

@@ -1,112 +0,0 @@
* {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
font-family: Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
background: #0b0d10;
color: #f5f7fa;
}
a {
color: inherit;
text-decoration: none;
}
.app-shell {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.topbar {
border-bottom: 1px solid #232830;
padding: 12px 16px;
display: flex;
gap: 16px;
align-items: center;
}
.topbar nav {
display: flex;
gap: 10px;
}
.tab-link {
padding: 8px 12px;
border-radius: 10px;
border: 1px solid #2e3642;
background: #171c23;
}
main {
padding: 18px;
}
.panel {
border: 1px solid #2a303a;
border-radius: 12px;
background: #141920;
padding: 14px;
}
.panel + .panel {
margin-top: 12px;
}
.muted {
color: #9fa8b5;
}
.error {
color: #ff8f8f;
}
.status-row {
display: flex;
gap: 12px;
flex-wrap: wrap;
margin-bottom: 12px;
}
.status-pill {
border: 1px solid #344051;
border-radius: 999px;
padding: 6px 10px;
background: #10151b;
}
.chat-log {
max-height: 48vh;
overflow: auto;
border: 1px solid #252c36;
border-radius: 10px;
padding: 10px;
background: #0f1419;
}
.input-row {
margin-top: 10px;
display: flex;
gap: 8px;
}
.input-row input {
flex: 1;
border-radius: 10px;
border: 1px solid #344051;
background: #0e1318;
color: #f5f7fa;
padding: 10px;
}
.input-row button {
border-radius: 10px;
border: 1px solid #3d4f66;
background: #1b2736;
color: #f5f7fa;
padding: 10px 14px;
}

View File

@@ -1,29 +0,0 @@
import Link from "next/link";
import type { ReactNode } from "react";
import "./globals.css";
import { GatewayProvider } from "../components/gateway-provider";
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="en">
<body>
<GatewayProvider>
<div className="app-shell">
<header className="topbar">
<strong>OpenClaw Dashboard (Next preview)</strong>
<nav>
<Link className="tab-link" href="/overview">
Overview
</Link>
<Link className="tab-link" href="/chat">
Chat
</Link>
</nav>
</header>
<main>{children}</main>
</div>
</GatewayProvider>
</body>
</html>
);
}

View File

@@ -1,5 +0,0 @@
import { OverviewPanel } from "../../components/overview-panel";
export default function OverviewPage() {
return <OverviewPanel />;
}

View File

@@ -1,5 +0,0 @@
import { redirect } from "next/navigation";
export default function HomePage() {
redirect("/overview");
}

View File

@@ -1,98 +0,0 @@
"use client";
import { useState } from "react";
import { useGateway } from "./gateway-provider";
type ChatEventPayload = {
runId?: string;
state?: string;
delta?: string;
text?: string;
};
export function ChatPanel() {
const gateway = useGateway();
const [sessionKey, setSessionKey] = useState("main");
const [message, setMessage] = useState("");
const [submitting, setSubmitting] = useState(false);
const [logLines, setLogLines] = useState<string[]>([]);
const latestChatEvent =
gateway.lastEvent?.event === "chat"
? (gateway.lastEvent.payload as ChatEventPayload | undefined)
: null;
async function onSend() {
const trimmed = message.trim();
if (!trimmed || submitting) {
return;
}
setSubmitting(true);
setLogLines((prev) => [`You: ${trimmed}`, ...prev].slice(0, 120));
setMessage("");
try {
await gateway.request("chat.send", {
sessionKey,
message: trimmed,
});
} catch (error) {
const text = error instanceof Error ? error.message : String(error);
setLogLines((prev) => [`Error: ${text}`, ...prev].slice(0, 120));
} finally {
setSubmitting(false);
}
}
return (
<section className="panel">
<h2>Chat (preview)</h2>
<p className="muted">
Minimal phase-1 chat path. Uses existing gateway method/event flow without introducing new
privileged API surfaces.
</p>
<div className="input-row">
<input
value={sessionKey}
onChange={(event) => setSessionKey(event.target.value)}
placeholder="session key"
/>
</div>
<div className="input-row">
<input
value={message}
onChange={(event) => setMessage(event.target.value)}
placeholder="Type a message"
onKeyDown={(event) => {
if (event.key === "Enter") {
void onSend();
}
}}
/>
<button
type="button"
onClick={() => void onSend()}
disabled={submitting || !gateway.connected}
>
{submitting ? "Sending..." : "Send"}
</button>
</div>
<div className="panel" style={{ marginTop: 12 }}>
<h3>Last chat event</h3>
<pre>{JSON.stringify(latestChatEvent, null, 2) || "(none)"}</pre>
</div>
<div className="panel" style={{ marginTop: 12 }}>
<h3>Local transcript</h3>
<div className="chat-log">
{logLines.length === 0 ? <p className="muted">No messages yet.</p> : null}
{logLines.map((line, index) => (
<div key={`${line}-${index}`}>{line}</div>
))}
</div>
</div>
</section>
);
}

View File

@@ -1,124 +0,0 @@
"use client";
import {
DashboardGatewayClient,
type GatewayClientEventFrame,
type GatewayClientHelloOk,
} from "@openclaw/dashboard-gateway-client";
import {
createContext,
useContext,
useEffect,
useMemo,
useRef,
useState,
type ReactNode,
} from "react";
import {
loadStoredGatewayUrl,
loadStoredToken,
storeGatewayUrl,
storeToken,
} from "../lib/local-settings";
import { consumeBootstrapUrlState } from "../lib/url-state";
type GatewayState = {
connected: boolean;
connecting: boolean;
lastError: string | null;
hello: GatewayClientHelloOk | null;
lastEvent: GatewayClientEventFrame | null;
request: <T = unknown>(method: string, params?: unknown) => Promise<T>;
};
const GatewayContext = createContext<GatewayState | null>(null);
function resolveDefaultGatewayUrl() {
return process.env.NEXT_PUBLIC_GATEWAY_URL ?? "ws://127.0.0.1:18789";
}
export function GatewayProvider({ children }: { children: ReactNode }) {
const clientRef = useRef<DashboardGatewayClient | null>(null);
const [connected, setConnected] = useState(false);
const [connecting, setConnecting] = useState(true);
const [lastError, setLastError] = useState<string | null>(null);
const [hello, setHello] = useState<GatewayClientHelloOk | null>(null);
const [lastEvent, setLastEvent] = useState<GatewayClientEventFrame | null>(null);
useEffect(() => {
const bootstrap = consumeBootstrapUrlState();
const token = bootstrap.token || loadStoredToken();
const gatewayUrl = bootstrap.gatewayUrl || loadStoredGatewayUrl() || resolveDefaultGatewayUrl();
if (bootstrap.token) {
storeToken(bootstrap.token);
}
if (bootstrap.gatewayUrl) {
storeGatewayUrl(bootstrap.gatewayUrl);
}
const client = new DashboardGatewayClient({
gatewayUrl,
token: token || undefined,
reconnect: true,
onOpen: () => {
setConnecting(true);
},
onHello: (nextHello) => {
setHello(nextHello);
setConnected(true);
setConnecting(false);
setLastError(null);
},
onEvent: (event) => {
setLastEvent(event);
},
onClose: () => {
setConnected(false);
setConnecting(true);
},
onError: (error) => {
setLastError(error.message || "gateway error");
},
onGap: ({ expected, received }) => {
setLastError(`event gap detected (expected ${expected}, got ${received})`);
},
});
clientRef.current = client;
client.start();
return () => {
client.stop();
clientRef.current = null;
};
}, []);
const value = useMemo<GatewayState>(
() => ({
connected,
connecting,
lastError,
hello,
lastEvent,
request: async (method, params) => {
const client = clientRef.current;
if (!client) {
throw new Error("gateway client unavailable");
}
return client.request(method, params);
},
}),
[connected, connecting, hello, lastError, lastEvent],
);
return <GatewayContext.Provider value={value}>{children}</GatewayContext.Provider>;
}
export function useGateway() {
const context = useContext(GatewayContext);
if (!context) {
throw new Error("useGateway must be used inside <GatewayProvider>");
}
return context;
}

View File

@@ -1,34 +0,0 @@
"use client";
import { useGateway } from "./gateway-provider";
export function OverviewPanel() {
const gateway = useGateway();
return (
<>
<section className="panel">
<h2>Connection</h2>
<div className="status-row">
<span className="status-pill">{gateway.connected ? "Connected" : "Disconnected"}</span>
<span className="status-pill">{gateway.connecting ? "Reconnecting" : "Stable"}</span>
</div>
{gateway.lastError ? <p className="error">{gateway.lastError}</p> : null}
<p className="muted">
Phase 1 preview: Gateway is still the security/control plane. This UI does not bypass
auth, pairing, or scope checks.
</p>
</section>
<section className="panel">
<h2>Hello snapshot</h2>
<pre>{JSON.stringify(gateway.hello, null, 2) || "(waiting for hello-ok)"}</pre>
</section>
<section className="panel">
<h2>Latest event</h2>
<pre>{JSON.stringify(gateway.lastEvent, null, 2) || "(no events yet)"}</pre>
</section>
</>
);
}

View File

@@ -1,40 +0,0 @@
"use client";
const TOKEN_KEY = "openclaw.dashboard-next.token";
const GATEWAY_URL_KEY = "openclaw.dashboard-next.gateway-url";
export function loadStoredToken() {
if (typeof window === "undefined") {
return "";
}
return window.localStorage.getItem(TOKEN_KEY) ?? "";
}
export function storeToken(token: string) {
if (typeof window === "undefined") {
return;
}
if (!token.trim()) {
window.localStorage.removeItem(TOKEN_KEY);
return;
}
window.localStorage.setItem(TOKEN_KEY, token.trim());
}
export function loadStoredGatewayUrl() {
if (typeof window === "undefined") {
return "";
}
return window.localStorage.getItem(GATEWAY_URL_KEY) ?? "";
}
export function storeGatewayUrl(url: string) {
if (typeof window === "undefined") {
return;
}
if (!url.trim()) {
window.localStorage.removeItem(GATEWAY_URL_KEY);
return;
}
window.localStorage.setItem(GATEWAY_URL_KEY, url.trim());
}

View File

@@ -1,52 +0,0 @@
"use client";
const TOKEN_PARAM = "token";
const PASSWORD_PARAM = "password";
const GATEWAY_URL_PARAM = "gatewayUrl";
export type BootstrapUrlState = {
token: string | null;
gatewayUrl: string | null;
};
function parseHash(hash: string) {
return new URLSearchParams(hash.startsWith("#") ? hash.slice(1) : hash);
}
export function consumeBootstrapUrlState(): BootstrapUrlState {
if (typeof window === "undefined") {
return { token: null, gatewayUrl: null };
}
const url = new URL(window.location.href);
const params = new URLSearchParams(url.search);
const hashParams = parseHash(url.hash);
const tokenRaw = params.get(TOKEN_PARAM) ?? hashParams.get(TOKEN_PARAM);
const gatewayUrlRaw = params.get(GATEWAY_URL_PARAM) ?? hashParams.get(GATEWAY_URL_PARAM);
const token = tokenRaw?.trim() || null;
const gatewayUrl = gatewayUrlRaw?.trim() || null;
const hadSensitiveParam =
tokenRaw !== null ||
gatewayUrlRaw !== null ||
params.has(PASSWORD_PARAM) ||
hashParams.has(PASSWORD_PARAM);
if (hadSensitiveParam) {
params.delete(TOKEN_PARAM);
params.delete(PASSWORD_PARAM);
params.delete(GATEWAY_URL_PARAM);
hashParams.delete(TOKEN_PARAM);
hashParams.delete(PASSWORD_PARAM);
hashParams.delete(GATEWAY_URL_PARAM);
url.search = params.toString();
const nextHash = hashParams.toString();
url.hash = nextHash ? `#${nextHash}` : "";
window.history.replaceState({}, "", url.toString());
}
return { token, gatewayUrl };
}

View File

@@ -1,6 +0,0 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/dev/types/routes.d.ts";
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

View File

@@ -1,21 +0,0 @@
const basePathEnv = process.env.OPENCLAW_CONTROL_UI_BASE_PATH ?? "";
function normalizeBasePath(value) {
const trimmed = value.trim();
if (!trimmed || trimmed === "/") {
return "";
}
const withLeading = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
return withLeading.endsWith("/") ? withLeading.slice(0, -1) : withLeading;
}
const basePath = normalizeBasePath(basePathEnv);
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
basePath: basePath || undefined,
transpilePackages: ["@openclaw/dashboard-gateway-client"],
};
export default nextConfig;

View File

@@ -1,24 +0,0 @@
{
"name": "@openclaw/dashboard-next",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"build": "next build",
"dev": "next dev",
"lint": "next lint",
"start": "next start"
},
"dependencies": {
"@openclaw/dashboard-gateway-client": "workspace:*",
"next": "^16.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@types/node": "^25.3.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"typescript": "^5.9.3"
}
}

View File

@@ -1,31 +0,0 @@
{
"compilerOptions": {
"target": "ES2022",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": false,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react-jsx",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"types": ["node"]
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
".next/dev/types/**/*.ts"
],
"exclude": ["node_modules"]
}

246
pnpm-lock.yaml generated
View File

@@ -546,33 +546,24 @@ importers:
packages/dashboard-gateway-client: {}
packages/dashboard-next:
packages/dashboard-lit:
dependencies:
'@lit/context':
specifier: ^1.1.6
version: 1.1.6
'@openclaw/dashboard-gateway-client':
specifier: workspace:*
version: link:../dashboard-gateway-client
next:
specifier: ^16.0.0
version: 16.1.6(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
react:
specifier: ^19.0.0
version: 19.2.4
react-dom:
specifier: ^19.0.0
version: 19.2.4(react@19.2.4)
lit:
specifier: ^3.3.2
version: 3.3.2
devDependencies:
'@types/node':
specifier: ^25.3.0
version: 25.3.0
'@types/react':
specifier: ^19.0.0
version: 19.2.14
'@types/react-dom':
specifier: ^19.0.0
version: 19.2.3(@types/react@19.2.14)
typescript:
specifier: ^5.9.3
version: 5.9.3
vite:
specifier: 7.3.1
version: 7.3.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)
packages/moltbot:
dependencies:
@@ -1681,57 +1672,6 @@ packages:
'@napi-rs/wasm-runtime@1.1.1':
resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==}
'@next/env@16.1.6':
resolution: {integrity: sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ==}
'@next/swc-darwin-arm64@16.1.6':
resolution: {integrity: sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
'@next/swc-darwin-x64@16.1.6':
resolution: {integrity: sha512-BLFPYPDO+MNJsiDWbeVzqvYd4NyuRrEYVB5k2N3JfWncuHAy2IVwMAOlVQDFjj+krkWzhY2apvmekMkfQR0CUQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
'@next/swc-linux-arm64-gnu@16.1.6':
resolution: {integrity: sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@next/swc-linux-arm64-musl@16.1.6':
resolution: {integrity: sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@next/swc-linux-x64-gnu@16.1.6':
resolution: {integrity: sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@next/swc-linux-x64-musl@16.1.6':
resolution: {integrity: sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@next/swc-win32-arm64-msvc@16.1.6':
resolution: {integrity: sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
'@next/swc-win32-x64-msvc@16.1.6':
resolution: {integrity: sha512-NRfO39AIrzBnixKbjuo2YiYhB6o9d8v/ymU9m/Xk8cyVk+k7XylniXkHwjs4s70wedVffc6bQNbufk5v0xEm0A==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
'@noble/ciphers@2.1.1':
resolution: {integrity: sha512-bysYuiVfhxNJuldNXlFEitTVdNnYUc+XNJZd7Qm2a5j1vZHgY+fazadNFWFaMK/2vye0JVlxV3gHmC0WDfAOQw==}
engines: {node: '>= 20.19.0'}
@@ -2900,9 +2840,6 @@ packages:
'@standard-schema/spec@1.1.0':
resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
'@swc/helpers@0.5.15':
resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
'@swc/helpers@0.5.18':
resolution: {integrity: sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==}
@@ -3043,14 +2980,6 @@ packages:
'@types/range-parser@1.2.7':
resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==}
'@types/react-dom@19.2.3':
resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==}
peerDependencies:
'@types/react': ^19.2.0
'@types/react@19.2.14':
resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==}
'@types/request@2.48.13':
resolution: {integrity: sha512-FGJ6udDNUCjd19pp0Q3iTiDkwhYup7J8hpMW9c4k53NrccQFFWKRho6hvtPPEhnXWKvukfwAlB6DbDz4yhH5Gg==}
@@ -3379,11 +3308,6 @@ packages:
base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
baseline-browser-mapping@2.10.0:
resolution: {integrity: sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==}
engines: {node: '>=6.0.0'}
hasBin: true
basic-auth@2.0.1:
resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==}
engines: {node: '>= 0.8'}
@@ -3456,9 +3380,6 @@ packages:
resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
engines: {node: '>= 0.4'}
caniuse-lite@1.0.30001770:
resolution: {integrity: sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==}
caseless@0.12.0:
resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==}
@@ -3509,9 +3430,6 @@ packages:
resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==}
engines: {node: '>=6'}
client-only@0.0.1:
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
cliui@7.0.4:
resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==}
@@ -3608,9 +3526,6 @@ packages:
cssom@0.5.0:
resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==}
csstype@3.2.3:
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
curve25519-js@0.0.4:
resolution: {integrity: sha512-axn2UMEnkhyDUPWOwVKBMVIzSQy2ejH2xRGy1wq81dqRwApXfIzfbE3hIX0ZRFBIihf/KDqK158DLwESu4AK1w==}
@@ -4671,27 +4586,6 @@ packages:
resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==}
engines: {node: '>= 0.4.0'}
next@16.1.6:
resolution: {integrity: sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw==}
engines: {node: '>=20.9.0'}
hasBin: true
peerDependencies:
'@opentelemetry/api': ^1.1.0
'@playwright/test': ^1.51.1
babel-plugin-react-compiler: '*'
react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
sass: ^1.3.0
peerDependenciesMeta:
'@opentelemetry/api':
optional: true
'@playwright/test':
optional: true
babel-plugin-react-compiler:
optional: true
sass:
optional: true
node-addon-api@8.5.0:
resolution: {integrity: sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A==}
engines: {node: ^18 || ^20 || >= 21}
@@ -5015,10 +4909,6 @@ packages:
resolution: {integrity: sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==}
engines: {node: '>=14.19.0'}
postcss@8.4.31:
resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
engines: {node: ^10 || ^12 || >=14}
postcss@8.5.6:
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
engines: {node: ^10 || ^12 || >=14}
@@ -5139,15 +5029,6 @@ packages:
resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
hasBin: true
react-dom@19.2.4:
resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==}
peerDependencies:
react: ^19.2.4
react@19.2.4:
resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==}
engines: {node: '>=0.10.0'}
readable-stream@2.3.8:
resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
@@ -5260,9 +5141,6 @@ packages:
sanitize-html@2.17.1:
resolution: {integrity: sha512-ehFCW+q1a4CSOWRAdX97BX/6/PDEkCqw7/0JXZAGQV57FQB3YOkTa/rrzHPeJ+Aghy4vZAFfWMYyfxIiB7F/gw==}
scheduler@0.27.0:
resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
selderee@0.11.0:
resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==}
@@ -5495,19 +5373,6 @@ packages:
resolution: {integrity: sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==}
engines: {node: '>=18'}
styled-jsx@5.1.6:
resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
engines: {node: '>= 12.0.0'}
peerDependencies:
'@babel/core': '*'
babel-plugin-macros: '*'
react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0'
peerDependenciesMeta:
'@babel/core':
optional: true
babel-plugin-macros:
optional: true
supports-color@7.2.0:
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
engines: {node: '>=8'}
@@ -7346,32 +7211,6 @@ snapshots:
'@tybys/wasm-util': 0.10.1
optional: true
'@next/env@16.1.6': {}
'@next/swc-darwin-arm64@16.1.6':
optional: true
'@next/swc-darwin-x64@16.1.6':
optional: true
'@next/swc-linux-arm64-gnu@16.1.6':
optional: true
'@next/swc-linux-arm64-musl@16.1.6':
optional: true
'@next/swc-linux-x64-gnu@16.1.6':
optional: true
'@next/swc-linux-x64-musl@16.1.6':
optional: true
'@next/swc-win32-arm64-msvc@16.1.6':
optional: true
'@next/swc-win32-x64-msvc@16.1.6':
optional: true
'@noble/ciphers@2.1.1': {}
'@noble/curves@2.0.1':
@@ -8519,10 +8358,6 @@ snapshots:
'@standard-schema/spec@1.1.0': {}
'@swc/helpers@0.5.15':
dependencies:
tslib: 2.8.1
'@swc/helpers@0.5.18':
dependencies:
tslib: 2.8.1
@@ -8708,14 +8543,6 @@ snapshots:
'@types/range-parser@1.2.7': {}
'@types/react-dom@19.2.3(@types/react@19.2.14)':
dependencies:
'@types/react': 19.2.14
'@types/react@19.2.14':
dependencies:
csstype: 3.2.3
'@types/request@2.48.13':
dependencies:
'@types/caseless': 0.12.5
@@ -9115,8 +8942,6 @@ snapshots:
base64-js@1.5.1: {}
baseline-browser-mapping@2.10.0: {}
basic-auth@2.0.1:
dependencies:
safe-buffer: 5.1.2
@@ -9207,8 +9032,6 @@ snapshots:
call-bind-apply-helpers: 1.0.2
get-intrinsic: 1.3.0
caniuse-lite@1.0.30001770: {}
caseless@0.12.0: {}
chai@6.2.2: {}
@@ -9251,8 +9074,6 @@ snapshots:
cli-spinners@2.9.2: {}
client-only@0.0.1: {}
cliui@7.0.4:
dependencies:
string-width: 4.2.3
@@ -9355,8 +9176,6 @@ snapshots:
cssom@0.5.0: {}
csstype@3.2.3: {}
curve25519-js@0.0.4: {}
dashdash@1.14.1:
@@ -10477,31 +10296,6 @@ snapshots:
netmask@2.0.2: {}
next@16.1.6(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
dependencies:
'@next/env': 16.1.6
'@swc/helpers': 0.5.15
baseline-browser-mapping: 2.10.0
caniuse-lite: 1.0.30001770
postcss: 8.4.31
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
styled-jsx: 5.1.6(react@19.2.4)
optionalDependencies:
'@next/swc-darwin-arm64': 16.1.6
'@next/swc-darwin-x64': 16.1.6
'@next/swc-linux-arm64-gnu': 16.1.6
'@next/swc-linux-arm64-musl': 16.1.6
'@next/swc-linux-x64-gnu': 16.1.6
'@next/swc-linux-x64-musl': 16.1.6
'@next/swc-win32-arm64-msvc': 16.1.6
'@next/swc-win32-x64-msvc': 16.1.6
'@opentelemetry/api': 1.9.0
sharp: 0.34.5
transitivePeerDependencies:
- '@babel/core'
- babel-plugin-macros
node-addon-api@8.5.0: {}
node-api-headers@1.8.0: {}
@@ -10895,12 +10689,6 @@ snapshots:
pngjs@7.0.0: {}
postcss@8.4.31:
dependencies:
nanoid: 3.3.11
picocolors: 1.1.1
source-map-js: 1.2.1
postcss@8.5.6:
dependencies:
nanoid: 3.3.11
@@ -11052,13 +10840,6 @@ snapshots:
minimist: 1.2.8
strip-json-comments: 2.0.1
react-dom@19.2.4(react@19.2.4):
dependencies:
react: 19.2.4
scheduler: 0.27.0
react@19.2.4: {}
readable-stream@2.3.8:
dependencies:
core-util-is: 1.0.3
@@ -11213,8 +10994,6 @@ snapshots:
parse-srcset: 1.0.2
postcss: 8.5.6
scheduler@0.27.0: {}
selderee@0.11.0:
dependencies:
parseley: 0.12.1
@@ -11514,11 +11293,6 @@ snapshots:
dependencies:
'@tokenizer/token': 0.3.0
styled-jsx@5.1.6(react@19.2.4):
dependencies:
client-only: 0.0.1
react: 19.2.4
supports-color@7.2.0:
dependencies:
has-flag: 4.0.0