feat: Add syntax highlighting and horizontal scroll to chat code blocks (#394)

This commit is contained in:
Arjun Mehta
2025-08-25 11:42:50 +08:00
committed by GitHub
parent e6cb8d4a12
commit 31daae13fc
9 changed files with 370 additions and 34 deletions
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { useMarkdown } from '@proj-airi/stage-ui/composables'
import { MarkdownRenderer } from '@proj-airi/stage-ui/components'
import { useChatStore } from '@proj-airi/stage-ui/stores/chat'
import { storeToRefs } from 'pinia'
import { nextTick, ref } from 'vue'
@@ -10,7 +10,6 @@ const chatHistoryRef = ref<HTMLDivElement>()
const { t } = useI18n()
const { messages, sending } = storeToRefs(useChatStore())
const { process } = useMarkdown()
const { onBeforeMessageComposed, onTokenLiteral } = useChatStore()
onBeforeMessageComposed(async () => {
@@ -52,9 +51,11 @@ onTokenLiteral(async () => {
<div i-solar:danger-triangle-bold-duotone text-violet-500 />
</div>
<div v-if="sending && index === messages.length - 1" i-eos-icons:three-dots-loading />
<div
v-else class="markdown-content break-words text-violet-500" text="base <sm:xs"
v-html="process(message.content as string)"
<MarkdownRenderer
v-else
:content="message.content as string"
class="break-words text-violet-500"
text="base <sm:xs"
/>
</div>
</div>
@@ -66,7 +67,7 @@ onTokenLiteral(async () => {
<div>
<span text-xs text="primary-400/90 dark:primary-600/90" font-normal class="inline <sm:hidden">{{ t('stage.chat.message.character-name.airi') }}</span>
</div>
<div v-if="message.content && index === messages.length - 1" class="markdown-content break-words" text="xs primary-400">
<div v-if="message.content && index === messages.length - 1" class="break-words" text="xs primary-400">
<div v-for="(slice, sliceIndex) in message.slices" :key="sliceIndex">
<div v-if="slice.type === 'tool-call'">
<div
@@ -76,7 +77,10 @@ onTokenLiteral(async () => {
</div>
</div>
<div v-else-if="slice.type === 'tool-call-result'" /> <!-- this line should be unreachable -->
<div v-else v-html="process(slice.text)" />
<MarkdownRenderer
v-else
:content="slice.text"
/>
</div>
</div>
<div v-else i-eos-icons:three-dots-loading />
@@ -90,7 +94,12 @@ onTokenLiteral(async () => {
<div>
<span text-xs text="cyan-400/90 dark:cyan-600/90" font-normal class="inline <sm:hidden">{{ t('stage.chat.message.character-name.you') }}</span>
</div>
<div v-if="message.content" class="markdown-content break-words" text="base <sm:xs" v-html="process(message.content as string)" />
<MarkdownRenderer
v-if="message.content"
:content="message.content as string"
class="break-words"
text="base <sm:xs"
/>
<div v-else />
</div>
</div>
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { useMarkdown } from '@proj-airi/stage-ui/composables'
import { MarkdownRenderer } from '@proj-airi/stage-ui/components'
import { useChatStore } from '@proj-airi/stage-ui/stores/chat'
import { storeToRefs } from 'pinia'
import { nextTick, ref } from 'vue'
@@ -10,7 +10,6 @@ const chatHistoryRef = ref<HTMLDivElement>()
const { t } = useI18n()
const { messages, sending } = storeToRefs(useChatStore())
const { process } = useMarkdown()
const { onBeforeMessageComposed, onTokenLiteral } = useChatStore()
onBeforeMessageComposed(async () => {
@@ -52,9 +51,11 @@ onTokenLiteral(async () => {
<div i-solar:danger-triangle-bold-duotone text-violet-500 />
</div>
<div v-if="sending && index === messages.length - 1" i-eos-icons:three-dots-loading />
<div
v-else class="markdown-content break-words text-violet-500" text="base <sm:xs"
v-html="process(message.content as string)"
<MarkdownRenderer
v-else
:content="message.content as string"
class="break-words text-violet-500"
text="base <sm:xs"
/>
</div>
</div>
@@ -66,7 +67,7 @@ onTokenLiteral(async () => {
<div>
<span text-xs text="primary-400/90 dark:primary-600/90" font-normal class="inline <sm:hidden">{{ t('stage.chat.message.character-name.airi') }}</span>
</div>
<div v-if="message.content" class="markdown-content break-words" text="xs primary-400">
<div v-if="message.content" class="break-words" text="xs primary-400">
<div v-for="(slice, sliceIndex) in message.slices" :key="sliceIndex">
<div v-if="slice.type === 'tool-call'">
<div
@@ -76,7 +77,10 @@ onTokenLiteral(async () => {
</div>
</div>
<div v-else-if="slice.type === 'tool-call-result'" /> <!-- this line should be unreachable -->
<div v-else v-html="process(slice.text)" />
<MarkdownRenderer
v-else
:content="slice.text"
/>
</div>
</div>
<div v-else-if="index === messages.length - 1 && !message.content" i-eos-icons:three-dots-loading />
@@ -90,7 +94,12 @@ onTokenLiteral(async () => {
<div>
<span text-xs text="cyan-400/90 dark:cyan-600/90" font-normal class="inline <sm:hidden">{{ t('stage.chat.message.character-name.you') }}</span>
</div>
<div v-if="message.content" class="markdown-content break-words" text="base <sm:xs" v-html="process(message.content as string)" />
<MarkdownRenderer
v-if="message.content"
:content="message.content as string"
class="break-words"
text="base <sm:xs"
/>
<div v-else />
</div>
</div>
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { useMarkdown } from '@proj-airi/stage-ui/composables'
import { MarkdownRenderer } from '@proj-airi/stage-ui/components'
import { useChatStore } from '@proj-airi/stage-ui/stores/chat'
import { storeToRefs } from 'pinia'
import { nextTick, ref } from 'vue'
@@ -10,7 +10,6 @@ const chatHistoryRef = ref<HTMLDivElement>()
const { t } = useI18n()
const { messages } = storeToRefs(useChatStore())
const { process } = useMarkdown()
const { onBeforeMessageComposed, onTokenLiteral } = useChatStore()
onBeforeMessageComposed(async () => {
@@ -53,7 +52,12 @@ onTokenLiteral(async () => {
</div>
<div i-solar:danger-triangle-bold-duotone text-violet-500 />
</div>
<div v-if="message.content" class="markdown-content break-words" text="base <sm:xs" v-html="process(message.content as string)" />
<MarkdownRenderer
v-if="message.content"
:content="message.content as string"
class="break-words"
text="base <sm:xs"
/>
<div v-else i-eos-icons:three-dots-loading />
</div>
</div>
@@ -69,7 +73,12 @@ onTokenLiteral(async () => {
<div>
<span text="primary-400/90 dark:primary-600/90" text-xs font-normal class="inline <sm:hidden">{{ t('stage.chat.message.character-name.airi') }}</span>
</div>
<div v-if="message.content" class="markdown-content break-words" text="base <sm:xs" v-html="process(message.content as string)" />
<MarkdownRenderer
v-if="message.content"
:content="message.content as string"
class="break-words"
text="base <sm:xs"
/>
<div v-else i-eos-icons:three-dots-loading />
</div>
</div>
@@ -85,7 +94,12 @@ onTokenLiteral(async () => {
<div>
<span text-xs text="cyan-400/90 dark:cyan-600/90" font-normal class="inline <sm:hidden">{{ t('stage.chat.message.character-name.you') }}</span>
</div>
<div v-if="message.content" class="markdown-content break-words" text="base <sm:xs" v-html="process(message.content as string)" />
<MarkdownRenderer
v-if="message.content"
:content="message.content as string"
class="break-words"
text="base <sm:xs"
/>
<div v-else />
</div>
</div>
+2
View File
@@ -69,6 +69,7 @@
"@proj-airi/tauri-plugin-mcp": "workspace:^",
"@proj-airi/ui": "workspace:^",
"@ricky0123/vad-web": "^0.0.24",
"@shikijs/rehype": "^3.9.1",
"@tresjs/cientos": "^4.3.1",
"@tresjs/core": "^4.3.6",
"@tresjs/post-processing": "^2.4.0",
@@ -103,6 +104,7 @@
"reka-ui": "^2.4.1",
"remark-parse": "^11.0.0",
"remark-rehype": "^11.1.2",
"shiki": "^3.9.1",
"three": "^0.179.0",
"unified": "^11.0.5",
"unist-builder": "^4.0.0",
@@ -0,0 +1,89 @@
<script setup lang="ts">
import { onMounted, ref, watch } from 'vue'
import { useMarkdown } from '../composables/markdown'
interface Props {
content: string
class?: string
}
const props = defineProps<Props>()
const processedContent = ref('')
const { process, processSync } = useMarkdown()
async function processContent() {
if (!props.content) {
processedContent.value = ''
return
}
try {
processedContent.value = await process(props.content)
}
catch (error) {
console.warn('Failed to process markdown with syntax highlighting, using fallback:', error)
processedContent.value = processSync(props.content)
}
}
// Process content when it changes
watch(() => props.content, processContent, { immediate: true })
onMounted(() => {
processContent()
})
</script>
<template>
<div
:class="props.class"
class="markdown-content"
v-html="processedContent"
/>
</template>
<style scoped>
.markdown-content :deep(pre) {
overflow-x: auto;
max-width: 100%;
border-radius: 6px;
padding: 1rem;
margin: 0.5rem 0;
}
.markdown-content :deep(code) {
font-family: 'Fira Code', 'Monaco', 'Consolas', monospace;
font-size: 0.875em;
}
.markdown-content :deep(pre code) {
display: block;
width: fit-content;
min-width: 100%;
}
/* Ensure horizontal scrolling for wide code blocks */
.markdown-content :deep(pre.shiki) {
overflow-x: auto;
white-space: pre;
}
.markdown-content :deep(.shiki) {
border-radius: 6px;
padding: 1rem;
margin: 0.5rem 0;
}
/* Fallback styles for non-shiki code blocks */
.markdown-content :deep(pre:not(.shiki)) {
background: #f6f8fa;
border: 1px solid #d0d7de;
}
.dark .markdown-content :deep(pre:not(.shiki)) {
background: #161b22;
border: 1px solid #30363d;
}
</style>
@@ -1,9 +1,9 @@
<script setup lang="ts">
import { useMarkdown } from '../../composables/markdown'
import MarkdownRenderer from '../MarkdownRenderer.vue'
import { useChatStore } from '../../stores/chat'
const { streamingMessage } = useChatStore()
const { process } = useMarkdown()
</script>
<template>
@@ -20,7 +20,7 @@ const { process } = useMarkdown()
transform="translate-x--1/2"
>
<div bg="primary-50" rounded-xl px-10 py-6>
<div class="markdown-content" v-html="process(streamingMessage.content as string)" />
<MarkdownRenderer :content="streamingMessage.content as string" />
</div>
</div>
</template>
@@ -2,8 +2,10 @@ export * from './DataPane'
export * from './Gadgets'
export * from './Graphics'
export * from './Layouts'
export { default as MarkdownRenderer } from './MarkdownRenderer.vue'
export * from './Menu'
export * from './Misc'
export * from './Physics'
export * from './Scenarios'
export * from './Widgets'
+32 -3
View File
@@ -1,17 +1,46 @@
import rehypeShiki from '@shikijs/rehype'
import RehypeStringify from 'rehype-stringify'
import RemarkParse from 'remark-parse'
import RemarkRehype from 'remark-rehype'
import { unified } from 'unified'
async function createProcessor() {
return unified()
.use(RemarkParse)
.use(RemarkRehype)
.use(rehypeShiki, {
themes: {
light: 'github-light',
dark: 'github-dark',
},
})
.use(RehypeStringify)
}
export function useMarkdown() {
const instance = unified()
const fallbackProcessor = unified()
.use(RemarkParse)
.use(RemarkRehype)
.use(RehypeStringify)
return {
process: (markdown: string): string => {
return instance
process: async (markdown: string): Promise<string> => {
try {
const processor = await createProcessor()
const result = await processor.process(markdown)
return result.toString()
}
catch (error) {
console.warn('Failed to process markdown with syntax highlighting, falling back to basic processing:', error)
// Fallback to basic processor without highlighting
return fallbackProcessor.processSync(markdown).toString()
}
},
// Synchronous version for backward compatibility
processSync: (markdown: string): string => {
return fallbackProcessor
.processSync(markdown)
.toString()
},
+189 -7
View File
@@ -1131,7 +1131,7 @@ importers:
version: 0.1.3
unplugin-yaml:
specifier: ^3.0.2
version: 3.0.2(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(@nuxt/schema@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(astro@5.10.1(@types/node@24.1.0)(encoding@0.1.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(rollup@4.46.2)(terser@5.43.1)(tsx@4.20.3)(typescript@5.9.2)(yaml@2.8.0))(esbuild@0.25.8)(rolldown@1.0.0-beta.30)(rollup@4.46.2)(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0))
version: 3.0.2(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(@nuxt/schema@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(astro@5.10.1(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(rollup@4.46.2)(terser@5.43.1)(tsx@4.20.3)(typescript@5.9.2)(yaml@2.8.0))(esbuild@0.25.8)(rolldown@1.0.0-beta.30)(rollup@4.46.2)(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0))
vitepress:
specifier: ^2.0.0-alpha.9
version: 2.0.0-alpha.9(@types/node@24.1.0)(change-case@5.4.4)(fuse.js@7.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(nprogress@0.2.0)(postcss@8.5.6)(terser@5.43.1)(tsx@4.20.3)(typescript@5.9.2)(yaml@2.8.0)
@@ -1174,7 +1174,7 @@ importers:
devDependencies:
unplugin-yaml:
specifier: ^3.0.2
version: 3.0.2(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(@nuxt/schema@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(astro@5.10.1(@types/node@24.1.0)(encoding@0.1.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(rollup@4.46.2)(terser@5.43.1)(tsx@4.20.3)(typescript@5.9.2)(yaml@2.8.0))(esbuild@0.25.8)(rolldown@1.0.0-beta.30)(rollup@4.46.2)(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0))
version: 3.0.2(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(@nuxt/schema@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(astro@5.10.1(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(rollup@4.46.2)(terser@5.43.1)(tsx@4.20.3)(typescript@5.9.2)(yaml@2.8.0))(esbuild@0.25.8)(rolldown@1.0.0-beta.30)(rollup@4.46.2)(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0))
packages/memory-pgvector:
dependencies:
@@ -1323,6 +1323,9 @@ importers:
'@ricky0123/vad-web':
specifier: ^0.0.24
version: 0.0.24
'@shikijs/rehype':
specifier: ^3.9.1
version: 3.11.0
'@tresjs/cientos':
specifier: ^4.3.1
version: 4.3.1(@tresjs/core@4.3.6(three@0.179.0)(typescript@5.9.2)(vue@3.5.18(typescript@5.9.2)))(@types/three@0.178.1)(react@18.3.1)(three@0.179.0)(typescript@5.9.2)(vue@3.5.18(typescript@5.9.2))
@@ -1425,6 +1428,9 @@ importers:
remark-rehype:
specifier: ^11.1.2
version: 11.1.2
shiki:
specifier: ^3.9.1
version: 3.9.1
three:
specifier: ^0.179.0
version: 0.179.0
@@ -1557,7 +1563,7 @@ importers:
version: 1.2.4(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(@nuxt/schema@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(esbuild@0.25.8)(rollup@4.46.2)(vite@6.3.5(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0))
unplugin-yaml:
specifier: ^3.0.2
version: 3.0.2(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(@nuxt/schema@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(astro@5.10.1(@types/node@24.1.0)(encoding@0.1.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(rollup@4.46.2)(terser@5.43.1)(tsx@4.20.3)(typescript@5.9.2)(yaml@2.8.0))(esbuild@0.25.8)(rolldown@1.0.0-beta.30)(rollup@4.46.2)(vite@6.3.5(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0))
version: 3.0.2(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(@nuxt/schema@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(astro@5.10.1(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(rollup@4.46.2)(terser@5.43.1)(tsx@4.20.3)(typescript@5.9.2)(yaml@2.8.0))(esbuild@0.25.8)(rolldown@1.0.0-beta.30)(rollup@4.46.2)(vite@6.3.5(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0))
vite:
specifier: ^6.3.5
version: 6.3.5(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)
@@ -5605,15 +5611,27 @@ packages:
'@sec-ant/readable-stream@0.4.1':
resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==}
'@shikijs/core@3.11.0':
resolution: {integrity: sha512-oJwU+DxGqp6lUZpvtQgVOXNZcVsirN76tihOLBmwILkKuRuwHteApP8oTXmL4tF5vS5FbOY0+8seXmiCoslk4g==}
'@shikijs/core@3.9.1':
resolution: {integrity: sha512-W5Vwen0KJCtR7KFRo+3JLGAqLUPsfW7e+wZ4yaRBGIogwI9ZlnkpRm9ZV8JtfzMxOkIwZwMmmN0hNErLtm3AYg==}
'@shikijs/engine-javascript@3.11.0':
resolution: {integrity: sha512-6/ov6pxrSvew13k9ztIOnSBOytXeKs5kfIR7vbhdtVRg+KPzvp2HctYGeWkqv7V6YIoLicnig/QF3iajqyElZA==}
'@shikijs/engine-javascript@3.9.1':
resolution: {integrity: sha512-4hGenxYpAmtALryKsdli2K58F0s7RBYpj/RSDcAAGfRM6eTEGI5cZnt86mr+d9/4BaZ5sH5s4p3VU5irIdhj9Q==}
'@shikijs/engine-oniguruma@3.11.0':
resolution: {integrity: sha512-4DwIjIgETK04VneKbfOE4WNm4Q7WC1wo95wv82PoHKdqX4/9qLRUwrfKlmhf0gAuvT6GHy0uc7t9cailk6Tbhw==}
'@shikijs/engine-oniguruma@3.9.1':
resolution: {integrity: sha512-WPlL/xqviwS3te4unSGGGfflKsuHLMI6tPdNYvgz/IygcBT6UiwDFSzjBKyebwi5GGSlXsjjdoJLIBnAplmEZw==}
'@shikijs/langs@3.11.0':
resolution: {integrity: sha512-Njg/nFL4HDcf/ObxcK2VeyidIq61EeLmocrwTHGGpOQx0BzrPWM1j55XtKQ1LvvDWH15cjQy7rg96aJ1/l63uw==}
'@shikijs/langs@3.9.1':
resolution: {integrity: sha512-Vyy2Yv9PP3Veh3VSsIvNncOR+O93wFsNYgN2B6cCCJlS7H9SKFYc55edsqernsg8WT/zam1cfB6llJsQWLnVhA==}
@@ -5625,12 +5643,21 @@ packages:
markdown-it-async:
optional: true
'@shikijs/rehype@3.11.0':
resolution: {integrity: sha512-4njEqPBoFn+fsQqSOEw8OjiIIg52jBM0I2qRC1NALFFmQm97qZuQvP570RI94HvAfzCT6agG6ZFBPofrNZ4tlQ==}
'@shikijs/themes@3.11.0':
resolution: {integrity: sha512-BhhWRzCTEk2CtWt4S4bgsOqPJRkapvxdsifAwqP+6mk5uxboAQchc0etiJ0iIasxnMsb764qGD24DK9albcU9Q==}
'@shikijs/themes@3.9.1':
resolution: {integrity: sha512-zAykkGECNICCMXpKeVvq04yqwaSuAIvrf8MjsU5bzskfg4XreU+O0B5wdNCYRixoB9snd3YlZ373WV5E/g5T9A==}
'@shikijs/transformers@3.9.1':
resolution: {integrity: sha512-QI4Bh565EhKGaefiDAyn5o7S8rQIUGXcOjZANSiQHa/KSGCyJTZP9UUiRbvdovVpaI/nagODX6mspFk/vcYOQQ==}
'@shikijs/types@3.11.0':
resolution: {integrity: sha512-RB7IMo2E7NZHyfkqAuaf4CofyY8bPzjWPjJRzn6SEak3b46fIQyG6Vx5fG/obqkfppQ+g8vEsiD7Uc6lqQt32Q==}
'@shikijs/types@3.9.1':
resolution: {integrity: sha512-rqM3T7a0iM1oPKz9iaH/cVgNX9Vz1HERcUcXJ94/fulgVdwqfnhXzGxO4bLrAnh/o5CPLy3IcYedogfV+Ns0Qg==}
@@ -11659,6 +11686,9 @@ packages:
shellwords@0.1.1:
resolution: {integrity: sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==}
shiki@3.11.0:
resolution: {integrity: sha512-VgKumh/ib38I1i3QkMn6mAQA6XjjQubqaAYhfge71glAll0/4xnt8L2oSuC45Qcr/G5Kbskj4RliMQddGmy/Og==}
shiki@3.9.1:
resolution: {integrity: sha512-HogZ8nMnv9VAQMrG+P7BleJFhrKHm3fi6CYyHRbUu61gJ0lpqLr6ecYEui31IYG1Cn9Bad7N2vf332iXHnn0bQ==}
@@ -17464,6 +17494,13 @@ snapshots:
'@sec-ant/readable-stream@0.4.1': {}
'@shikijs/core@3.11.0':
dependencies:
'@shikijs/types': 3.11.0
'@shikijs/vscode-textmate': 10.0.2
'@types/hast': 3.0.4
hast-util-to-html: 9.0.5
'@shikijs/core@3.9.1':
dependencies:
'@shikijs/types': 3.9.1
@@ -17471,17 +17508,32 @@ snapshots:
'@types/hast': 3.0.4
hast-util-to-html: 9.0.5
'@shikijs/engine-javascript@3.11.0':
dependencies:
'@shikijs/types': 3.11.0
'@shikijs/vscode-textmate': 10.0.2
oniguruma-to-es: 4.3.3
'@shikijs/engine-javascript@3.9.1':
dependencies:
'@shikijs/types': 3.9.1
'@shikijs/vscode-textmate': 10.0.2
oniguruma-to-es: 4.3.3
'@shikijs/engine-oniguruma@3.11.0':
dependencies:
'@shikijs/types': 3.11.0
'@shikijs/vscode-textmate': 10.0.2
'@shikijs/engine-oniguruma@3.9.1':
dependencies:
'@shikijs/types': 3.9.1
'@shikijs/vscode-textmate': 10.0.2
'@shikijs/langs@3.11.0':
dependencies:
'@shikijs/types': 3.11.0
'@shikijs/langs@3.9.1':
dependencies:
'@shikijs/types': 3.9.1
@@ -17491,6 +17543,19 @@ snapshots:
markdown-it: 14.1.0
shiki: 3.9.1
'@shikijs/rehype@3.11.0':
dependencies:
'@shikijs/types': 3.11.0
'@types/hast': 3.0.4
hast-util-to-string: 3.0.1
shiki: 3.11.0
unified: 11.0.5
unist-util-visit: 5.0.0
'@shikijs/themes@3.11.0':
dependencies:
'@shikijs/types': 3.11.0
'@shikijs/themes@3.9.1':
dependencies:
'@shikijs/types': 3.9.1
@@ -17500,6 +17565,11 @@ snapshots:
'@shikijs/core': 3.9.1
'@shikijs/types': 3.9.1
'@shikijs/types@3.11.0':
dependencies:
'@shikijs/vscode-textmate': 10.0.2
'@types/hast': 3.0.4
'@shikijs/types@3.9.1':
dependencies:
'@shikijs/vscode-textmate': 10.0.2
@@ -19649,6 +19719,107 @@ snapshots:
- yaml
optional: true
astro@5.10.1(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(rollup@4.46.2)(terser@5.43.1)(tsx@4.20.3)(typescript@5.9.2)(yaml@2.8.0):
dependencies:
'@astrojs/compiler': 2.12.2
'@astrojs/internal-helpers': 0.6.1
'@astrojs/markdown-remark': 6.3.2
'@astrojs/telemetry': 3.3.0
'@capsizecss/unpack': 2.4.0(encoding@0.1.13)
'@oslojs/encoding': 1.1.0
'@rollup/pluginutils': 5.2.0(rollup@4.46.2)
acorn: 8.15.0
aria-query: 5.3.2
axobject-query: 4.1.0
boxen: 8.0.1
ci-info: 4.3.0
clsx: 2.1.1
common-ancestor-path: 1.0.1
cookie: 1.0.2
cssesc: 3.0.0
debug: 4.4.1
deterministic-object-hash: 2.0.2
devalue: 5.1.1
diff: 5.2.0
dlv: 1.1.3
dset: 3.1.4
es-module-lexer: 1.7.0
esbuild: 0.25.8
estree-walker: 3.0.3
flattie: 1.1.1
fontace: 0.3.0
github-slugger: 2.0.0
html-escaper: 3.0.3
http-cache-semantics: 4.2.0
import-meta-resolve: 4.1.0
js-yaml: 4.1.0
kleur: 4.1.5
magic-string: 0.30.17
magicast: 0.3.5
mrmime: 2.0.1
neotraverse: 0.6.18
p-limit: 6.2.0
p-queue: 8.1.0
package-manager-detector: 1.3.0
picomatch: 4.0.3
prompts: 2.4.2
rehype: 13.0.2
semver: 7.7.2
shiki: 3.9.1
tinyexec: 0.3.2
tinyglobby: 0.2.14
tsconfck: 3.1.6(typescript@5.9.2)
ultrahtml: 1.6.0
unifont: 0.5.2
unist-util-visit: 5.0.0
unstorage: 1.16.0
vfile: 6.0.3
vite: 6.3.5(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)
vitefu: 1.0.7(vite@6.3.5(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0))
xxhash-wasm: 1.1.0
yargs-parser: 21.1.1
yocto-spinner: 0.2.3
zod: 3.25.76
zod-to-json-schema: 3.24.6(zod@3.25.76)
zod-to-ts: 1.2.0(typescript@5.9.2)(zod@3.25.76)
optionalDependencies:
sharp: 0.33.5
transitivePeerDependencies:
- '@azure/app-configuration'
- '@azure/cosmos'
- '@azure/data-tables'
- '@azure/identity'
- '@azure/keyvault-secrets'
- '@azure/storage-blob'
- '@capacitor/preferences'
- '@deno/kv'
- '@netlify/blobs'
- '@planetscale/database'
- '@types/node'
- '@upstash/redis'
- '@vercel/blob'
- '@vercel/kv'
- aws4fetch
- db0
- encoding
- idb-keyval
- ioredis
- jiti
- less
- lightningcss
- rollup
- sass
- sass-embedded
- stylus
- sugarss
- supports-color
- terser
- tsx
- typescript
- uploadthing
- yaml
optional: true
async-mutex@0.3.2:
dependencies:
tslib: 2.8.1
@@ -25288,6 +25459,17 @@ snapshots:
shellwords@0.1.1: {}
shiki@3.11.0:
dependencies:
'@shikijs/core': 3.11.0
'@shikijs/engine-javascript': 3.11.0
'@shikijs/engine-oniguruma': 3.11.0
'@shikijs/langs': 3.11.0
'@shikijs/themes': 3.11.0
'@shikijs/types': 3.11.0
'@shikijs/vscode-textmate': 10.0.2
'@types/hast': 3.0.4
shiki@3.9.1:
dependencies:
'@shikijs/core': 3.9.1
@@ -26516,7 +26698,7 @@ snapshots:
rollup: 4.46.2
vite: rolldown-vite@7.0.12(@types/node@24.1.0)(esbuild@0.25.8)(jiti@2.5.1)(less@4.4.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)
unplugin-yaml@3.0.2(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(@nuxt/schema@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(astro@5.10.1(@types/node@24.1.0)(encoding@0.1.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(rollup@4.46.2)(terser@5.43.1)(tsx@4.20.3)(typescript@5.9.2)(yaml@2.8.0))(esbuild@0.25.8)(rolldown@1.0.0-beta.30)(rollup@4.46.2)(vite@6.3.5(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)):
unplugin-yaml@3.0.2(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(@nuxt/schema@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(astro@5.10.1(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(rollup@4.46.2)(terser@5.43.1)(tsx@4.20.3)(typescript@5.9.2)(yaml@2.8.0))(esbuild@0.25.8)(rolldown@1.0.0-beta.30)(rollup@4.46.2)(vite@6.3.5(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)):
dependencies:
'@rollup/pluginutils': 5.2.0(rollup@4.46.2)
unplugin: 2.3.5
@@ -26524,13 +26706,13 @@ snapshots:
optionalDependencies:
'@nuxt/kit': 3.14.1592(magicast@0.3.5)(rollup@4.46.2)
'@nuxt/schema': 3.14.1592(magicast@0.3.5)(rollup@4.46.2)
astro: 5.10.1(@types/node@24.1.0)(encoding@0.1.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(rollup@4.46.2)(terser@5.43.1)(tsx@4.20.3)(typescript@5.9.2)(yaml@2.8.0)
astro: 5.10.1(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(rollup@4.46.2)(terser@5.43.1)(tsx@4.20.3)(typescript@5.9.2)(yaml@2.8.0)
esbuild: 0.25.8
rolldown: 1.0.0-beta.30
rollup: 4.46.2
vite: 6.3.5(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)
unplugin-yaml@3.0.2(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(@nuxt/schema@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(astro@5.10.1(@types/node@24.1.0)(encoding@0.1.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(rollup@4.46.2)(terser@5.43.1)(tsx@4.20.3)(typescript@5.9.2)(yaml@2.8.0))(esbuild@0.25.8)(rolldown@1.0.0-beta.30)(rollup@4.46.2)(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)):
unplugin-yaml@3.0.2(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(@nuxt/schema@3.14.1592(magicast@0.3.5)(rollup@4.46.2))(astro@5.10.1(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(rollup@4.46.2)(terser@5.43.1)(tsx@4.20.3)(typescript@5.9.2)(yaml@2.8.0))(esbuild@0.25.8)(rolldown@1.0.0-beta.30)(rollup@4.46.2)(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)):
dependencies:
'@rollup/pluginutils': 5.2.0(rollup@4.46.2)
unplugin: 2.3.5
@@ -26538,7 +26720,7 @@ snapshots:
optionalDependencies:
'@nuxt/kit': 3.14.1592(magicast@0.3.5)(rollup@4.46.2)
'@nuxt/schema': 3.14.1592(magicast@0.3.5)(rollup@4.46.2)
astro: 5.10.1(@types/node@24.1.0)(encoding@0.1.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(rollup@4.46.2)(terser@5.43.1)(tsx@4.20.3)(typescript@5.9.2)(yaml@2.8.0)
astro: 5.10.1(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(rollup@4.46.2)(terser@5.43.1)(tsx@4.20.3)(typescript@5.9.2)(yaml@2.8.0)
esbuild: 0.25.8
rolldown: 1.0.0-beta.30
rollup: 4.46.2