PIES Studio 1.7 · User Manual
From an empty workspace to a deployed application: creating an app, building with PIES AI, configuring it by hand, previewing a real build, deploying, and managing what is live.
PIES Studio is a browser IDE: you describe or draw an application, and it generates a working front end, back end and database. Everything below was captured from a running Studio, so what you see here is what the product does today — not a mock-up.
Open Studio and sign in with your PIES account. Enterprise installs can also use Sign in with Microsoft when SSO is configured.
After signing in you land on your applications. Applications are grouped into workspaces — use one per team or per client. This is where you come back to open, duplicate or delete an app.
The same editor runs whether or not it is connected to anything. What changes is what it can reach — and that is the difference between the plans.
The local IDE is the client, not an edition of the product: it ships in every plan. What differs is what it connects to — nothing at all, a PIES-operated server, or a server your organisation runs.
Everything that makes an application: creating it, designing screens,
authoring events and functions, the data model, and building and previewing it
locally. The IDE carries its own stack — database, back end, build toolchain and
their caches — so a machine that has never been online can create an application,
build it and run it.
AI works offline too, against a model on your own machine or in your own network.
Nothing you type and nothing your application contains leaves the device.
Features that are inherently about somewhere else are unavailable offline
and shown with a lock: hosting and deployment, boards
and team collaboration, mobile publishing, choosing a different
language or stack, cloud storage and backup, and the full
AI governance surface — policies, audit and knowledge bases.
Offline, the AI settings remain so you can point the editor at your own model.
None of this changes the application you have built. Connecting later unlocks
those features against work you already did offline.
An Enterprise install puts the server inside your network: your database, your identity provider, your audit trail. Paired with PIES Private AI the whole system — editor, platform and model — runs with no external dependency at all, which is what an air-gapped environment requires. See the installation guide for the platform and the PIES Private AI manual for the model.
An application is the whole deliverable: data model, screens, business logic, generated code and its deployments.
Click New Application, give it a name and pick a workspace (you can type a new workspace name to create one). Names take letters, digits and spaces — hyphens are rejected. From Template starts from a published template instead of an empty app.
The app opens in the editor. The left rail is the explorer — every object in your application. The centre is the canvas for whatever you have open. The right is PIES AI and the properties panel, and the bottom is the build console.
Read this chapter once and the rest of the product stops being surprising. PIES has a small number of object types and one strict rule about which does what — the same rule the AI is held to, and the same one the build validates.
Screens hold widgets (a table, a form, a
button, a chart). A widget raises an event — "this button was
clicked". The event calls a function, and the function is built
from steps: read a record, validate it, write it, return a
result. The event then reacts to that result — show a message, navigate,
refresh a table.
The division is deliberate, and the build enforces it:
Database holds tables and their relationships. Endpoints expose functions as REST APIs. Processes are long-running business workflows rather than single actions. Access Control defines groups and what each may see or do. Resources are things the app needs but does not own — email servers, secrets, environments. Components are your own custom widgets. Artefacts are documents (a BRS, a spec) that PIES AI reads before it builds.
Screens, functions and events can be grouped into folders in the explorer, and a folder can hold another. The grouping is yours — by feature, by area of the business, by whatever makes the application readable a year from now. Creating a screen inside a folder puts it there directly; dragging moves it later. Folders are presentation only: nothing about the application changes when you reorganise them.
Every application has an internal database and can additionally connect to databases you already run. You never write DDL — the schema is generated from what you define here, for every environment.
Open a table under Database to edit its columns: name, type, and constraints such as primary key, auto-increment, required or unique. PIES maintains the key and audit columns it needs, so a table you create is immediately usable by screens and functions. Seed rows can be attached to a table so previews render against realistic data.
Relationships shows the entity diagram: every table and the links between them. Define a relationship here — one-to-many, many-to-many — and PIES creates the keys (and the join table where one is needed), then makes the related data available to widgets: a dropdown bound to the parent, a table showing the child rows. The diagram is the fastest way to see whether a model — yours or one the AI generated — is actually normalised.
An application is not limited to its internal database: add a source to work against one you already run — MySQL, PostgreSQL, Snowflake and others, plus Zetaris for read-only analytics. Credentials go to the secret store, never into the application definition. Connected tables appear alongside the internal ones and can feed screens, functions and charts.
A screen is a canvas. You place widgets on it, bind them to data, and wire their events. What you place is what renders — the canvas resolves widths against the same drawable area the generated application uses.
The palette groups widgets by kind: Input (text, number, date, dropdown, checkbox…), Data (table, form, count card), Visualization (bar, line, pie and the ECharts family), Visual (text, image, divider) and Shape. Drag one onto the canvas to place it.
Select a widget and the right panel configures it: which table or query feeds it, which columns show, validation, default values, styling, and its events. A data table takes its columns from the bound table; a chart takes a measure and a dimension. Containers group widgets and lay them out in flex or grid, so a screen keeps its shape at different widths.
When nothing in the palette fits — a signature pad, a Kanban board, a third-party SDK — build a custom widget in the Widget Designer and it appears in the palette like any other. Custom widgets targeting a screen or event are React and run in the browser; those targeting a function are Go and run on the server. This is what stops a no-code application hitting a ceiling: you drop to code for one component, and everything around it stays generated.
This is where an application stops being a set of screens and starts doing something. Events and functions are built the same way — a flow of steps — but they are allowed to do different things.
An event is triggered by a widget: a button click, a row selection, a screen load. Its steps call a function and then branch on the result — show a success message, show the error, navigate to another screen, refresh a table. An event must not touch the database directly; it asks a function to.
A function takes parameters, does the work, and returns data. It is drawn as a flow: one start, one end, no orphans — the build rejects anything else. Inside, steps read and write records, call other functions, transform values, branch on conditions, loop, call REST APIs, send email.
Add a step from the catalogue and configure it: which data source it acts on, where its input comes from (a parameter, an earlier step's output, a literal), and where its output goes. Steps are chained by linking them, and a later step reads an earlier one's result by referencing it. The groups are Record (insert, update, delete, retrieve), Control (if, loop, end), String, Numeric, Date, Communication (email) and Retrieve (queries) — plus Return Data, which hands a result back to whatever called the function.
A process models work that spans time and people — approvals, onboarding, case handling — rather than a single action. It is a workflow of tasks and gateways, and the engine tracks each running instance. Use a function for "save this record"; use a process for "get this contract approved".
Applications produce paperwork — agreements, invoices, reports. In PIES the paperwork is designed once as a document template, and the running application fills it with live data, renders it as a PDF on the server, and either downloads it in the browser or emails it as an attachment. The text stays crisp and selectable — these are real PDFs, not screenshots of a page.
Each application carries its own document templates. They live in the explorer under DOCUMENT TEMPLATES, alongside screens and functions. The + button creates one; clicking a template opens it as an editor tab. Templates are part of the application, so they version, export and deploy with it.
The template editor has three panes. On the left, the document's frame:
page size and orientation, a header (logo, title, subtitle) that repeats on
every page, a footer with optional page numbers, and the base font and accent
colour. In the middle, the content as an ordered list of sections —
headings, paragraphs, key-value blocks, tables, images, signature lines,
dividers and page breaks — each edited with a small form and reordered by
dragging. On the right, a live preview of the page as you edit.
Anywhere you can type text you can also write a $token —
$customer.legal_name, $order.total_monthly. Tokens are
left as-is in the design and filled with real values when the document is
generated. A table section binds its rows the same way: its
data variable names a list (for example $items), and each
column names a field inside the rows, so a forty-line equipment schedule
paginates by itself.
A function turns the template into a file with the
Generate Document step (in the Document Actions
group of the step catalogue). It takes the template and a file name — the name
accepts tokens too, so lease_$customer_id.pdf names each customer's
document after them. The step's output is the generated file, ready for the next
step. The $tokens inside the template are filled automatically from
whatever the function has in scope: its parameters and the outputs of earlier
steps, dotted paths included — retrieve a customer record into
customer_row and $customer_row.legal_name resolves on
its own. The older Generate PDF step still exists for plain
title-and-text output; designed documents use Generate Document.
Two steps finish the job, and they compose with everything else a function can do:
The AI knows this whole chapter. Ask for the outcome — "create a rental invoice template and add a button on the Orders screen that emails it to the customer" — and it designs the template, builds the function with the right steps, wires the button, and reports what it made. The template it creates appears under DOCUMENT TEMPLATES like any hand-made one, so you can restyle it in the editor afterwards.
PIES AI builds inside your application using the same tools the IDE uses, so everything it produces is a normal PIES object you can open and edit by hand.
Open the PIES AI panel and describe it. Be specific about the shape of the thing — "add a screen that lists books with a search box" beats "make it better". Each request runs against the application as it stands, so you build an application up in steps.
The panel streams each tool call as it happens. Larger requests are planned first and show a Continue gate, so you approve the plan before it runs.
When it finishes you get a receipt: exactly what was created or updated, which model built it, and what it cost. Everything appears in the explorer and is yours to edit. Rewind undoes a build you did not want.
PIE Loop takes a larger request, decomposes it into units of work, builds them, then reads the build errors and fixes them — repeating until the application compiles. Use it for "build the whole thing"; use the chat for single changes.
Name the entities and how they relate, not just the theme. “A clinic
booking system” leaves every decision open; “patients, doctors and appointments,
where an appointment belongs to one patient and one doctor” produces the data
model you meant. The same applies to screens: describe what the page is for and
what it shows, and say which table it reads.
Ask for one thing at a time. A request that names a schema, four screens and a
report is planned as one large job; the same work asked for in three turns is
easier to steer, and each turn can be rewound on its own.
A large request is planned before it is built. The plan lists the units of work — tables, then functions, then screens — and pauses for you to approve it. Read it: correcting a plan costs a sentence, correcting a built application costs a rewind. Smaller requests skip the gate and build directly.
Each turn ends with a receipt: what was created or updated, counted from
the application itself rather than from the model's description of its own work.
Where the two disagree, the receipt is right. A turn that reports
“0 screens added” did not build a screen, whatever the surrounding text says.
The receipt also names the model that did the work, which matters when an
organisation routes some requests to a model inside its own network and others
to a cloud provider.
Every turn takes a version snapshot before it changes anything, so a turn that went the wrong way costs a click rather than an afternoon. Rewind returns the application to the state before that turn — and closes anything it removed that you had open. Rewinding does not undo work you did by hand afterwards, so rewind before you continue building on a bad turn, not after.
The AI works through the same tools you have — it cannot reach outside the application, and it cannot write code the platform would refuse from you. Where a request needs a component the platform has no widget for, it writes one (see “Views PIES has no widget for”). Where a request is ambiguous about data — which table, which column — it will ask or choose, and choosing is where it most often chooses differently from what you meant. Naming the table removes the guess.
An agent is a worker you configure once and then run: it reads its own instructions, uses the same tools the IDE and PIES AI use, and works on the apps you scope it to. A squad is several agents that deliver together under one set of rules. Agents live under Workspace → Agents, outside any single application, because one agent can look after several.
Agents in the workspace sidebar is the fleet's home — outside any one application, because an agent can look after several. A new install opens on an empty page and a single New Agent button; once you have a fleet, this page counts what is running, what needs your input and what has run today, and shows live activity, missions and a map of every team.
Three things, and keeping them apart is what makes the feature make sense.
An agent is one worker: a name, instructions, a set of tools, a
scope of apps, and a budget. A squad is a group of agents
created together with shared rules of engagement — it is a reusable
capability, not tied to any app. A mission is the work: a brief,
a target application, the documents to build from, its own board and its own
rollback point. You point a squad at an app by giving it a mission, and one
squad can run several missions in parallel.
That separation is deliberate. When the app was bound to the team, changing the
target meant editing every member's grants and redeploying all of them, and a
team could only ever work on one thing.
New Agent starts from a template for a single agent —
Blank agent, App Fixer,
App Monitor, Feature Builder or
Delivery Agent — or from a team template that
provisions several coordinated agents in one action. Three team templates ship
today:
Delivery Squad — nine members (Lead, BA, Architect, Data
Engineer, Backend Engineer, UX Engineer, UX Developer, QA, Ops) who hand work
over through the requirements board: the BA files requirements, the Architect
comments the data design, the UX Engineer specifies the screen, the builders
build to those comments, QA verifies with a real probe and closes the card, Ops
reports on health.
Delivery + Fixer — one agent turns requirements into a working
app and escalates stubborn build failures to a second agent that only works on
problems handed to it.
Monitor + Fixer — one watches an app and files a ticket for
every real problem (and hands urgent ones straight to the fixer), one resolves
tickets and never claims a fix it has not verified.
You also choose how it runs: Supervised pauses for your
approval before it creates, builds or deploys; Autonomous runs
to completion, bounded by its tool grants, budgets and run log. You can change
this at any time.
An agent's instructions are its job description in plain language, and it
reads them on every run — so running it needs no prompt at all. A prompt, when
you give one, is extra direction for that one run.
Write them the way you would brief a person: what it owns, what it must not
touch, and what "done" means. The shipped templates are worth reading as
examples — each one names the tools it should use, the evidence it must produce,
and the line it must not cross ("you never build", "you never close a card you
have not probed").
Alongside instructions an agent keeps memory: long-lived notes
it carries between runs.
The Tools tab is the real guardrail. The Studio toolkit is a
short list of switches: Build & modify apps,
Monitor & detect errors, Apply fixes and
Call other agents. Deploy & redeploy is
listed but not yet wired — an agent can get an app verified and ready, and the
deploy step remains manual. Creating and deleting apps is never permitted, for
any agent.
Apps this agent manages bounds it to specific applications,
each with read, write or admin permission; leave it empty and it can act on
every app you can access. Where an app has deployments you can narrow it further
to named deployments. A catalog-size estimate under the picker shows roughly how
large the resulting tool list is for the model — scope is not only a security
control, it is what keeps an agent's tools small enough to use well.
When Call other agents is on you pick who it may hand off to.
Nothing selected means any deployed agent in your organisation, delegation is
depth-capped, and only deployed agents can actually be reached at run
time however the list is set.
Role (Team Lead, Builder, Operator, Monitor, Tester,
Architect, Data Engineer, Backend Engineer, UX Engineer, UX Developer, Analyst)
is an organisational lens only: it groups the dashboard so a growing fleet stays
legible. It grants nothing — capability comes entirely from tool grants and the
approval mode.
Approvals is the autonomy dial: Autonomous runs to
completion, Supervised pauses before any change, Locked down
pauses before every single action. Denials and timeouts never kill a run — the
agent adapts and carries on.
Budget caps each run: maximum iterations, tokens per run,
tokens per month, and minutes per run.
There is no model picker. Every run uses the model your organisation's
AI governance policy selects, and an agent cannot
override it — the same rule that stops a person routing around an air gap.
Conversational is always on: the agent runs when you press
Run, when you answer it in the inbox, or when you POST to the
run API. On top of that you can add:
Schedule — a cron expression and a prompt
(0 9 * * 1-5 is weekdays at 9am).
Event — fires within seconds of a signal rather than polling:
any failure signal, a bug reported from the preview, or a failed build or
deployment. The agent needs that app in its scope.
Webhook — a signed endpoint you POST to; sign the raw body with
HMAC-SHA256 and send it as X-Pies-Signature: sha256=…. The secret is
shown once, on deploy.
An agent does not run until it is deployed, and deploying freezes the
current instructions, tools and triggers into an immutable numbered version.
The deploy dialog validates first — grants resolvable, triggers valid — and
refuses to deploy while anything is unresolved, then arms the enabled triggers
and shows any webhook secret once.
Because a version is frozen, editing an agent's instructions changes
nothing until you deploy again. Run rows show the version they
executed, so a run that ignored your edit is telling you it ran an older one.
Squad members are redeployed together, so their versions and settings stay in
step. Shutdown stops an agent without deleting it; deleting
removes it permanently but keeps the run history.
A mission carries the brief, the target app, any documents you attach
(requirements, a specification — the squad reads them), and its own delivery
history. Open one and you get a cockpit: the requirements board, the live feed
of every step each member takes, the run list, and the rules of engagement and
playbook you can edit.
One switch matters more than the rest. Plan this brief as several user
stories is off by default, and off means the brief is one piece of work
— a screen, a feature, a fix — that becomes exactly one card. Turn it on only
for a whole-app build from a specification. Left to decide for itself, the model
turned one screen into ten requirements every time.
Before each run the mission snapshots the application using the same version
machinery as the IDE's Rewind, so Roll back this mission
restores the app to exactly how it was before the squad touched it.
The delivery sequence is driven by the platform as code, not by one model's
judgement — a model asked to lead builds once and declares itself done. A
coordinator triages each card in turn, decides which specialists that card
actually needs, dispatches it to them one at a time, then verifies against the
application itself (tables, functions, screens, the board) rather than against
what the chat said. A card QA failed goes straight back to whoever built it; a
card that is verified and has nowhere left to go is closed.
Only the roles present in the squad take part, so a two-agent team works as well
as a nine-agent one — the missing phases are skipped. Platform configuration —
login, registration, password reset, roles and permissions, SSO, environments,
secrets, theming — is configured in Studio and is never treated as work to
build.
Every phase is an ordinary agent run, so the cockpit's live log shows the whole
relay. A run that fails at a step offers Retry step,
Skip & continue or Cancel run. An agent
that needs a decision asks you and waits — those show up as
Needs you on the dashboard.
The Agents dashboard counts agents, how many are running now, how many need
your input and how many runs happened today, and shows live activity, missions
and a fleet map of every team at a glance. Click any run to see exactly what the
agent did, step by step, and to recover it.
Agent runs are governed and audited like every other AI call, so the audit log
in AI governance is where you answer "what did the
agents do, on which models, at what cost".
Enterprises need to say which AI may see what. Governance is policy applied to every AI call, with an audit trail — not a setting somebody remembers to respect.
A policy decides which provider and model serves a request, by request type,
tier and data classification: cloud frontier models for the hardest work,
PIES Private AI on your own GPUs for anything that must not
leave the network, and an air-gapped policy that permits nothing else. Every
answer in the chat carries a chip showing which policy routed it, and
Why? explains the decision.
The enabled policy is what routes a build — not the model picker.
The model chosen under AI Settings configures endpoints and
keys; if a policy names a different provider, the policy wins and the model
picker is overruled. That is deliberate: it is what stops a user routing around
an air-gapped rule. When a policy allows the local provider, the model actually
loaded on your Private AI host is used rather than the name written into the
policy — provided that model is certified build-capable.
If governance authorises no model at all — no matching policy, or a deny — the
request fails rather than falling back to a cloud default.
A request nobody approved does not run.
A policy is scoped either to one organisation or to the whole install.
Install-scoped policies apply to every tenant and are how a platform-wide rule
(an air gap, a compliance pack) is expressed; org-scoped policies stay private
to that organisation.
Templates → Routing presets holds seven ready-made postures —
Air-Gapped, Regulated Industry, Cost-Optimised Hybrid, Frontier Quality,
Hybrid Burst-and-Train, Public Sector and Default Balanced. Each is a single
policy, not a bundle; Instantiate creates an editable copy in
your organisation, and from that moment it is an ordinary policy you can retune
on the Policies tab.
Instantiating offers two modes. Add creates the policy
alongside what you already have. Replace current preset removes
the policies you previously created from these same presets and installs this
one in their place — your own hand-written policies and any compliance-pack
policies are left alone. Use Replace when you are switching posture, so you do
not end up with two presets quietly competing.
Priority decides who wins. A preset that matches only part of
the traffic relies on a broader policy underneath it: Cost-Optimised Hybrid
matches only repetitive work, so it must sit above Default Balanced for
everything else to fall through to the cloud. Air-Gapped is the opposite — it
matches everything, which is what makes it an air gap.
Three presets put work on your own GPUs, and they differ in how much.
Air-Gapped sends every request to PIES Private AI and blocks
Anthropic and OpenAI outright. Regulated Industry sends only
the sensitive classes (PII, PHI, PCI) on-prem, with redaction, and lets
everything else use the cloud. Cost-Optimised Hybrid splits by
effort rather than sensitivity: repetitive work runs locally and free, real
thinking still goes to the cloud.
That split is decided by a heuristic read of the request — no extra model call,
no cost. Renaming, recolouring, adding a widget and other mechanical edits count
as light and route local; anything that names logic, knowledge, a build or a
design counts as heavy. Anything ambiguous is treated as heavy
on purpose: a real build handed to a small local model is the expensive mistake,
so the tie is broken towards quality.
Whichever preset routes it, the model that actually answers is the one
loaded on your Private AI host, not the name stored in the policy, and
it must be certified build-capable before it may drive a build.
If nothing loaded satisfies the policy, the request fails — there is no silent
fall back to a cloud model.
Two switches on Governance → Overview control the hybrid
behaviour. Cost-optimised routing is the one-click form of the
preset above. Decompose builds goes further: inside a single
build the cloud plans the work and writes the logic while the local model
executes the repetitive items, and any item the local model cannot finish is
escalated to the cloud automatically.
These switches are the source of truth. A
PIES_HYBRID_DECOMPOSE environment variable may be set on a server to
bootstrap a headless install, but it applies only while no choice has been made
here; once you use the toggle your decision wins and survives restarts. If the
environment is currently forcing decomposition on, the page says so beneath the
switch rather than showing you an Off that isn't true.
The savings panel underneath reads in requests, not tokens: the
headline percentage is the share of calls served locally and the figure beside
it is cloud spend avoided. Token share is shown separately and always looks
smaller — one cloud build outweighs hundreds of local edits.
Policies are only as good as the traffic they meet, and the way to find out
what yours does is the Test Console
(PIES AI → Governance → Test Console). Describe a request — the
prompt, the request type, optionally an app, a user, their roles and a region —
and it returns the decision the live engine would make: which policy matched,
whether it was allowed, the data classification, the provider and model chosen,
and what redaction would strip. View on a policy draws the same
decision as a diagram, with the matched path highlighted.
A shadow policy is one that never affects a live request. It is
evaluated only when you simulate or replay, which is how you measure what a new
rule would have done to real traffic before you let it route anything. The
Overview counts how many you have.
Overview also lints the set — the usual finding being a policy that can never
match because a broader one above it already caught everything. Priority is the
only thing that decides who wins, so a narrow policy sitting below a
catch-all is dead, not subtle.
The same page scores an output for factuality: paste a model
answer and the source text it should be faithful to, and it reports how much of
it is grounded and which citations are not.
A policy that names a cost-efficient model still allows its whole provider,
and not every request is the same size. Where a request is classified
heavy — screen authoring, architecture, a real build — the engine
upgrades to the stronger model within the provider that policy already
allows. The provider, the redaction and the audit trail are untouched; only
the model within an already-permitted boundary changes.
This is why agent and squad output should not read as weaker than the chat's.
Before it existed, every heavy step of a squad run took the cheaper model the
policy named while chat ran the frontier one, and the screens showed it.
Every governed call is recorded — provider, model, tokens, policy decision
and a factuality score — in a signed, hash-chained audit log. That includes the
assistant inside your deployed applications: every message an end user
sends is evaluated against policy as it arrives, redacted, routed, and audited
against the tenant that owns the app and the user who typed it. The
Data class column is the data classification of the content
(internal unless something sensitive is detected), not where the call
was routed — an internal row beside an Anthropic route means ordinary
content that policy allowed to go to the cloud.
Redaction strips sensitive data before it reaches a model. The
Knowledge Base holds documents the AI may build against, and
per-application Artefacts (a BRS, a specification) are fed into
builds so the AI works from your requirements rather than its own assumptions.
Point Studio at a model running on your own GPUs and no prompt, application definition or data leaves your network. Installing it is covered in the PIES Private AI manual; connecting it is a URL and a key under Administration → AI Settings.
Applications rarely live alone. These surfaces let an application call out, be called into, and share credentials safely.
Connect the platform to the systems around it — source control for generated code, cloud accounts for deployment, messaging and collaboration tools. A connection is made once and reused by every application.
Endpoints publish your functions as a REST API, so other systems can call your application. In the other direction, a REST Call step lets a function consume an external API with the response mapped into your own model. Credentials for both live in Resources → Secrets, never in the application definition.
A preview is a real build: the generated code is compiled and run against a real database. This is where errors surface — an AI chat receipt is not proof that an application builds.
Open the build console from ▶ Run, choose the Preview environment and click Build. The PROBLEMS tab groups anything that failed by area — Database, Interfaces, Events, Functions — each with a count. An application with build errors never reaches preview, so clear these first.
On a clean build, open the preview to get the real application in a new tab — logging in, saving records, navigating between screens. First start shows a short warm-up while screens compile.
Build turns your definition into a real application — a front end, a Go back end and a database schema — and compiles it. It is not a preview of the canvas: it is the same generation that produces the application you deploy, run against the Preview environment. That is why a build failure is worth reading rather than retrying; it is telling you the application as defined cannot be produced.
An application with build errors never reaches preview, so a preview that looks stale is usually a build that failed. PROBLEMS groups every failure by area — Database, Interfaces, Events, Functions — with the object at fault named. Clear it top to bottom: a missing table breaks the screens that read it, so the first error often explains the rest.
Preview runs your application with its own database, its own sign-in and its own data — not a mock. You can register a user, save a record and see it persist. This is also why it takes a moment to come up, and why a preview left running holds resources until it is closed. Sample data is generated so screens have something to show before you have entered anything.
Change the definition, build, look. Small changes rebuild quickly because only what changed is regenerated. If a change does not appear, check in this order: did the build succeed, is the preview session the current one, and is the widget actually bound to the data you changed. In that order the answer is usually the first question.
Deployment takes the same generated code beyond the preview sandbox — to a container host, a Kubernetes cluster, a cloud account you connect, or a mobile app.
DEPLOY is a tab in the build console, next to BUILD and PROBLEMS. A new application starts with no deploy target and says so — set one under Resources → Environments: Docker and Kubernetes deploy to infrastructure you control, AWS and Azure use credentials connected in Administration. Each deployment is versioned, so you always know which build is live.
A deployed application can be restarted, scaled, redeployed to a newer build, or torn down, and its logs are readable from the same place. Rolling back is redeploying an earlier version.
Switching an application to mobile generates a Flutter application from the same definition — the same data model, functions and events, rendered natively. From there you can preview it, download the APK, or take it through to a store listing. Desktop and mobile stay in step because both are generated from one source.
A calendar, a board, a timeline — some views have no standard widget. PIES builds them as a coded component and, more importantly, connects them to your data: the query that reads the rows, the event that runs when the page opens, and the delivery of those rows into the component.
Describe the view rather than the widget — the time range, what each column represents, what a single entry shows. You type this into PIES AI exactly as in chapter 3; what follows is what comes back. PIES recognises that no standard widget fits, writes the component, and puts it on a new screen.
A titled page with the component laid out inside it, the same as any screen you would draw by hand. The component is yours to edit: its source sits under Components in the explorer.
A view is only as good as the data behind it, so PIES writes the read function too — filtered on the date the view is showing, returning just those rows rather than the whole table.
An event runs when the screen opens: it calls the query and passes the result into the component. This is the step that separates a view that renders from one that shows your data — and it is wired for you. Open it and you can change what it reads, or when.
Who may open the application, and what each person may see or do inside it. This is separate from platform administration: it travels with the application to every environment it is deployed to.
Define groups — Administrator, Manager, Read-only — and grant each one access per screen and per operation. Every application starts with a user model and an Administrator group already wired, so a generated application has working sign-in from the first build.
Choose how users of the generated application authenticate — its own user table, or your identity provider. The Login, Register and Forgot Password screens are created with the application and can be restyled like any other screen.
The things an application needs but does not own: where it runs, what it connects to, and the credentials it must never contain.
An environment is a named target — Preview, Test, Production — with its own database connection, variables and deploy target. The same application definition builds to each; only the environment differs, which is what makes a promotion a redeploy rather than a rewrite.
Secrets holds API keys, database passwords and tokens. They are referenced by name from steps and connections, stored in the vault, and never written into the application definition or the generated code. Email Servers configures the SMTP account the Send Email step uses, per environment.
What every screen shares: the menu, the header, and the look.
Navigation lives in one shared Menu, not on each screen — add a screen to the menu and it is reachable everywhere. The Header carries the logo, notifications and the user pill with sign-out. Both are locked to the application rather than to a screen, so they stay consistent.
A theme is a reusable palette and type scale — colours, fonts, radii, button gradients — applied to the whole application and to every screen the AI generates afterwards. Change the theme and the application follows; you are not restyling widgets one at a time.
An application is a versioned artefact, not a live document you hope nobody breaks.
The branch selector in the toolbar works the way it looks: build on a branch, commit a set of changes, and compare or roll back to an earlier commit. Every build records which commit it came from.
Connect a GitHub or Bitbucket repository under Repositories and the generated code is pushed there — so your engineers can read it, review it, and run it in their own pipeline. Code generation is not a black box: what PIES builds is ordinary Go, React, Angular, Python or Flutter.
Each AI turn is a version. Rewind to here puts the application back to the state before that turn, so an experiment that went the wrong way costs a click rather than an afternoon.
Every change to an application is recorded — what changed, who changed it and when — covering work done by hand and work done by the AI alike. It answers the question a version list cannot: not just what the application looked like at a point in time, but how it got there. An entry can be restored, returning that object to the state in the record.
Three different questions: does it build, does it behave, and why is this screen wrong.
After a build, PROBLEMS groups every failure by area — Database, Interfaces, Events, Functions, Other — each with a count and the specific object at fault. This is the authoritative view: the AI's own summary of what it did is not evidence that the application compiles.
When a build fails, Analyse & Fix hands the failure to the AI with the context it needs — the failing object, the error, and the definition behind it — and applies the correction as an ordinary change you can inspect or rewind. It is the same loop you would run by hand, without copying error text into a prompt. Failures it cannot represent as a change to your application are reported rather than guessed at.
Most build failures name the object at fault, and the fix is usually a missing binding rather than anything deep. The ones seen most often:
A preview is a real deployment of your application, so it fails in the ways deployments do. 502 Bad Gateway means the preview server is still starting or has stopped — rebuild rather than refreshing. A preview that has been running for a long time can be closed from the preview list, which frees the resources it holds; sessions are not meant to be permanent. If a change you made is not visible, check the build succeeded before assuming the preview is stale — an application with build errors never reaches preview.
The preview carries a diagnostic overlay: it reports what actually rendered and, when something is missing, works down the layers — definition, generated code, data, render — to say which one is wrong. It can hand the finding straight to the AI as a fix request.
Work you have done once should not be done again.
Publish an application as a template and new applications can start from it. Published assets are the smaller units — screens, widgets, functions — shared across a workspace so a team converges on one way of doing things.
An application can be exported and imported whole — for moving between installs, for backup, or for handing a build to someone else. Generated code can be downloaded outright, which matters if you ever need to leave: the output is yours.
Platform-level settings, separate from any one application.
Invite users, assign roles, and configure authentication — local accounts or enterprise SSO. Permissions inside an application are separate, under its own Access Control.
Platform name, logos, favicon and the colour palette used across Studio and the applications it generates. Themes are reusable, so every application in a workspace can share one look.
A tab view holds several panels in one screen: put a form in one tab and a table in another rather than making the user scroll. Each tab carries its own widgets and its own bindings, and the elements list shows them nested under the tab they belong to — expand the tab view to reach a widget inside it.
Any widget can be marked hidden, and a rule can reveal it when a condition holds — an approval button that appears only for a manager, a warning that shows only when a field is empty. Hidden is a property of the widget, so it applies in preview and in the deployed application, not only on the canvas.
Drag a box across the canvas, or shift-click, to select several widgets at once. Their common properties — width, height, position — can then be set together, which is the quickest way to line up a row of cards or give a column of fields the same width. Setting the coordinates directly is exact where dragging is approximate.
A table can carry an action column — per-row buttons for View, Edit or Delete. Each action names the screen it opens or the event it raises, and the row's record is passed to it, so an Edit action lands on a form already filled in. This is how a list becomes a working screen rather than a read-only grid.
A widget without a data source renders nothing and fails the build with “Table Missing Data Source” — binding is not optional decoration. A table or list names the table it reads and the columns it shows; a form names the table it writes and the fields it edits; a chart names a table, a column to group by and a measure. Where a widget should read from more than one table, define the join on the data source rather than assembling columns in the widget.
The canvas is 1920 wide, and the navigation strip occupies the left of it, so the area your widgets actually occupy is narrower than the canvas. Widths are resolved against that same area in the generated application, which is why a widget that fits here fits there. Containers are the reliable way to keep a screen's shape: group widgets in a container laid out as a row or a grid, and the group holds together at different widths rather than each widget being positioned absolutely.
A widget's events are configured beside its properties: a button raises an event on click, a screen can raise one when it opens. The event is an ordinary event you can open and edit — see the next chapter. Two patterns cover most screens: a form whose submit button calls a function that saves the record, and a screen whose on-open event loads the rows a table or view displays.