diff --git a/CHANGELOG.md b/CHANGELOG.md index db00c82ff..aeb93d838 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ - Talk Mode: treat history timestamps as seconds or milliseconds to avoid stale assistant picks (macOS/iOS/Android). - Chat UI: clear streaming/tool bubbles when external runs finish, preventing duplicate assistant bubbles. - Chat UI: user bubbles use `ui.seamColor` (fallback to a calmer default blue). +- Control UI: sync sidebar navigation with the URL for deep-linking, and auto-scroll chat to the latest message. - Talk Mode: wait for chat history to surface the assistant reply before starting TTS (macOS/iOS/Android). - iOS Talk Mode: fix chat completion wait to time out even if no events arrive (prevents “Thinking…” hangs). - iOS Talk Mode: keep recognition running during playback to support interrupt-on-speech. diff --git a/package.json b/package.json index 293e7e4b2..30a30a37d 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "@mariozechner/pi-agent-core": "^0.30.2", "@mariozechner/pi-ai": "^0.30.2", "@mariozechner/pi-coding-agent": "^0.30.2", - "@sinclair/typebox": "^0.34.41", + "@sinclair/typebox": "^0.34.45", "@whiskeysockets/baileys": "7.0.0-rc.9", "ajv": "^8.17.1", "body-parser": "^2.2.1", @@ -87,7 +87,7 @@ "discord.js": "^14.25.1", "dotenv": "^17.2.3", "express": "^5.2.1", - "file-type": "^21.1.1", + "file-type": "^21.2.0", "grammy": "^1.38.4", "json5": "^2.2.3", "long": "5.3.2", @@ -101,7 +101,7 @@ }, "devDependencies": { "@biomejs/biome": "^2.3.10", - "@lit-labs/signals": "^0.1.3", + "@lit-labs/signals": "^0.2.0", "@lit/context": "^1.1.6", "@mariozechner/mini-lit": "0.2.1", "@types/body-parser": "^1.19.6", @@ -113,14 +113,14 @@ "@vitest/coverage-v8": "^4.0.16", "docx-preview": "^0.3.7", "jszip": "^3.10.1", - "lit": "^3.3.1", + "lit": "^3.3.2", "lucide": "^0.562.0", "markdown-it": "^14.1.0", "ollama": "^0.6.3", - "oxlint": "^1.35.0", + "oxlint": "^1.36.0", "oxlint-tsgolint": "^0.10.0", "quicktype-core": "^23.2.6", - "rolldown": "1.0.0-beta.55", + "rolldown": "1.0.0-beta.57", "signal-utils": "^0.21.1", "tsx": "^4.21.0", "typescript": "^5.9.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 86f28ae6a..d524e4c4a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,8 +29,8 @@ importers: specifier: ^0.30.2 version: 0.30.2(ws@8.18.3)(zod@4.2.1) '@sinclair/typebox': - specifier: ^0.34.41 - version: 0.34.41 + specifier: ^0.34.45 + version: 0.34.45 '@whiskeysockets/baileys': specifier: 7.0.0-rc.9 version: 7.0.0-rc.9(audio-decode@2.2.3)(sharp@0.34.5) @@ -68,8 +68,8 @@ importers: specifier: ^5.2.1 version: 5.2.1 file-type: - specifier: ^21.1.1 - version: 21.1.1 + specifier: ^21.2.0 + version: 21.2.0 grammy: specifier: ^1.38.4 version: 1.38.4 @@ -105,14 +105,14 @@ importers: specifier: ^2.3.10 version: 2.3.10 '@lit-labs/signals': - specifier: ^0.1.3 - version: 0.1.3 + specifier: ^0.2.0 + version: 0.2.0 '@lit/context': specifier: ^1.1.6 version: 1.1.6 '@mariozechner/mini-lit': specifier: 0.2.1 - version: 0.2.1(lit@3.3.1)(tailwindcss@4.1.17) + version: 0.2.1(lit@3.3.2)(tailwindcss@4.1.17) '@types/body-parser': specifier: ^1.19.6 version: 1.19.6 @@ -133,7 +133,7 @@ importers: version: 8.18.1 '@vitest/coverage-v8': specifier: ^4.0.16 - version: 4.0.16(vitest@4.0.16(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + version: 4.0.16(@vitest/browser@4.0.16(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.16))(vitest@4.0.16) docx-preview: specifier: ^0.3.7 version: 0.3.7 @@ -141,8 +141,8 @@ importers: specifier: ^3.10.1 version: 3.10.1 lit: - specifier: ^3.3.1 - version: 3.3.1 + specifier: ^3.3.2 + version: 3.3.2 lucide: specifier: ^0.562.0 version: 0.562.0 @@ -153,8 +153,8 @@ importers: specifier: ^0.6.3 version: 0.6.3 oxlint: - specifier: ^1.35.0 - version: 1.35.0(oxlint-tsgolint@0.10.0) + specifier: ^1.36.0 + version: 1.36.0(oxlint-tsgolint@0.10.0) oxlint-tsgolint: specifier: ^0.10.0 version: 0.10.0 @@ -162,8 +162,8 @@ importers: specifier: ^23.2.6 version: 23.2.6 rolldown: - specifier: 1.0.0-beta.55 - version: 1.0.0-beta.55 + specifier: 1.0.0-beta.57 + version: 1.0.0-beta.57 signal-utils: specifier: ^0.21.1 version: 0.21.1(signal-polyfill@0.2.2) @@ -175,7 +175,7 @@ importers: version: 5.9.3 vitest: specifier: ^4.0.16 - version: 4.0.16(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + version: 4.0.16(@types/node@25.0.3)(@vitest/browser-playwright@4.0.16)(@vitest/browser-preview@4.0.16)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) wireit: specifier: ^0.14.12 version: 0.14.12 @@ -183,15 +183,24 @@ importers: ui: dependencies: lit: - specifier: ^3.3.1 - version: 3.3.1 + specifier: ^3.3.2 + version: 3.3.2 devDependencies: + '@vitest/browser-playwright': + specifier: 4.0.16 + version: 4.0.16(playwright@1.57.0)(vite@8.0.0-beta.3(@types/node@25.0.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.16) + playwright: + specifier: ^1.57.0 + version: 1.57.0 typescript: specifier: ^5.9.3 version: 5.9.3 vite: specifier: 8.0.0-beta.3 version: 8.0.0-beta.3(@types/node@25.0.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vitest: + specifier: 4.0.16 + version: 4.0.16(@types/node@25.0.3)(@vitest/browser-playwright@4.0.16)(@vitest/browser-preview@4.0.16)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) packages: @@ -204,6 +213,10 @@ packages: zod: optional: true + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -285,18 +298,18 @@ packages: '@borewit/text-codec@0.1.1': resolution: {integrity: sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==} - '@borewit/text-codec@0.2.0': - resolution: {integrity: sha512-X999CKBxGwX8wW+4gFibsbiNdwqmdQEXmUejIWaIqdrHBgS5ARIOOeyiQbHjP9G58xVEPcuvP6VwwH3A0OFTOA==} + '@borewit/text-codec@0.2.1': + resolution: {integrity: sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw==} - '@cacheable/memory@2.0.6': - resolution: {integrity: sha512-7e8SScMocHxcAb8YhtkbMhGG+EKLRIficb1F5sjvhSYsWTZGxvg4KIDp8kgxnV2PUJ3ddPe6J9QESjKvBWRDkg==} + '@cacheable/memory@2.0.7': + resolution: {integrity: sha512-RbxnxAMf89Tp1dLhXMS7ceft/PGsDl1Ip7T20z5nZ+pwIAsQ1p2izPjVG69oCLv/jfQ7HDPHTWK0c9rcAWXN3A==} '@cacheable/node-cache@1.7.6': resolution: {integrity: sha512-6Omk2SgNnjtxB5f/E6bTIWIt5xhdpx39fGNRQgU9lojvRxU68v+qY+SXXLsp3ZGukqoPjsK21wZ6XABFr/Ge3A==} engines: {node: '>=18'} - '@cacheable/utils@2.3.2': - resolution: {integrity: sha512-8kGE2P+HjfY8FglaOiW+y8qxcaQAfAhVML+i66XJR3YX5FtyDqn6Txctr3K2FrbxLKixRRYYBWMbuGciOhYNDg==} + '@cacheable/utils@2.3.3': + resolution: {integrity: sha512-JsXDL70gQ+1Vc2W/KUFfkAJzgb4puKwwKehNLuB+HrNKWf91O736kGfxn4KujXCCSuh6mRRL4XEB0PkAFjWS0A==} '@discordjs/builders@1.13.1': resolution: {integrity: sha512-cOU0UDHc3lp/5nKByDxkmRiNZBpdp0kx55aarbiAfakfKJHlxv/yFW1zmIqCAmwH5CRlrH9iMFKJMpvW4DPB+w==} @@ -693,17 +706,17 @@ packages: '@keyv/serialize@1.1.1': resolution: {integrity: sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==} - '@lit-labs/signals@0.1.3': - resolution: {integrity: sha512-P0yWgH5blwVyEwBg+WFspLzeu1i0ypJP1QB0l1Omr9qZLIPsUu0p4Fy2jshOg7oQyha5n163K3GJGeUhQQ682Q==} + '@lit-labs/signals@0.2.0': + resolution: {integrity: sha512-68plyIbciumbwKaiilhLNyhz4Vg6/+nJwDufG2xxWA9r/fUw58jxLHCAlKs+q1CE5Lmh3cZ3ShyYKnOCebEpVA==} - '@lit-labs/ssr-dom-shim@1.4.0': - resolution: {integrity: sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==} + '@lit-labs/ssr-dom-shim@1.5.0': + resolution: {integrity: sha512-HLomZXMmrCFHSRKESF5vklAKsDY7/fsT/ZhqCu3V0UoW/Qbv8wxmO4W9bx4KnCCF2Zak4yuk+AGraK/bPmI4kA==} '@lit/context@1.1.6': resolution: {integrity: sha512-M26qDE6UkQbZA2mQ3RjJ3Gzd8TxP+/0obMgE5HfkfLhEEyYE3Bui4A5XHiGPjy0MUGAyxB3QgVuw2ciS0kHn6A==} - '@lit/reactive-element@2.1.1': - resolution: {integrity: sha512-N+dm5PAYdQ8e6UlywyyrgI2t++wFGXfHx+dSJ1oBrg6FAxUj40jId++EaRm80MKX5JnlH1sBsyZ5h0bcZKemCg==} + '@lit/reactive-element@2.1.2': + resolution: {integrity: sha512-pbCDiVMnne1lYUIaYNN5wrwQXDtHaYtg7YEFPeW+hws6U47WeFvISGUWekPGKWOP1ygrs0ef0o1VJMk1exos5A==} '@mariozechner/mini-lit@0.2.1': resolution: {integrity: sha512-u300euLgCsDDlb8o2Wbz+55eSJga5X2vB58s9XBuFIr2Bi3iI+GMR7t/NYo/O6Vr6obXShXgYjR3SRUJVgo+kQ==} @@ -731,8 +744,8 @@ packages: '@mistralai/mistralai@1.10.0': resolution: {integrity: sha512-tdIgWs4Le8vpvPiUEWne6tK0qbVc+jMenujnvTqOjogrJUsCSQhus0tHTU1avDDh5//Rq2dFgP9mWRAdIEoBqg==} - '@napi-rs/wasm-runtime@1.1.0': - resolution: {integrity: sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA==} + '@napi-rs/wasm-runtime@1.1.1': + resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -783,43 +796,43 @@ packages: cpu: [x64] os: [win32] - '@oxlint/darwin-arm64@1.35.0': - resolution: {integrity: sha512-ieiYVHkNZPo77Hgrxav595wGS4rRNKuDNrljf+4xhwpJsddrxMpM64IQUf2IvR3MhK4FxdGzhhB6OVmGVHY5/w==} + '@oxlint/darwin-arm64@1.36.0': + resolution: {integrity: sha512-MJkj82GH+nhvWKJhSIM6KlZ8tyGKdogSQXtNdpIyP02r/tTayFJQaAEWayG2Jhsn93kske+nimg5MYFhwO/rlg==} cpu: [arm64] os: [darwin] - '@oxlint/darwin-x64@1.35.0': - resolution: {integrity: sha512-1jNHu3j66X5jKySvgtE+jGtjx4ye+xioAucVTi2IuROZO6keK2YG74pnD+9FT+DpWZAtWRZGoW0r0x6aN9sEEg==} + '@oxlint/darwin-x64@1.36.0': + resolution: {integrity: sha512-VvEhfkqj/99dCTqOcfkyFXOSbx4lIy5u2m2GHbK4WCMDySokOcMTNRHGw8fH/WgQ5cDrDMSTYIGQTmnBGi9tiQ==} cpu: [x64] os: [darwin] - '@oxlint/linux-arm64-gnu@1.35.0': - resolution: {integrity: sha512-T1lc0UaYbTxZyqVpLfC7eipbauNG8pBpkaZEW4JGz8Y68rxTH7d9s+CF0zxUxNr5RCtcmT669RLVjQT7VrKVLg==} + '@oxlint/linux-arm64-gnu@1.36.0': + resolution: {integrity: sha512-EMx92X5q+hHc3olTuj/kgkx9+yP0p/AVs4yvHbUfzZhBekXNpUWxWvg4hIKmQWn+Ee2j4o80/0ACGO0hDYJ9mg==} cpu: [arm64] os: [linux] - '@oxlint/linux-arm64-musl@1.35.0': - resolution: {integrity: sha512-7Wv5Pke9kwWKFycUziSHsmi3EM0389TLzraB0KE/MArrKxx30ycwfJ5PYoMj9ERoW+Ybs0txdaOF/xJy/XyYkg==} + '@oxlint/linux-arm64-musl@1.36.0': + resolution: {integrity: sha512-7YCxtrPIctVYLqWrWkk8pahdCxch6PtsaucfMLC7TOlDt4nODhnQd4yzEscKqJ8Gjrw1bF4g+Ngob1gB+Qr9Fw==} cpu: [arm64] os: [linux] - '@oxlint/linux-x64-gnu@1.35.0': - resolution: {integrity: sha512-HDMPOzyVVy+rQl3H7UOq8oGHt7m1yaiWCanlhAu4jciK8dvXeO9OG/OQd74lD/h05IcJh93pCLEJ3wWOG8hTiQ==} + '@oxlint/linux-x64-gnu@1.36.0': + resolution: {integrity: sha512-lnaJVlx5r3NWmoOMesfQXJSf78jHTn8Z+sdAf795Kgteo72+qGC1Uax2SToCJVN2J8PNG3oRV5bLriiCNR2i6Q==} cpu: [x64] os: [linux] - '@oxlint/linux-x64-musl@1.35.0': - resolution: {integrity: sha512-kAPBBsUOM3HQQ6n3nnZauvFR9EoXqCSoj4O3OSXXarzsRTiItNrHabVUwxeswZEc+xMzQNR0FHEWg/d4QAAWLw==} + '@oxlint/linux-x64-musl@1.36.0': + resolution: {integrity: sha512-AhuEU2Qdl66lSfTGu/Htirq8r/8q2YnZoG3yEXLMQWnPMn7efy8spD/N1NA7kH0Hll+cdfwgQkQqC2G4MS2lPQ==} cpu: [x64] os: [linux] - '@oxlint/win32-arm64@1.35.0': - resolution: {integrity: sha512-qrpBkkOASS0WT8ra9xmBRXOEliN6D/MV9JhI/68lFHrtLhfFuRwg4AjzjxrCWrQCnQ0WkvAVpJzu73F4ICLYZw==} + '@oxlint/win32-arm64@1.36.0': + resolution: {integrity: sha512-GlWCBjUJY2QgvBFuNRkiRJu7K/djLmM0UQKfZV8IN+UXbP/JbjZHWKRdd4LXlQmzoz7M5Hd6p+ElCej8/90FCg==} cpu: [arm64] os: [win32] - '@oxlint/win32-x64@1.35.0': - resolution: {integrity: sha512-yPFcj6umrhusnG/kMS5wh96vblsqZ0kArQJS+7kEOSJDrH+DsFWaDCsSRF8U6gmSmZJ26KVMU3C3TMpqDN4M1g==} + '@oxlint/win32-x64@1.36.0': + resolution: {integrity: sha512-J+Vc00Utcf8p77lZPruQgb0QnQXuKnFogN88kCnOqs2a83I+vTBB8ILr0+L9sTwVRvIDMSC0pLdeQH4svWGFZg==} cpu: [x64] os: [win32] @@ -830,6 +843,9 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + '@preact/signals-core@1.12.1': resolution: {integrity: sha512-BwbTXpj+9QutoZLQvbttRg5x3l5468qaV2kufh+51yha1c53ep5dY4kTuZR35+3pAZxpfQerGJiQqg34ZNZ6uA==} @@ -869,80 +885,160 @@ packages: cpu: [arm64] os: [android] + '@rolldown/binding-android-arm64@1.0.0-beta.57': + resolution: {integrity: sha512-GoOVDy8bjw9z1K30Oo803nSzXJS/vWhFijFsW3kzvZCO8IZwFnNa6pGctmbbJstKl3Fv6UBwyjJQN6msejW0IQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + '@rolldown/binding-darwin-arm64@1.0.0-beta.55': resolution: {integrity: sha512-l0887CGU2SXZr0UJmeEcXSvtDCOhDTTYXuoWbhrEJ58YQhQk24EVhDhHMTyjJb1PBRniUgNc1G0T51eF8z+TWw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] + '@rolldown/binding-darwin-arm64@1.0.0-beta.57': + resolution: {integrity: sha512-9c4FOhRGpl+PX7zBK5p17c5efpF9aSpTPgyigv57hXf5NjQUaJOOiejPLAtFiKNBIfm5Uu6yFkvLKzOafNvlTw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + '@rolldown/binding-darwin-x64@1.0.0-beta.55': resolution: {integrity: sha512-d7qP2AVYzN0tYIP4vJ7nmr26xvmlwdkLD/jWIc9Z9dqh5y0UGPigO3m5eHoHq9BNazmwdD9WzDHbQZyXFZjgtA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] + '@rolldown/binding-darwin-x64@1.0.0-beta.57': + resolution: {integrity: sha512-6RsB8Qy4LnGqNGJJC/8uWeLWGOvbRL/KG5aJ8XXpSEupg/KQtlBEiFaYU/Ma5Usj1s+bt3ItkqZYAI50kSplBA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + '@rolldown/binding-freebsd-x64@1.0.0-beta.55': resolution: {integrity: sha512-j311E4NOB0VMmXHoDDZhrWidUf7L/Sa6bu/+i2cskvHKU40zcUNPSYeD2YiO2MX+hhDFa5bJwhliYfs+bTrSZw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] + '@rolldown/binding-freebsd-x64@1.0.0-beta.57': + resolution: {integrity: sha512-uA9kG7+MYkHTbqwv67Tx+5GV5YcKd33HCJIi0311iYBd25yuwyIqvJfBdt1VVB8tdOlyTb9cPAgfCki8nhwTQg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.55': resolution: {integrity: sha512-lAsaYWhfNTW2A/9O7zCpb5eIJBrFeNEatOS/DDOZ5V/95NHy50g4b/5ViCqchfyFqRb7MKUR18/+xWkIcDkeIw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.57': + resolution: {integrity: sha512-3KkS0cHsllT2T+Te+VZMKHNw6FPQihYsQh+8J4jkzwgvAQpbsbXmrqhkw3YU/QGRrD8qgcOvBr6z5y6Jid+rmw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.55': resolution: {integrity: sha512-2x6ffiVLZrQv7Xii9+JdtyT1U3bQhKj59K3eRnYlrXsKyjkjfmiDUVx2n+zSyijisUqD62fcegmx2oLLfeTkCA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.57': + resolution: {integrity: sha512-A3/wu1RgsHhqP3rVH2+sM81bpk+Qd2XaHTl8LtX5/1LNR7QVBFBCpAoiXwjTdGnI5cMdBVi7Z1pi52euW760Fw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.55': resolution: {integrity: sha512-QbNncvqAXziya5wleI+OJvmceEE15vE4yn4qfbI/hwT/+8ZcqxyfRZOOh62KjisXxp4D0h3JZspycXYejxAU3w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.57': + resolution: {integrity: sha512-d0kIVezTQtazpyWjiJIn5to8JlwfKITDqwsFv0Xc6s31N16CD2PC/Pl2OtKgS7n8WLOJbfqgIp5ixYzTAxCqMg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.55': resolution: {integrity: sha512-YZCTZZM+rujxwVc6A+QZaNMJXVtmabmFYLG2VGQTKaBfYGvBKUgtbMEttnp/oZ88BMi2DzadBVhOmfQV8SuHhw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.57': + resolution: {integrity: sha512-E199LPijo98yrLjPCmETx8EF43sZf9t3guSrLee/ej1rCCc3zDVTR4xFfN9BRAapGVl7/8hYqbbiQPTkv73kUg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + '@rolldown/binding-linux-x64-musl@1.0.0-beta.55': resolution: {integrity: sha512-28q9OQ/DDpFh2keS4BVAlc3N65/wiqKbk5K1pgLdu/uWbKa8hgUJofhXxqO+a+Ya2HVTUuYHneWsI2u+eu3N5Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + '@rolldown/binding-linux-x64-musl@1.0.0-beta.57': + resolution: {integrity: sha512-++EQDpk/UJ33kY/BNsh7A7/P1sr/jbMuQ8cE554ZIy+tCUWCivo9zfyjDUoiMdnxqX6HLJEqqGnbGQOvzm2OMQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + '@rolldown/binding-openharmony-arm64@1.0.0-beta.55': resolution: {integrity: sha512-LiCA4BjCnm49B+j1lFzUtlC+4ZphBv0d0g5VqrEJua/uyv9Ey1v9tiaMql1C8c0TVSNDUmrkfHQ71vuQC7YfpQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] + '@rolldown/binding-openharmony-arm64@1.0.0-beta.57': + resolution: {integrity: sha512-voDEBcNqxbUv/GeXKFtxXVWA+H45P/8Dec4Ii/SbyJyGvCqV1j+nNHfnFUIiRQ2Q40DwPe/djvgYBs9PpETiMA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + '@rolldown/binding-wasm32-wasi@1.0.0-beta.55': resolution: {integrity: sha512-nZ76tY7T0Oe8vamz5Cv5CBJvrqeQxwj1WaJ2GxX8Msqs0zsQMMcvoyxOf0glnJlxxgKjtoBxAOxaAU8ERbW6Tg==} engines: {node: '>=14.0.0'} cpu: [wasm32] + '@rolldown/binding-wasm32-wasi@1.0.0-beta.57': + resolution: {integrity: sha512-bRhcF7NLlCnpkzLVlVhrDEd0KH22VbTPkPTbMjlYvqhSmarxNIq5vtlQS8qmV7LkPKHrNLWyJW/V/sOyFba26Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.55': resolution: {integrity: sha512-TFVVfLfhL1G+pWspYAgPK/FSqjiBtRKYX9hixfs508QVEZPQlubYAepHPA7kEa6lZXYj5ntzF87KC6RNhxo+ew==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.57': + resolution: {integrity: sha512-rnDVGRks2FQ2hgJ2g15pHtfxqkGFGjJQUDWzYznEkE8Ra2+Vag9OffxdbJMZqBWXHVM0iS4dv8qSiEn7bO+n1Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.55': resolution: {integrity: sha512-j1WBlk0p+ISgLzMIgl0xHp1aBGXenoK2+qWYc/wil2Vse7kVOdFq9aeQ8ahK6/oxX2teQ5+eDvgjdywqTL+daA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.57': + resolution: {integrity: sha512-OqIUyNid1M4xTj6VRXp/Lht/qIP8fo25QyAZlCP+p6D2ATCEhyW4ZIFLnC9zAGN/HMbXoCzvwfa8Jjg/8J4YEg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + '@rolldown/pluginutils@1.0.0-beta.55': resolution: {integrity: sha512-vajw/B3qoi7aYnnD4BQ4VoCcXQWnF0roSwE2iynbNxgW4l9mFwtLmLmUhpDdcTBfKyZm1p/T0D13qG94XBLohA==} + '@rolldown/pluginutils@1.0.0-beta.57': + resolution: {integrity: sha512-aQNelgx14tGA+n2tNSa9x6/jeoCL9fkDeCei7nOKnHx0fEFRRMu5ReiITo+zZD5TzWDGGRjbSYCs93IfRIyTuQ==} + '@rollup/rollup-android-arm-eabi@4.54.0': resolution: {integrity: sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==} cpu: [arm] @@ -1065,18 +1161,28 @@ packages: resolution: {integrity: sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==} engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - '@sinclair/typebox@0.34.41': - resolution: {integrity: sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==} + '@sinclair/typebox@0.34.45': + resolution: {integrity: sha512-qJcFVfCa5jxBFSuv7S5WYbA8XdeCPmhnaVVfX/2Y6L8WYg8sk3XY2+6W0zH+3mq1Cz+YC7Ki66HfqX6IHAwnkg==} '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - '@thi.ng/bitstream@2.4.36': - resolution: {integrity: sha512-ACdNVjFEQSWKRj/BekNggXVBZgnUnLjmwg7nPL1DKdGZ3IlZl8lz48ETHi2c1bFJxFIbFqkoEFk4yNj2tPvuNA==} + '@testing-library/dom@10.4.1': + resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} - '@thi.ng/errors@2.5.50': - resolution: {integrity: sha512-81I9IHwrCAHpfzEVMaJQpRYaq87MvIXi7YQ/wccKSxtiaz4IpB8dz3zwds33Oy9g+v+6nQbahZ02+syhKFYSXQ==} + '@testing-library/user-event@14.6.1': + resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + + '@thi.ng/bitstream@2.4.37': + resolution: {integrity: sha512-ghVt+/73cChlhHDNQH9+DnxvoeVYYBu7AYsS0Gvwq25fpCa4LaqnEk5LAJfsY043HInwcV7/0KGO7P+XZCzumQ==} + engines: {node: '>=18'} + + '@thi.ng/errors@2.6.0': + resolution: {integrity: sha512-wBfSWz81sqM1FWX2ucW9KGLSFzGvsBxwX5y5t6Oty0QWO9mY8JIZC+ZBPzX5E6ExZiuGIgM8NtkTboTnXXlfUQ==} engines: {node: '>=18'} '@tokenizer/inflate@0.4.1': @@ -1089,6 +1195,9 @@ packages: '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + '@types/body-parser@1.19.6': resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} @@ -1155,6 +1264,22 @@ packages: '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@vitest/browser-playwright@4.0.16': + resolution: {integrity: sha512-I2Fy/ANdphi1yI46d15o0M1M4M0UJrUiVKkH5oKeRZZCdPg0fw/cfTKZzv9Ge9eobtJYp4BGblMzXdXH0vcl5g==} + peerDependencies: + playwright: '*' + vitest: 4.0.16 + + '@vitest/browser-preview@4.0.16': + resolution: {integrity: sha512-dfxJs4D5qSst4zY25txsklu0ZGPSQUhCq4VUuO2aOYtOO5+2EH7Dil37BTf1PG6DDdM8kF8NjAvnvZfsE2uzAQ==} + peerDependencies: + vitest: 4.0.16 + + '@vitest/browser@4.0.16': + resolution: {integrity: sha512-t4toy8X/YTnjYEPoY0pbDBg3EvDPg1elCDrfc+VupPHwoN/5/FNQ8Z+xBYIaEnOE2vVEyKwqYBzZ9h9rJtZVcg==} + peerDependencies: + vitest: 4.0.16 + '@vitest/coverage-v8@4.0.16': resolution: {integrity: sha512-2rNdjEIsPRzsdu6/9Eq0AYAzYdpP6Bx9cje9tL3FE5XzXRQF1fNU9pe/1yE8fCrS0HD+fBtt6gLPh6LI57tX7A==} peerDependencies: @@ -1270,6 +1395,10 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + ansi-styles@6.2.3: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} @@ -1284,12 +1413,15 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} - ast-v8-to-istanbul@0.3.9: - resolution: {integrity: sha512-dSC6tJeOJxbZrPzPbv5mMd6CMiQ1ugaVXXPRad2fXUSsy1kstFn9XQWemV9VW7Y7kpxgQ/4WMoZfwdH8XSU48w==} + ast-v8-to-istanbul@0.3.10: + resolution: {integrity: sha512-p4K7vMz2ZSk3wN8l5o3y2bJAoZXT3VuJI5OLTATY/01CYWumWvwkUw0SqDBnNq6IiTO3qDa1eSQDibAV8g7XOQ==} async-mutex@0.5.0: resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==} @@ -1370,8 +1502,8 @@ packages: resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} - chai@6.2.1: - resolution: {integrity: sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==} + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} chalk@4.1.2: @@ -1481,6 +1613,10 @@ packages: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} @@ -1502,6 +1638,9 @@ packages: docx-preview@0.3.7: resolution: {integrity: sha512-Lav69CTA/IYZPJTsKH7oYeoZjyg96N0wEJMNslGJnZJ+dMUZK85Lt5ASC79yUlD48ecWjuv+rkcmFt6EVPV0Xg==} + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + dotenv@17.2.3: resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} engines: {node: '>=12'} @@ -1599,8 +1738,8 @@ packages: fast-uri@3.1.0: resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} - fastq@1.19.1: - resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} @@ -1615,8 +1754,8 @@ packages: resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} engines: {node: ^12.20 || >= 14.13} - file-type@21.1.1: - resolution: {integrity: sha512-ifJXo8zUqbQ/bLbl9sFoqHNTNWbnPY1COImFfM6CCy7z+E+jC1eY9YfOKkx0fckIg+VljAy2/87T61fp0+eEkg==} + file-type@21.2.0: + resolution: {integrity: sha512-vCYBgFOrJQLoTzDyAXAL/RFfKnXXpUYt4+tipVy26nJJhT7ftgGETf2tAQF59EEL61i3MrorV/PG6tf7LJK7eg==} engines: {node: '>=20'} fill-range@7.1.1: @@ -1643,6 +1782,11 @@ packages: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1833,6 +1977,9 @@ packages: js-base64@3.7.8: resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==} + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-tokens@9.0.1: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} @@ -1946,14 +2093,14 @@ packages: linkify-it@5.0.0: resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} - lit-element@4.2.1: - resolution: {integrity: sha512-WGAWRGzirAgyphK2urmYOV72tlvnxw7YfyLDgQ+OZnM9vQQBQnumQ7jUJe6unEzwGU3ahFOjuz1iz1jjrpCPuw==} + lit-element@4.2.2: + resolution: {integrity: sha512-aFKhNToWxoyhkNDmWZwEva2SlQia+jfG0fjIWV//YeTaWrVnOxD89dPKfigCUspXFmjzOEUQpOkejH5Ly6sG0w==} - lit-html@3.3.1: - resolution: {integrity: sha512-S9hbyDu/vs1qNrithiNyeyv64c9yqiW9l+DBgI18fL+MTvOtWoFR0FWiyq1TxaYef5wNlpEmzlXoBlZEO+WjoA==} + lit-html@3.3.2: + resolution: {integrity: sha512-Qy9hU88zcmaxBXcc10ZpdK7cOLXvXpRoBxERdtqV9QOrfpMZZ6pSYP91LhpPtap3sFMUiL7Tw2RImbe0Al2/kw==} - lit@3.3.1: - resolution: {integrity: sha512-Ksr/8L3PTapbdXJCk+EJVB78jDodUMaP54gD24W186zGRARvwrsPfS60wae/SSCTCNZVPd1chXqio1qHQmu4NA==} + lit@3.3.2: + resolution: {integrity: sha512-NF9zbsP79l4ao2SNrH3NkfmFgN/hBYSQo90saIVI1o5GpjAdCPVstVzO1MrLOakHoEhYkrtRjPK6Ob521aoYWQ==} lodash.snakecase@4.1.1: resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} @@ -1980,6 +2127,10 @@ packages: lucide@0.562.0: resolution: {integrity: sha512-k1Fb8ZMnRQovWRlea7Jr0b9UKA29IM7/cu79+mJrhVohvA2YC/Ti3Sk+G+h/SIu3IlrKT4RAbWMHUBBQd1O6XA==} + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + magic-bytes.js@1.12.1: resolution: {integrity: sha512-ThQLOhN86ZkJ7qemtVRGYM+gRgR8GEXNli9H/PMvpnZsE44Xfh3wx9kGJaldg314v85m+bFW6WBMaVHJc/c3zA==} @@ -2056,6 +2207,10 @@ packages: mpg123-decoder@1.0.3: resolution: {integrity: sha512-+fjxnWigodWJm3+4pndi+KUg9TBojgn31DPk85zEsim7C6s0X5Ztc/hQYdytXkwuGXH+aB0/aEkG40Emukv6oQ==} + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -2148,8 +2303,8 @@ packages: resolution: {integrity: sha512-LDDSIu5J/4D4gFUuQQIEQpAC6maNEbMg4nC8JL/+Pe0cUDR86dtVZ09E2x5MwCh8f9yfktoaxt5x6UIVyzrajg==} hasBin: true - oxlint@1.35.0: - resolution: {integrity: sha512-QDX1aUgaiqznkGfTM2qHwva2wtKqhVoqPSVXrnPz+yLUhlNadikD3QRuRtppHl7WGuy3wG6nKAuR8lash3aWSg==} + oxlint@1.36.0: + resolution: {integrity: sha512-IicUdXfXgI8OKrDPnoSjvBfeEF8PkKtm+CoLlg4LYe4ypc8U+T4r7730XYshdBGZdelg+JRw8GtCb2w/KaaZvw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -2230,19 +2385,36 @@ packages: resolution: {integrity: sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==} hasBin: true + pixelmatch@7.1.0: + resolution: {integrity: sha512-1wrVzJ2STrpmONHKBy228LM1b84msXDUoAzVEl0R8Mz4Ce6EPr+IVtxm8+yvrqLYMHswREkjYFaMxnyGnaY3Ng==} + hasBin: true + playwright-core@1.57.0: resolution: {integrity: sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ==} engines: {node: '>=18'} hasBin: true + playwright@1.57.0: + resolution: {integrity: sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw==} + engines: {node: '>=18'} + hasBin: true + pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} + pngjs@7.0.0: + resolution: {integrity: sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==} + engines: {node: '>=14.19.0'} + postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} @@ -2283,8 +2455,8 @@ packages: resolution: {integrity: sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==} hasBin: true - qs@6.14.0: - resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + qs@6.14.1: + resolution: {integrity: sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==} engines: {node: '>=0.6'} queue-microtask@1.2.3: @@ -2304,6 +2476,9 @@ packages: resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} engines: {node: '>= 0.10'} + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} @@ -2351,6 +2526,11 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + rolldown@1.0.0-beta.57: + resolution: {integrity: sha512-lMMxcNN71GMsSko8RyeTaFoATHkCh4IWU7pYF73ziMYjhHZWfVesC6GQ+iaJCvZmVjvgSks9Ks1aaqEkBd8udg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rollup@4.54.0: resolution: {integrity: sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -2444,6 +2624,10 @@ packages: simple-yenc@1.0.4: resolution: {integrity: sha512-5gvxpSd79e9a3V4QDYUqnqxeD4HGlhCakVpb6gMnDD7lexJggSBJRBO5h52y/iJrdXRilX9UCuDaIJhSWm5OWw==} + sirv@3.0.2: + resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} + engines: {node: '>=18'} + sonic-boom@4.2.0: resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} @@ -2562,6 +2746,10 @@ packages: resolution: {integrity: sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ==} engines: {node: '>=14.16'} + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} @@ -2818,8 +3006,8 @@ packages: resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} engines: {node: '>=10'} - zod-to-json-schema@3.25.0: - resolution: {integrity: sha512-HvWtU2UG41LALjajJrML6uQejQhNJx+JBO9IflpSja4R03iNWfKXrj6W2h7ljuLyc1nKS+9yDyL/9tD1U/yBnQ==} + zod-to-json-schema@3.25.1: + resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} peerDependencies: zod: ^3.25 || ^4 @@ -2837,6 +3025,13 @@ snapshots: optionalDependencies: zod: 4.2.1 + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + optional: true + '@babel/helper-string-parser@7.27.1': {} '@babel/helper-validator-identifier@7.28.5': {} @@ -2891,11 +3086,11 @@ snapshots: '@borewit/text-codec@0.1.1': {} - '@borewit/text-codec@0.2.0': {} + '@borewit/text-codec@0.2.1': {} - '@cacheable/memory@2.0.6': + '@cacheable/memory@2.0.7': dependencies: - '@cacheable/utils': 2.3.2 + '@cacheable/utils': 2.3.3 '@keyv/bigmap': 1.3.0(keyv@5.5.5) hookified: 1.14.0 keyv: 5.5.5 @@ -2906,7 +3101,7 @@ snapshots: hookified: 1.14.0 keyv: 5.5.5 - '@cacheable/utils@2.3.2': + '@cacheable/utils@2.3.3': dependencies: hashery: 1.3.0 keyv: 5.5.5 @@ -3218,22 +3413,22 @@ snapshots: '@keyv/serialize@1.1.1': {} - '@lit-labs/signals@0.1.3': + '@lit-labs/signals@0.2.0': dependencies: - lit: 3.3.1 + lit: 3.3.2 signal-polyfill: 0.2.2 - '@lit-labs/ssr-dom-shim@1.4.0': {} + '@lit-labs/ssr-dom-shim@1.5.0': {} '@lit/context@1.1.6': dependencies: - '@lit/reactive-element': 2.1.1 + '@lit/reactive-element': 2.1.2 - '@lit/reactive-element@2.1.1': + '@lit/reactive-element@2.1.2': dependencies: - '@lit-labs/ssr-dom-shim': 1.4.0 + '@lit-labs/ssr-dom-shim': 1.5.0 - '@mariozechner/mini-lit@0.2.1(lit@3.3.1)(tailwindcss@4.1.17)': + '@mariozechner/mini-lit@0.2.1(lit@3.3.2)(tailwindcss@4.1.17)': dependencies: '@preact/signals-core': 1.12.1 class-variance-authority: 0.7.1 @@ -3241,7 +3436,7 @@ snapshots: highlight.js: 11.11.1 html-parse-string: 0.0.9 katex: 0.16.27 - lit: 3.3.1 + lit: 3.3.2 lucide: 0.544.0 marked: 16.4.2 tailwind-merge: 3.4.0 @@ -3267,13 +3462,13 @@ snapshots: '@anthropic-ai/sdk': 0.71.2(zod@4.2.1) '@google/genai': 1.34.0 '@mistralai/mistralai': 1.10.0 - '@sinclair/typebox': 0.34.41 + '@sinclair/typebox': 0.34.45 ajv: 8.17.1 ajv-formats: 3.0.1(ajv@8.17.1) chalk: 5.6.2 openai: 6.10.0(ws@8.18.3)(zod@4.2.1) partial-json: 0.1.7 - zod-to-json-schema: 3.25.0(zod@4.2.1) + zod-to-json-schema: 3.25.1(zod@4.2.1) transitivePeerDependencies: - '@modelcontextprotocol/sdk' - bufferutil @@ -3290,7 +3485,7 @@ snapshots: chalk: 5.6.2 cli-highlight: 2.1.11 diff: 8.0.2 - file-type: 21.1.1 + file-type: 21.2.0 glob: 11.1.0 jiti: 2.6.1 marked: 15.0.12 @@ -3313,9 +3508,9 @@ snapshots: '@mistralai/mistralai@1.10.0': dependencies: zod: 3.25.76 - zod-to-json-schema: 3.25.0(zod@3.25.76) + zod-to-json-schema: 3.25.1(zod@3.25.76) - '@napi-rs/wasm-runtime@1.1.0': + '@napi-rs/wasm-runtime@1.1.1': dependencies: '@emnapi/core': 1.7.1 '@emnapi/runtime': 1.7.1 @@ -3332,7 +3527,7 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.1 + fastq: 1.20.1 '@oxc-project/runtime@0.103.0': {} @@ -3356,28 +3551,28 @@ snapshots: '@oxlint-tsgolint/win32-x64@0.10.0': optional: true - '@oxlint/darwin-arm64@1.35.0': + '@oxlint/darwin-arm64@1.36.0': optional: true - '@oxlint/darwin-x64@1.35.0': + '@oxlint/darwin-x64@1.36.0': optional: true - '@oxlint/linux-arm64-gnu@1.35.0': + '@oxlint/linux-arm64-gnu@1.36.0': optional: true - '@oxlint/linux-arm64-musl@1.35.0': + '@oxlint/linux-arm64-musl@1.36.0': optional: true - '@oxlint/linux-x64-gnu@1.35.0': + '@oxlint/linux-x64-gnu@1.36.0': optional: true - '@oxlint/linux-x64-musl@1.35.0': + '@oxlint/linux-x64-musl@1.36.0': optional: true - '@oxlint/win32-arm64@1.35.0': + '@oxlint/win32-arm64@1.36.0': optional: true - '@oxlint/win32-x64@1.35.0': + '@oxlint/win32-x64@1.36.0': optional: true '@pinojs/redact@0.4.0': {} @@ -3385,6 +3580,8 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true + '@polka/url@1.0.0-next.29': {} + '@preact/signals-core@1.12.1': {} '@protobufjs/aspromise@1.1.2': {} @@ -3413,46 +3610,89 @@ snapshots: '@rolldown/binding-android-arm64@1.0.0-beta.55': optional: true + '@rolldown/binding-android-arm64@1.0.0-beta.57': + optional: true + '@rolldown/binding-darwin-arm64@1.0.0-beta.55': optional: true + '@rolldown/binding-darwin-arm64@1.0.0-beta.57': + optional: true + '@rolldown/binding-darwin-x64@1.0.0-beta.55': optional: true + '@rolldown/binding-darwin-x64@1.0.0-beta.57': + optional: true + '@rolldown/binding-freebsd-x64@1.0.0-beta.55': optional: true + '@rolldown/binding-freebsd-x64@1.0.0-beta.57': + optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.55': optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.57': + optional: true + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.55': optional: true + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.57': + optional: true + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.55': optional: true + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.57': + optional: true + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.55': optional: true + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.57': + optional: true + '@rolldown/binding-linux-x64-musl@1.0.0-beta.55': optional: true + '@rolldown/binding-linux-x64-musl@1.0.0-beta.57': + optional: true + '@rolldown/binding-openharmony-arm64@1.0.0-beta.55': optional: true + '@rolldown/binding-openharmony-arm64@1.0.0-beta.57': + optional: true + '@rolldown/binding-wasm32-wasi@1.0.0-beta.55': dependencies: - '@napi-rs/wasm-runtime': 1.1.0 + '@napi-rs/wasm-runtime': 1.1.1 + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.57': + dependencies: + '@napi-rs/wasm-runtime': 1.1.1 optional: true '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.55': optional: true + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.57': + optional: true + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.55': optional: true + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.57': + optional: true + '@rolldown/pluginutils@1.0.0-beta.55': {} + '@rolldown/pluginutils@1.0.0-beta.57': {} + '@rollup/rollup-android-arm-eabi@4.54.0': optional: true @@ -3528,16 +3768,33 @@ snapshots: '@sapphire/snowflake@3.5.3': {} - '@sinclair/typebox@0.34.41': {} + '@sinclair/typebox@0.34.45': {} '@standard-schema/spec@1.1.0': {} - '@thi.ng/bitstream@2.4.36': + '@testing-library/dom@10.4.1': dependencies: - '@thi.ng/errors': 2.5.50 + '@babel/code-frame': 7.27.1 + '@babel/runtime': 7.28.4 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + picocolors: 1.1.1 + pretty-format: 27.5.1 optional: true - '@thi.ng/errors@2.5.50': + '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)': + dependencies: + '@testing-library/dom': 10.4.1 + optional: true + + '@thi.ng/bitstream@2.4.37': + dependencies: + '@thi.ng/errors': 2.6.0 + optional: true + + '@thi.ng/errors@2.6.0': optional: true '@tokenizer/inflate@0.4.1': @@ -3554,6 +3811,9 @@ snapshots: tslib: 2.8.1 optional: true + '@types/aria-query@5.0.4': + optional: true + '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 @@ -3627,11 +3887,72 @@ snapshots: dependencies: '@types/node': 25.0.3 - '@vitest/coverage-v8@4.0.16(vitest@4.0.16(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/browser-playwright@4.0.16(playwright@1.57.0)(vite@8.0.0-beta.3(@types/node@25.0.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.16)': + dependencies: + '@vitest/browser': 4.0.16(vite@8.0.0-beta.3(@types/node@25.0.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.16) + '@vitest/mocker': 4.0.16(vite@8.0.0-beta.3(@types/node@25.0.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + playwright: 1.57.0 + tinyrainbow: 3.0.3 + vitest: 4.0.16(@types/node@25.0.3)(@vitest/browser-playwright@4.0.16)(@vitest/browser-preview@4.0.16)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite + + '@vitest/browser-preview@4.0.16(vite@8.0.0-beta.3(@types/node@25.0.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.16)': + dependencies: + '@testing-library/dom': 10.4.1 + '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.1) + '@vitest/browser': 4.0.16(vite@8.0.0-beta.3(@types/node@25.0.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.16) + vitest: 4.0.16(@types/node@25.0.3)(@vitest/browser-playwright@4.0.16)(@vitest/browser-preview@4.0.16)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite + optional: true + + '@vitest/browser@4.0.16(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.16)': + dependencies: + '@vitest/mocker': 4.0.16(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/utils': 4.0.16 + magic-string: 0.30.21 + pixelmatch: 7.1.0 + pngjs: 7.0.0 + sirv: 3.0.2 + tinyrainbow: 3.0.3 + vitest: 4.0.16(@types/node@25.0.3)(@vitest/browser-playwright@4.0.16)(@vitest/browser-preview@4.0.16)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + ws: 8.18.3 + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite + optional: true + + '@vitest/browser@4.0.16(vite@8.0.0-beta.3(@types/node@25.0.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.16)': + dependencies: + '@vitest/mocker': 4.0.16(vite@8.0.0-beta.3(@types/node@25.0.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/utils': 4.0.16 + magic-string: 0.30.21 + pixelmatch: 7.1.0 + pngjs: 7.0.0 + sirv: 3.0.2 + tinyrainbow: 3.0.3 + vitest: 4.0.16(@types/node@25.0.3)(@vitest/browser-playwright@4.0.16)(@vitest/browser-preview@4.0.16)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + ws: 8.18.3 + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite + + '@vitest/coverage-v8@4.0.16(@vitest/browser@4.0.16(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.16))(vitest@4.0.16)': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.0.16 - ast-v8-to-istanbul: 0.3.9 + ast-v8-to-istanbul: 0.3.10 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 @@ -3640,7 +3961,9 @@ snapshots: obug: 2.1.1 std-env: 3.10.0 tinyrainbow: 3.0.3 - vitest: 4.0.16(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vitest: 4.0.16(@types/node@25.0.3)(@vitest/browser-playwright@4.0.16)(@vitest/browser-preview@4.0.16)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + optionalDependencies: + '@vitest/browser': 4.0.16(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.16) transitivePeerDependencies: - supports-color @@ -3650,7 +3973,7 @@ snapshots: '@types/chai': 5.2.3 '@vitest/spy': 4.0.16 '@vitest/utils': 4.0.16 - chai: 6.2.1 + chai: 6.2.2 tinyrainbow: 3.0.3 '@vitest/mocker@4.0.16(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))': @@ -3661,6 +3984,14 @@ snapshots: optionalDependencies: vite: 7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + '@vitest/mocker@4.0.16(vite@8.0.0-beta.3(@types/node@25.0.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))': + dependencies: + '@vitest/spy': 4.0.16 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 8.0.0-beta.3(@types/node@25.0.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + '@vitest/pretty-format@4.0.16': dependencies: tinyrainbow: 3.0.3 @@ -3769,6 +4100,9 @@ snapshots: dependencies: color-convert: 2.0.1 + ansi-styles@5.2.0: + optional: true + ansi-styles@6.2.3: {} any-promise@1.3.0: {} @@ -3780,9 +4114,14 @@ snapshots: argparse@2.0.1: {} + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + optional: true + assertion-error@2.0.1: {} - ast-v8-to-istanbul@0.3.9: + ast-v8-to-istanbul@0.3.10: dependencies: '@jridgewell/trace-mapping': 0.3.31 estree-walker: 3.0.3 @@ -3830,7 +4169,7 @@ snapshots: http-errors: 2.0.1 iconv-lite: 0.7.1 on-finished: 2.4.1 - qs: 6.14.0 + qs: 6.14.1 raw-body: 3.0.2 type-is: 2.0.1 transitivePeerDependencies: @@ -3865,8 +4204,8 @@ snapshots: cacheable@2.3.1: dependencies: - '@cacheable/memory': 2.0.6 - '@cacheable/utils': 2.3.2 + '@cacheable/memory': 2.0.7 + '@cacheable/utils': 2.3.3 hookified: 1.14.0 keyv: 5.5.5 qified: 0.5.3 @@ -3881,7 +4220,7 @@ snapshots: call-bind-apply-helpers: 1.0.2 get-intrinsic: 1.3.0 - chai@6.2.1: {} + chai@6.2.2: {} chalk@4.1.2: dependencies: @@ -3982,6 +4321,9 @@ snapshots: depd@2.0.0: {} + dequal@2.0.3: + optional: true + detect-libc@2.1.2: {} devtools-protocol@0.0.1561482: {} @@ -4013,6 +4355,9 @@ snapshots: dependencies: jszip: 3.10.1 + dom-accessibility-api@0.5.16: + optional: true + dotenv@17.2.3: {} dunder-proto@1.0.1: @@ -4116,7 +4461,7 @@ snapshots: once: 1.4.0 parseurl: 1.3.3 proxy-addr: 2.0.7 - qs: 6.14.0 + qs: 6.14.1 range-parser: 1.2.1 router: 2.2.0 send: 1.2.1 @@ -4141,7 +4486,7 @@ snapshots: fast-uri@3.1.0: {} - fastq@1.19.1: + fastq@1.20.1: dependencies: reusify: 1.1.0 @@ -4154,7 +4499,7 @@ snapshots: node-domexception: 1.0.0 web-streams-polyfill: 3.3.3 - file-type@21.1.1: + file-type@21.2.0: dependencies: '@tokenizer/inflate': 0.4.1 strtok3: 10.3.4 @@ -4191,6 +4536,9 @@ snapshots: fresh@2.0.0: {} + fsevents@2.3.2: + optional: true + fsevents@2.3.3: optional: true @@ -4402,6 +4750,9 @@ snapshots: js-base64@3.7.8: {} + js-tokens@4.0.0: + optional: true + js-tokens@9.0.1: {} json-bigint@1.0.0: @@ -4502,21 +4853,21 @@ snapshots: dependencies: uc.micro: 2.1.0 - lit-element@4.2.1: + lit-element@4.2.2: dependencies: - '@lit-labs/ssr-dom-shim': 1.4.0 - '@lit/reactive-element': 2.1.1 - lit-html: 3.3.1 + '@lit-labs/ssr-dom-shim': 1.5.0 + '@lit/reactive-element': 2.1.2 + lit-html: 3.3.2 - lit-html@3.3.1: + lit-html@3.3.2: dependencies: '@types/trusted-types': 2.0.7 - lit@3.3.1: + lit@3.3.2: dependencies: - '@lit/reactive-element': 2.1.1 - lit-element: 4.2.1 - lit-html: 3.3.1 + '@lit/reactive-element': 2.1.2 + lit-element: 4.2.2 + lit-html: 3.3.2 lodash.snakecase@4.1.1: {} @@ -4534,6 +4885,9 @@ snapshots: lucide@0.562.0: {} + lz-string@1.5.0: + optional: true + magic-bytes.js@1.12.1: {} magic-string@0.30.21: @@ -4601,15 +4955,17 @@ snapshots: '@wasm-audio-decoders/common': 9.0.7 optional: true + mrmime@2.0.1: {} + ms@2.1.3: {} music-metadata@11.10.3: dependencies: - '@borewit/text-codec': 0.2.0 + '@borewit/text-codec': 0.2.1 '@tokenizer/token': 0.3.0 content-type: 1.0.5 debug: 4.4.3 - file-type: 21.1.1 + file-type: 21.2.0 media-typer: 1.1.0 strtok3: 10.3.4 token-types: 6.1.1 @@ -4691,16 +5047,16 @@ snapshots: '@oxlint-tsgolint/win32-arm64': 0.10.0 '@oxlint-tsgolint/win32-x64': 0.10.0 - oxlint@1.35.0(oxlint-tsgolint@0.10.0): + oxlint@1.36.0(oxlint-tsgolint@0.10.0): optionalDependencies: - '@oxlint/darwin-arm64': 1.35.0 - '@oxlint/darwin-x64': 1.35.0 - '@oxlint/linux-arm64-gnu': 1.35.0 - '@oxlint/linux-arm64-musl': 1.35.0 - '@oxlint/linux-x64-gnu': 1.35.0 - '@oxlint/linux-x64-musl': 1.35.0 - '@oxlint/win32-arm64': 1.35.0 - '@oxlint/win32-x64': 1.35.0 + '@oxlint/darwin-arm64': 1.36.0 + '@oxlint/darwin-x64': 1.36.0 + '@oxlint/linux-arm64-gnu': 1.36.0 + '@oxlint/linux-arm64-musl': 1.36.0 + '@oxlint/linux-x64-gnu': 1.36.0 + '@oxlint/linux-x64-musl': 1.36.0 + '@oxlint/win32-arm64': 1.36.0 + '@oxlint/win32-x64': 1.36.0 oxlint-tsgolint: 0.10.0 p-queue@9.0.1: @@ -4770,16 +5126,35 @@ snapshots: sonic-boom: 4.2.0 thread-stream: 3.1.0 + pixelmatch@7.1.0: + dependencies: + pngjs: 7.0.0 + playwright-core@1.57.0: {} + playwright@1.57.0: + dependencies: + playwright-core: 1.57.0 + optionalDependencies: + fsevents: 2.3.2 + pluralize@8.0.0: {} + pngjs@7.0.0: {} + postcss@8.5.6: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + optional: true + process-nextick-args@2.0.1: {} process-warning@5.0.0: {} @@ -4836,12 +5211,12 @@ snapshots: qoa-format@1.0.1: dependencies: - '@thi.ng/bitstream': 2.4.36 + '@thi.ng/bitstream': 2.4.37 optional: true qrcode-terminal@0.12.0: {} - qs@6.14.0: + qs@6.14.1: dependencies: side-channel: 1.1.0 @@ -4877,6 +5252,9 @@ snapshots: iconv-lite: 0.7.1 unpipe: 1.0.0 + react-is@17.0.2: + optional: true + readable-stream@2.3.8: dependencies: core-util-is: 1.0.3 @@ -4936,6 +5314,25 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.55 '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.55 + rolldown@1.0.0-beta.57: + dependencies: + '@oxc-project/types': 0.103.0 + '@rolldown/pluginutils': 1.0.0-beta.57 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-beta.57 + '@rolldown/binding-darwin-arm64': 1.0.0-beta.57 + '@rolldown/binding-darwin-x64': 1.0.0-beta.57 + '@rolldown/binding-freebsd-x64': 1.0.0-beta.57 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.57 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.57 + '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.57 + '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.57 + '@rolldown/binding-linux-x64-musl': 1.0.0-beta.57 + '@rolldown/binding-openharmony-arm64': 1.0.0-beta.57 + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.57 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.57 + '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.57 + rollup@4.54.0: dependencies: '@types/estree': 1.0.8 @@ -5097,6 +5494,12 @@ snapshots: simple-yenc@1.0.4: optional: true + sirv@3.0.2: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + sonic-boom@4.2.0: dependencies: atomic-sleep: 1.0.0 @@ -5206,6 +5609,8 @@ snapshots: '@tokenizer/token': 0.3.0 ieee754: 1.2.1 + totalist@3.0.1: {} + tr46@0.0.3: {} ts-algebra@2.0.0: {} @@ -5295,7 +5700,7 @@ snapshots: tsx: 4.21.0 yaml: 2.8.2 - vitest@4.0.16(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2): + vitest@4.0.16(@types/node@25.0.3)(@vitest/browser-playwright@4.0.16)(@vitest/browser-preview@4.0.16)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@vitest/expect': 4.0.16 '@vitest/mocker': 4.0.16(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) @@ -5319,6 +5724,8 @@ snapshots: why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 25.0.3 + '@vitest/browser-playwright': 4.0.16(playwright@1.57.0)(vite@8.0.0-beta.3(@types/node@25.0.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.16) + '@vitest/browser-preview': 4.0.16(vite@8.0.0-beta.3(@types/node@25.0.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.16) transitivePeerDependencies: - jiti - less @@ -5394,11 +5801,11 @@ snapshots: y18n: 5.0.8 yargs-parser: 20.2.9 - zod-to-json-schema@3.25.0(zod@3.25.76): + zod-to-json-schema@3.25.1(zod@3.25.76): dependencies: zod: 3.25.76 - zod-to-json-schema@3.25.0(zod@4.2.1): + zod-to-json-schema@3.25.1(zod@4.2.1): dependencies: zod: 4.2.1 diff --git a/ui/package.json b/ui/package.json index 9df8528b5..6c6e1ba95 100644 --- a/ui/package.json +++ b/ui/package.json @@ -5,13 +5,17 @@ "scripts": { "dev": "vite", "build": "vite build", - "preview": "vite preview" + "preview": "vite preview", + "test": "vitest run --config vitest.config.ts" }, "dependencies": { - "lit": "^3.3.1" + "lit": "^3.3.2" }, "devDependencies": { + "@vitest/browser-playwright": "4.0.16", + "playwright": "^1.57.0", "typescript": "^5.9.3", - "vite": "8.0.0-beta.3" + "vite": "8.0.0-beta.3", + "vitest": "4.0.16" } -} \ No newline at end of file +} diff --git a/ui/src/ui/app-render.ts b/ui/src/ui/app-render.ts index 6558a70e8..1130954dc 100644 --- a/ui/src/ui/app-render.ts +++ b/ui/src/ui/app-render.ts @@ -1,7 +1,13 @@ import { html, nothing } from "lit"; import type { GatewayBrowserClient, GatewayHelloOk } from "./gateway"; -import { TAB_GROUPS, subtitleForTab, titleForTab, type Tab } from "./navigation"; +import { + TAB_GROUPS, + pathForTab, + subtitleForTab, + titleForTab, + type Tab, +} from "./navigation"; import type { ConfigSnapshot, CronJob, @@ -51,6 +57,7 @@ export type AppViewState = { settings: { gatewayUrl: string; token: string; sessionKey: string }; password: string; tab: Tab; + basePath: string; connected: boolean; hello: GatewayHelloOk | null; lastError: string | null; @@ -352,12 +359,27 @@ export function renderApp(state: AppViewState) { } function renderTab(state: AppViewState, tab: Tab) { + const href = pathForTab(tab, state.basePath); return html` - + `; } diff --git a/ui/src/ui/app.ts b/ui/src/ui/app.ts index 4eacbb840..c206d67c9 100644 --- a/ui/src/ui/app.ts +++ b/ui/src/ui/app.ts @@ -4,7 +4,7 @@ import { customElement, state } from "lit/decorators.js"; import { GatewayBrowserClient, type GatewayEventFrame, type GatewayHelloOk } from "./gateway"; import { loadSettings, saveSettings, type UiSettings } from "./storage"; import { renderApp } from "./app-render"; -import type { Tab } from "./navigation"; +import { normalizePath, pathForTab, tabFromPath, type Tab } from "./navigation"; import type { ConfigSnapshot, CronJob, @@ -157,6 +157,8 @@ export class ClawdisApp extends LitElement { client: GatewayBrowserClient | null = null; private chatScrollFrame: number | null = null; + basePath = ""; + private popStateHandler = () => this.onPopState(); createRenderRoot() { return this; @@ -164,9 +166,17 @@ export class ClawdisApp extends LitElement { connectedCallback() { super.connectedCallback(); + this.basePath = this.inferBasePath(); + this.syncTabWithLocation(true); + window.addEventListener("popstate", this.popStateHandler); this.connect(); } + disconnectedCallback() { + window.removeEventListener("popstate", this.popStateHandler); + super.disconnectedCallback(); + } + protected updated(changed: Map) { if ( this.tab === "chat" && @@ -264,8 +274,9 @@ export class ClawdisApp extends LitElement { } setTab(next: Tab) { - this.tab = next; + if (this.tab !== next) this.tab = next; void this.refreshActiveTab(); + this.syncUrlWithTab(next, false); } private async refreshActiveTab() { @@ -276,11 +287,54 @@ export class ClawdisApp extends LitElement { if (this.tab === "cron") await this.loadCron(); if (this.tab === "skills") await loadSkills(this); if (this.tab === "nodes") await loadNodes(this); - if (this.tab === "chat") await loadChatHistory(this); + if (this.tab === "chat") { + await loadChatHistory(this); + this.scheduleChatScroll(); + } if (this.tab === "config") await loadConfig(this); if (this.tab === "debug") await loadDebug(this); } + private inferBasePath() { + if (typeof window === "undefined") return ""; + const path = window.location.pathname; + if (path === "/ui" || path.startsWith("/ui/")) return "/ui"; + return ""; + } + + private syncTabWithLocation(replace: boolean) { + if (typeof window === "undefined") return; + const resolved = tabFromPath(window.location.pathname, this.basePath) ?? "chat"; + this.setTabFromRoute(resolved); + this.syncUrlWithTab(resolved, replace); + } + + private onPopState() { + if (typeof window === "undefined") return; + const resolved = tabFromPath(window.location.pathname, this.basePath); + if (!resolved) return; + this.setTabFromRoute(resolved); + } + + private setTabFromRoute(next: Tab) { + if (this.tab !== next) this.tab = next; + if (this.connected) void this.refreshActiveTab(); + } + + private syncUrlWithTab(tab: Tab, replace: boolean) { + if (typeof window === "undefined") return; + const targetPath = normalizePath(pathForTab(tab, this.basePath)); + const currentPath = normalizePath(window.location.pathname); + if (currentPath === targetPath) return; + const url = new URL(window.location.href); + url.pathname = targetPath; + if (replace) { + window.history.replaceState({}, "", url.toString()); + } else { + window.history.pushState({}, "", url.toString()); + } + } + async loadOverview() { await Promise.all([ loadProviders(this, false), diff --git a/ui/src/ui/navigation.browser.test.ts b/ui/src/ui/navigation.browser.test.ts new file mode 100644 index 000000000..de8dd84ec --- /dev/null +++ b/ui/src/ui/navigation.browser.test.ts @@ -0,0 +1,93 @@ +import { afterEach, beforeEach, describe, expect, it } from "vitest"; + +import { ClawdisApp } from "./app"; + +const originalConnect = ClawdisApp.prototype.connect; + +function mountApp(pathname: string) { + window.history.replaceState({}, "", pathname); + const app = document.createElement("clawdis-app") as ClawdisApp; + document.body.append(app); + return app; +} + +function nextFrame() { + return new Promise((resolve) => { + requestAnimationFrame(() => resolve()); + }); +} + +beforeEach(() => { + ClawdisApp.prototype.connect = () => { + // no-op: avoid real gateway WS connections in browser tests + }; + document.body.innerHTML = ""; +}); + +afterEach(() => { + ClawdisApp.prototype.connect = originalConnect; + document.body.innerHTML = ""; +}); + +describe("control UI routing", () => { + it("hydrates the tab from the location", async () => { + const app = mountApp("/sessions"); + await app.updateComplete; + + expect(app.tab).toBe("sessions"); + expect(window.location.pathname).toBe("/sessions"); + }); + + it("respects /ui base paths", async () => { + const app = mountApp("/ui/cron"); + await app.updateComplete; + + expect(app.basePath).toBe("/ui"); + expect(app.tab).toBe("cron"); + expect(window.location.pathname).toBe("/ui/cron"); + }); + + it("updates the URL when clicking nav items", async () => { + const app = mountApp("/chat"); + await app.updateComplete; + + const link = app.querySelector( + 'a.nav-item[href="/connections"]', + ); + expect(link).not.toBeNull(); + link?.dispatchEvent( + new MouseEvent("click", { bubbles: true, cancelable: true, button: 0 }), + ); + + await app.updateComplete; + expect(app.tab).toBe("connections"); + expect(window.location.pathname).toBe("/connections"); + }); + + it("auto-scrolls chat history to the latest message", async () => { + const app = mountApp("/chat"); + await app.updateComplete; + + const initialContainer = app.querySelector(".messages") as HTMLElement | null; + expect(initialContainer).not.toBeNull(); + if (!initialContainer) return; + initialContainer.style.maxHeight = "180px"; + initialContainer.style.overflow = "auto"; + + app.chatMessages = Array.from({ length: 60 }, (_, index) => ({ + role: "assistant", + content: `Line ${index} - ${"x".repeat(200)}`, + timestamp: Date.now() + index, + })); + + await app.updateComplete; + await nextFrame(); + + const container = app.querySelector(".messages") as HTMLElement | null; + expect(container).not.toBeNull(); + if (!container) return; + const maxScroll = container.scrollHeight - container.clientHeight; + expect(maxScroll).toBeGreaterThan(0); + expect(container.scrollTop).toBe(maxScroll); + }); +}); diff --git a/ui/src/ui/navigation.ts b/ui/src/ui/navigation.ts index 6e74791d6..77ac49571 100644 --- a/ui/src/ui/navigation.ts +++ b/ui/src/ui/navigation.ts @@ -20,6 +20,64 @@ export type Tab = | "config" | "debug"; +const TAB_PATHS: Record = { + overview: "/overview", + connections: "/connections", + instances: "/instances", + sessions: "/sessions", + cron: "/cron", + skills: "/skills", + nodes: "/nodes", + chat: "/chat", + config: "/config", + debug: "/debug", +}; + +const PATH_TO_TAB = new Map( + Object.entries(TAB_PATHS).map(([tab, path]) => [path, tab as Tab]), +); + +function normalizeBasePath(basePath: string): string { + if (!basePath) return ""; + let base = basePath.trim(); + if (!base.startsWith("/")) base = `/${base}`; + if (base === "/") return ""; + if (base.endsWith("/")) base = base.slice(0, -1); + return base; +} + +export function normalizePath(path: string): string { + if (!path) return "/"; + let normalized = path.trim(); + if (!normalized.startsWith("/")) normalized = `/${normalized}`; + if (normalized.length > 1 && normalized.endsWith("/")) { + normalized = normalized.slice(0, -1); + } + return normalized; +} + +export function pathForTab(tab: Tab, basePath = ""): string { + const base = normalizeBasePath(basePath); + const path = TAB_PATHS[tab]; + return base ? `${base}${path}` : path; +} + +export function tabFromPath(pathname: string, basePath = ""): Tab | null { + const base = normalizeBasePath(basePath); + let path = pathname || "/"; + if (base) { + if (path === base) { + path = "/"; + } else if (path.startsWith(`${base}/`)) { + path = path.slice(base.length); + } + } + let normalized = normalizePath(path).toLowerCase(); + if (normalized.endsWith("/index.html")) normalized = "/"; + if (normalized === "/") return "chat"; + return PATH_TO_TAB.get(normalized) ?? null; +} + export function titleForTab(tab: Tab) { switch (tab) { case "overview": diff --git a/ui/vitest.config.ts b/ui/vitest.config.ts new file mode 100644 index 000000000..38d7342ff --- /dev/null +++ b/ui/vitest.config.ts @@ -0,0 +1,15 @@ +import { playwright } from "@vitest/browser-playwright"; +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + include: ["src/**/*.test.ts"], + browser: { + enabled: true, + provider: playwright(), + instances: [{ browser: "chromium", name: "chromium" }], + headless: true, + ui: false, + }, + }, +});