Skip to content

Velloo documentation

Markdown for LLMs ↗

MCP: codegen

emit_code and emit_snippet return agent-consumed IR in the screen framework's native idiom; emit_theme writes the framework's theme artifacts and a DTCG tokens file.

Velloo is the design source; the agent is the bridge to code. emit_code and emit_snippet return a structured, JSX-shaped intermediate representation meant for the agent to read and transform into the user’s app code, using the app’s conventions, routing, and providers. It is not paste-ready output: no import statements, no function wrapper, no prettier pass. emit_theme is the exception: direct, user-facing artifacts that need no agent translation. Workflow: Emit to code.

Emit is per screen or per snippet. Board layout (frames, positions, groups) is canvas metadata and is never part of the emitted code.

emit_code

Return agent-consumed IR for a screen, plus a full diagnostic pass over it.

ArgTypeRequiredDescription
screenIdstringyes
componentsAliasstringnoOverrides the components import prefix the IR is built against. Defaults to config.codegen.componentsAlias, else @/components/ui

Returns:

FieldDescription
screen{ id, name }
jsxThe JSX body: no imports, no wrapper
componentsUsedLibrary component identifiers referenced in the tree
iconsUsedIcon names rendered as JSX tags (<ArrowRight />), imported from lucide-react
snippetsUsedEach referenced snippet’s own IR (the emit_snippet shape), to materialize as a component or inline
classesUsedUnique Tailwind classes in the emitted JSX
componentsToInstallshadcn primitives the app needs, as kebab names ready for npx shadcn@latest add. Empty for native-framework and inline-style targets
helpersToMaterializeVelloo composition helpers with runtime logic (such as Gradient, SVG, Image, Layer, Divider) that the agent must author in the app. Empty for native-framework and inline-style targets
warningsNon-fatal caveats: things JSX couldn’t express faithfully, such as an unresolved icon name
tailwindV3CompatOnly when the host app is on Tailwind v3: [{ class, v3?, note }], the v4 classes to rename (or rework) while writing the file, covering the screen and its snippets
diagnosticsOnly when there is something to fix: the full-screen diagnostics pass

The JSX uses the screen framework’s native idiom:

  • shadcn: library component identifiers with Tailwind classes
  • MUI (and other native-framework libraries): components imported from the framework’s own module, styled with sx objects
  • no-framework, Tailwind channel: plain-HTML primitives with Tailwind classes
  • no-framework, inline-style channel (a none/none folder): Tailwind-free plain HTML with inline style objects

Snippet instances emit as component references with the snippet’s PascalCase name, matching emit_snippet; an instance’s extra classes pass as a className prop. An instance carrying $overrides can’t be expressed by the shared component, so its body is inlined instead: args substituted, overrides and extra classes applied. Extension nodes emit under their own id with the extension’s declared importPath. A node carrying $emitAs emits as a bare <Name /> of the named host component instead of its design subtree.

Errors: ScreenNotFound, UnknownComponent, SnippetNotFound.

emit_snippet

Same idea, scoped to a single snippet.

ArgTypeRequiredDescription
snippetIdstringyes
componentsAliasstringnoSame default chain as emit_code

Returns { id, componentName, params, jsx, componentsToInstall, helpersToMaterialize, warnings }: the PascalCase component name, the typed params (name, type, and default / optional where declared), and the JSX body with $param references emitted as {name}, plus tailwindV3Compat and diagnostics under the same conditions as emit_code.

emit_theme

Generate theme artifacts for the folder’s default library from a theme. Dry-run by default; the output is direct: write it as returned.

ArgTypeRequiredDescription
outputDirstringyesTarget app directory (relative paths resolve from the design folder root)
cssPathstringnoTailwind targets: globals.css location relative to outputDir; default app/globals.css (pass globals.css or src/index.css for Vite/Astro layouts)
themePathstringnoNative-framework targets: theme module location relative to outputDir; default depends on the framework (theme.ts for MUI)
applybooleannoWrite the files. Default false; dry-run returns per-file diffs
cssOnlybooleannoTailwind targets: skip the Tailwind config (v4) or preset (v3) file
themestringnoNamed theme to emit; default "default"
tailwind3 or 4noForce the Tailwind major of the emitted artifacts. Default: detected from outputDir’s package.json, falling back to v4

cssPath and themePath must stay inside outputDir; an absolute path or one that escapes with .. is rejected.

Per target:

  • Tailwind v4 (shadcn and Tailwind-channel folders): globals.css at cssPath, with the token tree as CSS custom properties and an @theme block, and the folder’s custom CSS appended; a typeset.css stylesheet next to it, which globals.css imports; and tailwind.config.ts in outputDir unless cssOnly.
  • Tailwind v3: never overwrites the app’s globals file. It writes velloo-theme.css in the same directory as cssPath (custom CSS appended), a velloo-typeset.css beside it, and, unless cssOnly, a Tailwind preset in outputDir: velloo.preset.ts when the app has a TypeScript Tailwind config, otherwise velloo.preset.cjs. notes spell out the @import lines and the presets registration to add by hand.
  • Native frameworks: a theme module at themePath exporting theme, built with the framework’s factory (createTheme(...) for MUI, extendTheme(...) for Chakra UI), plus a darkTheme export when the theme defines dark colors.

Every target also writes a framework-neutral DTCG tokens.json in outputDir.

Returns { files, warnings?, notes? }. Each file entry carries path, contents, a diff against what’s on disk, and whether it was applied. On Tailwind targets, warnings flag palette tokens skipped because they would shadow a semantic slot, and what tokens.json leaves out; native-framework targets return files only.