# Escape Sandbox Lock-In: Own Your AI-Powered Workflow with File-System Agents

> Discover how OTF's AI configurations let developers to use file-system agents, avoiding sandbox limitations and taking control of their workflow.
> By Dave · 2026-07-14
> Source: https://otf-kit.dev/blog/own-your-code-not-the-agent

## The sandbox won the demo

Lovable got me from a blank prompt to a deployed, auth-walled SaaS dashboard with a working Stripe checkout in twenty minutes. The signup form posted. The webhook fired. The Postgres schema was reasonable. Two years ago that was a Saturday and a half; now it's a lunch break.

This is worth saying plainly before any "but": the new wave of sandbox agents — Lovable, Bolt, v0, Rork — has genuinely collapsed the gap between idea and working prototype. They are not toys. The app they ship runs. The URL it lives at resolves. The bill it charges is real money. For anyone trying to validate a market, pitch an investor, or just see whether an idea has legs before committing three months to it, this is a real tailwind and you should use it today.

The realistic on-ramp is small:

```bash
npx create-lovable-app@latest my-saas
# five prompts later
# deployed URL in your clipboard
```

Five answers and you have a running app on a subdomain, with auth, with a database, with a checkout. Use it. Validate the thing.

## The export cliff

The trouble starts the day the prototype stops being a prototype.

You outgrow the sandbox for boring reasons: you need a custom domain. You need to add a column the editor doesn't expose. You need to wire a webhook that doesn't fit the agent's blessed-component list. You need to debug a race condition that only reproduces under load. You need to integrate a vendor whose SDK isn't on the sandbox's allowed-packages list.

So you click export to GitHub. You get a folder. The folder has two hundred files. Half are sensible. A third are abstractions the agent invented because it couldn't figure out your intent from five prompts. The rest are wiring that worked inside the sandbox's mental model and will not work anywhere else.

You open Cursor. You open Claude Code. You paste the repo URL. You ask the agent to add a CSV export to the reports page.

It tries. It edits six files. It breaks two. It invents a `payments.capture()` helper that calls a Stripe endpoint that doesn't exist. It suggests an npm package with no maintainer. You spend ninety minutes untangling what it did, and at the end of it the CSV is still missing. This is the seam. The sandbox won the demo. The file-system agent cannot carry the codebase the sandbox produced, because the codebase was shaped for a human to look at, not for another agent to extend.

## What a file-system agent actually needs

File-system agents — Cursor, Claude Code, Aider, Cline, Windsurf — are a different animal. They don't generate a project; they edit one. They read your files. They run your tests. They respect, or violate, your folder structure. They will follow whatever convention you hand them, or invent their own if you don't.

That difference is the whole game. A sandbox agent has a closed world: it knows its templates, its component library, its deployment shape. A file-system agent has an open world: your world. It is exactly as good as the codebase it touches. Give it a clean, conventional repo and it is astonishing — it can refactor across hundreds of files, run the test suite, fix the thing it broke, and explain itself in plain English. Give it a two-hundred-file export from a sandbox and it is lost, because no convention exists for it to follow and every file is a fresh negotiation.

The fix is not a better agent. There will be a better agent next month regardless. The fix is a better starting codebase — one that ships shaped for the agent the way a house is shaped for a person, with doors in the right places and plumbing already run.



![prototype to production on a single kit — idea, validate, customize, ship](https://cdn.otf-kit.dev/blog/own-your-code-not-the-agent/inline-1.png)



## What ships in the box

Every OTF kit ships with the configuration a file-system agent needs to be useful on day one. Not a README that suggests you read it. The actual config files, in the actual repo, with the actual conventions baked in.

```md
<!-- CLAUDE.md -->
# This kit

You are extending, not regenerating. The components, tokens, and routes
in this repo are the source of truth. If you are about to create a new
file that overlaps with one of these, stop and use the existing one.

## Commands
- `pnpm dev`        — start the web app
- `pnpm ios`        — start the iOS build
- `pnpm android`    — start the Android build
- `pnpm test`       — run the test suite
- `pnpm check`      — run the 24-item design checklist
- `pnpm ship`       — wire a custom domain, DNS, TLS, mobile build

## Conventions
- One component per file. Forward the ref. Variants via cva.
- Server actions for mutations. Route handlers only when the SDK requires it.
- All money flows through `lib/billing.ts`. Do not call Stripe directly.
- Every page has a loading state, an error state, and an empty state.
```

```md
<!-- .cursorrules -->
- Prefer editing an existing file over creating a new one.
- Match the import style already used in the file you are editing.
- Run `pnpm test` after any change under `lib/` or `app/`.
- Never regenerate the auth flow. It is wired and it works.
- Do not invent helpers. If `lib/` does not have it, ask before adding it.
```

```md
<!-- ai/prompts/add-a-billing-tier.md -->
Add a new billing tier called `<NAME>` at price `<PRICE>`.

1. Edit `lib/billing.ts`. Add the tier to the exported `tiers` array.
2. Edit `app/(marketing)/pricing/page.tsx`. Add a card using the existing
   `<PricingCard>` component. Do not create a new component.
3. Run `pnpm check`. Fix anything that fails.
4. Run `pnpm test`. Fix anything that fails.
5. Report back with a one-line summary and a diff.
```

```bash
$ ls ai/prompts/
add-a-billing-tier.md       add-a-page.md
fix-a-flaky-test.md         migrate-to-a-new-component.md
add-a-mobile-screen.md      wire-a-new-vendor.md
# ... twenty in total, each one tested by hand
```

Twenty prompts, each one written by a developer who actually used it to ship something. The agent extends the kit instead of regenerating it, because the kit told it to.

## The 24-item checklist

The other thing the kit ships with is a script. `pnpm check` runs twenty-four checks against the current state of the repo and either passes or tells you exactly which thing you broke.

```bash
$ pnpm check
[ 1/24] every page exports a default component              ok
[ 2/24] every form posts to a server action                  ok
[ 3/24] every async boundary has an error state              ok
[ 4/24] every page has a loading state                       ok
[ 5/24] every page has an empty state                        ok
[ 6/24] money flows only through lib/billing.ts              ok
[ 7/24] auth checks live in middleware, not in components    ok
[ 8/24] server actions validate input with zod               ok
[ 9/24] no client component imports server-only code         ok
[10/24] tokens come from @otfdashkit/tokens, not hex literals ok
...
[24/24] mobile screens match web component tree              ok

All 24 checks passed.
```

This is not a linter. Linters catch syntax. This catches the things that make a file-system agent wander: missing error states, inconsistent component imports, server actions without validation, money flows that bypass the billing module, tokens inlined as hex strings. Each of those is a place where the agent, left unsupervised, would invent its own convention. The checklist is the convention, written in code, runnable by the agent after every edit.

## The same kit, prototype to production

The workflow that falls out of this is roughly four steps, and the kit does all four with the same tools and the same agent — the one you already have open.

1. **Idea.** Open the kit. `pnpm dev`. Have something on screen in five minutes. The components are real, the tokens are real, the auth is real.
2. **Validate.** Ship the kit's defaults to a real domain with one script. `pnpm ship --domain=foo.com` wires DNS, TLS, and a mobile build. You have a real URL by lunch.
3. **Customize.** Use a file-system agent. Paste a prompt from `ai/prompts/`. The agent extends the kit instead of regenerating it. `pnpm check` after every change. The convention is enforced by a script, not by your memory.
4. **Ship mobile, if it's a Fitness or Booking kit.** `pnpm ios`. `pnpm android`. The same component name, the same props, the same look. One codebase. No separate mobile rewrite in month four.

The sandbox agent can win step one faster than the kit can. It cannot do steps two through four. The kit does all four with the same agent that the sandbox would have handed you anyway — but on a substrate that the agent understands.

## The durable layer

Sandbox agents will keep getting better. The one you used this month will not be the one you use next year. The file-system agent you wired your workflow to last quarter is already different from the one you wire it to next quarter. Tools churn.

What does not churn is the shape of the codebase the agent touches. A repo with a clear convention, a checked-in config file, a tested prompt library, and a script that enforces its own rules — that repo is useful to every agent that comes through it, including the one that does not exist yet.

That is the layer worth owning. Not the agent. Not the sandbox. The substrate.

Use the sandbox to win the demo. Use the file-system agent to win the product. Use a kit that ships shaped for both, with the configs already in place, so the seam between them is a Tuesday instead of a quarter.