# Deploy Flow

The only way to deploy is: **stage files first, then call deploy.**

## Normal flow

```
stage_files("my-app", [file1, file2, ..., file12])
→ "Staged 12 file(s). Total staged for 'my-app': 12 file(s)."

stage_files("my-app", [file13, ..., file24])   ← split into chunks if needed
→ "Staged 12 file(s). Total staged for 'my-app': 24 file(s)."

deploy("my-app")
→ deploys all staged files, returns live_url
```

For small edits to existing files, use edit_file instead:

```
edit_file({ project_id: "my-app", path: "main.ts", old_string: "...", new_string: "..." })
deploy("my-app")   ← no files needed; applies the staged edit
```

## Uploading files from disk (token-efficient)

If the files already exist on disk, you can stage them over HTTP instead of passing their
contents through the MCP protocol — this saves tokens, especially for many or large files:

```
POST https://onvibe.run/api/projects/{project_id}/stage
Authorization: Bearer <api_key>     ← create one with create_api_key
Content-Type: multipart/form-data   ← one form field per file, field name = file path

curl -X POST "https://onvibe.run/api/projects/my-app/stage" \
  -H "Authorization: Bearer onv_..." \
  -F "main.ts=@./main.ts" \
  -F "static/icon-192.png=@./icon-192.png" \
  -F "static/favicon.ico=@./favicon.ico"
→ {"staged": 3, "total": 3}

deploy("my-app")
```

- **Text and binary both work.** Binary content (PNG, ICO, fonts) is detected and preserved
  byte-for-byte. You do NOT need to base64-encode anything yourself.
- A `{"staged": N}` response means the bytes were stored intact, not merely received.
- Limits: **100 KB per file, 1 MB per request**. For larger static assets served from the
  CDN (big images, fonts), use `POST /api/projects/{id}/assets` (2 MB/file) or the
  `upload_asset` tool instead — see onvibe://docs/uploads.
- If your environment routes outbound HTTP through a text-only/transcoding proxy and you
  suspect it mangles binary, use the `stage_files` MCP tool with `encoding: "base64"`
  instead — base64 is pure ASCII and survives any text transport.

## Rules

- stage_files is idempotent — calling it twice with the same file overwrites the previous version
- Staged files persist until the next successful deploy or until overwritten
- deploy() uses whatever is staged; it does NOT accept inline files
- main.ts must be present in the staged files before calling deploy()
- For BINARY files via the stage_files MCP tool, set `encoding: "base64"`. The HTTP `/stage`
  endpoint above detects binary automatically; only the MCP tool needs the explicit flag.

## Checking staged files

Use list_project_files("my-app") to see paths and sizes, then read_project_files("my-app", ["main.ts"]) to read specific files.
