diff --git a/apps/studio/assets/midscene-icon.png b/apps/studio/assets/midscene-icon.png new file mode 100644 index 0000000000..3780090a91 Binary files /dev/null and b/apps/studio/assets/midscene-icon.png differ diff --git a/apps/studio/package.json b/apps/studio/package.json new file mode 100644 index 0000000000..12d44238c8 --- /dev/null +++ b/apps/studio/package.json @@ -0,0 +1,33 @@ +{ + "name": "studio", + "private": true, + "version": "0.1.0", + "type": "module", + "scripts": { + "build": "rsbuild build && node scripts/sync-static-assets.mjs", + "dev": "concurrently -k -n build,app \"rsbuild dev\" \"node scripts/wait-for-electron-build.mjs && node scripts/launch-electron-dev.mjs\"", + "preview": "rsbuild preview --environment renderer", + "start": "node scripts/sync-static-assets.mjs && electron dist/main/main.cjs", + "test": "vitest run" + }, + "dependencies": { + "react": "18.3.1", + "react-dom": "18.3.1" + }, + "devDependencies": { + "@rsbuild/core": "^1.6.15", + "@rsbuild/plugin-less": "^1.5.0", + "@rsbuild/plugin-react": "^1.4.1", + "@rsbuild/plugin-type-check": "^1.3.2", + "@tailwindcss/postcss": "4.1.11", + "@types/node": "^18.0.0", + "@types/react": "^18.3.1", + "@types/react-dom": "^18.3.1", + "concurrently": "^8.2.0", + "electron": "41.2.0", + "less": "^4.2.0", + "tailwindcss": "4.1.11", + "typescript": "^5.8.3", + "vitest": "3.0.5" + } +} diff --git a/apps/studio/postcss.config.mjs b/apps/studio/postcss.config.mjs new file mode 100644 index 0000000000..60cf15487f --- /dev/null +++ b/apps/studio/postcss.config.mjs @@ -0,0 +1,7 @@ +export default { + plugins: { + '@tailwindcss/postcss': { + preflight: false, + }, + }, +}; diff --git a/apps/studio/rsbuild.config.ts b/apps/studio/rsbuild.config.ts new file mode 100644 index 0000000000..bd52a410e5 --- /dev/null +++ b/apps/studio/rsbuild.config.ts @@ -0,0 +1,90 @@ +import { defineConfig } from '@rsbuild/core'; +import { pluginLess } from '@rsbuild/plugin-less'; +import { pluginReact } from '@rsbuild/plugin-react'; +import { pluginTypeCheck } from '@rsbuild/plugin-type-check'; +import { version as appVersion } from './package.json'; +import { + rendererDevHost, + rendererDevPort, +} from './scripts/renderer-dev-config.mjs'; + +export default defineConfig({ + server: { + host: rendererDevHost, + port: rendererDevPort, + }, + dev: { + writeToDisk: true, + }, + plugins: [pluginReact(), pluginLess(), pluginTypeCheck()], + environments: { + renderer: { + html: { + title: 'Midscene Studio', + }, + source: { + entry: { + index: './src/renderer/index.tsx', + }, + define: { + __APP_VERSION__: JSON.stringify(appVersion), + }, + }, + output: { + target: 'web', + distPath: { + root: 'dist/renderer', + }, + sourceMap: true, + }, + }, + main: { + tools: { + htmlPlugin: false, + }, + source: { + entry: { + main: { + import: './src/main/index.ts', + html: false, + }, + }, + }, + output: { + target: 'node', + distPath: { + root: 'dist/main', + }, + filename: { + js: '[name].cjs', + }, + externals: ['electron'], + sourceMap: true, + }, + }, + preload: { + tools: { + htmlPlugin: false, + }, + source: { + entry: { + preload: { + import: './src/preload/index.ts', + html: false, + }, + }, + }, + output: { + target: 'node', + distPath: { + root: 'dist/preload', + }, + filename: { + js: '[name].cjs', + }, + externals: ['electron'], + sourceMap: true, + }, + }, + }, +}); diff --git a/apps/studio/scripts/launch-electron-dev.mjs b/apps/studio/scripts/launch-electron-dev.mjs new file mode 100644 index 0000000000..521d4337f6 --- /dev/null +++ b/apps/studio/scripts/launch-electron-dev.mjs @@ -0,0 +1,37 @@ +import { spawn } from 'node:child_process'; +import { createRequire } from 'node:module'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { rendererDevUrl } from './renderer-dev-config.mjs'; + +// Spawns Electron with MIDSCENE_STUDIO_RENDERER_URL sourced from the shared +// dev config, so the port is not duplicated in package.json scripts. +const require = createRequire(import.meta.url); +const electronBinary = require('electron'); +const rootDir = path.resolve( + path.dirname(fileURLToPath(import.meta.url)), + '..', +); + +const child = spawn( + electronBinary, + [path.join(rootDir, 'dist/main/main.cjs')], + { + env: { ...process.env, MIDSCENE_STUDIO_RENDERER_URL: rendererDevUrl }, + stdio: 'inherit', + }, +); + +const forwardSignal = (signal) => { + if (!child.killed) child.kill(signal); +}; +process.on('SIGINT', forwardSignal); +process.on('SIGTERM', forwardSignal); + +child.on('exit', (code, signal) => { + if (signal) { + process.kill(process.pid, signal); + return; + } + process.exit(code ?? 0); +}); diff --git a/apps/studio/scripts/renderer-dev-config.mjs b/apps/studio/scripts/renderer-dev-config.mjs new file mode 100644 index 0000000000..824acd0837 --- /dev/null +++ b/apps/studio/scripts/renderer-dev-config.mjs @@ -0,0 +1,8 @@ +// Single source of truth for the renderer dev server host/port. +// Imported by rsbuild.config.ts (to bind the dev server), by +// scripts/wait-for-electron-build.mjs (to probe readiness) and by +// scripts/launch-electron-dev.mjs (to tell the main process where +// to load from via MIDSCENE_STUDIO_RENDERER_URL). +export const rendererDevHost = '127.0.0.1'; +export const rendererDevPort = 3210; +export const rendererDevUrl = `http://${rendererDevHost}:${rendererDevPort}`; diff --git a/apps/studio/scripts/sync-static-assets.mjs b/apps/studio/scripts/sync-static-assets.mjs new file mode 100644 index 0000000000..8af0933573 --- /dev/null +++ b/apps/studio/scripts/sync-static-assets.mjs @@ -0,0 +1,35 @@ +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { fileURLToPath, pathToFileURL } from 'node:url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const rootDir = path.resolve(__dirname, '..'); + +export const defaultSourceDir = path.join(rootDir, 'assets'); +export const defaultTargetDir = path.join(rootDir, 'dist/assets'); + +/** + * Copy the shell's static assets into the build output, wiping any prior + * target contents first so files removed from source do not linger in dist. + * Throws if `sourceDir` does not exist — there is no meaningful fallback + * when the asset bundle is missing. + */ +export const syncStaticAssets = async ({ + sourceDir = defaultSourceDir, + targetDir = defaultTargetDir, +} = {}) => { + await fs.access(sourceDir); + await fs.rm(targetDir, { force: true, recursive: true }); + await fs.mkdir(path.dirname(targetDir), { recursive: true }); + await fs.cp(sourceDir, targetDir, { recursive: true }); + return targetDir; +}; + +const isDirectInvocation = + process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href; + +if (isDirectInvocation) { + const targetDir = await syncStaticAssets(); + console.log(`Synced Midscene Studio static assets to ${targetDir}`); +} diff --git a/apps/studio/scripts/wait-for-electron-build.mjs b/apps/studio/scripts/wait-for-electron-build.mjs new file mode 100644 index 0000000000..25ac0b446a --- /dev/null +++ b/apps/studio/scripts/wait-for-electron-build.mjs @@ -0,0 +1,122 @@ +import fs from 'node:fs'; +import http from 'node:http'; +import path from 'node:path'; +import { fileURLToPath, pathToFileURL } from 'node:url'; +import { rendererDevUrl } from './renderer-dev-config.mjs'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const rootDir = path.resolve(__dirname, '..'); + +export const defaultRequiredFiles = [ + path.join(rootDir, 'dist/main/main.cjs'), + path.join(rootDir, 'dist/preload/preload.cjs'), +]; + +export const defaultRendererUrl = rendererDevUrl; +export const defaultMaxWaitMs = 180000; +export const defaultPollIntervalMs = 500; + +export const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); + +export const readMtimeMs = (file) => { + try { + return fs.statSync(file).mtimeMs; + } catch (error) { + // Missing file is an expected signal ("not built yet"); anything else + // (permission denied, IO error, ...) should surface instead of being + // silently swallowed into a stale-build state. + if (error && error.code === 'ENOENT') return null; + throw new Error( + `wait-for-electron-build: failed to stat ${file}: ${ + error instanceof Error ? error.message : String(error) + }`, + { cause: error }, + ); + } +}; + +/** + * Build a "has this dev cycle produced a fresh build?" checker. + * + * The checker snapshots each required file's mtime at creation time, then + * on every call it returns true only when every file exists AND either was + * absent in the snapshot or now has a strictly newer mtime. This avoids + * treating stale dist artifacts from a previous `pnpm dev` run as "fresh". + */ +export const createFreshBuildChecker = (files, readMtime = readMtimeMs) => { + const initialMtimes = new Map(files.map((file) => [file, readMtime(file)])); + + return () => + files.every((file) => { + const current = readMtime(file); + if (current === null) { + return false; + } + + const initial = initialMtimes.get(file); + return initial === null || current > initial; + }); +}; + +export const checkRendererReady = (url) => + new Promise((resolve) => { + const request = http.get(url, (response) => { + response.resume(); + resolve(response.statusCode === 200); + }); + + request.on('error', () => resolve(false)); + request.setTimeout(1000, () => { + request.destroy(); + resolve(false); + }); + }); + +/** + * Poll until the required build outputs are fresh AND the renderer dev + * server is serving a 200, or until `maxWaitMs` elapses. Dependencies are + * injectable so the loop can be unit-tested with a virtual clock. + */ +export const waitForBuild = async ({ + requiredFiles = defaultRequiredFiles, + rendererUrl = defaultRendererUrl, + maxWaitMs = defaultMaxWaitMs, + pollIntervalMs = defaultPollIntervalMs, + readMtime = readMtimeMs, + isRendererReady = () => checkRendererReady(rendererUrl), + now = () => Date.now(), + delay = sleep, +} = {}) => { + const hasFreshBuild = createFreshBuildChecker(requiredFiles, readMtime); + const startedAt = now(); + + while (now() - startedAt < maxWaitMs) { + if (hasFreshBuild() && (await isRendererReady())) { + return true; + } + + await delay(pollIntervalMs); + } + + return false; +}; + +const isDirectInvocation = + process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href; + +if (isDirectInvocation) { + console.log('Waiting for Midscene Studio shell build output...'); + + const ready = await waitForBuild(); + + if (ready) { + console.log('Midscene Studio shell build is ready.'); + process.exit(0); + } + + console.error( + 'Timed out waiting for the Midscene Studio shell build to finish.', + ); + process.exit(1); +} diff --git a/apps/studio/src/env.d.ts b/apps/studio/src/env.d.ts new file mode 100644 index 0000000000..260bcb2a80 --- /dev/null +++ b/apps/studio/src/env.d.ts @@ -0,0 +1,9 @@ +import type { ElectronShellApi } from './shared/electron-contract'; + +declare global { + interface Window { + electronShell?: ElectronShellApi; + } +} + +declare const __APP_VERSION__: string; diff --git a/apps/studio/src/main/index.ts b/apps/studio/src/main/index.ts new file mode 100644 index 0000000000..8218889bcf --- /dev/null +++ b/apps/studio/src/main/index.ts @@ -0,0 +1,150 @@ +import { existsSync } from 'node:fs'; +import path from 'node:path'; +import { IPC_CHANNELS } from '@shared/electron-contract'; +import { + BrowserWindow, + type NativeImage, + app, + ipcMain, + nativeImage, +} from 'electron'; +import type { TitleBarOverlay } from 'electron'; + +/** + * Main process owns native shell concerns only. + * Future device discovery / agent hosting should be bootstrapped from here and + * delegated to a dedicated Node-side service, not imported into the renderer. + */ + +let mainWindow: BrowserWindow | null = null; +let cachedAppIcon: NativeImage | null = null; + +const getRendererEntryPath = () => + path.join(__dirname, '../renderer/index.html'); + +const getPreloadEntryPath = () => + path.join(__dirname, '../preload/preload.cjs'); + +const getAppIconPath = () => { + const candidatePaths = [ + path.resolve(process.resourcesPath, 'assets/midscene-icon.png'), + path.resolve(app.getAppPath(), 'assets/midscene-icon.png'), + path.resolve(__dirname, '../assets/midscene-icon.png'), + ]; + + const iconPath = candidatePaths.find((candidatePath) => + existsSync(candidatePath), + ); + + if (!iconPath) { + throw new Error( + `Midscene Studio app icon not found. Checked: ${candidatePaths.join(', ')}`, + ); + } + + return iconPath; +}; + +const getAppIcon = () => { + if (cachedAppIcon) { + return cachedAppIcon; + } + + const icon = nativeImage.createFromPath(getAppIconPath()); + + if (icon.isEmpty()) { + throw new Error('Midscene Studio app icon could not be loaded.'); + } + + cachedAppIcon = icon; + return icon; +}; + +const getBackgroundColor = () => + process.platform === 'darwin' ? '#00000000' : '#eef1f5'; + +const getTitleBarOverlay = (): TitleBarOverlay => ({ + color: '#00000000', + height: 56, + symbolColor: '#17212b', +}); + +const createMainWindow = () => { + const rendererDevUrl = process.env.MIDSCENE_STUDIO_RENDERER_URL; + const appIcon = getAppIcon(); + const window = new BrowserWindow({ + width: 1440, + height: 900, + minWidth: 1180, + minHeight: 760, + backgroundColor: getBackgroundColor(), + autoHideMenuBar: true, + show: false, + titleBarStyle: process.platform === 'darwin' ? 'hiddenInset' : 'hidden', + titleBarOverlay: + process.platform === 'darwin' ? undefined : getTitleBarOverlay(), + trafficLightPosition: + process.platform === 'darwin' ? { x: 18, y: 18 } : undefined, + transparent: process.platform === 'darwin', + vibrancy: process.platform === 'darwin' ? 'under-window' : undefined, + visualEffectState: process.platform === 'darwin' ? 'active' : undefined, + backgroundMaterial: process.platform === 'win32' ? 'mica' : undefined, + icon: appIcon, + webPreferences: { + contextIsolation: true, + nodeIntegration: false, + preload: getPreloadEntryPath(), + sandbox: false, + }, + }); + + window.once('ready-to-show', () => { + window.show(); + }); + + if (rendererDevUrl) { + window.loadURL(rendererDevUrl); + } else { + window.loadFile(getRendererEntryPath()); + } + + mainWindow = window; +}; + +const registerIpcHandlers = () => { + ipcMain.handle(IPC_CHANNELS.minimizeWindow, () => { + mainWindow?.minimize(); + }); + ipcMain.handle(IPC_CHANNELS.toggleMaximizeWindow, () => { + if (!mainWindow) return; + if (mainWindow.isMaximized()) { + mainWindow.unmaximize(); + } else { + mainWindow.maximize(); + } + }); + ipcMain.handle(IPC_CHANNELS.closeWindow, () => { + mainWindow?.close(); + }); +}; + +app.whenReady().then(() => { + if (process.platform === 'darwin' && app.dock) { + app.dock.setIcon(getAppIcon()); + } + + registerIpcHandlers(); + createMainWindow(); + + app.on('activate', () => { + if (BrowserWindow.getAllWindows().length === 0) { + createMainWindow(); + } + }); +}); + +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { + app.quit(); + } +}); diff --git a/apps/studio/src/preload/index.ts b/apps/studio/src/preload/index.ts new file mode 100644 index 0000000000..a29e591512 --- /dev/null +++ b/apps/studio/src/preload/index.ts @@ -0,0 +1,16 @@ +import { type ElectronShellApi, IPC_CHANNELS } from '@shared/electron-contract'; +import { contextBridge, ipcRenderer } from 'electron'; + +/** + * Preload is intentionally thin. + * It exposes a typed bridge and keeps Electron access out of the renderer. + */ + +const electronShellApi: ElectronShellApi = { + closeWindow: () => ipcRenderer.invoke(IPC_CHANNELS.closeWindow), + minimizeWindow: () => ipcRenderer.invoke(IPC_CHANNELS.minimizeWindow), + toggleMaximizeWindow: () => + ipcRenderer.invoke(IPC_CHANNELS.toggleMaximizeWindow), +}; + +contextBridge.exposeInMainWorld('electronShell', electronShellApi); diff --git a/apps/studio/src/renderer/App.css b/apps/studio/src/renderer/App.css new file mode 100644 index 0000000000..4818c4c409 --- /dev/null +++ b/apps/studio/src/renderer/App.css @@ -0,0 +1,29 @@ +@layer theme, base, components, utilities; +@import "tailwindcss/theme.css" layer(theme); +@import "tailwindcss/utilities.css" layer(utilities); + +@layer base { + html, + body, + #root { + width: 100%; + height: 100%; + margin: 0; + overflow: hidden; + background: transparent; + } + + body { + overscroll-behavior: none; + } +} + +@layer utilities { + .app-drag { + -webkit-app-region: drag; + } + + .app-no-drag { + -webkit-app-region: no-drag; + } +} diff --git a/apps/studio/src/renderer/App.tsx b/apps/studio/src/renderer/App.tsx new file mode 100644 index 0000000000..c404196194 --- /dev/null +++ b/apps/studio/src/renderer/App.tsx @@ -0,0 +1,10 @@ +import './App.css'; +import { ShellLayout } from './components'; + +export default function App() { + return ( +
+ +
+ ); +} diff --git a/apps/studio/src/renderer/assets/index.ts b/apps/studio/src/renderer/assets/index.ts new file mode 100644 index 0000000000..04be1d1a18 --- /dev/null +++ b/apps/studio/src/renderer/assets/index.ts @@ -0,0 +1,26 @@ +export const assetUrls = { + main: { + chat: new URL('./main-chat.png', import.meta.url).href, + device: new URL('./main-device.png', import.meta.url).href, + disconnect: new URL('./main-disconnect.png', import.meta.url).href, + phoneScreen: new URL('./main-phone-screen.png', import.meta.url).href, + }, + playground: { + action: new URL('./playground-action.png', import.meta.url).href, + actionChevron: new URL('./playground-action-chevron.png', import.meta.url) + .href, + history: new URL('./playground-history.png', import.meta.url).href, + midsceneIcon: new URL('../../../assets/midscene-icon.png', import.meta.url) + .href, + send: new URL('./playground-send.png', import.meta.url).href, + tool: new URL('./playground-tool.png', import.meta.url).href, + }, + sidebar: { + computer: new URL('./sidebar-computer.png', import.meta.url).href, + harmony: new URL('./sidebar-harmony.png', import.meta.url).href, + ios: new URL('./sidebar-ios.png', import.meta.url).href, + overview: new URL('./sidebar-overview.png', import.meta.url).href, + settings: new URL('./sidebar-settings.png', import.meta.url).href, + web: new URL('./sidebar-web.png', import.meta.url).href, + }, +} as const; diff --git a/apps/studio/src/renderer/assets/main-chat.png b/apps/studio/src/renderer/assets/main-chat.png new file mode 100644 index 0000000000..959441d96a Binary files /dev/null and b/apps/studio/src/renderer/assets/main-chat.png differ diff --git a/apps/studio/src/renderer/assets/main-device.png b/apps/studio/src/renderer/assets/main-device.png new file mode 100644 index 0000000000..24ef5eef65 Binary files /dev/null and b/apps/studio/src/renderer/assets/main-device.png differ diff --git a/apps/studio/src/renderer/assets/main-disconnect.png b/apps/studio/src/renderer/assets/main-disconnect.png new file mode 100644 index 0000000000..c0659108c3 Binary files /dev/null and b/apps/studio/src/renderer/assets/main-disconnect.png differ diff --git a/apps/studio/src/renderer/assets/main-phone-screen.png b/apps/studio/src/renderer/assets/main-phone-screen.png new file mode 100644 index 0000000000..0cf97ac7d6 Binary files /dev/null and b/apps/studio/src/renderer/assets/main-phone-screen.png differ diff --git a/apps/studio/src/renderer/assets/playground-action-chevron.png b/apps/studio/src/renderer/assets/playground-action-chevron.png new file mode 100644 index 0000000000..7b37df9b21 Binary files /dev/null and b/apps/studio/src/renderer/assets/playground-action-chevron.png differ diff --git a/apps/studio/src/renderer/assets/playground-action.png b/apps/studio/src/renderer/assets/playground-action.png new file mode 100644 index 0000000000..8b862ef413 Binary files /dev/null and b/apps/studio/src/renderer/assets/playground-action.png differ diff --git a/apps/studio/src/renderer/assets/playground-history.png b/apps/studio/src/renderer/assets/playground-history.png new file mode 100644 index 0000000000..630a358fa5 Binary files /dev/null and b/apps/studio/src/renderer/assets/playground-history.png differ diff --git a/apps/studio/src/renderer/assets/playground-send.png b/apps/studio/src/renderer/assets/playground-send.png new file mode 100644 index 0000000000..abea6d051e Binary files /dev/null and b/apps/studio/src/renderer/assets/playground-send.png differ diff --git a/apps/studio/src/renderer/assets/playground-tool.png b/apps/studio/src/renderer/assets/playground-tool.png new file mode 100644 index 0000000000..bca142ebda Binary files /dev/null and b/apps/studio/src/renderer/assets/playground-tool.png differ diff --git a/apps/studio/src/renderer/assets/sidebar-computer.png b/apps/studio/src/renderer/assets/sidebar-computer.png new file mode 100644 index 0000000000..39af4a8273 Binary files /dev/null and b/apps/studio/src/renderer/assets/sidebar-computer.png differ diff --git a/apps/studio/src/renderer/assets/sidebar-harmony.png b/apps/studio/src/renderer/assets/sidebar-harmony.png new file mode 100644 index 0000000000..0776a78747 Binary files /dev/null and b/apps/studio/src/renderer/assets/sidebar-harmony.png differ diff --git a/apps/studio/src/renderer/assets/sidebar-ios.png b/apps/studio/src/renderer/assets/sidebar-ios.png new file mode 100644 index 0000000000..8d31fe3ce8 Binary files /dev/null and b/apps/studio/src/renderer/assets/sidebar-ios.png differ diff --git a/apps/studio/src/renderer/assets/sidebar-overview.png b/apps/studio/src/renderer/assets/sidebar-overview.png new file mode 100644 index 0000000000..97bcf63c0a Binary files /dev/null and b/apps/studio/src/renderer/assets/sidebar-overview.png differ diff --git a/apps/studio/src/renderer/assets/sidebar-settings.png b/apps/studio/src/renderer/assets/sidebar-settings.png new file mode 100644 index 0000000000..fb5158727e Binary files /dev/null and b/apps/studio/src/renderer/assets/sidebar-settings.png differ diff --git a/apps/studio/src/renderer/assets/sidebar-web.png b/apps/studio/src/renderer/assets/sidebar-web.png new file mode 100644 index 0000000000..d0e0635427 Binary files /dev/null and b/apps/studio/src/renderer/assets/sidebar-web.png differ diff --git a/apps/studio/src/renderer/components/MainContent/index.tsx b/apps/studio/src/renderer/components/MainContent/index.tsx new file mode 100644 index 0000000000..f6c7c72866 --- /dev/null +++ b/apps/studio/src/renderer/components/MainContent/index.tsx @@ -0,0 +1,59 @@ +import { assetUrls } from '../../assets'; + +export default function MainContent() { + return ( +
+
+
+
+ +
+ + 三星 Galaxy S26 Ultra + +
+
+ + Live + +
+
+ +
+ + +
+
+ +
+ Phone screen +
+
+ ); +} diff --git a/apps/studio/src/renderer/components/Playground/index.tsx b/apps/studio/src/renderer/components/Playground/index.tsx new file mode 100644 index 0000000000..f33d42ff5d --- /dev/null +++ b/apps/studio/src/renderer/components/Playground/index.tsx @@ -0,0 +1,75 @@ +import { assetUrls } from '../../assets'; + +export default function Playground() { + return ( +
+
+ + Playground + +
+ +
+ Logo +

+ Welcome to
Midscene.js Playground! +

+
+ {`This is a panel for experimenting and testing Midscene.js features. +You can use natural language instructions to operate the web page, such as clicking buttons, filling in forms, querying information, etc. +Please enter your instructions in the input box below to start experiencing.`} +
+
+ +
+
+ + Type a message + +
+
+
+ + + Action + + +
+
+ +
+
+ +
+
+ Send +
+
+
+
+ ); +} diff --git a/apps/studio/src/renderer/components/ShellLayout/index.tsx b/apps/studio/src/renderer/components/ShellLayout/index.tsx new file mode 100644 index 0000000000..9516fbdd6d --- /dev/null +++ b/apps/studio/src/renderer/components/ShellLayout/index.tsx @@ -0,0 +1,24 @@ +import MainContent from '../MainContent'; +import Playground from '../Playground'; +import Sidebar, { SidebarFooter } from '../Sidebar'; + +export default function ShellLayout() { + return ( +
+
+
+ +
+ +
+ +
+
+ +
+ + +
+
+ ); +} diff --git a/apps/studio/src/renderer/components/Sidebar/index.tsx b/apps/studio/src/renderer/components/Sidebar/index.tsx new file mode 100644 index 0000000000..25afe8f124 --- /dev/null +++ b/apps/studio/src/renderer/components/Sidebar/index.tsx @@ -0,0 +1,292 @@ +import { useState } from 'react'; +import { assetUrls } from '../../assets'; + +type DeviceStatus = 'active' | 'idle'; + +interface DeviceItem { + id: string; + label: string; + status: DeviceStatus; +} + +interface SectionItem { + count?: number; + countClassName?: string; + iconSrc?: string; + key: string; + label: string; + devices: DeviceItem[]; +} + +const sections: SectionItem[] = [ + { + key: 'android', + label: 'Android', + devices: [ + { + id: 'android-primary', + label: '三星 Galaxy S26 Ultra', + status: 'idle', + }, + { + id: 'android-1', + label: '三星 Galaxy S26 Ultra', + status: 'idle', + }, + { + id: 'android-2', + label: '三星 Galaxy S26 Ultra', + status: 'idle', + }, + { + id: 'android-3', + label: '三星 Galaxy S26 Ultra', + status: 'idle', + }, + ], + }, + { + iconSrc: assetUrls.sidebar.ios, + key: 'ios', + label: 'iOS', + devices: [ + { + id: 'ios-1', + label: 'iPhone 12 Pro Max', + status: 'active', + }, + { + id: 'ios-2', + label: 'iPhone 17 Pro', + status: 'idle', + }, + ], + }, + { + iconSrc: assetUrls.sidebar.computer, + key: 'computer', + label: 'Computer', + devices: [ + { + id: 'computer-1', + label: 'Macbook pro 16', + status: 'idle', + }, + ], + }, + { + count: 0, + countClassName: + "absolute left-[155.5px] top-[6px] text-[12px] leading-[20px] font-normal text-[#474848] font-['PingFang_SC']", + iconSrc: assetUrls.sidebar.harmony, + key: 'harmony', + label: 'HarmonyOS', + devices: [ + { + id: 'harmony-1', + label: '华为P50(鸿蒙3.0.0)', + status: 'idle', + }, + { + id: 'harmony-2', + label: '华为P50(鸿蒙3.0.0)', + status: 'idle', + }, + ], + }, + { + iconSrc: assetUrls.sidebar.web, + key: 'web', + label: 'Web', + devices: [], + }, +]; + +function ChevronDown({ className }: { className?: string }) { + return ( +
+ +
+ ); +} + +function SectionHeader({ + count, + countClassName, + iconSrc, + label, + onClick, +}: { + count?: number; + countClassName?: string; + iconSrc?: string; + label: string; + onClick: () => void; +}) { + return ( + + ); +} + +function DeviceRow({ + label, + selected, + status, +}: DeviceItem & { + selected: boolean; +}) { + return ( +
+
+ + {label} + +
+
+
+
+ ); +} + +export default function Sidebar() { + const [expandedSections, setExpandedSections] = useState< + Record + >({ + android: true, + computer: true, + harmony: true, + ios: true, + web: true, + }); + + const toggleSection = (sectionKey: string) => { + setExpandedSections((current) => ({ + ...current, + [sectionKey]: !current[sectionKey], + })); + }; + + return ( +
+
+ + + 设备总览 + +
+ +
+
+ + Platform + + + 4 + +
+ +
+ {sections.map((section) => ( +
+ toggleSection(section.key)} + /> + + {expandedSections[section.key] + ? section.devices.map((device, index) => ( + + )) + : null} +
+ ))} +
+
+
+ ); +} + +export function SidebarFooter() { + return ( +
+
+ + + 设置 + +
+ + +
+
+
+ ); +} diff --git a/apps/studio/src/renderer/components/index.ts b/apps/studio/src/renderer/components/index.ts new file mode 100644 index 0000000000..a01503a1e8 --- /dev/null +++ b/apps/studio/src/renderer/components/index.ts @@ -0,0 +1,4 @@ +export { default as MainContent } from './MainContent'; +export { default as Playground } from './Playground'; +export { default as ShellLayout } from './ShellLayout'; +export { default as Sidebar, SidebarFooter } from './Sidebar'; diff --git a/apps/studio/src/renderer/index.tsx b/apps/studio/src/renderer/index.tsx new file mode 100644 index 0000000000..8f562fef3e --- /dev/null +++ b/apps/studio/src/renderer/index.tsx @@ -0,0 +1,9 @@ +import { StrictMode } from 'react'; +import { createRoot } from 'react-dom/client'; +import App from './App'; + +createRoot(document.getElementById('root') as HTMLElement).render( + + + , +); diff --git a/apps/studio/src/shared/electron-contract.ts b/apps/studio/src/shared/electron-contract.ts new file mode 100644 index 0000000000..150d0934ff --- /dev/null +++ b/apps/studio/src/shared/electron-contract.ts @@ -0,0 +1,29 @@ +/** + * IPC channel names bridging the Midscene Studio main process and renderer. + * Shared with {@link ElectronShellApi} so both sides agree on the wire + * contract without importing renderer- or main-only code. + */ +export const IPC_CHANNELS = { + closeWindow: 'shell:close-window', + minimizeWindow: 'shell:minimize-window', + toggleMaximizeWindow: 'shell:toggle-maximize-window', +} as const; + +/** + * Public API exposed on `window.electronShell` by the preload bridge. + * + * Every method is a one-way command sent over IPC to the main process. The + * renderer never talks to Electron directly — all native interactions must + * pass through this interface so the renderer stays trivially sandboxable. + */ +export interface ElectronShellApi { + /** Request the main process to close the current shell window. */ + closeWindow: () => Promise; + /** Request the main process to minimize the current shell window. */ + minimizeWindow: () => Promise; + /** + * Toggle maximize/unmaximize on the current shell window. No-op if the + * window is not available (e.g. during teardown). + */ + toggleMaximizeWindow: () => Promise; +} diff --git a/apps/studio/tests/sync-static-assets.test.mjs b/apps/studio/tests/sync-static-assets.test.mjs new file mode 100644 index 0000000000..9f402cb3d0 --- /dev/null +++ b/apps/studio/tests/sync-static-assets.test.mjs @@ -0,0 +1,63 @@ +import fs from 'node:fs/promises'; +import os from 'node:os'; +import path from 'node:path'; +import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { syncStaticAssets } from '../scripts/sync-static-assets.mjs'; + +let workDir; +let sourceDir; +let targetDir; + +beforeEach(async () => { + workDir = await fs.mkdtemp(path.join(os.tmpdir(), 'studio-sync-assets-')); + sourceDir = path.join(workDir, 'assets'); + targetDir = path.join(workDir, 'dist/assets'); + await fs.mkdir(sourceDir, { recursive: true }); +}); + +afterEach(async () => { + await fs.rm(workDir, { force: true, recursive: true }); +}); + +describe('syncStaticAssets', () => { + it('copies every file from source into target', async () => { + await fs.writeFile(path.join(sourceDir, 'a.png'), 'a'); + await fs.writeFile(path.join(sourceDir, 'b.png'), 'b'); + + const returned = await syncStaticAssets({ sourceDir, targetDir }); + + expect(returned).toBe(targetDir); + expect(await fs.readFile(path.join(targetDir, 'a.png'), 'utf8')).toBe('a'); + expect(await fs.readFile(path.join(targetDir, 'b.png'), 'utf8')).toBe('b'); + }); + + it('preserves nested directories', async () => { + await fs.mkdir(path.join(sourceDir, 'nested'), { recursive: true }); + await fs.writeFile(path.join(sourceDir, 'nested', 'c.png'), 'c'); + + await syncStaticAssets({ sourceDir, targetDir }); + + expect( + await fs.readFile(path.join(targetDir, 'nested', 'c.png'), 'utf8'), + ).toBe('c'); + }); + + it('removes stale files that exist in target but are no longer in source', async () => { + await fs.mkdir(targetDir, { recursive: true }); + await fs.writeFile(path.join(targetDir, 'old.png'), 'stale'); + await fs.writeFile(path.join(sourceDir, 'new.png'), 'fresh'); + + await syncStaticAssets({ sourceDir, targetDir }); + + expect(await fs.readFile(path.join(targetDir, 'new.png'), 'utf8')).toBe( + 'fresh', + ); + await expect(fs.access(path.join(targetDir, 'old.png'))).rejects.toThrow(); + }); + + it('throws when the source directory does not exist', async () => { + await fs.rm(sourceDir, { force: true, recursive: true }); + + await expect(syncStaticAssets({ sourceDir, targetDir })).rejects.toThrow(); + }); +}); diff --git a/apps/studio/tests/wait-for-electron-build.test.mjs b/apps/studio/tests/wait-for-electron-build.test.mjs new file mode 100644 index 0000000000..ee7d431c54 --- /dev/null +++ b/apps/studio/tests/wait-for-electron-build.test.mjs @@ -0,0 +1,189 @@ +import { describe, expect, it } from 'vitest'; +import { + createFreshBuildChecker, + waitForBuild, +} from '../scripts/wait-for-electron-build.mjs'; + +const FILE_A = '/fake/main.cjs'; +const FILE_B = '/fake/preload.cjs'; + +const readerFrom = (mtimes) => (file) => + mtimes.has(file) ? mtimes.get(file) : null; + +describe('createFreshBuildChecker', () => { + it('returns false when any required file is missing at the moment of the check', () => { + const mtimes = new Map([[FILE_A, 100]]); + const isFresh = createFreshBuildChecker( + [FILE_A, FILE_B], + readerFrom(mtimes), + ); + + expect(isFresh()).toBe(false); + }); + + it('returns false when every file existed at startup and no mtime has moved forward', () => { + const mtimes = new Map([ + [FILE_A, 100], + [FILE_B, 200], + ]); + const isFresh = createFreshBuildChecker( + [FILE_A, FILE_B], + readerFrom(mtimes), + ); + + expect(isFresh()).toBe(false); + }); + + it('returns true when a file that was absent at startup now exists and the rest are strictly newer', () => { + const mtimes = new Map([[FILE_A, 100]]); + const read = readerFrom(mtimes); + const isFresh = createFreshBuildChecker([FILE_A, FILE_B], read); + + expect(isFresh()).toBe(false); + + mtimes.set(FILE_B, 200); + mtimes.set(FILE_A, 300); + + expect(isFresh()).toBe(true); + }); + + it('stays false until every required file has a strictly newer mtime', () => { + const mtimes = new Map([ + [FILE_A, 100], + [FILE_B, 200], + ]); + const read = readerFrom(mtimes); + const isFresh = createFreshBuildChecker([FILE_A, FILE_B], read); + + mtimes.set(FILE_A, 150); + expect(isFresh()).toBe(false); + + mtimes.set(FILE_B, 250); + expect(isFresh()).toBe(true); + }); + + it('returns false if a previously present file disappears mid-poll', () => { + const mtimes = new Map([ + [FILE_A, 100], + [FILE_B, 200], + ]); + const read = readerFrom(mtimes); + const isFresh = createFreshBuildChecker([FILE_A, FILE_B], read); + + mtimes.delete(FILE_A); + + expect(isFresh()).toBe(false); + }); + + it('does not treat an equal mtime as fresh (regression guard for the dropped freshness window)', () => { + const mtimes = new Map([[FILE_A, 500]]); + const read = readerFrom(mtimes); + const isFresh = createFreshBuildChecker([FILE_A], read); + + // Mtime unchanged — the previous implementation had a 3s "freshness + // window" fallback that would mark this as fresh. The fix drops that + // fallback, so equal-mtime must stay false. + expect(isFresh()).toBe(false); + }); + + it('propagates non-ENOENT read errors instead of treating them as missing files', () => { + // Regression guard: readMtimeMs narrows its catch to ENOENT so real IO + // errors (permission denied, disk failure, ...) surface instead of being + // silently reinterpreted as "file not built yet". If someone widens the + // catch back to `catch {}`, this test must break. + const throwingReader = () => { + const error = new Error('permission denied'); + error.code = 'EACCES'; + throw error; + }; + + expect(() => createFreshBuildChecker([FILE_A], throwingReader)).toThrow( + /permission denied/, + ); + }); +}); + +describe('waitForBuild', () => { + const makeVirtualClock = () => { + let tick = 0; + return { + now: () => tick, + delay: async (ms) => { + tick += ms; + }, + advance: (ms) => { + tick += ms; + }, + }; + }; + + it('resolves true as soon as the build is fresh and the renderer is ready', async () => { + const mtimes = new Map(); + const read = readerFrom(mtimes); + const clock = makeVirtualClock(); + + const promise = waitForBuild({ + requiredFiles: [FILE_A], + maxWaitMs: 10000, + pollIntervalMs: 250, + readMtime: read, + isRendererReady: async () => true, + now: clock.now, + delay: clock.delay, + }); + + // File appears right after the checker's initial snapshot. + mtimes.set(FILE_A, 42); + + await expect(promise).resolves.toBe(true); + }); + + it('resolves false after maxWaitMs elapses with a perpetually stale build', async () => { + const staleMtimes = new Map([[FILE_A, 100]]); + const read = readerFrom(staleMtimes); + const clock = makeVirtualClock(); + + const result = await waitForBuild({ + requiredFiles: [FILE_A], + maxWaitMs: 1000, + pollIntervalMs: 500, + readMtime: read, + isRendererReady: async () => true, + now: clock.now, + delay: clock.delay, + }); + + expect(result).toBe(false); + }); + + it('keeps polling while the renderer is not yet serving after the build becomes fresh', async () => { + const mtimes = new Map(); + const read = readerFrom(mtimes); + const clock = makeVirtualClock(); + + let rendererReadyCalls = 0; + const isRendererReady = async () => { + rendererReadyCalls += 1; + return rendererReadyCalls >= 3; + }; + + const resultPromise = waitForBuild({ + requiredFiles: [FILE_A], + maxWaitMs: 10000, + pollIntervalMs: 250, + readMtime: read, + isRendererReady, + now: clock.now, + delay: clock.delay, + }); + + // File appears right after the checker's initial snapshot, so the build is + // fresh from the first poll onward. + mtimes.set(FILE_A, 1); + + const result = await resultPromise; + + expect(result).toBe(true); + expect(rendererReadyCalls).toBe(3); + }); +}); diff --git a/apps/studio/tsconfig.json b/apps/studio/tsconfig.json new file mode 100644 index 0000000000..89b15d9dfc --- /dev/null +++ b/apps/studio/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../packages/shared/tsconfig.app.base.json", + "compilerOptions": { + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "types": ["node"], + "baseUrl": "./src", + "paths": { + "@main/*": ["main/*"], + "@preload/*": ["preload/*"], + "@renderer/*": ["renderer/*"], + "@shared/*": ["shared/*"] + } + }, + "include": ["src"] +} diff --git a/apps/studio/vitest.config.ts b/apps/studio/vitest.config.ts new file mode 100644 index 0000000000..dbdfc1b7f7 --- /dev/null +++ b/apps/studio/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + environment: 'node', + include: ['tests/**/*.test.mjs'], + }, +}); diff --git a/docs/plan/studio-phase-1.md b/docs/plan/studio-phase-1.md new file mode 100644 index 0000000000..cd28a6ddd1 --- /dev/null +++ b/docs/plan/studio-phase-1.md @@ -0,0 +1,33 @@ +# Midscene Studio Phase 1 + +## Goal + +Create a new `apps/studio` shell application powered by `Rsbuild` and +Electron. + +## Scope + +- Add a new Nx-detected app package under `apps/` +- Use one `rsbuild.config.ts` with three environments: + - `renderer`: React + Less shell UI + - `main`: Electron main process bundle + - `preload`: typed IPC bridge for the renderer +- Ship a light-themed native-feeling two-pane layout +- Vendor shell assets inside `apps/studio` so the app does not depend on + remote design-export URLs at runtime +- Keep the runtime layering explicit so phase 2 can plug in real device and + agent flows without reorganizing the app + +## Architecture Decisions + +- `src/main`: owns native window lifecycle and OS-specific Electron + integration; static assets are synced from `apps/studio/assets` + into `dist/assets` by `scripts/sync-static-assets.mjs` +- `src/preload`: the only trusted renderer bridge; business logic stays out +- `src/renderer`: UI only, no direct Node or Electron imports +- `src/shared`: cross-process contracts and types + +## Validation + +- `pnpm --filter studio build` +- `pnpm run lint` diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 053fcba7c4..7dc23a175d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -92,7 +92,7 @@ importers: version: 1.2.2(@rsbuild/core@1.6.15)(typescript@5.8.3) '@rsbuild/plugin-type-check': specifier: ^1.3.2 - version: 1.3.2(@rsbuild/core@1.6.15)(@rspack/core@1.6.8(@swc/helpers@0.5.17))(typescript@5.8.3) + version: 1.3.2(@rsbuild/core@1.6.15)(@rspack/core@1.6.8(@swc/helpers@0.5.21))(typescript@5.8.3) '@types/react': specifier: ^18.3.1 version: 18.3.23 @@ -183,7 +183,7 @@ importers: version: 1.2.2(@rsbuild/core@1.6.15)(typescript@5.8.3) '@rsbuild/plugin-type-check': specifier: ^1.3.2 - version: 1.3.2(@rsbuild/core@1.6.15)(@rspack/core@1.6.8(@swc/helpers@0.5.17))(typescript@5.8.3) + version: 1.3.2(@rsbuild/core@1.6.15)(@rspack/core@1.6.8(@swc/helpers@0.5.21))(typescript@5.8.3) '@tailwindcss/postcss': specifier: 4.1.11 version: 4.1.11 @@ -259,7 +259,7 @@ importers: version: 1.2.2(@rsbuild/core@1.6.15)(typescript@5.8.3) '@rsbuild/plugin-type-check': specifier: ^1.3.2 - version: 1.3.2(@rsbuild/core@1.6.15)(@rspack/core@1.6.8(@swc/helpers@0.5.17))(typescript@5.8.3) + version: 1.3.2(@rsbuild/core@1.6.15)(@rspack/core@1.6.8(@swc/helpers@0.5.21))(typescript@5.8.3) '@types/react': specifier: ^18.3.1 version: 18.3.23 @@ -311,7 +311,7 @@ importers: version: 1.2.2(@rsbuild/core@1.6.15)(typescript@5.8.3) '@rsbuild/plugin-type-check': specifier: ^1.3.2 - version: 1.3.2(@rsbuild/core@1.6.15)(@rspack/core@1.6.8(@swc/helpers@0.5.17))(typescript@5.8.3) + version: 1.3.2(@rsbuild/core@1.6.15)(@rspack/core@1.6.8(@swc/helpers@0.5.21))(typescript@5.8.3) '@types/react': specifier: ^18.3.1 version: 18.3.23 @@ -372,7 +372,7 @@ importers: version: 1.4.1(@rsbuild/core@1.6.15) '@rsbuild/plugin-type-check': specifier: ^1.3.2 - version: 1.3.2(@rsbuild/core@1.6.15)(@rspack/core@1.6.8(@swc/helpers@0.5.17))(typescript@5.8.3) + version: 1.3.2(@rsbuild/core@1.6.15)(@rspack/core@1.6.8(@swc/helpers@0.5.21))(typescript@5.8.3) '@types/react': specifier: ^18.3.1 version: 18.3.23 @@ -508,6 +508,58 @@ importers: specifier: 4.1.11 version: 4.1.11 + apps/studio: + dependencies: + react: + specifier: 18.3.1 + version: 18.3.1 + react-dom: + specifier: 18.3.1 + version: 18.3.1(react@18.3.1) + devDependencies: + '@rsbuild/core': + specifier: ^1.6.15 + version: 1.6.15 + '@rsbuild/plugin-less': + specifier: ^1.5.0 + version: 1.5.0(@rsbuild/core@1.6.15) + '@rsbuild/plugin-react': + specifier: ^1.4.1 + version: 1.4.6(@rsbuild/core@1.6.15) + '@rsbuild/plugin-type-check': + specifier: ^1.3.2 + version: 1.3.2(@rsbuild/core@1.6.15)(@rspack/core@1.6.8(@swc/helpers@0.5.21))(typescript@5.8.3) + '@tailwindcss/postcss': + specifier: 4.1.11 + version: 4.1.11 + '@types/node': + specifier: ^18.0.0 + version: 18.19.130 + '@types/react': + specifier: ^18.3.1 + version: 18.3.23 + '@types/react-dom': + specifier: ^18.3.1 + version: 18.3.7(@types/react@18.3.23) + concurrently: + specifier: ^8.2.0 + version: 8.2.2 + electron: + specifier: 41.2.0 + version: 41.2.0 + less: + specifier: ^4.2.0 + version: 4.3.0 + tailwindcss: + specifier: 4.1.11 + version: 4.1.11 + typescript: + specifier: ^5.8.3 + version: 5.8.3 + vitest: + specifier: 3.0.5 + version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.130)(jsdom@26.1.0)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) + packages/android: dependencies: '@midscene/core': @@ -623,7 +675,7 @@ importers: version: 5.8.3 vitest: specifier: 3.0.5 - version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) + version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) packages/android-playground: dependencies: @@ -813,7 +865,7 @@ importers: version: 5.8.3 vitest: specifier: 3.0.5 - version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) + version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) packages/computer-linux: dependencies: @@ -903,7 +955,7 @@ importers: version: 5.8.3 vitest: specifier: 3.0.5 - version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) + version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) packages/computer-playground: dependencies: @@ -1088,7 +1140,7 @@ importers: version: 5.8.3 vitest: specifier: 3.0.5 - version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) + version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) zod: specifier: ^3.25.1 version: 3.25.76 @@ -1183,7 +1235,7 @@ importers: version: 5.8.3 vitest: specifier: 3.0.5 - version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) + version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) zod: specifier: ^3.25.1 version: 3.25.76 @@ -1241,7 +1293,7 @@ importers: version: 5.8.3 vitest: specifier: 3.0.5 - version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) + version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) packages/ios-playground: dependencies: @@ -1336,7 +1388,7 @@ importers: version: 5.8.3 vitest: specifier: 3.0.5 - version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) + version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) packages/playground-app: dependencies: @@ -1400,7 +1452,7 @@ importers: version: 5.8.3 vitest: specifier: 3.0.5 - version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) + version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) packages/recorder: dependencies: @@ -1641,7 +1693,7 @@ importers: version: 5.8.3 vitest: specifier: 3.0.5 - version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) + version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) packages/web-integration: dependencies: @@ -1748,7 +1800,7 @@ importers: version: 5.8.3 vitest: specifier: 3.0.5 - version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) + version: 3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) packages: @@ -2257,6 +2309,10 @@ packages: resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} engines: {node: '>=10.0.0'} + '@electron/get@2.0.3': + resolution: {integrity: sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==} + engines: {node: '>=12'} + '@emnapi/core@1.7.1': resolution: {integrity: sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==} @@ -3237,9 +3293,6 @@ packages: '@jimp/utils@0.22.12': resolution: {integrity: sha512-yJ5cWUknGnilBq97ZXOyOS0HhsHOyAyjHwYfHxGbSyMTohgQI6sVyE8KPgDwH8HHW/nMKXk8TrSwAE71zt716Q==} - '@jridgewell/gen-mapping@0.3.12': - resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} - '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -3253,9 +3306,6 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.29': - resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} - '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} @@ -4536,6 +4586,10 @@ packages: '@sinclair/typebox@0.34.41': resolution: {integrity: sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==} + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + '@sindresorhus/is@5.6.0': resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} engines: {node: '>=14.16'} @@ -4621,12 +4675,13 @@ packages: peerDependencies: '@svgr/core': '*' - '@swc/helpers@0.5.17': - resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} - '@swc/helpers@0.5.21': resolution: {integrity: sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==} + '@szmarczak/http-timer@4.0.6': + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} + engines: {node: '>=10'} + '@szmarczak/http-timer@5.0.1': resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} engines: {node: '>=14.16'} @@ -4756,6 +4811,9 @@ packages: '@types/body-parser@1.19.5': resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + '@types/cacheable-request@6.0.3': + resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + '@types/chrome@0.0.279': resolution: {integrity: sha512-wl0IxQ2OQiMazPZM5LimHQ7Jwd72/O8UvvzyptplXT2S4eUqXH5C0n8S+v8PtKhyX89p0igCPpNy3Bwksyk57g==} @@ -4837,6 +4895,9 @@ packages: '@types/jsonfile@6.1.4': resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} + '@types/keyv@3.1.4': + resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} + '@types/lodash.merge@4.6.9': resolution: {integrity: sha512-23sHDPmzd59kUgWyKGiOMO2Qb9YtqRO/x4IhkgNUiPQ1+5MUVqi6bCZeq9nBJ17msjIMbEIO5u+XW4Kz6aGUhQ==} @@ -4879,6 +4940,9 @@ packages: '@types/node@18.19.62': resolution: {integrity: sha512-UOGhw+yZV/icyM0qohQVh3ktpY40Sp7tdTW7HxG3pTd7AiMrlFlAJNUrGK9t5mdW0+ViQcFV74zCSIx9ZJpncA==} + '@types/node@24.12.2': + resolution: {integrity: sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==} + '@types/node@25.5.2': resolution: {integrity: sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg==} @@ -4913,6 +4977,9 @@ packages: '@types/react@19.1.5': resolution: {integrity: sha512-piErsCVVbpMMT2r7wbawdZsq4xMvIAhQuac2gedQHysu1TZYEigE6pnFfgZT+/jQnrRuF5r+SHzuehFjfRjr4g==} + '@types/responselike@1.0.3': + resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} + '@types/retry@0.12.0': resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} @@ -5579,6 +5646,10 @@ packages: boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + boolean@3.2.0: + resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + boxen@8.0.1: resolution: {integrity: sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==} engines: {node: '>=18'} @@ -5698,6 +5769,10 @@ packages: resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} engines: {node: '>=20.19.0'} + cacheable-lookup@5.0.4: + resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} + engines: {node: '>=10.6.0'} + cacheable-lookup@7.0.0: resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} engines: {node: '>=14.16'} @@ -5706,6 +5781,10 @@ packages: resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} engines: {node: '>=14.16'} + cacheable-request@7.0.4: + resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} + engines: {node: '>=8'} + cachedir@2.3.0: resolution: {integrity: sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==} engines: {node: '>=6'} @@ -5776,10 +5855,6 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - chalk@5.4.1: - resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - chalk@5.6.2: resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} @@ -5900,6 +5975,9 @@ packages: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} + clone-response@1.0.3: + resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + clone@1.0.4: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} @@ -6429,6 +6507,9 @@ packages: detect-node-es@1.1.0: resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + detect-node@2.1.0: + resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} + devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} @@ -6518,6 +6599,11 @@ packages: electron-to-chromium@1.5.260: resolution: {integrity: sha512-ov8rBoOBhVawpzdre+Cmz4FB+y66Eqrk6Gwqd8NGxuhv99GQ8XqMAr351KEkOt7gukXWDg6gJWEMKgL2RLMPtA==} + electron@41.2.0: + resolution: {integrity: sha512-0OKLiymqfV0WK68RBXqAm3Myad2TpI5wwxLCBEUcH5Nugo3YfSk7p1Js/AL9266qTz5xZioUnxt9hG8FFwax0g==} + engines: {node: '>= 12.20.55'} + hasBin: true + elliptic@6.6.0: resolution: {integrity: sha512-dpwoQcLc/2WLQvJvLRHKZ+f9FgOdjnq11rurqwekGQygGPsYSK29OMMD2WalatiqQ+XGFDglTNixpPfI+lpaAA==} @@ -6559,10 +6645,6 @@ packages: resolution: {integrity: sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==} engines: {node: '>=10.13.0'} - enhanced-resolve@5.18.1: - resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} - engines: {node: '>=10.13.0'} - enhanced-resolve@5.20.1: resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} engines: {node: '>=10.13.0'} @@ -7092,10 +7174,6 @@ packages: fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - fs-extra@11.2.0: - resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} - engines: {node: '>=14.14'} - fs-extra@11.3.1: resolution: {integrity: sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==} engines: {node: '>=14.14'} @@ -7267,6 +7345,10 @@ packages: engines: {node: '>=12'} deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + global-agent@3.0.0: + resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==} + engines: {node: '>=10.0'} + global-directory@4.0.1: resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} engines: {node: '>=18'} @@ -7302,6 +7384,10 @@ packages: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} + got@11.8.6: + resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} + engines: {node: '>=10.19.0'} + got@12.6.1: resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} engines: {node: '>=14.16'} @@ -7477,6 +7563,10 @@ packages: engines: {node: '>=12'} hasBin: true + http2-wrapper@1.0.3: + resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} + engines: {node: '>=10.19.0'} + http2-wrapper@2.2.1: resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} engines: {node: '>=10.19.0'} @@ -7959,10 +8049,6 @@ packages: jimp@0.22.10: resolution: {integrity: sha512-lCaHIJAgTOsplyJzC1w/laxSxrbSsEBw4byKwXgUdMmh+ayPsnidTblenQm+IvhIs44Gcuvlb6pd2LQ0wcKaKg==} - jiti@2.4.2: - resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} - hasBin: true - jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true @@ -8043,6 +8129,9 @@ packages: json-stream-stringify@3.0.1: resolution: {integrity: sha512-vuxs3G1ocFDiAQ/SX0okcZbtqXwgj1g71qE9+vrjJ2EkjKQlEFDAcUNRxRU8O+GekV4v5cM2qXP0Wyt/EMDBiQ==} + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + json2mq@0.2.0: resolution: {integrity: sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==} @@ -8057,9 +8146,6 @@ packages: jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - jsonfile@6.2.0: resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} @@ -8315,6 +8401,10 @@ packages: lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + lowercase-keys@2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} + engines: {node: '>=8'} + lowercase-keys@3.0.0: resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -8382,6 +8472,10 @@ packages: marky@1.3.0: resolution: {integrity: sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==} + matcher@3.0.0: + resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==} + engines: {node: '>=10'} + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -8673,6 +8767,10 @@ packages: resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} engines: {node: '>=18'} + mimic-response@1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} + mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} @@ -8795,11 +8893,6 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - nanoid@3.3.8: - resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -8895,6 +8988,10 @@ packages: resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} engines: {node: '>=0.10.0'} + normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + normalize-url@8.1.1: resolution: {integrity: sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==} engines: {node: '>=14.16'} @@ -9046,6 +9143,10 @@ packages: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} + p-cancelable@2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} + p-cancelable@3.0.0: resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} engines: {node: '>=12.20'} @@ -9356,10 +9457,6 @@ packages: postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.5.1: - resolution: {integrity: sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==} - engines: {node: ^10 || ^12 || >=14} - postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} @@ -9457,12 +9554,6 @@ packages: public-encrypt@4.0.3: resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} - pump@3.0.2: - resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} - - pump@3.0.3: - resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} - pump@3.0.4: resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} @@ -10075,6 +10166,9 @@ packages: engines: {node: '>= 0.4'} hasBin: true + responselike@2.0.1: + resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + responselike@3.0.0: resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} engines: {node: '>=14.16'} @@ -10113,6 +10207,10 @@ packages: ripemd160@2.0.2: resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} + roarr@2.15.4: + resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==} + engines: {node: '>=8.0'} + rollup@4.24.3: resolution: {integrity: sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -10362,6 +10460,9 @@ packages: resolution: {integrity: sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==} hasBin: true + semver-compare@1.0.0: + resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} + semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -10408,6 +10509,10 @@ packages: resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} engines: {node: '>= 18'} + serialize-error@7.0.1: + resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} + engines: {node: '>=10'} + serve-handler@6.1.6: resolution: {integrity: sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==} @@ -10606,10 +10711,6 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - source-map@0.7.4: - resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} - engines: {node: '>= 8'} - source-map@0.7.6: resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} engines: {node: '>= 12'} @@ -10838,6 +10939,10 @@ packages: stylis@4.3.4: resolution: {integrity: sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==} + sumchecker@3.0.1: + resolution: {integrity: sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==} + engines: {node: '>= 8.0'} + supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -10896,10 +11001,6 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} - tapable@2.2.2: - resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} - engines: {node: '>=6'} - tapable@2.3.2: resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==} engines: {node: '>=6'} @@ -11069,12 +11170,6 @@ packages: resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} engines: {node: '>=18'} - tree-dump@1.0.3: - resolution: {integrity: sha512-il+Cv80yVHFBwokQSfd4bldvr1Md951DpgAGfmhydt04L+YzHgubm2tQ7zueWDcGENKHq0ZvGFR/hjvNXilHEg==} - engines: {node: '>=10.0'} - peerDependencies: - tslib: '2' - tree-dump@1.1.0: resolution: {integrity: sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==} engines: {node: '>=10.0'} @@ -11242,6 +11337,9 @@ packages: undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + undici-types@7.18.2: resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} @@ -11862,8 +11960,8 @@ snapshots: '@ampproject/remapping@2.3.0': dependencies: - '@jridgewell/gen-mapping': 0.3.12 - '@jridgewell/trace-mapping': 0.3.29 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 '@ant-design/colors@7.1.0': dependencies: @@ -11891,7 +11989,7 @@ snapshots: '@ant-design/fast-color@2.0.6': dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.28.4 '@ant-design/icons-svg@4.4.2': {} @@ -12066,8 +12164,8 @@ snapshots: dependencies: '@babel/parser': 7.28.0 '@babel/types': 7.28.1 - '@jridgewell/gen-mapping': 0.3.12 - '@jridgewell/trace-mapping': 0.3.29 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 '@babel/helper-compilation-targets@7.27.2': @@ -12608,6 +12706,20 @@ snapshots: '@discoveryjs/json-ext@0.5.7': {} + '@electron/get@2.0.3': + dependencies: + debug: 4.4.0 + env-paths: 2.2.1 + fs-extra: 8.1.0 + got: 11.8.6 + progress: 2.0.3 + semver: 6.3.1 + sumchecker: 3.0.1 + optionalDependencies: + global-agent: 3.0.0 + transitivePeerDependencies: + - supports-color + '@emnapi/core@1.7.1': dependencies: '@emnapi/wasi-threads': 1.1.0 @@ -13540,11 +13652,6 @@ snapshots: dependencies: regenerator-runtime: 0.13.11 - '@jridgewell/gen-mapping@0.3.12': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.29 - '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -13559,11 +13666,6 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.29': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 @@ -14534,7 +14636,7 @@ snapshots: '@rc-component/async-validator@5.0.4': dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.28.4 '@rc-component/color-picker@2.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: @@ -14547,14 +14649,14 @@ snapshots: '@rc-component/context@1.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.28.4 rc-util: 5.43.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) '@rc-component/mini-decimal@1.1.0': dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.28.4 '@rc-component/mutate-observer@1.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: @@ -14566,7 +14668,7 @@ snapshots: '@rc-component/portal@1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.28.4 classnames: 2.5.1 rc-util: 5.43.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 @@ -14657,9 +14759,9 @@ snapshots: '@rsbuild/core@1.6.15': dependencies: - '@rspack/core': 1.6.8(@swc/helpers@0.5.17) + '@rspack/core': 1.6.8(@swc/helpers@0.5.21) '@rspack/lite-tapable': 1.1.0 - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.21 core-js: 3.47.0 jiti: 2.6.1 @@ -14678,7 +14780,7 @@ snapshots: browserslist-to-es-version: 1.0.0 htmlparser2: 10.0.0 picocolors: 1.1.1 - source-map: 0.7.4 + source-map: 0.7.6 optionalDependencies: '@rsbuild/core': 1.6.15 @@ -14782,6 +14884,15 @@ snapshots: transitivePeerDependencies: - webpack-hot-middleware + '@rsbuild/plugin-react@1.4.6(@rsbuild/core@1.6.15)': + dependencies: + '@rspack/plugin-react-refresh': 1.6.2(react-refresh@0.18.0) + react-refresh: 0.18.0 + optionalDependencies: + '@rsbuild/core': 1.6.15 + transitivePeerDependencies: + - webpack-hot-middleware + '@rsbuild/plugin-react@1.4.6(@rsbuild/core@2.0.0-beta.11(core-js@3.47.0))': dependencies: '@rspack/plugin-react-refresh': 1.6.2(react-refresh@0.18.0) @@ -14819,12 +14930,12 @@ snapshots: - typescript - webpack-hot-middleware - '@rsbuild/plugin-type-check@1.3.2(@rsbuild/core@1.6.15)(@rspack/core@1.6.8(@swc/helpers@0.5.17))(typescript@5.8.3)': + '@rsbuild/plugin-type-check@1.3.2(@rsbuild/core@1.6.15)(@rspack/core@1.6.8(@swc/helpers@0.5.21))(typescript@5.8.3)': dependencies: deepmerge: 4.3.1 json5: 2.2.3 reduce-configs: 1.1.1 - ts-checker-rspack-plugin: 1.2.2(@rspack/core@1.6.8(@swc/helpers@0.5.17))(typescript@5.8.3) + ts-checker-rspack-plugin: 1.2.2(@rspack/core@1.6.8(@swc/helpers@0.5.21))(typescript@5.8.3) optionalDependencies: '@rsbuild/core': 1.6.15 transitivePeerDependencies: @@ -14856,11 +14967,11 @@ snapshots: browserslist-load-config: 1.0.0 enhanced-resolve: 5.12.0 filesize: 10.1.6 - fs-extra: 11.2.0 - lodash: 4.17.21 + fs-extra: 11.3.4 + lodash: 4.17.23 path-browserify: 1.0.1 semver: 7.7.3 - source-map: 0.7.4 + source-map: 0.7.6 webpack-bundle-analyzer: 4.10.2(bufferutil@4.0.9) transitivePeerDependencies: - '@rsbuild/core' @@ -14877,7 +14988,7 @@ snapshots: '@rsdoctor/utils': 1.0.2(@rspack/core@2.0.0-beta.9(@swc/helpers@0.5.21))(webpack@5.99.5) lodash.unionby: 4.8.0 socket.io: 4.8.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) - source-map: 0.7.4 + source-map: 0.7.6 transitivePeerDependencies: - '@rspack/core' - bufferutil @@ -14912,13 +15023,13 @@ snapshots: body-parser: 1.20.3 cors: 2.8.5 dayjs: 1.11.13 - fs-extra: 11.2.0 + fs-extra: 11.3.4 json-cycle: 1.5.0 - lodash: 4.17.21 + lodash: 4.17.23 open: 8.4.2 sirv: 2.0.4 socket.io: 4.8.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) - source-map: 0.7.4 + source-map: 0.7.6 tapable: 2.2.1 transitivePeerDependencies: - '@rspack/core' @@ -14932,7 +15043,7 @@ snapshots: '@types/connect': 3.4.38 '@types/estree': 1.0.5 '@types/tapable': 2.2.7 - source-map: 0.7.4 + source-map: 0.7.6 webpack: 5.99.5 optionalDependencies: '@rspack/core': 2.0.0-beta.9(@swc/helpers@0.5.21) @@ -14950,7 +15061,7 @@ snapshots: deep-eql: 4.1.4 envinfo: 7.14.0 filesize: 10.1.6 - fs-extra: 11.2.0 + fs-extra: 11.3.4 get-port: 5.1.1 json-stream-stringify: 3.0.1 lines-and-columns: 2.0.4 @@ -15133,13 +15244,13 @@ snapshots: optionalDependencies: '@swc/helpers': 0.5.21 - '@rspack/core@1.6.8(@swc/helpers@0.5.17)': + '@rspack/core@1.6.8(@swc/helpers@0.5.21)': dependencies: '@module-federation/runtime-tools': 0.21.6 '@rspack/binding': 1.6.8 '@rspack/lite-tapable': 1.1.0 optionalDependencies: - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.21 '@rspack/core@2.0.0-beta.9(@swc/helpers@0.5.21)': dependencies: @@ -15418,6 +15529,8 @@ snapshots: '@sinclair/typebox@0.34.41': {} + '@sindresorhus/is@4.6.0': {} + '@sindresorhus/is@5.6.0': {} '@sindresorhus/merge-streams@4.0.0': {} @@ -15503,13 +15616,13 @@ snapshots: transitivePeerDependencies: - typescript - '@swc/helpers@0.5.17': + '@swc/helpers@0.5.21': dependencies: tslib: 2.8.1 - '@swc/helpers@0.5.21': + '@szmarczak/http-timer@4.0.6': dependencies: - tslib: 2.8.1 + defer-to-connect: 2.0.1 '@szmarczak/http-timer@5.0.1': dependencies: @@ -15518,8 +15631,8 @@ snapshots: '@tailwindcss/node@4.1.11': dependencies: '@ampproject/remapping': 2.3.0 - enhanced-resolve: 5.18.1 - jiti: 2.4.2 + enhanced-resolve: 5.20.1 + jiti: 2.6.1 lightningcss: 1.30.1 magic-string: 0.30.17 source-map-js: 1.2.1 @@ -15584,7 +15697,7 @@ snapshots: '@alloc/quick-lru': 5.2.0 '@tailwindcss/node': 4.1.11 '@tailwindcss/oxide': 4.1.11 - postcss: 8.5.1 + postcss: 8.5.6 tailwindcss: 4.1.11 '@tokenizer/token@0.3.0': {} @@ -15618,7 +15731,14 @@ snapshots: '@types/body-parser@1.19.5': dependencies: '@types/connect': 3.4.38 - '@types/node': 18.19.118 + '@types/node': 18.19.130 + + '@types/cacheable-request@6.0.3': + dependencies: + '@types/http-cache-semantics': 4.0.4 + '@types/keyv': 3.1.4 + '@types/node': 18.19.130 + '@types/responselike': 1.0.3 '@types/chrome@0.0.279': dependencies: @@ -15627,17 +15747,17 @@ snapshots: '@types/connect@3.4.38': dependencies: - '@types/node': 18.19.118 + '@types/node': 18.19.130 '@types/conventional-commits-parser@5.0.2': dependencies: - '@types/node': 18.19.118 + '@types/node': 18.19.130 '@types/cookie@0.4.1': {} '@types/cors@2.8.19': dependencies: - '@types/node': 18.19.118 + '@types/node': 18.19.130 '@types/debug@4.1.12': dependencies: @@ -15665,7 +15785,7 @@ snapshots: '@types/express-serve-static-core@4.19.6': dependencies: - '@types/node': 18.19.118 + '@types/node': 18.19.130 '@types/qs': 6.9.16 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 @@ -15688,7 +15808,7 @@ snapshots: '@types/fs-extra@11.0.4': dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 18.19.118 + '@types/node': 18.19.130 '@types/har-format@1.2.16': {} @@ -15714,7 +15834,11 @@ snapshots: '@types/jsonfile@6.1.4': dependencies: - '@types/node': 18.19.118 + '@types/node': 18.19.130 + + '@types/keyv@3.1.4': + dependencies: + '@types/node': 18.19.130 '@types/lodash.merge@4.6.9': dependencies: @@ -15738,7 +15862,7 @@ snapshots: '@types/node-fetch@2.6.11': dependencies: - '@types/node': 18.19.118 + '@types/node': 18.19.130 form-data: 4.0.1 '@types/node@12.20.55': {} @@ -15757,6 +15881,10 @@ snapshots: dependencies: undici-types: 5.26.5 + '@types/node@24.12.2': + dependencies: + undici-types: 7.16.0 + '@types/node@25.5.2': dependencies: undici-types: 7.18.2 @@ -15783,17 +15911,21 @@ snapshots: '@types/react@18.3.23': dependencies: '@types/prop-types': 15.7.13 - csstype: 3.1.3 + csstype: 3.2.3 '@types/react@19.1.5': dependencies: csstype: 3.2.3 + '@types/responselike@1.0.3': + dependencies: + '@types/node': 18.19.130 + '@types/retry@0.12.0': {} '@types/screenshot-desktop@1.15.0': dependencies: - '@types/node': 18.19.118 + '@types/node': 18.19.130 '@types/semver@6.2.7': {} @@ -15802,17 +15934,17 @@ snapshots: '@types/send@0.17.4': dependencies: '@types/mime': 1.3.5 - '@types/node': 18.19.118 + '@types/node': 18.19.130 '@types/serve-static@1.15.7': dependencies: '@types/http-errors': 2.0.4 - '@types/node': 18.19.118 + '@types/node': 18.19.130 '@types/send': 0.17.4 '@types/tapable@2.2.7': dependencies: - tapable: 2.2.2 + tapable: 2.3.2 '@types/unist@2.0.11': {} @@ -15822,7 +15954,7 @@ snapshots: '@types/ws@8.18.1': dependencies: - '@types/node': 18.19.118 + '@types/node': 18.19.130 '@types/yargs-parser@21.0.3': {} @@ -15832,7 +15964,7 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 18.19.118 + '@types/node': 18.19.130 '@ui-tars/action-parser@1.2.3': dependencies: @@ -15865,6 +15997,14 @@ snapshots: optionalDependencies: vite: 5.4.10(@types/node@18.19.118)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) + '@vitest/mocker@3.0.5(vite@5.4.10(@types/node@18.19.130)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1))': + dependencies: + '@vitest/spy': 3.0.5 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + vite: 5.4.10(@types/node@18.19.130)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) + '@vitest/mocker@3.0.5(vite@5.4.10(@types/node@18.19.62)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1))': dependencies: '@vitest/spy': 3.0.5 @@ -16392,7 +16532,7 @@ snapshots: glob: 8.1.0 graceful-fs: 4.2.11 lazystream: 1.0.1 - lodash: 4.17.21 + lodash: 4.17.23 normalize-path: 3.0.0 readable-stream: 3.6.2 @@ -16402,7 +16542,7 @@ snapshots: graceful-fs: 4.2.11 is-stream: 2.0.1 lazystream: 1.0.1 - lodash: 4.17.21 + lodash: 4.17.23 normalize-path: 3.0.0 readable-stream: 4.7.0 @@ -16510,14 +16650,14 @@ snapshots: async@2.6.4: dependencies: - lodash: 4.17.21 + lodash: 4.17.23 async@3.2.6: {} asyncbox@3.0.0: dependencies: bluebird: 3.7.2 - lodash: 4.17.21 + lodash: 4.17.23 source-map-support: 0.5.21 asynckit@0.4.0: {} @@ -16692,6 +16832,9 @@ snapshots: boolbase@1.0.0: {} + boolean@3.2.0: + optional: true + boxen@8.0.1: dependencies: ansi-align: 3.0.1 @@ -16699,7 +16842,7 @@ snapshots: chalk: 5.6.2 cli-boxes: 3.0.0 string-width: 7.2.0 - type-fest: 4.40.1 + type-fest: 4.41.0 widest-line: 5.0.0 wrap-ansi: 9.0.2 @@ -16841,6 +16984,8 @@ snapshots: cac@7.0.0: {} + cacheable-lookup@5.0.4: {} + cacheable-lookup@7.0.0: {} cacheable-request@10.2.14: @@ -16853,6 +16998,16 @@ snapshots: normalize-url: 8.1.1 responselike: 3.0.0 + cacheable-request@7.0.4: + dependencies: + clone-response: 1.0.3 + get-stream: 5.2.0 + http-cache-semantics: 4.2.0 + keyv: 4.5.4 + lowercase-keys: 2.0.0 + normalize-url: 6.1.0 + responselike: 2.0.1 + cachedir@2.3.0: {} call-bind-apply-helpers@1.0.2: @@ -16926,8 +17081,6 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 - chalk@5.4.1: {} - chalk@5.6.2: {} character-entities-html4@2.1.0: {} @@ -16995,7 +17148,7 @@ snapshots: chrome-launcher@1.2.0: dependencies: - '@types/node': 18.19.118 + '@types/node': 18.19.130 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 2.0.2 @@ -17067,6 +17220,10 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + clone-response@1.0.3: + dependencies: + mimic-response: 1.0.1 + clone@1.0.4: {} clsx@2.1.1: {} @@ -17199,7 +17356,7 @@ snapshots: dependencies: chalk: 4.1.2 date-fns: 2.30.0 - lodash: 4.17.21 + lodash: 4.17.23 rxjs: 7.8.2 shell-quote: 1.8.3 spawn-command: 0.0.2 @@ -17210,7 +17367,7 @@ snapshots: concurrently@9.2.0: dependencies: chalk: 4.1.2 - lodash: 4.17.21 + lodash: 4.17.23 rxjs: 7.8.2 shell-quote: 1.8.3 supports-color: 8.1.1 @@ -17625,6 +17782,9 @@ snapshots: detect-node-es@1.1.0: {} + detect-node@2.1.0: + optional: true + devlop@1.1.0: dependencies: dequal: 2.0.3 @@ -17682,7 +17842,7 @@ snapshots: dot-prop@9.0.0: dependencies: - type-fest: 4.40.1 + type-fest: 4.41.0 dotenv-expand@11.0.7: dependencies: @@ -17716,6 +17876,14 @@ snapshots: electron-to-chromium@1.5.260: {} + electron@41.2.0: + dependencies: + '@electron/get': 2.0.3 + '@types/node': 24.12.2 + extract-zip: 2.0.1 + transitivePeerDependencies: + - supports-color + elliptic@6.6.0: dependencies: bn.js: 4.12.0 @@ -17763,7 +17931,7 @@ snapshots: dependencies: '@types/cookie': 0.4.1 '@types/cors': 2.8.19 - '@types/node': 18.19.118 + '@types/node': 18.19.130 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.7.2 @@ -17779,12 +17947,7 @@ snapshots: enhanced-resolve@5.12.0: dependencies: graceful-fs: 4.2.11 - tapable: 2.2.2 - - enhanced-resolve@5.18.1: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.2.1 + tapable: 2.3.2 enhanced-resolve@5.20.1: dependencies: @@ -18542,16 +18705,10 @@ snapshots: fs-constants@1.0.0: {} - fs-extra@11.2.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 - fs-extra@11.3.1: dependencies: graceful-fs: 4.2.11 - jsonfile: 6.1.0 + jsonfile: 6.2.0 universalify: 2.0.1 fs-extra@11.3.4: @@ -18559,7 +18716,6 @@ snapshots: graceful-fs: 4.2.11 jsonfile: 6.2.0 universalify: 2.0.1 - optional: true fs-extra@7.0.1: dependencies: @@ -18650,7 +18806,7 @@ snapshots: get-stream@5.2.0: dependencies: - pump: 3.0.2 + pump: 3.0.4 get-stream@6.0.1: {} @@ -18755,6 +18911,16 @@ snapshots: minimatch: 5.1.6 once: 1.4.0 + global-agent@3.0.0: + dependencies: + boolean: 3.2.0 + es6-error: 4.1.1 + matcher: 3.0.0 + roarr: 2.15.4 + semver: 7.5.2 + serialize-error: 7.0.1 + optional: true + global-directory@4.0.1: dependencies: ini: 4.1.1 @@ -18806,6 +18972,20 @@ snapshots: gopd@1.2.0: {} + got@11.8.6: + dependencies: + '@sindresorhus/is': 4.6.0 + '@szmarczak/http-timer': 4.0.6 + '@types/cacheable-request': 6.0.3 + '@types/responselike': 1.0.3 + cacheable-lookup: 5.0.4 + cacheable-request: 7.0.4 + decompress-response: 6.0.0 + http2-wrapper: 1.0.3 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 + responselike: 2.0.1 + got@12.6.1: dependencies: '@sindresorhus/is': 5.6.0 @@ -18832,7 +19012,7 @@ snapshots: graphlib@2.1.8: dependencies: - lodash: 4.17.21 + lodash: 4.17.23 gray-matter@4.0.3: dependencies: @@ -19088,6 +19268,11 @@ snapshots: transitivePeerDependencies: - debug + http2-wrapper@1.0.3: + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + http2-wrapper@2.2.1: dependencies: quick-lru: 5.1.1 @@ -19195,7 +19380,7 @@ snapshots: cli-width: 3.0.0 external-editor: 3.1.0 figures: 3.2.0 - lodash: 4.17.21 + lodash: 4.17.23 mute-stream: 0.0.8 run-async: 2.4.1 rxjs: 6.6.7 @@ -19211,7 +19396,7 @@ snapshots: cli-width: 3.0.0 external-editor: 3.1.0 figures: 3.2.0 - lodash: 4.17.21 + lodash: 4.17.23 mute-stream: 0.0.8 ora: 5.4.1 run-async: 2.4.1 @@ -19531,8 +19716,6 @@ snapshots: - debug - encoding - jiti@2.4.2: {} - jiti@2.6.1: {} jju@1.4.0: {} @@ -19619,6 +19802,9 @@ snapshots: json-stream-stringify@3.0.1: {} + json-stringify-safe@5.0.1: + optional: true + json2mq@0.2.0: dependencies: string-convert: 0.2.1 @@ -19631,12 +19817,6 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 - jsonfile@6.1.0: - dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 - jsonfile@6.2.0: dependencies: universalify: 2.0.1 @@ -19854,8 +20034,7 @@ snapshots: lodash@4.17.21: {} - lodash@4.17.23: - optional: true + lodash@4.17.23: {} log-symbols@4.1.0: dependencies: @@ -19879,6 +20058,8 @@ snapshots: dependencies: tslib: 2.8.1 + lowercase-keys@2.0.0: {} + lowercase-keys@3.0.0: {} lru-cache@10.4.3: {} @@ -19934,6 +20115,11 @@ snapshots: marky@1.3.0: {} + matcher@3.0.0: + dependencies: + escape-string-regexp: 4.0.0 + optional: true + math-intrinsics@1.1.0: {} md5.js@1.3.5: @@ -20121,7 +20307,7 @@ snapshots: '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) thingies: 2.5.0(tslib@2.8.1) - tree-dump: 1.0.3(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 meow@12.1.1: {} @@ -20488,6 +20674,8 @@ snapshots: mimic-function@5.0.1: {} + mimic-response@1.0.1: {} + mimic-response@3.1.0: {} mimic-response@4.0.0: {} @@ -20517,7 +20705,7 @@ snapshots: minimatch@5.1.6: dependencies: - brace-expansion: 2.0.1 + brace-expansion: 2.0.2 minimatch@9.0.3: dependencies: @@ -20525,7 +20713,7 @@ snapshots: minimatch@9.0.5: dependencies: - brace-expansion: 2.0.1 + brace-expansion: 2.0.2 minimist-options@4.1.0: dependencies: @@ -20592,8 +20780,6 @@ snapshots: nanoid@3.3.11: {} - nanoid@3.3.8: {} - natural-compare@1.4.0: {} ncp@2.0.0: {} @@ -20675,6 +20861,8 @@ snapshots: normalize-range@0.1.2: {} + normalize-url@6.1.0: {} + normalize-url@8.1.1: {} npm-run-path@2.0.2: @@ -20878,6 +21066,8 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 + p-cancelable@2.1.1: {} + p-cancelable@3.0.0: {} p-event@5.0.1: @@ -21172,12 +21362,6 @@ snapshots: postcss-value-parser@4.2.0: {} - postcss@8.5.1: - dependencies: - nanoid: 3.3.8 - picocolors: 1.1.1 - source-map-js: 1.2.1 - postcss@8.5.6: dependencies: nanoid: 3.3.11 @@ -21289,16 +21473,6 @@ snapshots: randombytes: 2.1.0 safe-buffer: 5.2.1 - pump@3.0.2: - dependencies: - end-of-stream: 1.4.5 - once: 1.4.0 - - pump@3.0.3: - dependencies: - end-of-stream: 1.4.5 - once: 1.4.0 - pump@3.0.4: dependencies: end-of-stream: 1.4.5 @@ -21540,7 +21714,7 @@ snapshots: rc-overflow@1.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.28.4 classnames: 2.5.1 rc-resize-observer: 1.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) rc-util: 5.43.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -21711,14 +21885,14 @@ snapshots: rc-util@5.43.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.28.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) react-is: 18.3.1 rc-virtual-list@3.14.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.28.4 classnames: 2.5.1 rc-resize-observer: 1.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) rc-util: 5.43.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -22092,6 +22266,10 @@ snapshots: supports-preserve-symlinks-flag: 1.0.0 optional: true + responselike@2.0.1: + dependencies: + lowercase-keys: 2.0.0 + responselike@3.0.0: dependencies: lowercase-keys: 3.0.0 @@ -22127,6 +22305,16 @@ snapshots: hash-base: 3.0.4 inherits: 2.0.4 + roarr@2.15.4: + dependencies: + boolean: 3.2.0 + detect-node: 2.1.0 + globalthis: 1.0.4 + json-stringify-safe: 5.0.1 + semver-compare: 1.0.0 + sprintf-js: 1.1.3 + optional: true + rollup@4.24.3: dependencies: '@types/estree': 1.0.6 @@ -22382,6 +22570,9 @@ snapshots: dependencies: commander: 2.20.3 + semver-compare@1.0.0: + optional: true + semver@5.7.2: {} semver@6.3.1: {} @@ -22437,6 +22628,11 @@ snapshots: transitivePeerDependencies: - supports-color + serialize-error@7.0.1: + dependencies: + type-fest: 0.13.1 + optional: true + serve-handler@6.1.6: dependencies: bytes: 3.0.0 @@ -22744,8 +22940,6 @@ snapshots: source-map@0.6.1: {} - source-map@0.7.4: {} - source-map@0.7.6: {} space-separated-tokens@2.0.2: {} @@ -22754,7 +22948,7 @@ snapshots: spawn-rx@5.1.2: dependencies: - debug: 4.4.3 + debug: 4.4.0 rxjs: 7.8.2 transitivePeerDependencies: - supports-color @@ -22987,6 +23181,12 @@ snapshots: stylis@4.3.4: {} + sumchecker@3.0.1: + dependencies: + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + supports-color@5.5.0: dependencies: has-flag: 3.0.0 @@ -23042,13 +23242,11 @@ snapshots: tapable@2.2.1: {} - tapable@2.2.2: {} - tapable@2.3.2: {} tar-fs@3.1.1: dependencies: - pump: 3.0.3 + pump: 3.0.4 tar-stream: 3.1.7 optionalDependencies: bare-fs: 4.5.2 @@ -23084,7 +23282,7 @@ snapshots: teen_process@2.3.1: dependencies: bluebird: 3.7.2 - lodash: 4.17.21 + lodash: 4.17.23 shell-quote: 1.8.3 source-map-support: 0.5.21 @@ -23208,10 +23406,6 @@ snapshots: punycode: 2.3.1 optional: true - tree-dump@1.0.3(tslib@2.8.1): - dependencies: - tslib: 2.8.1 - tree-dump@1.1.0(tslib@2.8.1): dependencies: tslib: 2.8.1 @@ -23232,7 +23426,7 @@ snapshots: dependencies: utf8-byte-length: 1.0.5 - ts-checker-rspack-plugin@1.2.2(@rspack/core@1.6.8(@swc/helpers@0.5.17))(typescript@5.8.3): + ts-checker-rspack-plugin@1.2.2(@rspack/core@1.6.8(@swc/helpers@0.5.21))(typescript@5.8.3): dependencies: '@babel/code-frame': 7.27.1 '@rspack/lite-tapable': 1.1.0 @@ -23243,7 +23437,7 @@ snapshots: picocolors: 1.1.1 typescript: 5.8.3 optionalDependencies: - '@rspack/core': 1.6.8(@swc/helpers@0.5.17) + '@rspack/core': 1.6.8(@swc/helpers@0.5.21) ts-checker-rspack-plugin@1.2.2(@rspack/core@2.0.0-beta.9(@swc/helpers@0.5.21))(typescript@5.8.3): dependencies: @@ -23414,6 +23608,8 @@ snapshots: undici-types@5.26.5: {} + undici-types@7.16.0: {} + undici-types@7.18.2: {} undici@6.22.0: {} @@ -23502,7 +23698,7 @@ snapshots: update-notifier@7.3.1: dependencies: boxen: 8.0.1 - chalk: 5.4.1 + chalk: 5.6.2 configstore: 7.1.0 is-in-ci: 1.0.0 is-installed-globally: 1.0.0 @@ -23615,6 +23811,24 @@ snapshots: - supports-color - terser + vite-node@3.0.5(@types/node@18.19.130)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1): + dependencies: + cac: 6.7.14 + debug: 4.4.0 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 5.4.10(@types/node@18.19.130)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vite-node@3.0.5(@types/node@18.19.62)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1): dependencies: cac: 6.7.14 @@ -23682,6 +23896,19 @@ snapshots: sass-embedded: 1.86.3 terser: 5.46.1 + vite@5.4.10(@types/node@18.19.130)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.6 + rollup: 4.24.3 + optionalDependencies: + '@types/node': 18.19.130 + fsevents: 2.3.3 + less: 4.3.0 + lightningcss: 1.30.1 + sass-embedded: 1.86.3 + terser: 5.46.1 + vite@5.4.10(@types/node@18.19.62)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1): dependencies: esbuild: 0.21.5 @@ -23721,7 +23948,7 @@ snapshots: sass-embedded: 1.86.3 terser: 5.46.1 - vitest@3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1): + vitest@3.0.5(@types/debug@4.1.12)(@types/node@18.19.118)(jsdom@26.1.0)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1): dependencies: '@vitest/expect': 3.0.5 '@vitest/mocker': 3.0.5(vite@5.4.10(@types/node@18.19.118)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1)) @@ -23758,6 +23985,43 @@ snapshots: - supports-color - terser + vitest@3.0.5(@types/debug@4.1.12)(@types/node@18.19.130)(jsdom@26.1.0)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1): + dependencies: + '@vitest/expect': 3.0.5 + '@vitest/mocker': 3.0.5(vite@5.4.10(@types/node@18.19.130)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1)) + '@vitest/pretty-format': 3.1.1 + '@vitest/runner': 3.0.5 + '@vitest/snapshot': 3.0.5 + '@vitest/spy': 3.0.5 + '@vitest/utils': 3.0.5 + chai: 5.2.0 + debug: 4.4.0 + expect-type: 1.2.1 + magic-string: 0.30.17 + pathe: 2.0.3 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.1.1 + tinyrainbow: 2.0.0 + vite: 5.4.10(@types/node@18.19.130)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) + vite-node: 3.0.5(@types/node@18.19.130)(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/debug': 4.1.12 + '@types/node': 18.19.130 + jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vitest@3.0.5(@types/debug@4.1.12)(@types/node@18.19.62)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.3.0)(lightningcss@1.30.1)(sass-embedded@1.86.3)(terser@5.46.1): dependencies: '@vitest/expect': 3.0.5