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 experiments, share with stakeholders, track usage, and finally publish to production 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, so 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 is required, and 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 if you no longer need it.

What you learned

  • files.writeMany pushes multiple files atomically in a single request. This is 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, so it is 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 it when the user wants to keep editing.
  • sbx.deploy(name=...) produces an immutable release; the sandbox can be destroyed immediately after.

Was this helpful?