diff --git a/Cargo.lock b/Cargo.lock index 6a4bdd0..5b6befc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -290,9 +290,9 @@ dependencies = [ [[package]] name = "astral-tokio-tar" -version = "0.5.6" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec179a06c1769b1e42e1e2cbe74c7dcdb3d6383c838454d063eaac5bbb7ebbe5" +checksum = "3c23f3af104b40a3430ccb90ed5f7bd877a8dc5c26fc92fde51a22b40890dcf9" dependencies = [ "filetime", "futures-core", @@ -1319,9 +1319,9 @@ dependencies = [ [[package]] name = "bollard" -version = "0.19.4" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87a52479c9237eb04047ddb94788c41ca0d26eaff8b697ecfbb4c32f7fdc3b1b" +checksum = "ee04c4c84f1f811b017f2fbb7dd8815c976e7ca98593de9c1e2afad0f636bff4" dependencies = [ "async-stream", "base64 0.22.1", @@ -1329,7 +1329,6 @@ dependencies = [ "bollard-buildkit-proto", "bollard-stubs", "bytes", - "chrono", "futures-core", "futures-util", "hex", @@ -1347,14 +1346,13 @@ dependencies = [ "rand 0.9.2", "rustls 0.23.36", "rustls-native-certs", - "rustls-pemfile", "rustls-pki-types", "serde", "serde_derive", "serde_json", - "serde_repr", "serde_urlencoded", "thiserror 2.0.18", + "time", "tokio", "tokio-stream", "tokio-util", @@ -1379,19 +1377,18 @@ dependencies = [ [[package]] name = "bollard-stubs" -version = "1.49.1-rc.28.4.0" +version = "1.52.1-rc.29.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5731fe885755e92beff1950774068e0cae67ea6ec7587381536fca84f1779623" +checksum = "0f0a8ca8799131c1837d1282c3f81f31e76ceb0ce426e04a7fe1ccee3287c066" dependencies = [ "base64 0.22.1", "bollard-buildkit-proto", "bytes", - "chrono", "prost 0.14.3", "serde", "serde_json", "serde_repr", - "serde_with", + "time", ] [[package]] @@ -7640,15 +7637,6 @@ dependencies = [ "security-framework 3.5.1", ] -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - [[package]] name = "rustls-pki-types" version = "1.14.0" @@ -8857,9 +8845,9 @@ dependencies = [ [[package]] name = "testcontainers" -version = "0.26.3" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a81ec0158db5fbb9831e09d1813fe5ea9023a2b5e6e8e0a5fe67e2a820733629" +checksum = "0bd36b06a2a6c0c3c81a83be1ab05fe86460d054d4d51bf513bc56b3e15bdc22" dependencies = [ "astral-tokio-tar", "async-trait", @@ -8870,6 +8858,7 @@ dependencies = [ "etcetera 0.11.0", "ferroid", "futures", + "http 1.4.0", "itertools 0.14.0", "log", "memchr", @@ -8887,9 +8876,9 @@ dependencies = [ [[package]] name = "testcontainers-modules" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e75e78ff453128a2c7da9a5d5a3325ea34ea214d4bf51eab3417de23a4e5147" +checksum = "e5985fde5befe4ffa77a052e035e16c2da86e8bae301baa9f9904ad3c494d357" dependencies = [ "testcontainers", ] @@ -10325,7 +10314,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 93691da..aee52f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -384,7 +384,7 @@ rstest = "0.24" serial_test = "3.2" temp-env = "0.3" tempfile = "3.23.0" -testcontainers-modules = { version = "0.14", features = ["postgres", "redis"] } +testcontainers-modules = { version = "0.15", features = ["postgres", "redis"] } tokio-stream = "0.1.17" wiremock = "0.6" diff --git a/docs/content/docs/configuration/providers.mdx b/docs/content/docs/configuration/providers.mdx index c5eb27e..561a435 100644 --- a/docs/content/docs/configuration/providers.mdx +++ b/docs/content/docs/configuration/providers.mdx @@ -48,10 +48,12 @@ base_url = "https://openrouter.ai/api/v1" # App attribution headers are sent automatically: # HTTP-Referer: https://hadriangateway.com # X-OpenRouter-Title: Hadrian Gateway +# X-OpenRouter-Categories: general-chat # Override to customize, or set to "" to opt out: # [providers.openrouter.headers] # HTTP-Referer = "https://myapp.example.com" # X-OpenRouter-Title = "My Application" +# X-OpenRouter-Categories = "coding-app" ``` **Ollama** (local, no API key needed): diff --git a/docs/content/docs/configuration/server.mdx b/docs/content/docs/configuration/server.mdx index b59296c..108d685 100644 --- a/docs/content/docs/configuration/server.mdx +++ b/docs/content/docs/configuration/server.mdx @@ -140,25 +140,25 @@ permissions_policy = "geolocation=(), microphone=()" ### Default Content Security Policy -Hadrian ships a default CSP tailored for the web UI's frontend tools (Python, JavaScript, SQL, charts, Wikipedia, and Wikidata via WASM and external APIs): +Hadrian ships a default CSP tailored for the web UI's frontend tools and MCP server connections: ``` default-src 'self'; script-src 'self' blob: 'unsafe-eval' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; -connect-src 'self' https://cdn.jsdelivr.net https://*.wikipedia.org https://www.wikidata.org; +connect-src 'self' https: http: wss: ws:; worker-src 'self' blob:; frame-src 'self' blob:; object-src 'none'; base-uri 'self' ``` -| Directive | Value | Reason | -| ------------- | ---------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | -| `script-src` | `'self' blob: 'unsafe-eval' https://cdn.jsdelivr.net` | WASM workers as blob URLs; `unsafe-eval` for Pyodide bytecode execution and Vega `Function()` evaluation; CDN for Pyodide/DuckDB modules. | -| `style-src` | `'self' 'unsafe-inline'` | Tailwind CSS injects styles dynamically. | -| `worker-src` | `'self' blob:` | Web Workers run sandboxed code execution. | -| `frame-src` | `'self' blob:` | HTML artifact previews render in sandboxed iframes. | -| `img-src` | `'self' data: blob:` | Generated charts and inline images use data/blob URIs. | -| `connect-src` | `'self' https://cdn.jsdelivr.net https://*.wikipedia.org https://www.wikidata.org` | Pyodide/DuckDB fetch WASM and packages from CDN; Wikipedia and Wikidata tools query REST APIs. | -| `object-src` | `'none'` | Blocks plugin-based content (Flash, Java applets). | -| `base-uri` | `'self'` | Prevents `` tag injection attacks. | +| Directive | Value | Reason | +| ------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `script-src` | `'self' blob: 'unsafe-eval' https://cdn.jsdelivr.net` | WASM workers as blob URLs; `unsafe-eval` for Pyodide bytecode execution and Vega `Function()` evaluation; CDN for Pyodide/DuckDB modules. | +| `style-src` | `'self' 'unsafe-inline'` | Tailwind CSS injects styles dynamically. | +| `worker-src` | `'self' blob:` | Web Workers run sandboxed code execution. | +| `frame-src` | `'self' blob:` | HTML artifact previews render in sandboxed iframes. | +| `img-src` | `'self' data: blob:` | Generated charts and inline images use data/blob URIs. | +| `connect-src` | `'self' https: http: wss: ws:` | MCP servers are user-configured at arbitrary URLs; also covers CDN fetches for Pyodide/DuckDB and REST API queries for frontend tools. | +| `object-src` | `'none'` | Blocks plugin-based content (Flash, Java applets). | +| `base-uri` | `'self'` | Prevents `` tag injection attacks. | Override this by setting `content_security_policy` explicitly. Set to an empty string to disable the CSP header entirely. diff --git a/docs/public/config-schema.json b/docs/public/config-schema.json index 2006118..5e8445c 100644 --- a/docs/public/config-schema.json +++ b/docs/public/config-schema.json @@ -396,7 +396,7 @@ "max_response_body_bytes": 104857600, "port": 8080, "security_headers": { - "content_security_policy": "default-src 'self'; script-src 'self' blob: 'unsafe-eval' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; media-src 'self' blob:; connect-src 'self' https://cdn.jsdelivr.net https://*.wikipedia.org https://www.wikidata.org; worker-src 'self' blob:; frame-src 'self' blob:; object-src 'none'; base-uri 'self'", + "content_security_policy": "default-src 'self'; script-src 'self' blob: 'unsafe-eval' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; media-src 'self' blob:; connect-src 'self' https: http: wss: ws:; worker-src 'self' blob:; frame-src 'self' blob:; object-src 'none'; base-uri 'self'", "content_type_options": "nosniff", "enabled": true, "frame_options": "DENY", @@ -8011,7 +8011,7 @@ "properties": { "content_security_policy": { "description": "Content-Security-Policy header value. Controls resource loading to prevent XSS attacks.", - "default": "default-src 'self'; script-src 'self' blob: 'unsafe-eval' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; media-src 'self' blob:; connect-src 'self' https://cdn.jsdelivr.net https://*.wikipedia.org https://www.wikidata.org; worker-src 'self' blob:; frame-src 'self' blob:; object-src 'none'; base-uri 'self'", + "default": "default-src 'self'; script-src 'self' blob: 'unsafe-eval' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; media-src 'self' blob:; connect-src 'self' https: http: wss: ws:; worker-src 'self' blob:; frame-src 'self' blob:; object-src 'none'; base-uri 'self'", "type": [ "string", "null" @@ -8302,7 +8302,7 @@ "security_headers": { "description": "Security headers configuration.", "default": { - "content_security_policy": "default-src 'self'; script-src 'self' blob: 'unsafe-eval' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; media-src 'self' blob:; connect-src 'self' https://cdn.jsdelivr.net https://*.wikipedia.org https://www.wikidata.org; worker-src 'self' blob:; frame-src 'self' blob:; object-src 'none'; base-uri 'self'", + "content_security_policy": "default-src 'self'; script-src 'self' blob: 'unsafe-eval' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; media-src 'self' blob:; connect-src 'self' https: http: wss: ws:; worker-src 'self' blob:; frame-src 'self' blob:; object-src 'none'; base-uri 'self'", "content_type_options": "nosniff", "enabled": true, "frame_options": "DENY", diff --git a/src/app.rs b/src/app.rs index ba8ebeb..950d3a9 100644 --- a/src/app.rs +++ b/src/app.rs @@ -2087,7 +2087,8 @@ pub fn build_app(config: &config::GatewayConfig, state: AppState) -> Router { app = app.layer(cors_layer); } - app.layer(TraceLayer::new_for_http()) + app.layer(axum::extract::DefaultBodyLimit::disable()) + .layer(TraceLayer::new_for_http()) .layer(RequestBodyLimitLayer::new(config.server.body_limit_bytes)) .with_state(state) } diff --git a/src/bin/record_fixtures.rs b/src/bin/record_fixtures.rs index bf2c130..d374107 100644 --- a/src/bin/record_fixtures.rs +++ b/src/bin/record_fixtures.rs @@ -1920,7 +1920,8 @@ async fn record_fixture( if def.provider == "openrouter" { request = request .header("HTTP-Referer", "https://hadriangateway.com") - .header("X-OpenRouter-Title", "Hadrian Gateway"); + .header("X-OpenRouter-Title", "Hadrian Gateway") + .header("X-OpenRouter-Categories", "general-chat"); } } diff --git a/src/cli/mod.rs b/src/cli/mod.rs index dc2b4d4..9a13fa3 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -176,6 +176,8 @@ pub(crate) fn default_config_toml() -> &'static str { [server] host = "127.0.0.1" port = 8080 +# Allow providers on localhost (e.g. Ollama) +allow_loopback_urls = true # CORS: Allow local development origins [server.cors] diff --git a/src/config/features.rs b/src/config/features.rs index 1f4f10e..965dda5 100644 --- a/src/config/features.rs +++ b/src/config/features.rs @@ -2194,6 +2194,13 @@ pub struct WebSearchConfig { /// Lower than file_search since web search rarely needs multiple rounds. #[serde(default = "default_web_search_max_iterations")] pub max_iterations: usize, + + /// Maximum characters of content text per search result. + /// Applies to Exa's `text.maxCharacters` parameter. Tavily returns concise + /// summaries by default so this is not needed there. + /// Set to 0 to disable (return full text). Default: 2000. + #[serde(default = "default_web_search_max_content_chars")] + pub max_content_chars: usize, } impl std::fmt::Debug for WebSearchConfig { @@ -2208,6 +2215,7 @@ impl std::fmt::Debug for WebSearchConfig { &self.cost_microcents_per_request, ) .field("max_iterations", &self.max_iterations) + .field("max_content_chars", &self.max_content_chars) .finish() } } @@ -2237,6 +2245,10 @@ fn default_web_search_max_iterations() -> usize { 3 } +fn default_web_search_max_content_chars() -> usize { + 2000 +} + // ───────────────────────────────────────────────────────────────────────────── // Web Fetch // ───────────────────────────────────────────────────────────────────────────── diff --git a/src/config/providers.rs b/src/config/providers.rs index 9c11b27..136a39d 100644 --- a/src/config/providers.rs +++ b/src/config/providers.rs @@ -606,8 +606,9 @@ pub struct OpenAiProviderConfig { pub model_aliases: HashMap, /// Custom headers to include in requests. - /// For OpenRouter providers, `HTTP-Referer` and `X-OpenRouter-Title` are set - /// automatically for app attribution. Override here to customize or opt out. + /// For OpenRouter providers, `HTTP-Referer`, `X-OpenRouter-Title`, and + /// `X-OpenRouter-Categories` are set automatically for app attribution. + /// Override here to customize or opt out. #[serde(default)] pub headers: HashMap, diff --git a/src/config/server.rs b/src/config/server.rs index 7548f2d..def455f 100644 --- a/src/config/server.rs +++ b/src/config/server.rs @@ -469,12 +469,13 @@ fn default_frame_options() -> Option { /// - `frame-src blob:` — HTML artifact preview iframes /// - `img-src data: blob:` — Generated charts/images and inline assets /// - `media-src blob:` — Audio playback from generated TTS blob URLs -/// - `connect-src https://cdn.jsdelivr.net https://*.wikipedia.org https://www.wikidata.org` — -/// Pyodide/DuckDB fetch WASM/packages from CDN; Wikipedia and Wikidata tools query REST APIs +/// - `connect-src https: http: wss: ws:` — MCP servers are user-configured at arbitrary URLs +/// and discovered at runtime (stored in localStorage), so connect-src must allow all schemes. +/// Also covers Pyodide/DuckDB CDN fetches and Wikipedia/Wikidata tool queries. /// - `object-src 'none'` — Blocks plugins (Flash, Java applets) /// - `base-uri 'self'` — Prevents `` tag injection fn default_csp() -> Option { - Some("default-src 'self'; script-src 'self' blob: 'unsafe-eval' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; media-src 'self' blob:; connect-src 'self' https://cdn.jsdelivr.net https://*.wikipedia.org https://www.wikidata.org; worker-src 'self' blob:; frame-src 'self' blob:; object-src 'none'; base-uri 'self'".to_string()) + Some("default-src 'self'; script-src 'self' blob: 'unsafe-eval' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; media-src 'self' blob:; connect-src 'self' https: http: wss: ws:; worker-src 'self' blob:; frame-src 'self' blob:; object-src 'none'; base-uri 'self'".to_string()) } fn default_xss_protection() -> Option { diff --git a/src/providers/open_ai/mod.rs b/src/providers/open_ai/mod.rs index 0697c96..85e5701 100644 --- a/src/providers/open_ai/mod.rs +++ b/src/providers/open_ai/mod.rs @@ -79,6 +79,9 @@ impl OpenAICompatibleProvider { headers .entry("X-OpenRouter-Title".to_string()) .or_insert_with(|| "Hadrian Gateway".to_string()); + headers + .entry("X-OpenRouter-Categories".to_string()) + .or_insert_with(|| "general-chat".to_string()); } Self { diff --git a/src/routes/api/tools.rs b/src/routes/api/tools.rs index 8df37bc..063d299 100644 --- a/src/routes/api/tools.rs +++ b/src/routes/api/tools.rs @@ -76,7 +76,16 @@ struct ExaSearchRequest { #[derive(Debug, Serialize)] struct ExaContents { - text: bool, + text: ExaTextOptions, +} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +struct ExaTextOptions { + /// Maximum characters of text to return per result. + /// Omit to return full text (Exa default). + #[serde(skip_serializing_if = "Option::is_none")] + max_characters: Option, } #[derive(Debug, Deserialize)] @@ -103,6 +112,15 @@ pub async fn execute_web_search( max_results: usize, ) -> Result, WebSearchError> { let timeout = std::time::Duration::from_secs(config.timeout_secs); + let max_chars = config.max_content_chars; + + let truncate = |s: String| -> String { + if max_chars == 0 || s.len() <= max_chars { + return s; + } + let end = s.floor_char_boundary(max_chars); + format!("{}…[truncated]", &s[..end]) + }; match config.provider { WebSearchProvider::Tavily => { @@ -140,7 +158,7 @@ pub async fn execute_web_search( .map(|r| WebSearchResult { title: r.title, url: r.url, - content: r.content, + content: truncate(r.content), score: r.score, }) .collect()) @@ -149,7 +167,11 @@ pub async fn execute_web_search( let req = ExaSearchRequest { query: query.to_string(), num_results: max_results, - contents: ExaContents { text: true }, + contents: ExaContents { + text: ExaTextOptions { + max_characters: if max_chars > 0 { Some(max_chars) } else { None }, + }, + }, }; let resp = client .post("https://api.exa.ai/search") diff --git a/src/wizard.rs b/src/wizard.rs index 395e53c..03be401 100644 --- a/src/wizard.rs +++ b/src/wizard.rs @@ -971,6 +971,10 @@ fn generate_config(mode: DeploymentMode, wizard_config: &WizardConfig) -> String config.push_str("[server]\n"); config.push_str("host = \"0.0.0.0\"\n"); config.push_str("port = 8080\n"); + if matches!(mode, DeploymentMode::LocalDev) { + config.push_str("# Allow providers on localhost (e.g. Ollama)\n"); + config.push_str("allow_loopback_urls = true\n"); + } config.push('\n'); // CORS (always enabled for UI) @@ -1179,6 +1183,7 @@ mod tests { let config = generate_config(DeploymentMode::LocalDev, &wizard_config); assert!(config.contains("[server]")); + assert!(config.contains("allow_loopback_urls = true")); assert!(config.contains("[database]")); assert!(config.contains("type = \"sqlite\"")); assert!(config.contains("[cache]")); @@ -1222,6 +1227,7 @@ mod tests { let config = generate_config(DeploymentMode::SingleNode, &wizard_config); + assert!(!config.contains("allow_loopback_urls")); assert!(config.contains("[auth.mode]")); assert!(config.contains("type = \"api_key\"")); assert!(config.contains("[auth.api_key]")); diff --git a/ui/package.json b/ui/package.json index 1853c15..1b68c78 100644 --- a/ui/package.json +++ b/ui/package.json @@ -29,7 +29,7 @@ "@jitl/quickjs-singlefile-browser-release-sync": "^0.31.0", "@mcp-ui/client": "^6.1.0", "@radix-ui/react-popover": "^1.1.15", - "@streamdown/code": "^1.0.3", + "@streamdown/code": "^1.1.1", "@streamdown/math": "^1.0.2", "@streamdown/mermaid": "^1.0.2", "@tanstack/react-query": "^5.90.21", @@ -50,7 +50,7 @@ "remark-gfm": "^4.0.1", "shiki": "^3.22.0", "sql.js": "^1.12.0", - "streamdown": "^2.3.0", + "streamdown": "^2.5.0", "tailwind-merge": "^3.5.0", "use-debounce": "^10.1.0", "vega": "^6.2.0", diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml index 89ef60d..bfa2a45 100644 --- a/ui/pnpm-lock.yaml +++ b/ui/pnpm-lock.yaml @@ -50,8 +50,8 @@ importers: specifier: ^1.1.15 version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@streamdown/code': - specifier: ^1.0.3 - version: 1.0.3(react@19.2.4) + specifier: ^1.1.1 + version: 1.1.1(react@19.2.4) '@streamdown/math': specifier: ^1.0.2 version: 1.0.2(react@19.2.4) @@ -113,8 +113,8 @@ importers: specifier: ^1.12.0 version: 1.14.1 streamdown: - specifier: ^2.3.0 - version: 2.3.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: ^2.5.0 + version: 2.5.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) tailwind-merge: specifier: ^3.5.0 version: 3.5.0 @@ -148,19 +148,19 @@ importers: version: 10.2.11(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) '@storybook/addon-docs': specifier: ^10.2.11 - version: 10.2.11(@types/react@19.2.14)(esbuild@0.27.3)(rollup@2.80.0)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)) + version: 10.2.11(@types/react@19.2.14)(esbuild@0.27.3)(rollup@2.80.0)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1)) '@storybook/addon-vitest': specifier: ^10.2.11 - version: 10.2.11(@vitest/browser-playwright@4.0.18)(@vitest/browser@4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))(vitest@4.0.18))(@vitest/runner@4.0.18)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vitest@4.0.18) + version: 10.2.11(@vitest/browser-playwright@4.0.18)(@vitest/browser@4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))(vitest@4.0.18))(@vitest/runner@4.0.18)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vitest@4.0.18) '@storybook/react': specifier: ^10.2.11 version: 10.2.11(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) '@storybook/react-vite': specifier: ^10.2.11 - version: 10.2.11(esbuild@0.27.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@2.80.0)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)) + version: 10.2.11(esbuild@0.27.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@2.80.0)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1)) '@tailwindcss/vite': specifier: ^4.2.1 - version: 4.2.1(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)) + version: 4.2.1(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1)) '@types/node': specifier: ^24.10.13 version: 24.10.13 @@ -172,13 +172,13 @@ importers: version: 19.2.3(@types/react@19.2.14) '@vitejs/plugin-react': specifier: ^5.1.4 - version: 5.1.4(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)) + version: 5.1.4(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1)) '@vitest/browser-playwright': specifier: ^4.0.18 - version: 4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(playwright@1.58.2)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))(vitest@4.0.18) + version: 4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(playwright@1.58.2)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))(vitest@4.0.18) '@vitest/coverage-v8': specifier: ^4.0.18 - version: 4.0.18(@vitest/browser@4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))(vitest@4.0.18))(vitest@4.0.18) + version: 4.0.18(@vitest/browser@4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))(vitest@4.0.18))(vitest@4.0.18) autoprefixer: specifier: ^10.4.24 version: 10.4.24(postcss@8.5.6) @@ -232,13 +232,13 @@ importers: version: 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) vite: specifier: ^7.3.1 - version: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0) + version: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1) vite-plugin-pwa: specifier: ^1.2.0 - version: 1.2.0(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))(workbox-build@7.4.0(@types/babel__core@7.20.5))(workbox-window@7.4.0) + version: 1.2.0(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))(workbox-build@7.4.0(@types/babel__core@7.20.5))(workbox-window@7.4.0) vitest: specifier: ^4.0.18 - version: 4.0.18(@types/node@24.10.13)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.31.1)(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(terser@5.46.0) + version: 4.0.18(@types/node@24.10.13)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.31.1)(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(terser@5.46.1) packages: @@ -290,8 +290,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-define-polyfill-provider@0.6.6': - resolution: {integrity: sha512-mOAsxeeKkUKayvZR3HeTYD/fICpCPLJrU5ZjelT/PA6WHtNDBOE436YiaEUvHN454bRM3CebhDsIpieCc4texA==} + '@babel/helper-define-polyfill-provider@0.6.8': + resolution: {integrity: sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -734,8 +734,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/preset-env@7.29.0': - resolution: {integrity: sha512-fNEdfc0yi16lt6IZo2Qxk3knHVdfMYX33czNb4v8yWhemoBhibCpQK/uYHtSKIiO+p/zd3+8fYVXhQdOVV608w==} + '@babel/preset-env@7.29.2': + resolution: {integrity: sha512-DYD23veRYGvBFhcTY1iUvJnDNpuqNd/BzBwCvzOTKUnJjKg5kpUBh3/u9585Agdkgj+QuygG7jLfOPWMa2KVNw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -745,8 +745,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 - '@babel/runtime@7.28.6': - resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} engines: {node: '>=6.9.0'} '@babel/template@7.28.6': @@ -1839,8 +1839,8 @@ packages: typescript: optional: true - '@streamdown/code@1.0.3': - resolution: {integrity: sha512-3Ym5TCLcGhrHY2qBaUVWpqNRtxnZvqh4Y5Qm/pTIKA4AmEWwAAoYjZnxG7mOsvOpWVWiDwETjUtchNL1XzQEAw==} + '@streamdown/code@1.1.1': + resolution: {integrity: sha512-i7HTNuDgZWb+VdrNVOam9gQhIc5MSSDXKWXgbUrn/4vSRaSMM+Rtl10MQj4wLWPNpF7p80waJsAqFP8HZfb0Jg==} peerDependencies: react: ^18.0.0 || ^19.0.0 @@ -2470,18 +2470,18 @@ packages: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} - babel-plugin-polyfill-corejs2@0.4.15: - resolution: {integrity: sha512-hR3GwrRwHUfYwGfrisXPIDP3JcYfBrW7wKE7+Au6wDYl7fm/ka1NEII6kORzxNU556JjfidZeBsO10kYvtV1aw==} + babel-plugin-polyfill-corejs2@0.4.17: + resolution: {integrity: sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-corejs3@0.14.0: - resolution: {integrity: sha512-AvDcMxJ34W4Wgy4KBIIePQTAOP1Ie2WFwkQp3dB7FQ/f0lI5+nM96zUnYEOE1P9sEg0es5VCP0HxiWu5fUHZAQ==} + babel-plugin-polyfill-corejs3@0.14.2: + resolution: {integrity: sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-regenerator@0.6.6: - resolution: {integrity: sha512-hYm+XLYRMvupxiQzrvXUj7YyvFFVfv5gI0R71AJzudg1g2AI2vyCPPIFEBjk162/wFzti3inBHo7isWFuEVS/A==} + babel-plugin-polyfill-regenerator@0.6.8: + resolution: {integrity: sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -2700,8 +2700,8 @@ packages: resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} engines: {node: '>=18'} - core-js-compat@3.48.0: - resolution: {integrity: sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==} + core-js-compat@3.49.0: + resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} cors@2.8.6: resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} @@ -3260,9 +3260,8 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} - filelist@1.0.5: - resolution: {integrity: sha512-ct/ckWBV/9Dg3MlvCXsLcSUyoWwv9mCKqlhLNB2DAuXR/NZolSXlQqP5dyy6guWlPXBhodZyZ5lGPQcbQDxrEQ==} - engines: {node: 20 || >=22} + filelist@1.0.6: + resolution: {integrity: sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==} finalhandler@2.1.1: resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} @@ -4651,8 +4650,8 @@ packages: remark-stringify@11.0.0: resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} - remend@1.2.1: - resolution: {integrity: sha512-4wC12bgXsfKAjF1ewwkNIQz5sqewz/z1xgIgjEMb3r1pEytQ37F0Cm6i+OhbTWEvguJD7lhOUJhK5fSasw9f0w==} + remend@1.3.0: + resolution: {integrity: sha512-iIhggPkhW3hFImKtB10w0dz4EZbs28mV/dmbcYVonWEJ6UGHHpP+bFZnTh6GNWJONg5m+U56JrL+8IxZRdgWjw==} require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} @@ -4740,8 +4739,8 @@ packages: resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} engines: {node: '>= 18'} - serialize-javascript@7.0.3: - resolution: {integrity: sha512-h+cZ/XXarqDgCjo+YSyQU/ulDEESGGf8AMK9pPNmhNSl/FzPl6L8pMp1leca5z6NuG6tvV/auC8/43tmovowww==} + serialize-javascript@7.0.4: + resolution: {integrity: sha512-DuGdB+Po43Q5Jxwpzt1lhyFSYKryqoNjQSA9M92tyw0lyHIOur+XCalOUe0KTJpyqzT8+fQ5A0Jf7vCx/NKmIg==} engines: {node: '>=20.0.0'} serve-static@2.2.1: @@ -4857,8 +4856,8 @@ packages: prettier: optional: true - streamdown@2.3.0: - resolution: {integrity: sha512-OqS3by/lt91lSicE8RQP2nTsYI6Q/dQgGP2vcyn9YesCmRHhNjswAuBAZA1z0F4+oBU3II/eV51LqjCqwTb1lw==} + streamdown@2.5.0: + resolution: {integrity: sha512-/tTnURfIOxZK/pqJAxsfCvETG/XCJHoWnk3jq9xLcuz6CSpnjjuxSRBTTL4PKGhxiZQf0lqPxGhImdpwcZ2XwA==} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 @@ -4976,8 +4975,8 @@ packages: resolution: {integrity: sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==} engines: {node: '>=10'} - terser@5.46.0: - resolution: {integrity: sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==} + terser@5.46.1: + resolution: {integrity: sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==} engines: {node: '>=10'} hasBin: true @@ -5751,7 +5750,7 @@ snapshots: regexpu-core: 6.4.0 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.6(@babel/core@7.29.0)': + '@babel/helper-define-polyfill-provider@0.6.8(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 '@babel/helper-compilation-targets': 7.28.6 @@ -6239,7 +6238,7 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 - '@babel/preset-env@7.29.0(@babel/core@7.29.0)': + '@babel/preset-env@7.29.2(@babel/core@7.29.0)': dependencies: '@babel/compat-data': 7.29.0 '@babel/core': 7.29.0 @@ -6307,10 +6306,10 @@ snapshots: '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) '@babel/plugin-transform-unicode-sets-regex': 7.28.6(@babel/core@7.29.0) '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.0) - babel-plugin-polyfill-corejs2: 0.4.15(@babel/core@7.29.0) - babel-plugin-polyfill-corejs3: 0.14.0(@babel/core@7.29.0) - babel-plugin-polyfill-regenerator: 0.6.6(@babel/core@7.29.0) - core-js-compat: 3.48.0 + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.14.2(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -6322,7 +6321,7 @@ snapshots: '@babel/types': 7.29.0 esutils: 2.0.3 - '@babel/runtime@7.28.6': {} + '@babel/runtime@7.29.2': {} '@babel/template@7.28.6': dependencies: @@ -6627,11 +6626,11 @@ snapshots: dependencies: '@jitl/quickjs-ffi-types': 0.31.0 - '@joshwooding/vite-plugin-react-docgen-typescript@0.6.4(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))': + '@joshwooding/vite-plugin-react-docgen-typescript@0.6.4(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))': dependencies: glob: 13.0.6 react-docgen-typescript: 2.4.0(typescript@5.9.3) - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0) + vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1) optionalDependencies: typescript: 5.9.3 @@ -7060,9 +7059,9 @@ snapshots: '@rollup/plugin-terser@0.4.4(rollup@2.80.0)': dependencies: - serialize-javascript: 7.0.3 + serialize-javascript: 7.0.4 smob: 1.6.1 - terser: 5.46.0 + terser: 5.46.1 optionalDependencies: rollup: 2.80.0 @@ -7199,10 +7198,10 @@ snapshots: axe-core: 4.11.1 storybook: 10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@storybook/addon-docs@10.2.11(@types/react@19.2.14)(esbuild@0.27.3)(rollup@2.80.0)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))': + '@storybook/addon-docs@10.2.11(@types/react@19.2.14)(esbuild@0.27.3)(rollup@2.80.0)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))': dependencies: '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.4) - '@storybook/csf-plugin': 10.2.11(esbuild@0.27.3)(rollup@2.80.0)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)) + '@storybook/csf-plugin': 10.2.11(esbuild@0.27.3)(rollup@2.80.0)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1)) '@storybook/icons': 2.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@storybook/react-dom-shim': 10.2.11(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) react: 19.2.4 @@ -7216,39 +7215,39 @@ snapshots: - vite - webpack - '@storybook/addon-vitest@10.2.11(@vitest/browser-playwright@4.0.18)(@vitest/browser@4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))(vitest@4.0.18))(@vitest/runner@4.0.18)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vitest@4.0.18)': + '@storybook/addon-vitest@10.2.11(@vitest/browser-playwright@4.0.18)(@vitest/browser@4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))(vitest@4.0.18))(@vitest/runner@4.0.18)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vitest@4.0.18)': dependencies: '@storybook/global': 5.0.0 '@storybook/icons': 2.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) storybook: 10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) optionalDependencies: - '@vitest/browser': 4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))(vitest@4.0.18) - '@vitest/browser-playwright': 4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(playwright@1.58.2)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))(vitest@4.0.18) + '@vitest/browser': 4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))(vitest@4.0.18) + '@vitest/browser-playwright': 4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(playwright@1.58.2)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))(vitest@4.0.18) '@vitest/runner': 4.0.18 - vitest: 4.0.18(@types/node@24.10.13)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.31.1)(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(terser@5.46.0) + vitest: 4.0.18(@types/node@24.10.13)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.31.1)(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(terser@5.46.1) transitivePeerDependencies: - react - react-dom - '@storybook/builder-vite@10.2.11(esbuild@0.27.3)(rollup@2.80.0)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))': + '@storybook/builder-vite@10.2.11(esbuild@0.27.3)(rollup@2.80.0)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))': dependencies: - '@storybook/csf-plugin': 10.2.11(esbuild@0.27.3)(rollup@2.80.0)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)) + '@storybook/csf-plugin': 10.2.11(esbuild@0.27.3)(rollup@2.80.0)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1)) storybook: 10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) ts-dedent: 2.2.0 - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0) + vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1) transitivePeerDependencies: - esbuild - rollup - webpack - '@storybook/csf-plugin@10.2.11(esbuild@0.27.3)(rollup@2.80.0)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))': + '@storybook/csf-plugin@10.2.11(esbuild@0.27.3)(rollup@2.80.0)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))': dependencies: storybook: 10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) unplugin: 2.3.11 optionalDependencies: esbuild: 0.27.3 rollup: 2.80.0 - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0) + vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1) '@storybook/global@5.0.0': {} @@ -7263,11 +7262,11 @@ snapshots: react-dom: 19.2.4(react@19.2.4) storybook: 10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@storybook/react-vite@10.2.11(esbuild@0.27.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@2.80.0)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))': + '@storybook/react-vite@10.2.11(esbuild@0.27.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@2.80.0)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))': dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.6.4(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)) + '@joshwooding/vite-plugin-react-docgen-typescript': 0.6.4(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1)) '@rollup/pluginutils': 5.3.0(rollup@2.80.0) - '@storybook/builder-vite': 10.2.11(esbuild@0.27.3)(rollup@2.80.0)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)) + '@storybook/builder-vite': 10.2.11(esbuild@0.27.3)(rollup@2.80.0)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1)) '@storybook/react': 10.2.11(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) empathic: 2.0.0 magic-string: 0.30.21 @@ -7277,7 +7276,7 @@ snapshots: resolve: 1.22.11 storybook: 10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) tsconfig-paths: 4.2.0 - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0) + vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1) transitivePeerDependencies: - esbuild - rollup @@ -7298,7 +7297,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@streamdown/code@1.0.3(react@19.2.4)': + '@streamdown/code@1.1.1(react@19.2.4)': dependencies: react: 19.2.4 shiki: 3.22.0 @@ -7389,12 +7388,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.2.1 '@tailwindcss/oxide-win32-x64-msvc': 4.2.1 - '@tailwindcss/vite@4.2.1(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))': + '@tailwindcss/vite@4.2.1(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))': dependencies: '@tailwindcss/node': 4.2.1 '@tailwindcss/oxide': 4.2.1 tailwindcss: 4.2.1 - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0) + vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1) '@tanstack/query-core@5.90.20': {} @@ -7422,7 +7421,7 @@ snapshots: '@testing-library/dom@10.4.1': dependencies: '@babel/code-frame': 7.29.0 - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 '@types/aria-query': 5.0.4 aria-query: 5.3.0 dom-accessibility-api: 0.5.16 @@ -7763,7 +7762,7 @@ snapshots: d3-selection: 3.0.0 d3-transition: 3.0.1(d3-selection@3.0.0) - '@vitejs/plugin-react@5.1.4(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))': + '@vitejs/plugin-react@5.1.4(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) @@ -7771,33 +7770,33 @@ snapshots: '@rolldown/pluginutils': 1.0.0-rc.3 '@types/babel__core': 7.20.5 react-refresh: 0.18.0 - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0) + vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1) transitivePeerDependencies: - supports-color - '@vitest/browser-playwright@4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(playwright@1.58.2)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))(vitest@4.0.18)': + '@vitest/browser-playwright@4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(playwright@1.58.2)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))(vitest@4.0.18)': dependencies: - '@vitest/browser': 4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))(vitest@4.0.18) - '@vitest/mocker': 4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)) + '@vitest/browser': 4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))(vitest@4.0.18) + '@vitest/mocker': 4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1)) playwright: 1.58.2 tinyrainbow: 3.0.3 - vitest: 4.0.18(@types/node@24.10.13)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.31.1)(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(terser@5.46.0) + vitest: 4.0.18(@types/node@24.10.13)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.31.1)(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(terser@5.46.1) transitivePeerDependencies: - bufferutil - msw - utf-8-validate - vite - '@vitest/browser@4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))(vitest@4.0.18)': + '@vitest/browser@4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))(vitest@4.0.18)': dependencies: - '@vitest/mocker': 4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)) + '@vitest/mocker': 4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1)) '@vitest/utils': 4.0.18 magic-string: 0.30.21 pixelmatch: 7.1.0 pngjs: 7.0.0 sirv: 3.0.2 tinyrainbow: 3.0.3 - vitest: 4.0.18(@types/node@24.10.13)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.31.1)(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(terser@5.46.0) + vitest: 4.0.18(@types/node@24.10.13)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.31.1)(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(terser@5.46.1) ws: 8.19.0 transitivePeerDependencies: - bufferutil @@ -7805,7 +7804,7 @@ snapshots: - utf-8-validate - vite - '@vitest/coverage-v8@4.0.18(@vitest/browser@4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))(vitest@4.0.18))(vitest@4.0.18)': + '@vitest/coverage-v8@4.0.18(@vitest/browser@4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))(vitest@4.0.18))(vitest@4.0.18)': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.0.18 @@ -7817,9 +7816,9 @@ snapshots: obug: 2.1.1 std-env: 3.10.0 tinyrainbow: 3.0.3 - vitest: 4.0.18(@types/node@24.10.13)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.31.1)(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(terser@5.46.0) + vitest: 4.0.18(@types/node@24.10.13)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.31.1)(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(terser@5.46.1) optionalDependencies: - '@vitest/browser': 4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))(vitest@4.0.18) + '@vitest/browser': 4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))(vitest@4.0.18) '@vitest/expect@3.2.4': dependencies: @@ -7838,14 +7837,14 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))': + '@vitest/mocker@4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))': dependencies: '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: msw: 2.12.10(@types/node@24.10.13)(typescript@5.9.3) - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0) + vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1) '@vitest/pretty-format@3.2.4': dependencies: @@ -8031,27 +8030,27 @@ snapshots: axobject-query@4.1.0: {} - babel-plugin-polyfill-corejs2@0.4.15(@babel/core@7.29.0): + babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.0): dependencies: '@babel/compat-data': 7.29.0 '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) semver: 6.3.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.14.0(@babel/core@7.29.0): + babel-plugin-polyfill-corejs3@0.14.2(@babel/core@7.29.0): dependencies: '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) - core-js-compat: 3.48.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.6(@babel/core@7.29.0): + babel-plugin-polyfill-regenerator@0.6.8(@babel/core@7.29.0): dependencies: '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) transitivePeerDependencies: - supports-color @@ -8265,7 +8264,7 @@ snapshots: cookie@1.1.1: {} - core-js-compat@3.48.0: + core-js-compat@3.49.0: dependencies: browserslist: 4.28.1 @@ -8936,7 +8935,7 @@ snapshots: dependencies: flat-cache: 4.0.1 - filelist@1.0.5: + filelist@1.0.6: dependencies: minimatch: 10.2.4 @@ -9479,7 +9478,7 @@ snapshots: jake@10.9.4: dependencies: async: 3.2.6 - filelist: 1.0.5 + filelist: 1.0.6 picocolors: 1.1.1 jiti@2.6.1: {} @@ -10655,7 +10654,7 @@ snapshots: mdast-util-to-markdown: 2.1.2 unified: 11.0.5 - remend@1.2.1: {} + remend@1.3.0: {} require-directory@2.1.1: {} @@ -10776,7 +10775,7 @@ snapshots: transitivePeerDependencies: - supports-color - serialize-javascript@7.0.3: {} + serialize-javascript@7.0.4: {} serve-static@2.2.1: dependencies: @@ -10923,12 +10922,13 @@ snapshots: - react-dom - utf-8-validate - streamdown@2.3.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + streamdown@2.5.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: clsx: 2.1.1 hast-util-to-jsx-runtime: 2.3.6 html-url-attributes: 3.0.1 marked: 17.0.3 + mermaid: 11.13.0 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) rehype-harden: 1.1.8 @@ -10937,7 +10937,7 @@ snapshots: remark-gfm: 4.0.1 remark-parse: 11.0.0 remark-rehype: 11.1.2 - remend: 1.2.1 + remend: 1.3.0 tailwind-merge: 3.5.0 unified: 11.0.5 unist-util-visit: 5.1.0 @@ -11077,7 +11077,7 @@ snapshots: type-fest: 0.16.0 unique-string: 2.0.0 - terser@5.46.0: + terser@5.46.1: dependencies: '@jridgewell/source-map': 0.3.11 acorn: 8.16.0 @@ -11626,18 +11626,18 @@ snapshots: d3-time: 3.1.0 d3-timer: 3.0.1 - vite-plugin-pwa@1.2.0(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))(workbox-build@7.4.0(@types/babel__core@7.20.5))(workbox-window@7.4.0): + vite-plugin-pwa@1.2.0(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))(workbox-build@7.4.0(@types/babel__core@7.20.5))(workbox-window@7.4.0): dependencies: debug: 4.4.3 pretty-bytes: 6.1.1 tinyglobby: 0.2.15 - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0) + vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1) workbox-build: 7.4.0(@types/babel__core@7.20.5) workbox-window: 7.4.0 transitivePeerDependencies: - supports-color - vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0): + vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1): dependencies: esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.3) @@ -11650,12 +11650,12 @@ snapshots: fsevents: 2.3.3 jiti: 2.6.1 lightningcss: 1.31.1 - terser: 5.46.0 + terser: 5.46.1 - vitest@4.0.18(@types/node@24.10.13)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.31.1)(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(terser@5.46.0): + vitest@4.0.18(@types/node@24.10.13)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.31.1)(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(terser@5.46.1): dependencies: '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)) + '@vitest/mocker': 4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1)) '@vitest/pretty-format': 4.0.18 '@vitest/runner': 4.0.18 '@vitest/snapshot': 4.0.18 @@ -11672,11 +11672,11 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0) + vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.10.13 - '@vitest/browser-playwright': 4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(playwright@1.58.2)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0))(vitest@4.0.18) + '@vitest/browser-playwright': 4.0.18(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(playwright@1.58.2)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.1))(vitest@4.0.18) transitivePeerDependencies: - jiti - less @@ -11786,8 +11786,8 @@ snapshots: dependencies: '@apideck/better-ajv-errors': 0.3.6(ajv@8.18.0) '@babel/core': 7.29.0 - '@babel/preset-env': 7.29.0(@babel/core@7.29.0) - '@babel/runtime': 7.28.6 + '@babel/preset-env': 7.29.2(@babel/core@7.29.0) + '@babel/runtime': 7.29.2 '@rollup/plugin-babel': 5.3.1(@babel/core@7.29.0)(@types/babel__core@7.20.5)(rollup@2.80.0) '@rollup/plugin-node-resolve': 15.3.1(rollup@2.80.0) '@rollup/plugin-replace': 2.4.2(rollup@2.80.0) diff --git a/ui/src/components/ChatMessage/ChatMessage.stories.tsx b/ui/src/components/ChatMessage/ChatMessage.stories.tsx index d62726d..9f72241 100644 --- a/ui/src/components/ChatMessage/ChatMessage.stories.tsx +++ b/ui/src/components/ChatMessage/ChatMessage.stories.tsx @@ -135,8 +135,6 @@ export const StreamingMessage: Story = { isStreaming: true, }, play: async ({ canvasElement }) => { - const canvas = within(canvasElement); - // Verify streaming indicator has aria-live for accessibility const streamingContent = canvasElement.querySelector('[aria-live="polite"]'); await expect(streamingContent).toBeInTheDocument(); @@ -145,12 +143,9 @@ export const StreamingMessage: Story = { const busyElement = canvasElement.querySelector('[aria-busy="true"]'); await expect(busyElement).toBeInTheDocument(); - // Verify blinking cursor is present (screen reader hidden) - const cursor = canvasElement.querySelector('[aria-hidden="true"]'); - await expect(cursor).toBeInTheDocument(); - - // Verify screen reader text for streaming state - await expect(canvas.getByText("Generating response...")).toBeInTheDocument(); + // Verify StreamingMarkdown component renders the content container + const markdownContainer = canvasElement.querySelector(".markdown-content"); + await expect(markdownContainer).toBeInTheDocument(); }, }; diff --git a/ui/src/components/ChatMessage/ChatMessage.tsx b/ui/src/components/ChatMessage/ChatMessage.tsx index 8f2cea9..25cdd92 100644 --- a/ui/src/components/ChatMessage/ChatMessage.tsx +++ b/ui/src/components/ChatMessage/ChatMessage.tsx @@ -23,6 +23,7 @@ import { import { Avatar, AvatarFallback } from "@/components/Avatar/Avatar"; import { Button } from "@/components/Button/Button"; import { Markdown } from "@/components/Markdown/Markdown"; +import { StreamingMarkdown } from "@/components/StreamingMarkdown/StreamingMarkdown"; import { QuoteSelectionPopover } from "@/components/QuoteSelectionPopover"; import { Textarea } from "@/components/Textarea/Textarea"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/Tooltip/Tooltip"; @@ -324,19 +325,10 @@ function ChatMessageComponent({ ) : ( ) + ) : isStreaming ? ( + ) : ( - <> - - {isStreaming && ( - <> -