feat: Replace DB component tools with filesystem-based user-components/

Components are now .vue files in user-components/<folder>/ parsed at runtime.
Replaces 6 DB MCP tools with 2 (list_fs_components, load_fs_component).
Adds vue-parser, fs-components API, and file watcher for live reload.
This commit is contained in:
2026-02-18 10:24:05 -06:00
parent e9451b2a47
commit d27da30494
13 changed files with 597 additions and 19 deletions

View File

@@ -0,0 +1,24 @@
import { join } from 'path'
import { jsonResponse, errorResponse } from '../utils/cors'
import { USER_COMPONENTS_DIR, WORKING_DIR } from '../config'
import { listAllComponents, parseComponentFolder } from '../services/vue-parser'
const baseDir = join(WORKING_DIR, USER_COMPONENTS_DIR)
export function handleFsComponents(req: Request) {
if (req.method !== 'GET') return null
const components = listAllComponents(baseDir)
return jsonResponse(components)
}
export function handleFsComponentByName(req: Request, folderName: string) {
if (req.method !== 'GET') return null
const component = parseComponentFolder(baseDir, folderName)
if (!component) {
return errorResponse(`Component folder "${folderName}" not found or has no .vue file`, 404)
}
return jsonResponse(component)
}

View File

@@ -3,6 +3,7 @@ import { handleHistory } from './history'
import { handleConfig, handleHealth } from './config'
import { handleWebMCPToken, handleWebMCPRequestToken } from './webmcp'
import { handleComponents, handleComponentById, handleComponentUsage } from './components'
import { handleFsComponents, handleFsComponentByName } from './fs-components'
import { handleThemes, handleActiveTheme, handleDesignTokens, handleThemeById, handleThemeExport } from './themes'
import { handleCanvas, handleCanvasById, handleToolbarCanvas, handleDefaultCanvas, handleCanvasComponents, handleCanvasComponentById } from './canvas'
import { handleGiteaRepo, handleGiteaTree, handleGiteaFile } from './gitea'
@@ -107,6 +108,18 @@ export async function handleRequest(req: Request): Promise<Response> {
if (res) return res
}
// Filesystem components
if (path === '/api/fs-components') {
const res = handleFsComponents(req)
if (res) return res
}
if (path.startsWith('/api/fs-components/')) {
const folderName = path.split('/').pop()!
const res = handleFsComponentByName(req, folderName)
if (res) return res
}
// Themes
if (path === '/api/themes') {
const res = await handleThemes(req)