diff --git a/frontend/package.json b/frontend/package.json index f3b79ad16..3d0c5e6af 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -22,6 +22,16 @@ "i18n:mark": "i18n-unused mark-unused" }, "dependencies": { + "@codemirror/commands": "^6.8.1", + "@codemirror/lang-yaml": "^6.1.2", + "@codemirror/language": "^6.11.3", + "@codemirror/legacy-modes": "^6.5.2", + "@codemirror/lint": "^6.9.1", + "@codemirror/history": "^0.19.2", + "@codemirror/state": "^6.5.2", + "@codemirror/view": "^6.38.1", + "@lezer/highlight": "^1.2.1", + "@uiw/codemirror-themes": "^4.25.2", "@shikijs/monaco": "^3.20.0", "@sveltejs/adapter-static": "^3.0.10", "@sveltejs/kit": "^2.49.3", diff --git a/frontend/src/app.css b/frontend/src/app.css index b7c5d7a72..2ddf19a1b 100644 --- a/frontend/src/app.css +++ b/frontend/src/app.css @@ -424,6 +424,17 @@ main { overflow-x: hidden; } +/* Monaco editor widget positioning fixes - ensure suggestions align with cursor */ +.monaco-editor .suggest-widget { + z-index: 50; +} + +/* Allow Monaco suggestion widgets to overflow card boundaries when needed */ +.monaco-editor .monaco-editor-overlaymessage, +.monaco-editor .suggest-widget { + contain: none !important; +} + @media (max-width: 768px) { .mobile-centered-popover { position: fixed !important; diff --git a/frontend/src/lib/components/codemirror-code-editor/editor.svelte b/frontend/src/lib/components/codemirror-code-editor/editor.svelte new file mode 100644 index 000000000..9b3186fca --- /dev/null +++ b/frontend/src/lib/components/codemirror-code-editor/editor.svelte @@ -0,0 +1,176 @@ + + +
diff --git a/frontend/src/lib/components/codemirror-code-editor/theme.ts b/frontend/src/lib/components/codemirror-code-editor/theme.ts new file mode 100644 index 000000000..c7d824492 --- /dev/null +++ b/frontend/src/lib/components/codemirror-code-editor/theme.ts @@ -0,0 +1,85 @@ +import { tags as t } from '@lezer/highlight'; +import { createTheme, type CreateThemeOptions } from '@uiw/codemirror-themes'; + +function getAccentColor(): string { + if (typeof document === 'undefined') return 'oklch(0.606 0.25 292.717)'; + const primary = getComputedStyle(document.documentElement).getPropertyValue('--primary').trim(); + return primary || 'oklch(0.606 0.25 292.717)'; +} + +function getAccentColorWithAlpha(alpha: number): string { + const accent = getAccentColor(); + + if (accent.startsWith('oklch')) { + const hasAlpha = accent.includes('/'); + if (hasAlpha) { + return accent.replace(/\/\s*[\d.]+\s*\)/, ` / ${alpha})`); + } + return accent.replace(')', ` / ${alpha})`); + } + + if (accent.startsWith('#') && accent.length >= 7) { + const r = parseInt(accent.slice(1, 3), 16); + const g = parseInt(accent.slice(3, 5), 16); + const b = parseInt(accent.slice(5, 7), 16); + return `rgba(${r}, ${g}, ${b}, ${alpha})`; + } + + return accent; +} + +export function arcaneCodeMirrorTheme(options?: Partial) { + const { theme = 'dark', settings = {}, styles = [] } = options || {}; + + const accentColor = getAccentColor(); + const accentWithAlpha35 = getAccentColorWithAlpha(0.35); + const accentWithAlpha15 = getAccentColorWithAlpha(0.15); + const accentWithAlpha05 = getAccentColorWithAlpha(0.05); + + // Keep backgrounds transparent so the editor inherits the card background. + const dynamicSettings: CreateThemeOptions['settings'] = { + background: 'transparent', + foreground: 'hsl(var(--foreground))', + caret: accentColor, + selection: accentWithAlpha35, + selectionMatch: accentWithAlpha15, + lineHighlight: accentWithAlpha05, + gutterBackground: 'transparent', + gutterForeground: 'hsl(var(--muted-foreground))', + gutterActiveForeground: 'hsl(var(--foreground))', + gutterBorder: 'transparent', + + fontFamily: + '"Geist Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace' + }; + + // These colors mirror the project's previous CodeMirror implementation to ensure + // highlighting is clearly visible on mobile. + const dynamicStyles: CreateThemeOptions['styles'] = [ + { tag: [t.comment, t.meta], color: 'hsl(var(--muted-foreground))' }, + { tag: [t.keyword, t.modifier, t.operatorKeyword], color: '#ff7b72' }, + + { tag: [t.typeName, t.namespace, t.number, t.atom, t.bool], color: '#ffa657' }, + { tag: [t.function(t.variableName), t.labelName], color: accentColor }, + { tag: [t.className, t.definition(t.variableName), t.propertyName, t.attributeName], color: '#d2a8ff' }, + + { tag: [t.variableName, t.name], color: 'hsl(var(--foreground))' }, + { tag: [t.string, t.inserted, t.regexp, t.special(t.string)], color: '#7ee787' }, + { tag: [t.operator, t.url, t.link, t.escape], color: '#a5d6ff' }, + + { tag: [t.separator, t.punctuation], color: 'hsl(var(--muted-foreground))' }, + + { tag: t.heading, color: 'hsl(var(--foreground))', fontWeight: 'bold' }, + { tag: t.strong, fontWeight: 'bold' }, + { tag: t.emphasis, fontStyle: 'italic' }, + { tag: t.strikethrough, textDecoration: 'line-through' }, + { tag: t.invalid, color: 'hsl(var(--destructive))' }, + { tag: t.link, textDecoration: 'underline' } + ]; + + return createTheme({ + theme, + settings: { ...dynamicSettings, ...settings }, + styles: [...dynamicStyles, ...styles] + }); +} \ No newline at end of file diff --git a/frontend/src/lib/components/monaco-code-editor/editor.svelte b/frontend/src/lib/components/monaco-code-editor/editor.svelte index f511ac186..6fd35e394 100644 --- a/frontend/src/lib/components/monaco-code-editor/editor.svelte +++ b/frontend/src/lib/components/monaco-code-editor/editor.svelte @@ -102,9 +102,10 @@ minimap: { enabled: false }, scrollBeyondLastLine: false, wordWrap: 'on', - fixedOverflowWidgets: true, + fixedOverflowWidgets: false, dragAndDrop: false, contextmenu: true, + selectionClipboard: true, quickSuggestions: { other: true, comments: false, @@ -127,7 +128,7 @@ label: m.common_select_all(), contextMenuGroupId: '9_cutcopypaste', contextMenuOrder: 4, - run: (ed) => { + run: (ed: monaco.editor.IStandaloneCodeEditor) => { ed.focus(); const model = ed.getModel(); if (model) { @@ -184,8 +185,9 @@ theme, fontSize: parseInt(fontSize.replace('px', '')), wordWrap: 'on', - fixedOverflowWidgets: true, + fixedOverflowWidgets: false, dragAndDrop: false, + selectionClipboard: true, scrollbar: autoHeight ? { vertical: 'hidden', diff --git a/frontend/src/routes/(app)/projects/components/CodePanel.svelte b/frontend/src/routes/(app)/projects/components/CodePanel.svelte index c092ebde3..142df2e84 100644 --- a/frontend/src/routes/(app)/projects/components/CodePanel.svelte +++ b/frontend/src/routes/(app)/projects/components/CodePanel.svelte @@ -1,8 +1,10 @@ @@ -35,8 +39,10 @@ -
- {#if effectiveAutoHeight} +
+ {#if useMobileEditor} + + {:else if effectiveAutoHeight} {:else}
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index dcc86dfd3..a22c37f39 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -6,6 +6,17 @@ import { defineConfig } from 'vite'; import Icons from 'unplugin-icons/vite'; export default defineConfig({ + resolve: { + dedupe: [ + '@codemirror/state', + '@codemirror/view', + '@codemirror/language', + '@codemirror/commands', + '@codemirror/history', + '@codemirror/lang-yaml', + '@lezer/highlight' + ] + }, plugins: [ tailwindcss(), sveltekit(), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d3a612e76..6b9810bab 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -55,6 +55,33 @@ importers: frontend: dependencies: + '@codemirror/commands': + specifier: ^6.8.1 + version: 6.10.1 + '@codemirror/history': + specifier: ^0.19.2 + version: 0.19.2 + '@codemirror/lang-yaml': + specifier: ^6.1.2 + version: 6.1.2 + '@codemirror/language': + specifier: ^6.11.3 + version: 6.12.1 + '@codemirror/legacy-modes': + specifier: ^6.5.2 + version: 6.5.2 + '@codemirror/lint': + specifier: ^6.9.1 + version: 6.9.2 + '@codemirror/state': + specifier: ^6.5.2 + version: 6.5.3 + '@codemirror/view': + specifier: ^6.38.1 + version: 6.39.9 + '@lezer/highlight': + specifier: ^1.2.1 + version: 1.2.3 '@shikijs/monaco': specifier: ^3.20.0 version: 3.20.0 @@ -67,6 +94,9 @@ importers: '@tanstack/table-core': specifier: ^8.21.3 version: 8.21.3 + '@uiw/codemirror-themes': + specifier: ^4.25.2 + version: 4.25.4(@codemirror/language@6.12.1)(@codemirror/state@6.5.3)(@codemirror/view@6.39.9) '@xterm/addon-fit': specifier: ^0.11.0 version: 0.11.0 @@ -280,6 +310,48 @@ packages: resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} engines: {node: '>=6.9.0'} + '@codemirror/autocomplete@6.20.0': + resolution: {integrity: sha512-bOwvTOIJcG5FVo5gUUupiwYh8MioPLQ4UcqbcRf7UQ98X90tCa9E1kZ3Z7tqwpZxYyOvh1YTYbmZE9RTfTp5hg==} + + '@codemirror/commands@6.10.1': + resolution: {integrity: sha512-uWDWFypNdQmz2y1LaNJzK7fL7TYKLeUAU0npEC685OKTF3KcQ2Vu3klIM78D7I6wGhktme0lh3CuQLv0ZCrD9Q==} + + '@codemirror/history@0.19.2': + resolution: {integrity: sha512-unhP4t3N2smzmHoo/Yio6ueWi+il8gm9VKrvi6wlcdGH5fOfVDNkmjHQ495SiR+EdOG35+3iNebSPYww0vN7ow==} + deprecated: As of 0.20.0, this package has been merged into @codemirror/commands + + '@codemirror/lang-yaml@6.1.2': + resolution: {integrity: sha512-dxrfG8w5Ce/QbT7YID7mWZFKhdhsaTNOYjOkSIMt1qmC4VQnXSDSYVHHHn8k6kJUfIhtLo8t1JJgltlxWdsITw==} + + '@codemirror/language@6.12.1': + resolution: {integrity: sha512-Fa6xkSiuGKc8XC8Cn96T+TQHYj4ZZ7RdFmXA3i9xe/3hLHfwPZdM+dqfX0Cp0zQklBKhVD8Yzc8LS45rkqcwpQ==} + + '@codemirror/legacy-modes@6.5.2': + resolution: {integrity: sha512-/jJbwSTazlQEDOQw2FJ8LEEKVS72pU0lx6oM54kGpL8t/NJ2Jda3CZ4pcltiKTdqYSRk3ug1B3pil1gsjA6+8Q==} + + '@codemirror/lint@6.9.2': + resolution: {integrity: sha512-sv3DylBiIyi+xKwRCJAAsBZZZWo82shJ/RTMymLabAdtbkV5cSKwWDeCgtUq3v8flTaXS2y1kKkICuRYtUswyQ==} + + '@codemirror/rangeset@0.19.9': + resolution: {integrity: sha512-V8YUuOvK+ew87Xem+71nKcqu1SXd5QROMRLMS/ljT5/3MCxtgrRie1Cvild0G/Z2f1fpWxzX78V0U4jjXBorBQ==} + deprecated: As of 0.20.0, this package has been merged into @codemirror/state + + '@codemirror/state@0.19.9': + resolution: {integrity: sha512-psOzDolKTZkx4CgUqhBQ8T8gBc0xN5z4gzed109aF6x7D7umpDRoimacI/O6d9UGuyl4eYuDCZmDFr2Rq7aGOw==} + + '@codemirror/state@6.5.3': + resolution: {integrity: sha512-MerMzJzlXogk2fxWFU1nKp36bY5orBG59HnPiz0G9nLRebWa0zXuv2siH6PLIHBvv5TH8CkQRqjBs0MlxCZu+A==} + + '@codemirror/text@0.19.6': + resolution: {integrity: sha512-T9jnREMIygx+TPC1bOuepz18maGq/92q2a+n4qTqObKwvNMg+8cMTslb8yxeEDEq7S3kpgGWxgO1UWbQRij0dA==} + deprecated: As of 0.20.0, this package has been merged into @codemirror/state + + '@codemirror/view@0.19.48': + resolution: {integrity: sha512-0eg7D2Nz4S8/caetCTz61rK0tkHI17V/d15Jy0kLOT8dTLGGNJUponDnW28h2B6bERmPlVHKh8MJIr5OCp1nGw==} + + '@codemirror/view@6.39.9': + resolution: {integrity: sha512-miGSIfBOKC1s2oHoa80dp+BjtsL8sXsrgGlQnQuOcfvaedcQUtqddTmKbJSDkLl4mkgPvZyXuKic2HDNYcJLYA==} + '@csstools/color-helpers@5.1.0': resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} engines: {node: '>=18'} @@ -1010,6 +1082,18 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@lezer/common@1.5.0': + resolution: {integrity: sha512-PNGcolp9hr4PJdXR4ix7XtixDrClScvtSCYW3rQG106oVMOOI+jFb+0+J3mbeL/53g1Zd6s0kJzaw6Ri68GmAA==} + + '@lezer/highlight@1.2.3': + resolution: {integrity: sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==} + + '@lezer/lr@1.4.7': + resolution: {integrity: sha512-wNIFWdSUfX9Jc6ePMzxSPVgTVB4EOfDIwLQLWASyiUdHKaMsiilj9bYiGkGQCKVodd0x6bgQCV207PILGFCF9Q==} + + '@lezer/yaml@1.0.3': + resolution: {integrity: sha512-GuBLekbw9jDBDhGur82nuwkxKQ+a3W5H0GfaAthDXcAu+XdpS43VlnxA9E9hllkpSP5ellRDKjLLj7Lu9Wr6xA==} + '@lix-js/sdk@0.4.7': resolution: {integrity: sha512-pRbW+joG12L0ULfMiWYosIW0plmW4AsUdiPCp+Z8rAsElJ+wJ6in58zhD3UwUcd4BNcpldEGjg6PdA7e0RgsDQ==} engines: {node: '>=18'} @@ -1017,6 +1101,9 @@ packages: '@lix-js/server-protocol-schema@0.1.1': resolution: {integrity: sha512-jBeALB6prAbtr5q4vTuxnRZZv1M2rKe8iNqRQhFJ4Tv7150unEa0vKyz0hs8Gl3fUGsWaNJBh3J8++fpbrpRBQ==} + '@marijn/find-cluster-break@1.0.2': + resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==} + '@napi-rs/wasm-runtime@1.1.1': resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} @@ -1785,6 +1872,13 @@ packages: resolution: {integrity: sha512-GkMZ4alU9Pr/5pUjZRzA9NMQ2wadrCPN+YHhjOlr8VM2gCFoSg5+ewLVMu4ZcdjdJDs8DUcCyuHQiW6Zr5iBvQ==} hasBin: true + '@uiw/codemirror-themes@4.25.4': + resolution: {integrity: sha512-2SLktItgcZC4p0+PfFusEbAHwbuAWe3bOOntCevVgHtrWGtGZX3IPv2k8IKZMgOXtAHyGKpJvT9/nspPn/uCQg==} + peerDependencies: + '@codemirror/language': '>=6.0.0' + '@codemirror/state': '>=6.0.0' + '@codemirror/view': '>=6.0.0' + '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} @@ -2024,6 +2118,9 @@ packages: resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} engines: {node: '>= 0.10'} + crelt@1.0.6: + resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -3154,6 +3251,9 @@ packages: stubborn-utils@1.0.2: resolution: {integrity: sha512-zOh9jPYI+xrNOyisSelgym4tolKTJCQd5GBhK0+0xJvcYDcwlOoxF/rnFKQ2KRZknXSG9jWAp66fwP6AxN9STg==} + style-mod@4.1.3: + resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==} + style-to-object@1.0.11: resolution: {integrity: sha512-5A560JmXr7wDyGLK12Nq/EYS38VkGlglVzkis1JEdbGWSnbQIEhZzTJhzURXN5/8WwwFCs/f/VVcmkTppbXLow==} @@ -3513,6 +3613,9 @@ packages: vite: optional: true + w3c-keyname@2.2.8: + resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + w3c-xmlserializer@5.0.0: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} @@ -3682,6 +3785,83 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 + '@codemirror/autocomplete@6.20.0': + dependencies: + '@codemirror/language': 6.12.1 + '@codemirror/state': 6.5.3 + '@codemirror/view': 6.39.9 + '@lezer/common': 1.5.0 + + '@codemirror/commands@6.10.1': + dependencies: + '@codemirror/language': 6.12.1 + '@codemirror/state': 6.5.3 + '@codemirror/view': 6.39.9 + '@lezer/common': 1.5.0 + + '@codemirror/history@0.19.2': + dependencies: + '@codemirror/state': 0.19.9 + '@codemirror/view': 0.19.48 + + '@codemirror/lang-yaml@6.1.2': + dependencies: + '@codemirror/autocomplete': 6.20.0 + '@codemirror/language': 6.12.1 + '@codemirror/state': 6.5.3 + '@lezer/common': 1.5.0 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.7 + '@lezer/yaml': 1.0.3 + + '@codemirror/language@6.12.1': + dependencies: + '@codemirror/state': 6.5.3 + '@codemirror/view': 6.39.9 + '@lezer/common': 1.5.0 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.7 + style-mod: 4.1.3 + + '@codemirror/legacy-modes@6.5.2': + dependencies: + '@codemirror/language': 6.12.1 + + '@codemirror/lint@6.9.2': + dependencies: + '@codemirror/state': 6.5.3 + '@codemirror/view': 6.39.9 + crelt: 1.0.6 + + '@codemirror/rangeset@0.19.9': + dependencies: + '@codemirror/state': 0.19.9 + + '@codemirror/state@0.19.9': + dependencies: + '@codemirror/text': 0.19.6 + + '@codemirror/state@6.5.3': + dependencies: + '@marijn/find-cluster-break': 1.0.2 + + '@codemirror/text@0.19.6': {} + + '@codemirror/view@0.19.48': + dependencies: + '@codemirror/rangeset': 0.19.9 + '@codemirror/state': 0.19.9 + '@codemirror/text': 0.19.6 + style-mod: 4.1.3 + w3c-keyname: 2.2.8 + + '@codemirror/view@6.39.9': + dependencies: + '@codemirror/state': 6.5.3 + crelt: 1.0.6 + style-mod: 4.1.3 + w3c-keyname: 2.2.8 + '@csstools/color-helpers@5.1.0': {} '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': @@ -4163,6 +4343,22 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@lezer/common@1.5.0': {} + + '@lezer/highlight@1.2.3': + dependencies: + '@lezer/common': 1.5.0 + + '@lezer/lr@1.4.7': + dependencies: + '@lezer/common': 1.5.0 + + '@lezer/yaml@1.0.3': + dependencies: + '@lezer/common': 1.5.0 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.7 + '@lix-js/sdk@0.4.7': dependencies: '@lix-js/server-protocol-schema': 0.1.1 @@ -4177,6 +4373,8 @@ snapshots: '@lix-js/server-protocol-schema@0.1.1': {} + '@marijn/find-cluster-break@1.0.2': {} + '@napi-rs/wasm-runtime@1.1.1': dependencies: '@emnapi/core': 1.8.1 @@ -4804,6 +5002,12 @@ snapshots: '@typescript/native-preview-win32-arm64': 7.0.0-dev.20260107.1 '@typescript/native-preview-win32-x64': 7.0.0-dev.20260107.1 + '@uiw/codemirror-themes@4.25.4(@codemirror/language@6.12.1)(@codemirror/state@6.5.3)(@codemirror/view@6.39.9)': + dependencies: + '@codemirror/language': 6.12.1 + '@codemirror/state': 6.5.3 + '@codemirror/view': 6.39.9 + '@ungap/structured-clone@1.3.0': {} '@valibot/to-json-schema@1.5.0(valibot@1.2.0(typescript@5.9.3))': @@ -5033,6 +5237,8 @@ snapshots: object-assign: 4.1.1 vary: 1.1.2 + crelt@1.0.6: {} + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -6282,6 +6488,8 @@ snapshots: stubborn-utils@1.0.2: {} + style-mod@4.1.3: {} + style-to-object@1.0.11: dependencies: inline-style-parser: 0.2.4 @@ -6626,6 +6834,8 @@ snapshots: optionalDependencies: vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1) + w3c-keyname@2.2.8: {} + w3c-xmlserializer@5.0.0: dependencies: xml-name-validator: 5.0.0