Skip to main content
Version: 3.0

App Studio, start to finish

Beta: follow one app from an idea on the shop floor to a wall screen, then switch it off, roll it back, back it up and watch it run.

Who it is for
Plant teams and IT administrators
Example
Line 3 Operator Console
Screenshots
A Lite instance, synthetic plant and people
Beta

App Studio is in release 3.0 as Beta: a paid add-on that no edition includes by default. A licence or a trial licence that includes the app_studio feature switches it on. The module is on by default, so the licence decides. Names and steps may change while it is in Beta.

This page follows one app through its whole life, in the order a plant meets each step. Each step names who does it, what they press, and what MaestroHub checks on the way. The details behind each step are in the Builder guide and the Operator guide; the questions people ask most are answered in the FAQ, and How App Studio works now looks at the same product person by person.

The plant in the screenshots. A workspace called Plant North with one packaging line, line 3. Its stations publish their state to the namespace, and a REST gateway in front of the line's PLC offers one function, Release interlock. Three people work there: Ada Admin (workspace administrator), Ben Okafor (builds apps) and Olga Petrov (operator on line 3). Everything shown is synthetic: the people, the plant and the gateway, which is a stand-in on the same machine.

1. An idea​

The shift on line 3 keeps asking the same three things: which station is down, what the last shift wrote down, and who may release the interlock after a jam. Today that is a whiteboard, a paper book and a phone call. Ada wants one screen.

She opens App Studio → New App and writes one sentence. She can also start from a template or open one of the showcase apps that MaestroHub ships to see what an app can do. Here she picks the Line Operator Console template, which has exactly those three cards, and calls it Line 3 Operator Console.

App Studio New App page: a sentence box, template sentences, the Build with your AI client button and the showcase apps belowApp Studio New App page: a sentence box, template sentences, the Build with your AI client button and the showcase apps below

New App: describe the app, or start from a template or a showcase app. Build here is off because this instance has no AI provider; Build with your AI client works without one.

Nothing is live yet. Creating an app makes a draft: nobody can run it, and it is listed with a Draft badge. In this release, people who can open apps in the workspace can also read a draft's files; only people who may edit the app can change it.

2. Building it, with Maestro or with your own AI client​

The builder opens. On the left is whatever writes the code; on the right, the live preview of the draft, running on real data from the namespace with the permissions of the person looking at it.

Two things can write the code:

  • Maestro, MaestroHub's own assistant (in release 3.0 as Beta, early access on request), as a chat beside the preview.
  • Your own AI client (Claude Desktop, Claude Code, Cursor or any MCP client), through MaestroHub's MCP server. This instance has no AI provider set up, so the builder opens on the Build with your AI client panel: connect the client once, give it the prompt shown, and watch the preview change as it works. This route needs MaestroHub's MCP server switched on. It is on by default: on the single binary the setting is mcp.enabled in the server configuration, and on Enterprise (Helm) it is the mcpgateway pod (mcpgateway.enabled). An administrator who has switched it off turns it back on there; until then the Connect an AI client page says that the MCP server is switched off. The walkthrough records one such session from start to end.
The builder: the Build with your AI client panel on the left with the prompt to copy, the live preview of the Operator console on the rightThe builder: the Build with your AI client panel on the left with the prompt to copy, the live preview of the Operator console on the right

The builder: the AI client panel on the left, the live preview of the draft on the right. Draft builds clean means it will also publish.

Whoever writes, the result is the same kind of thing: a small React app in a git repository that MaestroHub keeps for that app, compiled inside MaestroHub. An app can import only a fixed set of libraries (React, the MaestroHub SDK and UI kit, the 3D scene kit, and three.js with three of its add-ons); there is no npm and no download from the internet. Every change is saved as a checkpoint you can go back to. One person at a time holds the edit seat, so two builders do not overwrite each other.

3. Bindings: the app names what it uses​

This step matters to the plant for one reason: the same app can later run on another line without anyone changing its code. (It is written for builders; the screenshots show the code.)

An app does not write the address of a topic or a connector function into its code. It declares each thing it uses once, by a name, in its manifest.json, and the code asks for it by that name. In the console, stations is the line's station-state topic and interlock is the gateway's Release interlock function:

The builder's Code tab with manifest.json open: bindings named stations (a topic) and interlock (a connector function), and an action release bound to interlock with a confirm rungThe builder's Code tab with manifest.json open: bindings named stations (a topic) and interlock (a connector function), and an action release bound to interlock with a confirm rung

manifest.json: two bindings by name, and one action, release, that runs the interlock binding and asks the person to confirm first

The builder's Code tab with src/App.tsx open: the code reads useBinding('stations', 'topic') and useFunction('release')The builder's Code tab with src/App.tsx open: the code reads useBinding('stations', 'topic') and useFunction('release')

The code reads the binding by its name, never the topic's address

Why it matters: to put the same app on line 5, you change the two targets in manifest.json and publish; the code does not change. A target written into the code by hand, as a literal string, is refused, at validation and again at publish, with the line and the fix:

The builder's Code tab marking a line of App.tsx as an error because the station topic's address is written into the code, with the fix to read it by nameThe builder's Code tab marking a line of App.tsx as an error because the station topic's address is written into the code, with the fix to read it by name

A topic address written into the code is an error that names the fix: read it with useBinding

The manifest also lists the scopes the app asks for (here: read the namespace, run connector functions) and every action that writes. Those are a ceiling, not a grant: at run time the app gets only what both the manifest and the person looking at it allow. The Builder guide describes every field.

4. Review and go live through one door​

When the draft is ready, Ada presses Publish. Publishing is a request that a person approves: MaestroHub builds the version and shows what would go live before anything changes.

Release review dialog: who asked and how, the scopes viewers would start granting, the files that changed, and the Reject and Approve and go live buttonsRelease review dialog: who asked and how, the scopes viewers would start granting, the files that changed, and the Reject and Approve and go live buttons

The release review: who asked, from where, which permissions viewers would start granting, and which files changed

What the review checks, and who may approve:

  • A person signed in to MaestroHub approves. Anyone who may publish the app (app:publish: its owner, an Apps editor, a workspace administrator) can approve, including the person who asked. There is no second-approver rule. A token, an AI client or Maestro can ask for a release, which then waits as a banner in the builder; none of them can approve one.
  • One door for every way a version goes live. Approving a release, activating a version, rolling back, opening a showcase app and switching a switched-off app back on all go through the same check, and each leaves one app.published row in the audit log that says which way it went.
  • Actions that act as the app itself (rare; see the Builder guide) need an approver who holds everything those actions do. The review lists them; if the approver does not hold them, the version does not go live and the refusal names what is missing.

Approved, the version is live and fixed: version 1 can no longer change. Further edits make a new draft, and the next Publish makes version 2.

5. Running it​

People open the app from Apps, from a star on their sidebar, or from a link. The Run page shows the app inside MaestroHub with a strip above it: who built it, that it is not part of MaestroHub, and that it acts with the viewer's own permissions only.

The Run page: the Line 3 Operator Console with live station states, shift notes and the Release interlock button, under a strip naming who built itThe Run page: the Line 3 Operator Console with live station states, shift notes and the Release interlock button, under a strip naming who built it

The Run page: live station states from the namespace, shared shift notes, and the interlock button

What keeps the app in its lane:

  • It sees what the viewer sees. The app works with a short-lived token (5 minutes, renewed while it runs) that holds only what both the manifest and the viewer's own permissions allow. Olga sees the same app as Ada but only the data Olga may see. The SDK tells the app which of its actions the viewer may use and why not, and the templates show a button the viewer cannot use disabled, with that reason.
  • It cannot touch MaestroHub itself. Each app runs in an isolated frame that the browser treats as an anonymous origin (a page with no identity of its own, so the browser gives it none of MaestroHub's sign-in or storage): it cannot read the MaestroHub sign-in, the MaestroHub page or another app's data, and it may talk only to MaestroHub. How that works, and what it does not cover, is in How apps are served.
  • The first time someone opens an app they did not build, a notice names the builder and lists what the app can do with their permissions.

When an action writes something that matters, the app asks MaestroHub to confirm with the person. MaestroHub, not the app, draws the dialog over the app: what the app says, exactly what MaestroHub will send, and who is signed in. Cancel has the focus and Confirm becomes active after half a second, so a stray tap does not release an interlock. The confirmation is valid once, for 60 seconds, for that exact request.

Confirm in MaestroHub dialog over the app: the app's message, the request MaestroHub will send to the gateway function, the signed-in person, Cancel and ConfirmConfirm in MaestroHub dialog over the app: the app's message, the request MaestroHub will send to the gateway function, the signed-in person, Cancel and Confirm

Confirm in MaestroHub: drawn by MaestroHub, not by the app, with the exact request it will send

6. On the line: Kiosk page and paired displays​

There are two ways to put an app on a screen at the line, and they differ in one thing: whether anyone can press its buttons.

The Kiosk page is the app full screen, at a fixed address (/<workspace>/apps/<app>/kiosk), opened by a person who is signed in. It is for a station where operators act: the buttons work, within that person's permissions, and confirmations name that person. The page checks the app every 30 seconds, so a switched-off app comes back by itself once it is switched on again.

The Kiosk page: the operator console full screen with only a slim strip naming the app and its builderThe Kiosk page: the operator console full screen with only a slim strip naming the app and its builder

The Kiosk page: the app full screen on a station where a person is signed in

A paired display is a screen with nobody signed in: an andon board, a TV on the wall. It gets its own identity instead of a person's session. The screen opens /pair and shows a code; an administrator types the code under Identity & Access → Devices, names the screen, picks the app and approves.

The pairing page on the wall screen showing an eight-character codeThe pairing page on the wall screen showing an eight-character code

On the screen: /pair shows a code

Pair a display dialog: the code, the display name Line 3 andon screen, the app to show, and the note that the display is read-only; the screen's network address is blurredPair a display dialog: the code, the display name Line 3 andon screen, the app to show, and the note that the display is read-only; the screen's network address is blurred

At a desk: the administrator names the screen, picks the app, and is told before approving that the screen is read-only

A paired display is read-only. It shows the app and its live values, and every button that writes is disabled with the reason and the way out:

The paired display showing the console with the Release interlock button disabled and the sentence This screen is read-only: a person must be signed in to press thisThe paired display showing the console with the Release interlock button disabled and the sentence This screen is read-only: a person must be signed in to press this

The paired display: live values, and the interlock button disabled with the reason

That is a deliberate rule, not a setting: a wall screen's identity lives for up to a year and no person stands behind its clicks, so it never holds a write permission. A station where an operator presses buttons is a Kiosk page with that operator signed in. Revoking the display under Devices ends its session on its next request.

7. Sharing it, and roles​

Who can open the app is decided the same way as for pipelines and dashboards:

  • By role. The built-in roles that open and run every published app in the workspace are Apps Viewer (Apps.Viewer), Plant Operator (Persona.PlantOperator) and Analyst (Persona.Analyst). Apps.Editor also builds and publishes; Apps.Admin also shares, deletes and backs up; Workspace.Display is what a paired display holds. The full table is in the Operator guide.
  • By sharing one app. Share on the app's menu (needs app:share) gives a person, group, role, API client or paired display access to this one app, optionally until a date. While you choose who, the dialog shows how many of the app's bound resources that audience can actually reach, so you see before granting whether the app would work for them.
Share app dialog with Olga Petrov chosen, the run action ticked, and the preview of how many bound resources she can reachShare app dialog with Olga Petrov chosen, the run action ticked, and the preview of how many bound resources she can reach

Share: pick who, pick what they may do, and see what the app would reach for them before you grant it

Sharing one app needs the Advanced Access Control licence feature. Without it, give people a role that opens apps; existing shares can still be revoked.

8. Switching it off​

On day three the interlock release misbehaves on the case packer. Ada opens the app's Operations page and presses Switch off. A reason is required, because everyone who opens the app will read it.

Switch off dialog on the Operations page with the reason typed inSwitch off dialog on the Operations page with the reason typed in

Switch off asks for the reason

The app is off for everyone at once: no new app token is issued, tokens already issued are refused on their next request, and live data stops at the next revocation sweep (about every 60 seconds by default). Nothing is unpublished or deleted, and the builder keeps working.

Operations page kill-switch card showing switched off, who switched it off, when and why, and the Switch on buttonOperations page kill-switch card showing switched off, who switched it off, when and why, and the Switch on button

The kill-switch card: who switched it off, when, why, and Switch on

Olga, opening the app on the line, sees who switched it off, when, why, and who can switch it back on:

App switched off page as the operator sees it: Ada Admin switched this app off at a time, with the reason, and who can switch it onApp switched off page as the operator sees it: Ada Admin switched this app off at a time, with the reason, and who can switch it on

What a viewer sees: who, when, why, and who can switch it on

Anyone who may edit the app can switch it off; an AI client can too. Switching it on is a go-live decision: it needs a signed-in person who may publish the app and passes the same door as a release. People who may not see the button disabled with that reason.

9. Rolling back​

Rather than wait for a fix, Ada can put the previous version back. The builder's History tab lists every version with its runtime; Activate on an older version serves it again, after a confirm that shows the scopes viewers will be granted. The draft is not touched.

The builder's History tab: the checkpoints and the versions, v2 live and v1 with an Activate buttonThe builder's History tab: the checkpoints and the versions, v2 live and v1 with an Activate button

History: checkpoints of the draft, and every published version

Activate v1 confirm dialog: viewers start being served v1, the draft is untouched, and the scopes the version grantsActivate v1 confirm dialog: viewers start being served v1, the draft is untouched, and the scopes the version grants

Rolling back to v1: one confirm. New opens get v1 at once; screens already showing the app switch over when their app token is renewed, within 5 minutes

A rollback goes through the same go-live door as a release (it needs app:publish and a person), and the audit row says rollback.

10. Backup and restore​

App Studio → App Backup & Restore (needs app:backup) downloads one archive of the workspace's App Studio: every app, version, checkpoint and stored document, with each app's git history, so the two cannot drift apart. Restore reads the same archive back, and by default refuses if the workspace already has apps.

App Backup and Restore page: Download backup, and Restore with the choice to refuse when the workspace has apps or to replace everythingApp Backup and Restore page: Download backup, and Restore with the choice to refuse when the workspace has apps or to replace everything

App Backup & Restore: one archive, database and git together

Restored apps that were live come back switched off, with "restored from a backup" as the reason: putting a restored app back on line is a release decision for a person who may publish it. Shares and an app's own rights are never read from an archive. The details, and what a file-level backup must include, are in Backup and restore.

11. Operating it​

Two pages tell you how apps are doing.

App Studio → Overview is the front door: how many apps are live, what needs attention (only what you can fix), your apps, and, for people who may publish, the App Studio health panel: calls, denials, rate limits and errors per minute across every app.

App Studio Overview: 3 apps live, nothing needs attention, the workspace's four apps with Run and Builder, and the App Studio health panelApp Studio Overview: 3 apps live, nothing needs attention, the workspace's four apps with Run and Builder, and the App Studio health panel

App Studio Overview: the state in one sentence, your apps, and the health of every app over the last minute

Each app's Operations page (needs app:update) holds its name and description, its owner (and Transfer ownership for workspace administrators), the kill switch, and what the app asked MaestroHub for on its viewers' behalf: calls, denials, errors and timing per kind of data, the notable calls, and problems the app reported, such as an app that keeps leaving its page.

The app's Operations page: what the app asked the platform for per kind of data, with calls, denials, errors and timingThe app's Operations page: what the app asked the platform for per kind of data, with calls, denials, errors and timing

The app's Operations page: what the app asked for, per kind of data, since MaestroHub started

These figures are kept in memory and start again when MaestroHub restarts. For alerts and long-term figures, App Studio exports Prometheus metrics and ships alert rules; see Operations. Writes an app makes are in the audit log with the app and version that made them: each confirmed write is its own row, recording who confirmed it and what the dialog showed; repeated plain writes are one row per person, app and action per minute, with a count. Reads are not audited.

What happens when people leave​

Apps outlive the people who built them. When the owner's account is deleted, ownership moves the way it does for every other resource: to the workspace's designated owner if one is set, otherwise to a workspace administrator. A live version stays live. If the app has actions that act as the app itself and the person who approved it leaves or is deactivated, the app keeps running and the people who can publish it are told once that the next release must be approved by someone who holds what those actions do. Nothing is revoked because someone left.

Where to go next​