/**
* Auto-discovered registry of UI components rendered by the navi_ui MCP server.
*
* Add a new Vue SFC named in PascalCase matching the snake_case component name:
* card_grid -> CardGrid.vue
* code_block -> CodeBlock.vue
*
* The registry exports:
* - resolve(name): look up a component constructor by snake_case name
* - list(): array of registered names
*/
import { defineAsyncComponent, markRaw } from 'vue'
const modules = import.meta.glob('./*.vue', { eager: true })
function pascalCaseFromSnake(name) {
return name
.split('_')
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
.join('')
}
const registry = new Map()
for (const path in modules) {
const fileName = path.replace(/^.*\//, '').replace(/\.vue$/, '')
const component = modules[path].default
if (!component) continue
// Register under PascalCase file name (e.g. CardGrid)
registry.set(fileName, markRaw(component))
// Also register under snake_case alias (e.g. card_grid)
const snakeAlias = fileName
.replace(/([a-z0-9])([A-Z])/g, '$1_$2')
.toLowerCase()
registry.set(snakeAlias, markRaw(component))
}
export function resolve(name) {
if (!name || typeof name !== 'string') return null
if (registry.has(name)) return registry.get(name)
const pascal = pascalCaseFromSnake(name)
return registry.get(pascal) || null
}
export function list() {
return Array.from(registry.keys())
}