On this page

Agent builds an app

~15 min Python TypeScript

Goal: Wire an LLM agent to MIOSA so it can write code, boot a live dev server, iterate on feedback with real-time preview, checkpoint progress, branch into experiments, share with stakeholders, track usage, and finally publish to production - all from a single user prompt.

What you’ll use: Sandboxes, Processes, Previews, Snapshots, Shares, Deployments, Usage

What you’ll build

A full-lifecycle function agent_app_lifecycle(prompt) that:

  1. Generates initial files with an LLM and writes them atomically
  2. Boots a dev server and mints a preview token for iframe embed
  3. Iterates on user feedback - patches files, watches the file tree, preview auto-refreshes
  4. Checkpoints between iterations so experiments can branch safely
  5. Forks into parallel branches for A/B comparison without losing the working version
  6. Creates a shareable public URL for stakeholder review
  7. Tracks usage so you can bill the end-user
  8. Promotes to an immutable production deployment

The pattern is model-agnostic - MIOSA is the execution layer, your agent loop is the reasoning layer.

Flow diagram

Prerequisites

  • A MIOSA workspace API key (msk_live_*) - see API Keys
  • An Anthropic API key (or substitute your preferred provider)
  • Node 22+ or Python 3.11+

Step 1 - Install and configure

Step 2 - Boot a sandbox and write initial files

Create a Next.js sandbox. The template already has Node, pnpm, and a scaffold - skip npx create-next-app. Use files.writeMany to push all initial files in a single atomic call.

Step 3 - Start the dev server and mint a preview token

Use processes.start to boot the dev server as a long-running background process. Then call sbx.previewToken to get a short-lived token your frontend uses in an iframe - no public URL required, no msk_* key ever reaches the browser.

Step 4 - Iterate on feedback

When the user gives feedback, generate a patch, write it with writeMany, and optionally watch the file tree via SSE so your UI can reflect what changed. The preview iframe auto-refreshes because the dev server is still running.

Watch file changes over SSE

If your backend needs to push file-tree diffs to your UI in real time:

Step 5 - Checkpoint progress

Snapshot the sandbox between iterations. Each snapshot captures filesystem state. If a later iteration breaks things, you can fork back to a known-good point.

Step 6 - Branch into experiments

Fork the sandbox to create an independent copy for a risky or experimental change. The original sandbox is unaffected. Destroy the branch when you’re done comparing.

Step 7 - Share with stakeholders

Create a preview record for the running port, then mint a share token. The share URL is publicly accessible (read-only) for the TTL you specify.

Step 8 - Track usage

Query usage attributed to the end-user who initiated this session. Use this to drive per-user billing in your platform.

Step 9 - Promote to production

When the user confirms, run the production build and deploy. The deployment is immutable. Destroy the sandbox after deploy - you no longer need it.

What you learned

  • files.writeMany pushes multiple files atomically in a single request - faster than individual writes and avoids partial state.
  • processes.start keeps the dev server alive across multiple exec calls. The sandbox does not have to restart between iterations.
  • sbx.previewToken(expires_in) returns an iframe-safe URL with no msk_* key - safe to embed directly in your frontend.
  • sbx.files.watch() is an SSE stream of file changes you can relay to your UI for live file-tree updates.
  • sbx.snapshots.create(comment) checkpoints without stopping the sandbox. The sandbox keeps running while the snapshot uploads.
  • sbx.fork() creates a fully independent copy of the live sandbox for A/B experiments. No shared state, no interference.
  • sbx.previews.create(port) + sbx.previews.share(preview_id, ttl_seconds=86400) produce a public stakeholder link that expires automatically.
  • sbx.update(always_on=True) makes a sandbox persistent after the agent session ends - use when the user wants to keep editing.
  • sbx.deploy(name=...) produces an immutable release; the sandbox can be destroyed immediately after.

Was this helpful?