This commit is contained in:
Aidan Bleser 2025-06-17 10:06:39 -05:00
parent 7d234c0db6
commit 64dc3b9201
11 changed files with 671 additions and 9 deletions

View file

@ -22,12 +22,16 @@
"@eslint/js": "^9.18.0", "@eslint/js": "^9.18.0",
"@iconify/json": "^2.2.349", "@iconify/json": "^2.2.349",
"@playwright/test": "^1.49.1", "@playwright/test": "^1.49.1",
"@shikijs/langs": "^3.6.0",
"@shikijs/markdown-it": "^3.6.0",
"@shikijs/themes": "^3.6.0",
"@sveltejs/adapter-auto": "^6.0.0", "@sveltejs/adapter-auto": "^6.0.0",
"@sveltejs/kit": "^2.16.0", "@sveltejs/kit": "^2.16.0",
"@sveltejs/vite-plugin-svelte": "^5.0.0", "@sveltejs/vite-plugin-svelte": "^5.0.0",
"@tailwindcss/vite": "^4.0.0", "@tailwindcss/vite": "^4.0.0",
"@testing-library/jest-dom": "^6.6.3", "@testing-library/jest-dom": "^6.6.3",
"@testing-library/svelte": "^5.2.4", "@testing-library/svelte": "^5.2.4",
"@types/markdown-it": "^14.1.2",
"@vercel/functions": "^2.2.0", "@vercel/functions": "^2.2.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"concurrently": "^9.1.2", "concurrently": "^9.1.2",
@ -39,6 +43,7 @@
"eslint-plugin-svelte": "^3.0.0", "eslint-plugin-svelte": "^3.0.0",
"globals": "^16.0.0", "globals": "^16.0.0",
"jsdom": "^26.0.0", "jsdom": "^26.0.0",
"markdown-it": "^14.1.0",
"melt": "^0.35.0", "melt": "^0.35.0",
"mode-watcher": "^1.0.8", "mode-watcher": "^1.0.8",
"neverthrow": "^8.2.0", "neverthrow": "^8.2.0",
@ -46,6 +51,7 @@
"prettier-plugin-svelte": "^3.3.3", "prettier-plugin-svelte": "^3.3.3",
"prettier-plugin-tailwindcss": "^0.6.11", "prettier-plugin-tailwindcss": "^0.6.11",
"runed": "^0.28.0", "runed": "^0.28.0",
"shiki": "^3.6.0",
"svelte": "^5.0.0", "svelte": "^5.0.0",
"svelte-check": "^4.0.0", "svelte-check": "^4.0.0",
"tailwind-merge": "^3.3.1", "tailwind-merge": "^3.3.1",

412
pnpm-lock.yaml generated
View file

@ -60,6 +60,15 @@ importers:
'@playwright/test': '@playwright/test':
specifier: ^1.49.1 specifier: ^1.49.1
version: 1.53.0 version: 1.53.0
'@shikijs/langs':
specifier: ^3.6.0
version: 3.6.0
'@shikijs/markdown-it':
specifier: ^3.6.0
version: 3.6.0(markdown-it-async@2.2.0)
'@shikijs/themes':
specifier: ^3.6.0
version: 3.6.0
'@sveltejs/adapter-auto': '@sveltejs/adapter-auto':
specifier: ^6.0.0 specifier: ^6.0.0
version: 6.0.1(@sveltejs/kit@2.21.5(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.1)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(lightningcss@1.30.1)))(svelte@5.34.1)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(lightningcss@1.30.1))) version: 6.0.1(@sveltejs/kit@2.21.5(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.1)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(lightningcss@1.30.1)))(svelte@5.34.1)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(lightningcss@1.30.1)))
@ -78,6 +87,9 @@ importers:
'@testing-library/svelte': '@testing-library/svelte':
specifier: ^5.2.4 specifier: ^5.2.4
version: 5.2.8(svelte@5.34.1)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(lightningcss@1.30.1))(vitest@3.2.3(@types/node@24.0.1)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)) version: 5.2.8(svelte@5.34.1)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(lightningcss@1.30.1))(vitest@3.2.3(@types/node@24.0.1)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1))
'@types/markdown-it':
specifier: ^14.1.2
version: 14.1.2
'@vercel/functions': '@vercel/functions':
specifier: ^2.2.0 specifier: ^2.2.0
version: 2.2.0 version: 2.2.0
@ -111,6 +123,9 @@ importers:
jsdom: jsdom:
specifier: ^26.0.0 specifier: ^26.0.0
version: 26.1.0 version: 26.1.0
markdown-it:
specifier: ^14.1.0
version: 14.1.0
melt: melt:
specifier: ^0.35.0 specifier: ^0.35.0
version: 0.35.0(@floating-ui/dom@1.7.1)(svelte@5.34.1) version: 0.35.0(@floating-ui/dom@1.7.1)(svelte@5.34.1)
@ -132,6 +147,9 @@ importers:
runed: runed:
specifier: ^0.28.0 specifier: ^0.28.0
version: 0.28.0(svelte@5.34.1) version: 0.28.0(svelte@5.34.1)
shiki:
specifier: ^3.6.0
version: 3.6.0
svelte: svelte:
specifier: ^5.0.0 specifier: ^5.0.0
version: 5.34.1 version: 5.34.1
@ -818,6 +836,35 @@ packages:
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@shikijs/core@3.6.0':
resolution: {integrity: sha512-9By7Xb3olEX0o6UeJyPLI1PE1scC4d3wcVepvtv2xbuN9/IThYN4Wcwh24rcFeASzPam11MCq8yQpwwzCgSBRw==}
'@shikijs/engine-javascript@3.6.0':
resolution: {integrity: sha512-7YnLhZG/TU05IHMG14QaLvTW/9WiK8SEYafceccHUSXs2Qr5vJibUwsDfXDLmRi0zHdzsxrGKpSX6hnqe0k8nA==}
'@shikijs/engine-oniguruma@3.6.0':
resolution: {integrity: sha512-nmOhIZ9yT3Grd+2plmW/d8+vZ2pcQmo/UnVwXMUXAKTXdi+LK0S08Ancrz5tQQPkxvjBalpMW2aKvwXfelauvA==}
'@shikijs/langs@3.6.0':
resolution: {integrity: sha512-IdZkQJaLBu1LCYCwkr30hNuSDfllOT8RWYVZK1tD2J03DkiagYKRxj/pDSl8Didml3xxuyzUjgtioInwEQM/TA==}
'@shikijs/markdown-it@3.6.0':
resolution: {integrity: sha512-OFJb0EY1GOfWEpeXyfav4mDXt4QjqURwhQLTYaBeWP4QjBUUYIdPri+Jf8Fgkds+i4I6WcmX47Wu9vAq8USZsA==}
peerDependencies:
markdown-it-async: ^2.2.0
peerDependenciesMeta:
markdown-it-async:
optional: true
'@shikijs/themes@3.6.0':
resolution: {integrity: sha512-Fq2j4nWr1DF4drvmhqKq8x5vVQ27VncF8XZMBuHuQMZvUSS3NBgpqfwz/FoGe36+W6PvniZ1yDlg2d4kmYDU6w==}
'@shikijs/types@3.6.0':
resolution: {integrity: sha512-cLWFiToxYu0aAzJqhXTQsFiJRTFDAGl93IrMSBNaGSzs7ixkLfdG6pH11HipuWFGW5vyx4X47W8HDQ7eSrmBUg==}
'@shikijs/vscode-textmate@10.0.2':
resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
'@simplewebauthn/browser@13.1.0': '@simplewebauthn/browser@13.1.0':
resolution: {integrity: sha512-WuHZ/PYvyPJ9nxSzgHtOEjogBhwJfC8xzYkPC+rR/+8chl/ft4ngjiK8kSU5HtRJfczupyOh33b25TjYbvwAcg==} resolution: {integrity: sha512-WuHZ/PYvyPJ9nxSzgHtOEjogBhwJfC8xzYkPC+rR/+8chl/ft4ngjiK8kSU5HtRJfczupyOh33b25TjYbvwAcg==}
@ -991,12 +1038,30 @@ packages:
'@types/estree@1.0.8': '@types/estree@1.0.8':
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
'@types/hast@3.0.4':
resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
'@types/json-schema@7.0.15': '@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
'@types/linkify-it@5.0.0':
resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==}
'@types/markdown-it@14.1.2':
resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==}
'@types/mdast@4.0.4':
resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
'@types/mdurl@2.0.0':
resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==}
'@types/node@24.0.1': '@types/node@24.0.1':
resolution: {integrity: sha512-MX4Zioh39chHlDJbKmEgydJDS3tspMP/lnQC67G3SWsTnb9NeYVWOjkxpOSy4oMfPs4StcWHwBrvUb4ybfnuaw==} resolution: {integrity: sha512-MX4Zioh39chHlDJbKmEgydJDS3tspMP/lnQC67G3SWsTnb9NeYVWOjkxpOSy4oMfPs4StcWHwBrvUb4ybfnuaw==}
'@types/unist@3.0.3':
resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
'@typescript-eslint/eslint-plugin@8.34.0': '@typescript-eslint/eslint-plugin@8.34.0':
resolution: {integrity: sha512-QXwAlHlbcAwNlEEMKQS2RCgJsgXrTJdjXT08xEgbPFa2yYQgVjBymxP5DrfrE7X7iodSzd9qBUHUycdyVJTW1w==} resolution: {integrity: sha512-QXwAlHlbcAwNlEEMKQS2RCgJsgXrTJdjXT08xEgbPFa2yYQgVjBymxP5DrfrE7X7iodSzd9qBUHUycdyVJTW1w==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@ -1056,6 +1121,9 @@ packages:
resolution: {integrity: sha512-qHV7pW7E85A0x6qyrFn+O+q1k1p3tQCsqIZ1KZ5ESLXY57aTvUd3/a4rdPTeXisvhXn2VQG0VSKUqs8KHF2zcA==} resolution: {integrity: sha512-qHV7pW7E85A0x6qyrFn+O+q1k1p3tQCsqIZ1KZ5ESLXY57aTvUd3/a4rdPTeXisvhXn2VQG0VSKUqs8KHF2zcA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@ungap/structured-clone@1.3.0':
resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
'@vercel/functions@2.2.0': '@vercel/functions@2.2.0':
resolution: {integrity: sha512-x1Zrc2jOclTSB9+Ic/XNMDinO0SG4ZS5YeV2Xz1m/tuJOM7QtPVU3Epw2czBao0dukefmC8HCNpyUL8ZchJ/Tg==} resolution: {integrity: sha512-x1Zrc2jOclTSB9+Ic/XNMDinO0SG4ZS5YeV2Xz1m/tuJOM7QtPVU3Epw2czBao0dukefmC8HCNpyUL8ZchJ/Tg==}
engines: {node: '>= 18'} engines: {node: '>= 18'}
@ -1176,6 +1244,9 @@ packages:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'} engines: {node: '>=6'}
ccount@2.0.1:
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
chai@5.2.0: chai@5.2.0:
resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -1188,6 +1259,12 @@ packages:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
engines: {node: '>=10'} engines: {node: '>=10'}
character-entities-html4@2.1.0:
resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
character-entities-legacy@3.0.0:
resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
check-error@2.1.1: check-error@2.1.1:
resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==}
engines: {node: '>= 16'} engines: {node: '>= 16'}
@ -1215,6 +1292,9 @@ packages:
color-name@1.1.4: color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
comma-separated-tokens@2.0.3:
resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
concat-map@0.0.1: concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
@ -1334,6 +1414,9 @@ packages:
devalue@5.1.1: devalue@5.1.1:
resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==} resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==}
devlop@1.1.0:
resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
diff-sequences@29.6.3: diff-sequences@29.6.3:
resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@ -1355,6 +1438,10 @@ packages:
resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==}
engines: {node: '>=10.13.0'} engines: {node: '>=10.13.0'}
entities@4.5.0:
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
engines: {node: '>=0.12'}
entities@6.0.1: entities@6.0.1:
resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
engines: {node: '>=0.12'} engines: {node: '>=0.12'}
@ -1541,10 +1628,19 @@ packages:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'} engines: {node: '>=8'}
hast-util-to-html@9.0.5:
resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==}
hast-util-whitespace@3.0.0:
resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
html-encoding-sniffer@4.0.0: html-encoding-sniffer@4.0.0:
resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
html-void-elements@3.0.0:
resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
http-proxy-agent@7.0.2: http-proxy-agent@7.0.2:
resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
engines: {node: '>= 14'} engines: {node: '>= 14'}
@ -1749,6 +1845,9 @@ packages:
resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
linkify-it@5.0.0:
resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==}
local-pkg@1.1.1: local-pkg@1.1.1:
resolution: {integrity: sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==} resolution: {integrity: sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==}
engines: {node: '>=14'} engines: {node: '>=14'}
@ -1779,6 +1878,19 @@ packages:
magic-string@0.30.17: magic-string@0.30.17:
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
markdown-it-async@2.2.0:
resolution: {integrity: sha512-sITME+kf799vMeO/ww/CjH6q+c05f6TLpn6VOmmWCGNqPJzSh+uFgZoMB9s0plNtW6afy63qglNAC3MhrhP/gg==}
markdown-it@14.1.0:
resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==}
hasBin: true
mdast-util-to-hast@13.2.0:
resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==}
mdurl@2.0.0:
resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==}
melt@0.35.0: melt@0.35.0:
resolution: {integrity: sha512-Y8/ImbAN83rf11AaqtQ6u9DXcZ2/Ozu6HM7/oV0BZUt0Dh8Q/j06TKyyBB3u65FRsZDJBuxiQHPklCW7dQcfLw==} resolution: {integrity: sha512-Y8/ImbAN83rf11AaqtQ6u9DXcZ2/Ozu6HM7/oV0BZUt0Dh8Q/j06TKyyBB3u65FRsZDJBuxiQHPklCW7dQcfLw==}
peerDependencies: peerDependencies:
@ -1789,6 +1901,21 @@ packages:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
micromark-util-character@2.1.1:
resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==}
micromark-util-encode@2.0.1:
resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==}
micromark-util-sanitize-uri@2.0.1:
resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==}
micromark-util-symbol@2.0.1:
resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==}
micromark-util-types@2.0.2:
resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==}
micromatch@4.0.8: micromatch@4.0.8:
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
engines: {node: '>=8.6'} engines: {node: '>=8.6'}
@ -1860,6 +1987,12 @@ packages:
nwsapi@2.2.20: nwsapi@2.2.20:
resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==} resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==}
oniguruma-parser@0.12.1:
resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==}
oniguruma-to-es@4.3.3:
resolution: {integrity: sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg==}
openai@5.3.0: openai@5.3.0:
resolution: {integrity: sha512-VIKmoF7y4oJCDOwP/oHXGzM69+x0dpGFmN9QmYO+uPbLFOmmnwO+x1GbsgUtI+6oraxomGZ566Y421oYVu191w==} resolution: {integrity: sha512-VIKmoF7y4oJCDOwP/oHXGzM69+x0dpGFmN9QmYO+uPbLFOmmnwO+x1GbsgUtI+6oraxomGZ566Y421oYVu191w==}
hasBin: true hasBin: true
@ -2049,6 +2182,13 @@ packages:
resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
property-information@7.1.0:
resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==}
punycode.js@2.3.1:
resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==}
engines: {node: '>=6'}
punycode@2.3.1: punycode@2.3.1:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'} engines: {node: '>=6'}
@ -2080,6 +2220,15 @@ packages:
resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
engines: {node: '>=8'} engines: {node: '>=8'}
regex-recursion@6.0.2:
resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==}
regex-utilities@2.3.0:
resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==}
regex@6.0.1:
resolution: {integrity: sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==}
require-directory@2.1.1: require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -2155,6 +2304,9 @@ packages:
resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
shiki@3.6.0:
resolution: {integrity: sha512-tKn/Y0MGBTffQoklaATXmTqDU02zx8NYBGQ+F6gy87/YjKbizcLd+Cybh/0ZtOBX9r1NEnAy/GTRDKtOsc1L9w==}
siginfo@2.0.0: siginfo@2.0.0:
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
@ -2166,6 +2318,9 @@ packages:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
space-separated-tokens@2.0.2:
resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
stackback@0.0.2: stackback@0.0.2:
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
@ -2176,6 +2331,9 @@ packages:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'} engines: {node: '>=8'}
stringify-entities@4.0.4:
resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
strip-ansi@6.0.1: strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -2307,6 +2465,9 @@ packages:
resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
hasBin: true hasBin: true
trim-lines@3.0.1:
resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
ts-api-utils@2.1.0: ts-api-utils@2.1.0:
resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==}
engines: {node: '>=18.12'} engines: {node: '>=18.12'}
@ -2332,6 +2493,9 @@ packages:
engines: {node: '>=14.17'} engines: {node: '>=14.17'}
hasBin: true hasBin: true
uc.micro@2.1.0:
resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==}
ufo@1.6.1: ufo@1.6.1:
resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==}
@ -2341,6 +2505,21 @@ packages:
undici-types@7.8.0: undici-types@7.8.0:
resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==}
unist-util-is@6.0.0:
resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==}
unist-util-position@5.0.0:
resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
unist-util-stringify-position@4.0.0:
resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
unist-util-visit-parents@6.0.1:
resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==}
unist-util-visit@5.0.0:
resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==}
unplugin-icons@22.1.0: unplugin-icons@22.1.0:
resolution: {integrity: sha512-ect2ZNtk1Zgwb0NVHd0C1IDW/MV+Jk/xaq4t8o6rYdVS3+L660ZdD5kTSQZvsgdwCvquRw+/wYn75hsweRjoIA==} resolution: {integrity: sha512-ect2ZNtk1Zgwb0NVHd0C1IDW/MV+Jk/xaq4t8o6rYdVS3+L660ZdD5kTSQZvsgdwCvquRw+/wYn75hsweRjoIA==}
peerDependencies: peerDependencies:
@ -2374,6 +2553,12 @@ packages:
util-deprecate@1.0.2: util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
vfile-message@4.0.2:
resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==}
vfile@6.0.3:
resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
vite-node@3.2.3: vite-node@3.2.3:
resolution: {integrity: sha512-gc8aAifGuDIpZHrPjuHyP4dpQmYXqWw7D1GmDnWeNWP654UEXzVfQ5IHPSK5HaHkwB/+p1atpYpSdw/2kOv8iQ==} resolution: {integrity: sha512-gc8aAifGuDIpZHrPjuHyP4dpQmYXqWw7D1GmDnWeNWP654UEXzVfQ5IHPSK5HaHkwB/+p1atpYpSdw/2kOv8iQ==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
@ -2545,6 +2730,9 @@ packages:
zod@3.25.64: zod@3.25.64:
resolution: {integrity: sha512-hbP9FpSZf7pkS7hRVUrOjhwKJNyampPgtXKc3AN6DsWtoHsg2Sb4SQaS4Tcay380zSwd2VPo9G9180emBACp5g==} resolution: {integrity: sha512-hbP9FpSZf7pkS7hRVUrOjhwKJNyampPgtXKc3AN6DsWtoHsg2Sb4SQaS4Tcay380zSwd2VPo9G9180emBACp5g==}
zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
snapshots: snapshots:
'@adobe/css-tools@4.4.3': {} '@adobe/css-tools@4.4.3': {}
@ -3017,6 +3205,46 @@ snapshots:
'@rollup/rollup-win32-x64-msvc@4.43.0': '@rollup/rollup-win32-x64-msvc@4.43.0':
optional: true optional: true
'@shikijs/core@3.6.0':
dependencies:
'@shikijs/types': 3.6.0
'@shikijs/vscode-textmate': 10.0.2
'@types/hast': 3.0.4
hast-util-to-html: 9.0.5
'@shikijs/engine-javascript@3.6.0':
dependencies:
'@shikijs/types': 3.6.0
'@shikijs/vscode-textmate': 10.0.2
oniguruma-to-es: 4.3.3
'@shikijs/engine-oniguruma@3.6.0':
dependencies:
'@shikijs/types': 3.6.0
'@shikijs/vscode-textmate': 10.0.2
'@shikijs/langs@3.6.0':
dependencies:
'@shikijs/types': 3.6.0
'@shikijs/markdown-it@3.6.0(markdown-it-async@2.2.0)':
dependencies:
markdown-it: 14.1.0
shiki: 3.6.0
optionalDependencies:
markdown-it-async: 2.2.0
'@shikijs/themes@3.6.0':
dependencies:
'@shikijs/types': 3.6.0
'@shikijs/types@3.6.0':
dependencies:
'@shikijs/vscode-textmate': 10.0.2
'@types/hast': 3.0.4
'@shikijs/vscode-textmate@10.0.2': {}
'@simplewebauthn/browser@13.1.0': {} '@simplewebauthn/browser@13.1.0': {}
'@simplewebauthn/server@13.1.1': '@simplewebauthn/server@13.1.1':
@ -3194,13 +3422,32 @@ snapshots:
'@types/estree@1.0.8': {} '@types/estree@1.0.8': {}
'@types/hast@3.0.4':
dependencies:
'@types/unist': 3.0.3
'@types/json-schema@7.0.15': {} '@types/json-schema@7.0.15': {}
'@types/linkify-it@5.0.0': {}
'@types/markdown-it@14.1.2':
dependencies:
'@types/linkify-it': 5.0.0
'@types/mdurl': 2.0.0
'@types/mdast@4.0.4':
dependencies:
'@types/unist': 3.0.3
'@types/mdurl@2.0.0': {}
'@types/node@24.0.1': '@types/node@24.0.1':
dependencies: dependencies:
undici-types: 7.8.0 undici-types: 7.8.0
optional: true optional: true
'@types/unist@3.0.3': {}
'@typescript-eslint/eslint-plugin@8.34.0(@typescript-eslint/parser@8.34.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': '@typescript-eslint/eslint-plugin@8.34.0(@typescript-eslint/parser@8.34.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)':
dependencies: dependencies:
'@eslint-community/regexpp': 4.12.1 '@eslint-community/regexpp': 4.12.1
@ -3293,6 +3540,8 @@ snapshots:
'@typescript-eslint/types': 8.34.0 '@typescript-eslint/types': 8.34.0
eslint-visitor-keys: 4.2.1 eslint-visitor-keys: 4.2.1
'@ungap/structured-clone@1.3.0': {}
'@vercel/functions@2.2.0': {} '@vercel/functions@2.2.0': {}
'@vitest/expect@3.2.3': '@vitest/expect@3.2.3':
@ -3421,6 +3670,8 @@ snapshots:
callsites@3.1.0: {} callsites@3.1.0: {}
ccount@2.0.1: {}
chai@5.2.0: chai@5.2.0:
dependencies: dependencies:
assertion-error: 2.0.1 assertion-error: 2.0.1
@ -3439,6 +3690,10 @@ snapshots:
ansi-styles: 4.3.0 ansi-styles: 4.3.0
supports-color: 7.2.0 supports-color: 7.2.0
character-entities-html4@2.1.0: {}
character-entities-legacy@3.0.0: {}
check-error@2.1.1: {} check-error@2.1.1: {}
chokidar@4.0.3: chokidar@4.0.3:
@ -3461,6 +3716,8 @@ snapshots:
color-name@1.1.4: {} color-name@1.1.4: {}
comma-separated-tokens@2.0.3: {}
concat-map@0.0.1: {} concat-map@0.0.1: {}
concurrently@9.1.2: concurrently@9.1.2:
@ -3537,6 +3794,10 @@ snapshots:
devalue@5.1.1: {} devalue@5.1.1: {}
devlop@1.1.0:
dependencies:
dequal: 2.0.3
diff-sequences@29.6.3: {} diff-sequences@29.6.3: {}
dom-accessibility-api@0.5.16: {} dom-accessibility-api@0.5.16: {}
@ -3552,6 +3813,8 @@ snapshots:
graceful-fs: 4.2.11 graceful-fs: 4.2.11
tapable: 2.2.2 tapable: 2.2.2
entities@4.5.0: {}
entities@6.0.1: {} entities@6.0.1: {}
es-module-lexer@1.7.0: {} es-module-lexer@1.7.0: {}
@ -3791,10 +4054,30 @@ snapshots:
has-flag@4.0.0: {} has-flag@4.0.0: {}
hast-util-to-html@9.0.5:
dependencies:
'@types/hast': 3.0.4
'@types/unist': 3.0.3
ccount: 2.0.1
comma-separated-tokens: 2.0.3
hast-util-whitespace: 3.0.0
html-void-elements: 3.0.0
mdast-util-to-hast: 13.2.0
property-information: 7.1.0
space-separated-tokens: 2.0.2
stringify-entities: 4.0.4
zwitch: 2.0.4
hast-util-whitespace@3.0.0:
dependencies:
'@types/hast': 3.0.4
html-encoding-sniffer@4.0.0: html-encoding-sniffer@4.0.0:
dependencies: dependencies:
whatwg-encoding: 3.1.1 whatwg-encoding: 3.1.1
html-void-elements@3.0.0: {}
http-proxy-agent@7.0.2: http-proxy-agent@7.0.2:
dependencies: dependencies:
agent-base: 7.1.3 agent-base: 7.1.3
@ -3980,6 +4263,10 @@ snapshots:
lilconfig@2.1.0: {} lilconfig@2.1.0: {}
linkify-it@5.0.0:
dependencies:
uc.micro: 2.1.0
local-pkg@1.1.1: local-pkg@1.1.1:
dependencies: dependencies:
mlly: 1.7.4 mlly: 1.7.4
@ -4006,6 +4293,35 @@ snapshots:
dependencies: dependencies:
'@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/sourcemap-codec': 1.5.0
markdown-it-async@2.2.0:
dependencies:
'@types/markdown-it': 14.1.2
markdown-it: 14.1.0
optional: true
markdown-it@14.1.0:
dependencies:
argparse: 2.0.1
entities: 4.5.0
linkify-it: 5.0.0
mdurl: 2.0.0
punycode.js: 2.3.1
uc.micro: 2.1.0
mdast-util-to-hast@13.2.0:
dependencies:
'@types/hast': 3.0.4
'@types/mdast': 4.0.4
'@ungap/structured-clone': 1.3.0
devlop: 1.1.0
micromark-util-sanitize-uri: 2.0.1
trim-lines: 3.0.1
unist-util-position: 5.0.0
unist-util-visit: 5.0.0
vfile: 6.0.3
mdurl@2.0.0: {}
melt@0.35.0(@floating-ui/dom@1.7.1)(svelte@5.34.1): melt@0.35.0(@floating-ui/dom@1.7.1)(svelte@5.34.1):
dependencies: dependencies:
'@floating-ui/dom': 1.7.1 '@floating-ui/dom': 1.7.1
@ -4017,6 +4333,23 @@ snapshots:
merge2@1.4.1: {} merge2@1.4.1: {}
micromark-util-character@2.1.1:
dependencies:
micromark-util-symbol: 2.0.1
micromark-util-types: 2.0.2
micromark-util-encode@2.0.1: {}
micromark-util-sanitize-uri@2.0.1:
dependencies:
micromark-util-character: 2.1.1
micromark-util-encode: 2.0.1
micromark-util-symbol: 2.0.1
micromark-util-symbol@2.0.1: {}
micromark-util-types@2.0.2: {}
micromatch@4.0.8: micromatch@4.0.8:
dependencies: dependencies:
braces: 3.0.3 braces: 3.0.3
@ -4073,6 +4406,14 @@ snapshots:
nwsapi@2.2.20: {} nwsapi@2.2.20: {}
oniguruma-parser@0.12.1: {}
oniguruma-to-es@4.3.3:
dependencies:
oniguruma-parser: 0.12.1
regex: 6.0.1
regex-recursion: 6.0.2
openai@5.3.0(ws@8.18.2)(zod@3.25.64): openai@5.3.0(ws@8.18.2)(zod@3.25.64):
optionalDependencies: optionalDependencies:
ws: 8.18.2 ws: 8.18.2
@ -4194,6 +4535,10 @@ snapshots:
ansi-styles: 5.2.0 ansi-styles: 5.2.0
react-is: 18.3.1 react-is: 18.3.1
property-information@7.1.0: {}
punycode.js@2.3.1: {}
punycode@2.3.1: {} punycode@2.3.1: {}
pvtsutils@1.3.6: pvtsutils@1.3.6:
@ -4217,6 +4562,16 @@ snapshots:
indent-string: 4.0.0 indent-string: 4.0.0
strip-indent: 3.0.0 strip-indent: 3.0.0
regex-recursion@6.0.2:
dependencies:
regex-utilities: 2.3.0
regex-utilities@2.3.0: {}
regex@6.0.1:
dependencies:
regex-utilities: 2.3.0
require-directory@2.1.1: {} require-directory@2.1.1: {}
resolve-from@4.0.0: {} resolve-from@4.0.0: {}
@ -4298,6 +4653,17 @@ snapshots:
shell-quote@1.8.3: {} shell-quote@1.8.3: {}
shiki@3.6.0:
dependencies:
'@shikijs/core': 3.6.0
'@shikijs/engine-javascript': 3.6.0
'@shikijs/engine-oniguruma': 3.6.0
'@shikijs/langs': 3.6.0
'@shikijs/themes': 3.6.0
'@shikijs/types': 3.6.0
'@shikijs/vscode-textmate': 10.0.2
'@types/hast': 3.0.4
siginfo@2.0.0: {} siginfo@2.0.0: {}
sirv@3.0.1: sirv@3.0.1:
@ -4308,6 +4674,8 @@ snapshots:
source-map-js@1.2.1: {} source-map-js@1.2.1: {}
space-separated-tokens@2.0.2: {}
stackback@0.0.2: {} stackback@0.0.2: {}
std-env@3.9.0: {} std-env@3.9.0: {}
@ -4318,6 +4686,11 @@ snapshots:
is-fullwidth-code-point: 3.0.0 is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1 strip-ansi: 6.0.1
stringify-entities@4.0.4:
dependencies:
character-entities-html4: 2.1.0
character-entities-legacy: 3.0.0
strip-ansi@6.0.1: strip-ansi@6.0.1:
dependencies: dependencies:
ansi-regex: 5.0.1 ansi-regex: 5.0.1
@ -4454,6 +4827,8 @@ snapshots:
tree-kill@1.2.2: {} tree-kill@1.2.2: {}
trim-lines@3.0.1: {}
ts-api-utils@2.1.0(typescript@5.8.3): ts-api-utils@2.1.0(typescript@5.8.3):
dependencies: dependencies:
typescript: 5.8.3 typescript: 5.8.3
@ -4476,6 +4851,8 @@ snapshots:
typescript@5.8.3: {} typescript@5.8.3: {}
uc.micro@2.1.0: {}
ufo@1.6.1: {} ufo@1.6.1: {}
uncrypto@0.1.3: {} uncrypto@0.1.3: {}
@ -4483,6 +4860,29 @@ snapshots:
undici-types@7.8.0: undici-types@7.8.0:
optional: true optional: true
unist-util-is@6.0.0:
dependencies:
'@types/unist': 3.0.3
unist-util-position@5.0.0:
dependencies:
'@types/unist': 3.0.3
unist-util-stringify-position@4.0.0:
dependencies:
'@types/unist': 3.0.3
unist-util-visit-parents@6.0.1:
dependencies:
'@types/unist': 3.0.3
unist-util-is: 6.0.0
unist-util-visit@5.0.0:
dependencies:
'@types/unist': 3.0.3
unist-util-is: 6.0.0
unist-util-visit-parents: 6.0.1
unplugin-icons@22.1.0(svelte@5.34.1): unplugin-icons@22.1.0(svelte@5.34.1):
dependencies: dependencies:
'@antfu/install-pkg': 1.1.0 '@antfu/install-pkg': 1.1.0
@ -4507,6 +4907,16 @@ snapshots:
util-deprecate@1.0.2: {} util-deprecate@1.0.2: {}
vfile-message@4.0.2:
dependencies:
'@types/unist': 3.0.3
unist-util-stringify-position: 4.0.0
vfile@6.0.3:
dependencies:
'@types/unist': 3.0.3
vfile-message: 4.0.2
vite-node@3.2.3(@types/node@24.0.1)(jiti@2.4.2)(lightningcss@1.30.1): vite-node@3.2.3(@types/node@24.0.1)(jiti@2.4.2)(lightningcss@1.30.1):
dependencies: dependencies:
cac: 6.7.14 cac: 6.7.14
@ -4653,3 +5063,5 @@ snapshots:
zimmerframe@1.1.2: {} zimmerframe@1.1.2: {}
zod@3.25.64: {} zod@3.25.64: {}
zwitch@2.0.4: {}

View file

@ -14,7 +14,7 @@
--card-foreground: oklch(0.3257 0.1161 325.0372); --card-foreground: oklch(0.3257 0.1161 325.0372);
--popover: oklch(1 0 0); --popover: oklch(1 0 0);
--popover-foreground: oklch(0.3257 0.1161 325.0372); --popover-foreground: oklch(0.3257 0.1161 325.0372);
--primary: oklch(0.5316 0.1409 355.1999); --primary: oklch(0.5797 0.1194 237.7893);
--heading: oklch(0.5797 0.1194 237.7893); --heading: oklch(0.5797 0.1194 237.7893);
--primary-foreground: oklch(1 0 0); --primary-foreground: oklch(1 0 0);
--secondary: oklch(0.8696 0.0675 334.8991); --secondary: oklch(0.8696 0.0675 334.8991);

View file

@ -5,6 +5,6 @@
let { class: className, children, ...restProps }: HTMLAttributes<HTMLDivElement> = $props(); let { class: className, children, ...restProps }: HTMLAttributes<HTMLDivElement> = $props();
</script> </script>
<div class={cn('bg-card flex flex-col gap-4 rounded-lg border p-4', className)} {...restProps}> <div class={cn('bg-card flex flex-col gap-4 rounded-lg border-border border p-4', className)} {...restProps}>
{@render children?.()} {@render children?.()}
</div> </div>

46
src/lib/utils/markdown.ts Normal file
View file

@ -0,0 +1,46 @@
import { createJavaScriptRegexEngine } from 'shiki/engine/javascript';
import { fromHighlighter } from '@shikijs/markdown-it/core';
import MarkdownIt from 'markdown-it';
import { createHighlighterCore } from 'shiki/core';
import type { Getter } from 'runed';
const bundledLanguages = {
bash: () => import('@shikijs/langs/bash'),
diff: () => import('@shikijs/langs/diff'),
javascript: () => import('@shikijs/langs/javascript'),
json: () => import('@shikijs/langs/json'),
svelte: () => import('@shikijs/langs/svelte'),
typescript: () => import('@shikijs/langs/typescript'),
};
/** A preloaded highlighter instance. */
export const highlighter = createHighlighterCore({
themes: [
import('@shikijs/themes/github-light-default'),
import('@shikijs/themes/github-dark-default'),
],
langs: Object.entries(bundledLanguages).map(([_, lang]) => lang),
engine: createJavaScriptRegexEngine(),
});
const md = MarkdownIt();
highlighter.then((h) => {
md.use(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
fromHighlighter(h as any, {
themes: {
light: 'github-light-default',
dark: 'github-dark-default',
},
})
);
});
export class Markdown {
constructor(readonly code: Getter<string>) {}
get current() {
return md.render(this.code());
}
}

174
src/markdown.css Normal file
View file

@ -0,0 +1,174 @@
@import 'tailwindcss';
@reference './app.css';
html.dark .shiki,
html.dark .shiki span {
color: var(--shiki-dark) !important;
background-color: var(--shiki-dark-bg) !important;
/* Optional, if you also want font styles */
font-style: var(--shiki-dark-font-style) !important;
font-weight: var(--shiki-dark-font-weight) !important;
text-decoration: var(--shiki-dark-text-decoration) !important;
}
.prose {
@apply text-foreground max-w-[65ch];
& h1:not(.not-prose h1) {
@apply scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl;
}
& h2:not(.not-prose h2) {
@apply mt-12 scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight first:mt-0;
}
& h3:not(.not-prose h3) {
@apply mt-12 scroll-m-20 text-2xl font-semibold tracking-tight first:mt-0;
}
& h4:not(.not-prose h4) {
@apply mt-12 scroll-m-20 text-xl font-semibold tracking-tight first:mt-0;
}
& h5:not(.not-prose h5) {
@apply mt-12 scroll-m-20 text-lg font-semibold tracking-tight first:mt-0;
}
& h6:not(.not-prose h6) {
@apply mt-12 scroll-m-20 text-base font-semibold tracking-tight first:mt-0;
}
& h1:not(.not-prose h1),
& h2:not(.not-prose h2),
& h3:not(.not-prose h3),
& h4:not(.not-prose h4),
& h5:not(.not-prose h5),
& h6:not(.not-prose h6) {
& + p {
@apply mt-0;
}
}
& p:not(.not-prose p) {
@apply leading-[175%] [&:not(:first-child)]:mt-6;
}
& li:not(.not-prose li) {
@apply leading-[175%];
}
& a:not(.not-prose a) {
@apply text-primary font-medium underline underline-offset-4;
}
& blockquote:not(.not-prose blockquote) {
@apply mt-6 border-l-2 pl-6 italic;
}
& table:not(.not-prose table) {
@apply my-6 w-full overflow-y-auto;
& thead tr {
@apply even:bg-muted m-0 border-t p-0;
}
& th {
@apply border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right;
}
& tbody tr {
@apply even:bg-muted m-0 border-t p-0;
}
& td {
@apply border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right;
}
}
& ul:not(.not-prose ul) {
@apply my-6 ml-6 list-disc [&>li]:mt-2;
& p {
@apply my-0 inline;
}
}
& ol:not(.not-prose ol) {
@apply my-6 ml-6 list-decimal [&>li]:mt-2;
& p {
@apply my-0 inline;
}
}
& pre:not(.not-prose pre) {
@apply bg-muted my-6 overflow-y-auto rounded-md p-4 text-sm;
}
& code:not(pre code):not(.not-prose code) {
@apply bg-muted relative rounded px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold;
}
& .lead:not(.not-prose .lead) {
@apply text-muted-foreground text-xl;
}
& .large:not(.not-prose .large) {
@apply text-lg font-semibold;
}
& .small:not(.not-prose .small) {
@apply text-sm leading-none font-medium;
}
& .muted:not(.not-prose .muted) {
@apply text-muted-foreground text-sm;
}
& img:not(.not-prose img),
& picture:not(.not-prose picture),
& video:not(.not-prose video) {
@apply my-6;
}
& picture > img:not(.not-prose picture > img) {
@apply my-0;
}
& kbd:not(.not-prose kbd) {
@apply bg-muted rounded-md px-1.5 py-0.5 text-xs font-semibold;
}
& hr {
@apply my-10;
}
& dl:not(.not-prose dl) {
@apply my-6;
& dt {
@apply mt-6 font-semibold tracking-tight first:mt-0;
}
}
& details:not(.not-prose details) {
@apply mt-6;
& summary {
@apply mt-6 cursor-pointer font-semibold tracking-tight;
}
& p {
@apply [&:first-of-type]:mt-2;
}
}
& mark:not(.not-prose mark) {
@apply bg-yellow-300;
}
& small:not(.not-prose small) {
@apply text-xs leading-none;
}
}

View file

@ -83,7 +83,7 @@
</div> </div>
<div class="md:col-start-2 md:pl-12"> <div class="md:col-start-2 md:pl-12">
<div <div
class="bg-card scrollbar-hide text-muted-foreground flex w-fit max-w-full place-items-center gap-2 overflow-x-auto rounded-lg p-1 text-sm" class="bg-accent scrollbar-hide text-muted-foreground flex w-fit max-w-full place-items-center gap-2 overflow-x-auto rounded-lg p-1 text-sm"
> >
{#each navigation as tab (tab)} {#each navigation as tab (tab)}
<a <a

View file

@ -237,7 +237,7 @@ async function generateAIResponse({
const systemMessage: ChatCompletionSystemMessageParam = { const systemMessage: ChatCompletionSystemMessageParam = {
role: 'system', role: 'system',
content: `The user may have mentioned one or more rules to follow with the @<rule_name> syntax. Please follow these rules. content: `Respond in markdown format. The user may have mentioned one or more rules to follow with the @<rule_name> syntax. Please follow these rules.
Rules to follow: Rules to follow:
${attachedRules.map((r) => `- ${r.name}: ${r.rule}`).join('\n')}`, ${attachedRules.map((r) => `- ${r.name}: ${r.rule}`).join('\n')}`,
}; };
@ -251,7 +251,6 @@ ${attachedRules.map((r) => `- ${r.name}: ${r.rule}`).join('\n')}`,
openai.chat.completions.create({ openai.chat.completions.create({
model: model.model_id, model: model.model_id,
messages: [...messages.map((m) => ({ role: m.role, content: m.content })), systemMessage], messages: [...messages.map((m) => ({ role: m.role, content: m.content })), systemMessage],
max_tokens: 1000,
temperature: 0.7, temperature: 0.7,
stream: true, stream: true,
}), }),

View file

@ -0,0 +1,13 @@
<script lang="ts">
import { Markdown } from '$lib/utils/markdown';
type Props = {
content: string;
};
let { content }: Props = $props();
const markdown = new Markdown(() => content);
</script>
{@html markdown.current}

View file

@ -3,12 +3,14 @@
import { tv } from 'tailwind-variants'; import { tv } from 'tailwind-variants';
import type { Doc } from '$lib/backend/convex/_generated/dataModel'; import type { Doc } from '$lib/backend/convex/_generated/dataModel';
import { CopyButton } from '$lib/components/ui/copy-button'; import { CopyButton } from '$lib/components/ui/copy-button';
import '../../../markdown.css';
import MarkdownRenderer from './markdown-renderer.svelte';
const style = tv({ const style = tv({
base: 'rounded-lg p-2', base: 'prose rounded-lg p-2',
variants: { variants: {
role: { role: {
user: 'bg-primary text-primary-foreground self-end', user: 'bg-primary !text-primary-foreground self-end',
assistant: 'text-foreground', assistant: 'text-foreground',
}, },
}, },
@ -24,7 +26,16 @@
{#if message.role !== 'system' && !(message.role === 'assistant' && message.content.length === 0)} {#if message.role !== 'system' && !(message.role === 'assistant' && message.content.length === 0)}
<div class={cn('group flex max-w-[80%] flex-col gap-1', { 'self-end': message.role === 'user' })}> <div class={cn('group flex max-w-[80%] flex-col gap-1', { 'self-end': message.role === 'user' })}>
<div class={style({ role: message.role })}> <div class={style({ role: message.role })}>
{message.content} <svelte:boundary>
<MarkdownRenderer content={message.content} />
{#snippet failed(error)}
<div class="text-destructive">
<span>Error rendering markdown:</span>
<pre class="!bg-sidebar"><code>{error.message}</code></pre>
</div>
{/snippet}
</svelte:boundary>
</div> </div>
<div <div
class={cn('flex place-items-center opacity-0 transition-opacity group-hover:opacity-100', { class={cn('flex place-items-center opacity-0 transition-opacity group-hover:opacity-100', {

View file

@ -3,6 +3,7 @@
import { useCachedQuery } from '$lib/cache/cached-query.svelte'; import { useCachedQuery } from '$lib/cache/cached-query.svelte';
import { session } from '$lib/state/session.svelte'; import { session } from '$lib/state/session.svelte';
import { settings } from '$lib/state/settings.svelte'; import { settings } from '$lib/state/settings.svelte';
import { cn } from '$lib/utils/utils';
type Props = { type Props = {
class?: string; class?: string;
@ -23,7 +24,7 @@
}); });
</script> </script>
<select bind:value={settings.modelId} class="border {className}"> <select bind:value={settings.modelId} class={cn('border-border border', className)}>
{#each enabledArr as model (model._id)} {#each enabledArr as model (model._id)}
<option value={model.model_id}>{model.model_id}</option> <option value={model.model_id}>{model.model_id}</option>
{/each} {/each}