AI app-builder
Turn a natural-language prompt into a real app — graph + files — gated by the framework's own `voltro check` (errors-as-LLM-API), never auto-written. Drive it from the CLI (`voltro generate`) or the cloud dashboard, with an in-browser live preview of the result.
The app-builder turns a natural-language prompt into a working app — the app
GRAPH (tables + procedures + routes) plus the FILES that realise it — and it does
so without ever trusting the model to be right. Every candidate is run through
the framework's own voltro check; a structurally-invalid proposal is re-prompted
with its typed diagnostics and never written. Nothing hits your tree (or
deploys) without an explicit accept.
The loop (errors-as-LLM-API)
prompt ─▶ model proposes { graph, artifacts } ─▶ voltro check(graph)
▲ │
└────── diagnostics fed back ◀── fails ──┤
└── passes ─▶ proposalThe model only ever sees the framework's capability grammar (the primitives +
your existing tables/procedures), and the real allow-list is runCheck — so a
hallucinated table or an unbound route is caught and corrected, not shipped. After
a bounded number of failed rounds the run is rejected; either way nothing is
written.
From the CLI — voltro generate
voltro generate "add a comments table with a list + create" # dry-run: prints the proposal
voltro generate "add a comments table with a list + create" --write # applies the accepted artifactsReads the committed capability manifest (app.manifest.generated.json) as the
grammar, gates every candidate through voltro check, and writes only an
accepted proposal only with --write (dry-run by default — the guardrail).
See Scaffolding for the full flag
list.
From the cloud dashboard
The dashboard's /builder panel drives the apps.generateAppGraph action,
which runs the same loop server-side and returns a proposal for review — it
never writes or deploys. The whole surface is behind the aiBuilder feature
flag (off by default → a typed FlagDisabled), so you opt projects in
deliberately. A model provider (AI_PROVIDER / AI_MODEL + key) backs the
generation.
Live preview — runs in your browser
Below an accepted proposal, the builder renders a live, interactive preview that runs the generated app's data behaviour entirely in your browser — an in-memory reactive store + an interpreter over the proposal graph + the columns parsed from the entity artifacts. No server, no provisioning, no compile. Try it right here — add a row and watch it appear in that table's live list, reactively:
// Fed a sample generated proposal — the { graph, artifacts } apps.generateAppGraph returns.
<GeneratedAppPreview graph={proposal.graph} artifacts={proposal.artifacts} />
Each generated table gets a real create form (fields + widgets derived from its columns) and a live list; submitting the form writes to the in-memory store, which pushes to the open list — the same write→push reactivity the real runtime gives.
Guardrails
- Never auto-writes. CLI: dry-run unless
--write. Cloud: a proposal you review, never an auto-deploy. voltro checkgate. A proposal is accepted only whenrunCheck(graph).ok; a structurally-invalid one is re-prompted, then rejected — never written.- Flag-gated (cloud).
aiBuilderis off by default; the endpoint failsFlagDisableduntil an operator turns it on. - Size caps. Generation is bounded by file count + total bytes.
What the preview is — and isn't
The preview simulates the app from its spec: it interprets the graph + parsed columns against an in-memory store, giving faithful CRUD + reactivity without any infrastructure. It does not execute the literal generated TypeScript against a database — the deployed app does that, running the real artifacts on a real store. So the preview is a true feel for how the app behaves, not a bit-for-bit run of the code.