cargo-hosting
Put something on the internet from Cargo — Vite single-page apps served at https://<slug>.cargo.app and serverless edge workers that answer HTTP requests, plus the deployments that build and promote them. Triggers: "build me a dashboard for this", "host this app", "give me a URL
Install
npx skills add https://github.com/getcargohq/cargo-skills/tree/main/cargo-hosting
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install getcargohq-cargo-skills@llmmart
git clone https://github.com/getcargohq/cargo-skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole getcargohq/cargo-skills collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Cargo CLI — Hosting
Cargo Hosting runs two kinds of workspace-scoped resources, plus the deployments that ship them:
- App — a Vite single-page app served on
https://<slug>.cargo.app, built on@cargo-ai/app-sdk(Vite + refine + shadcn primitives, withgetCargoEnv()/useCargoApi()wired to the workspace). - Worker — a serverless HTTP handler that runs on the edge (
fetch(request, env)), built on@cargo-ai/worker-sdk(auto OpenAPI 3.1 spec at/openapi.json, Swagger UI at/docs). - Deployment — one build+upload of a local source directory to an app or worker. A deployment is not live until it's promoted.
For organizing apps/workers into folders, use
cargo-workspace-management(folder …). The--folder-uuidflags here consume those folder UUIDs.
See
references/examples/apps.md,references/examples/workers.md, andreferences/examples/deployments.mdfor end-to-end walkthroughs. Seereferences/response-shapes.mdfor JSON response structures. Seereferences/troubleshooting.mdfor common errors and how to fix them.
Bootstrap
Already signed in (cargo-ai whoami returns a workspace)? Skip to the next section.
npm install -g @cargo-ai/cli # no global install? prefix every command with `npx @cargo-ai/cli`
cargo-ai login --email you@company.com # emailed code, no browser; creates the account on first use
# alternatives: --oauth (browser) · --token <api-token> (CI)
cargo-ai whoami # confirm the active workspace before any write
Every command prints JSON to stdout; failures exit non-zero with {"errorMessage": "..."}. Anything that creates a run or a batch is async — pass --wait-until-finished or poll the matching get. When the full skill bundle is installed, ../cargo/references/prerequisites.md adds the CLI version pin, token scopes, and the admin-only surface.
The lifecycle
Apps and workers follow the same shape — scaffold → create slot → deploy → promote:
init (local scaffold) → create (slot + slug) → deployment create (build+upload) → deployment promote (go live)
- Scaffold a local project from a template —
hosting app init <dir>/hosting worker init <dir>. - Create the slot in the workspace —
hosting app create --name --slug→appUuid(orworkerUuid). The--slugbecomes the subdomain and must be globally unique within the hosting domain. - (apps, optional) Wire local dev —
hosting app env <appUuid>prints the.env.locallines a local copy needs (Cargo OAuth + workspace + app UUID + API URL). - Deploy —
hosting deployment create --app-uuid <uuid> --source <dir>uploads the source; the backend runsnpm ci && vite build(apps) or bundles the entrypoint (workers) in a sandbox. Returns adeploymentUuid. - Promote —
hosting deployment promote --uuid <deploymentUuid>points the live URL at that build.
Deploys build asynchronously — poll hosting deployment get <uuid> until the status is terminal before promoting (see Async polling).
Apps
# Discover
cargo-ai hosting app list # all apps (filter with --folder-uuid <uuid>)
cargo-ai hosting app get <uuid> # one app's details + URL
# Scaffold locally (Vite + @cargo-ai/app-sdk)
cargo-ai hosting app init ./my-app --list-templates # see available templates, then:
cargo-ai hosting app init ./my-app --template blank --name "My App"
# Create the slot (slug must be globally unique → it's the subdomain)
cargo-ai hosting app create --name "My App" --slug my-app --folder-uuid <folder-uuid>
# Print .env.local for local development
cargo-ai hosting app env <app-uuid>
cargo-ai hosting app env <app-uuid> --api-url https://api.getcargo.io
# Update / remove
cargo-ai hosting app update --uuid <app-uuid> --name "Renamed"
cargo-ai hosting app update --uuid <app-uuid> --folder-uuid null # move to workspace root
cargo-ai hosting app remove <app-uuid> # also removes its deployments
Templates: blank (minimal starting point) and territories-overview (read-only territories grid demoing useCargoApi() + react-query). Run app init <dir> --list-templates for the current list.
Workers
Same command shape as apps — substitute worker for app:
cargo-ai hosting worker list # filter with --folder-uuid <uuid>
cargo-ai hosting worker get <uuid>
# Scaffold (edge fetch(request, env) handler on @cargo-ai/worker-sdk)
cargo-ai hosting worker init ./my-worker --list-templates
cargo-ai hosting worker init ./my-worker --template blank --name "My Worker"
cargo-ai hosting worker create --name "My Worker" --slug my-worker --folder-uuid <folder-uuid>
cargo-ai hosting worker update --uuid <worker-uuid> --name "Renamed"
cargo-ai hosting worker remove <worker-uuid> # also removes its deployments
Templates: blank (auto OpenAPI spec + Swagger UI) and custom-integration (a Cargo Custom Integration — manifest / actions / extractors / autocompletes / dynamic schemas). Workers have no env subcommand — they read config from the env argument passed to fetch at runtime.
Deployments
A deployment belongs to exactly one app or one worker (--app-uuid and --worker-uuid are mutually exclusive).
# List / inspect
cargo-ai hosting deployment list --app-uuid <uuid> # or --worker-uuid <uuid>
cargo-ai hosting deployment get <deployment-uuid> # status + metadata
cargo-ai hosting deployment get-promoted --app-uuid <uuid> # what's currently live
# Build & upload a local source directory (point at the package root, NOT dist/)
cargo-ai hosting deployment create --app-uuid <uuid> --source ./my-app
cargo-ai hosting deployment create --worker-uuid <uuid> --source ./my-worker
# default ignores: node_modules,dist,build,.git,.next — override with --ignore "a,b,c"
# Go live
cargo-ai hosting deployment promote --uuid <deployment-uuid>
Critical rules
--slugmust be globally unique within the hosting domain — it's the live subdomain (<slug>.cargo.app). A clash fails atcreate.- Deploying ≠ going live.
deployment createbuilds and uploads; the URL only changes when youdeployment promotethat deployment. Usedeployment get-promotedto see what's live now. --sourceis the package root, notdist/. The build runs in a Cargo sandbox:npm ci && vite buildfor apps, entrypoint bundling for workers. Shipping a pre-builtdist/will not work.- Builds are async — poll
deployment getuntil terminal before promoting (see below). --app-uuid/--worker-uuidare mutually exclusive ondeployment create,deployment list, anddeployment get-promoted. Pass exactly one.removecascades — removing an app or worker also removes all of its deployments.update --folder-uuid null(literal stringnull) moves a resource back to the workspace root.- Hosting consumes credits monthly per resource. Each app/worker carries a
chargedUntilthat an hourly sweep advances a month at a time, so a live app or worker bills hosting credits on an ongoing basis —removeresources you no longer serve. Track consumption viacargo-billing.
Async polling
deployment create kicks off a sandboxed build. The deployment's status moves pending → building → success (or error / cancelled). Poll until terminal, then promote the success one:
cargo-ai hosting deployment get <deployment-uuid> # poll ~2–5s until status is terminal
Terminal statuses are success, error, and cancelled — only promote a success deployment. On error, read the deployment's errorMessage (and buildLogS3Filename) to diagnose the build. For the general polling pattern (intervals, retries), see ../cargo-orchestration/references/polling.md.
Help
Every command supports --help:
cargo-ai hosting app create --help
cargo-ai hosting deployment create --help
Files (cargo-skills)
-
references
-
examples
-
apps.md 3.2 KB
# App examples Apps are Vite single-page apps served on `https://<slug>.cargo.app`, scaffolded from `@cargo-ai/app-sdk`. ## Scaffold → create → deploy → promote (end to end) ```bash # 1. See what templates exist, then scaffold a local project cargo-ai hosting app init ./territories --list-templates cargo-ai hosting app init ./territories --template territories-overview --name "Territories" # 2. Create the workspace slot. --slug is the live subdomain → must be globally unique. cargo-ai hosting app create --name "Territories" --slug territories # → { "uuid": "<app-uuid>", "slug": "territories", "url": "https://territories.cargo.app", ... } # 3. (optional) Develop locally — write the .env.local the app needs, then run Vite cargo-ai hosting app env <app-uuid> > ./territories/.env.local cd ./territories && npm install && npm run dev # 4. Build & upload (source = package root, not dist/). The backend runs `npm ci && vite build`. cargo-ai hosting deployment create --app-uuid <app-uuid> --source ./territories # → { "uuid": "<deployment-uuid>", "status": "...", ... } # 5. Poll until the build is terminal cargo-ai hosting deployment get <deployment-uuid> # 6. Promote to make it live at https://territories.cargo.app cargo-ai hosting deployment promote --uuid <deployment-uuid> # 7. Confirm what's live cargo-ai hosting deployment get-promoted --app-uuid <app-uuid> ``` ## List and inspect ```bash cargo-ai hosting app list # all apps in the workspace cargo-ai hosting app list --folder-uuid <uuid> # only apps in one folder cargo-ai hosting app get <app-uuid> # one app's details + live URL ``` ## Local development env `app env` prints the `.env.local` lines a local copy of the app needs — Cargo OAuth client, workspace UUID, app UUID, and API URL — so `getCargoEnv()` / `useCargoApi()` talk to the right workspace. ```bash # Default API URL (https://api.getcargo.io) cargo-ai hosting app env <app-uuid> > ./my-app/.env.local # Point at a different API (e.g. a staging environment) cargo-ai hosting app env <app-uuid> --api-url https://api.staging.getcargo.io > ./my-app/.env.local ``` ## Rename, move, remove ```bash # Rename cargo-ai hosting app update --uuid <app-uuid> --name "Renamed App" # Move into a folder (folders are managed by cargo-workspace-management) cargo-ai workspaceManagement folder list # find the folder UUID cargo-ai hosting app update --uuid <app-uuid> --folder-uuid <folder-uuid> # Move back to the workspace root (literal string "null") cargo-ai hosting app update --uuid <app-uuid> --folder-uuid null # Remove (also removes every deployment of this app) cargo-ai hosting app remove <app-uuid> ``` ## Ship a new version of an existing app The app slot and slug stay put; you just create and promote a fresh deployment. ```bash cargo-ai hosting deployment create --app-uuid <app-uuid> --source ./my-app # poll deployment get <new-deployment-uuid> until terminal cargo-ai hosting deployment promote --uuid <new-deployment-uuid> ``` Roll back by promoting an earlier deployment — `deployment list --app-uuid <uuid>` shows the history; `deployment promote --uuid <older-uuid>` points the live URL back at it. -
deployments.md 2.2 KB
# Deployment examples A deployment is one build+upload of a local source directory to an app or worker. Two facts drive everything below: 1. A deployment belongs to **exactly one** app or worker — `--app-uuid` and `--worker-uuid` are mutually exclusive. 2. **Building is not promoting.** `deployment create` builds; the live URL only moves when you `deployment promote`. ## Create a deployment ```bash # App: backend runs `npm ci && vite build` in a sandbox cargo-ai hosting deployment create --app-uuid <app-uuid> --source ./my-app # Worker: backend bundles the entrypoint cargo-ai hosting deployment create --worker-uuid <worker-uuid> --source ./my-worker ``` - `--source` is the **package root** (where `package.json` lives), not a pre-built `dist/`. The build happens server-side. - Default ignore list: `node_modules,dist,build,.git,.next`. Override the whole list with `--ignore`: ```bash cargo-ai hosting deployment create --app-uuid <app-uuid> --source ./my-app \ --ignore "node_modules,dist,build,.git,.next,coverage,.turbo" ``` ## Poll the build, then promote ```bash # Builds are async — poll until the status field is terminal cargo-ai hosting deployment get <deployment-uuid> # when terminal (built/succeeded), promote: cargo-ai hosting deployment promote --uuid <deployment-uuid> ``` If the build failed, inspect the deployment record for the error and fix the source before re-running `deployment create`. See `../response-shapes.md` for the fields to check. ## List deployment history ```bash cargo-ai hosting deployment list --app-uuid <app-uuid> # newest first cargo-ai hosting deployment list --worker-uuid <worker-uuid> ``` ## See what's currently live ```bash cargo-ai hosting deployment get-promoted --app-uuid <app-uuid> cargo-ai hosting deployment get-promoted --worker-uuid <worker-uuid> ``` ## Roll back to a previous deployment Promotion just points the live URL at a deployment, so rolling back is promoting an older one — no rebuild needed. ```bash # 1. Find the deployment you want to go back to cargo-ai hosting deployment list --app-uuid <app-uuid> # 2. Promote it cargo-ai hosting deployment promote --uuid <older-deployment-uuid> # 3. Verify cargo-ai hosting deployment get-promoted --app-uuid <app-uuid> ``` -
workers.md 2.8 KB
# Worker examples Workers are serverless HTTP handlers that run on the edge — a standard `fetch(request, env)` entrypoint built on `@cargo-ai/worker-sdk`. The `blank` template ships an automatic OpenAPI 3.1 spec at `/openapi.json` and Swagger UI at `/docs`. ## Scaffold → create → deploy → promote (end to end) ```bash # 1. Scaffold a local worker project cargo-ai hosting worker init ./my-api --list-templates cargo-ai hosting worker init ./my-api --template blank --name "My API" # 2. Create the workspace slot. --slug is the live subdomain → must be globally unique. cargo-ai hosting worker create --name "My API" --slug my-api # → { "uuid": "<worker-uuid>", "slug": "my-api", "url": "https://my-api.cargo.app", ... } # 3. Build & upload (source = package root). The backend bundles the entrypoint. cargo-ai hosting deployment create --worker-uuid <worker-uuid> --source ./my-api # → { "uuid": "<deployment-uuid>", "status": "...", ... } # 4. Poll until the build is terminal cargo-ai hosting deployment get <deployment-uuid> # 5. Promote to go live cargo-ai hosting deployment promote --uuid <deployment-uuid> # 6. Confirm what's live, then hit it cargo-ai hosting deployment get-promoted --worker-uuid <worker-uuid> curl https://my-api.cargo.app/openapi.json ``` ## List and inspect ```bash cargo-ai hosting worker list # all workers cargo-ai hosting worker list --folder-uuid <uuid> # only workers in one folder cargo-ai hosting worker get <worker-uuid> # one worker's details + URL ``` ## Templates ```bash cargo-ai hosting worker init ./tmp --list-templates ``` - **`blank`** — edge worker on `@cargo-ai/worker-sdk` with automatic OpenAPI 3.1 spec at `/openapi.json` and Swagger UI at `/docs`. - **`custom-integration`** — a Cargo Custom Integration worker: manifest / actions / extractors / autocompletes / dynamic schemas, also with `/openapi.json`. Use this when you're building an integration the rest of Cargo can call as a connector action. ## Rename, move, remove ```bash cargo-ai hosting worker update --uuid <worker-uuid> --name "Renamed Worker" cargo-ai hosting worker update --uuid <worker-uuid> --folder-uuid <folder-uuid> cargo-ai hosting worker update --uuid <worker-uuid> --folder-uuid null # back to root cargo-ai hosting worker remove <worker-uuid> # also removes its deployments ``` ## App vs worker — when to use which - **App** — you want a UI on `*.cargo.app` (dashboard, internal tool, data grid). Vite SPA, `app init`, has an `env` subcommand for local dev. - **Worker** — you want an HTTP endpoint with no UI (webhook receiver, API, custom integration backend). Edge `fetch` handler, `worker init`, **no** `env` subcommand — runtime config arrives via the `env` argument to `fetch`.
-
-
response-shapes.md 3.8 KB
# Hosting response shapes JSON response structures for the `hosting` domain. All commands output JSON to stdout; failures exit non-zero with `{"errorMessage": "..."}`. ## App (`hosting app get` / items in `hosting app list`) ```json { "uuid": "app-uuid", "workspaceUuid": "...", "name": "My App", "description": null, "slug": "my-app", "url": "https://my-app.cargo.app", "userUuid": "...", "folderUuid": null, "promotedDeployment": null, "chargedUntil": "2026-02-01T00:00:00Z", "createdAt": "2026-01-01T00:00:00Z", "updatedAt": "2026-01-15T00:00:00Z", "deletedAt": null } ``` **Key fields:** `uuid` (pass as `--app-uuid` to deployment commands), `slug` (the live subdomain), `url` (the live address), `folderUuid` (null unless filed into a folder), `promotedDeployment` (the App Deployment object currently live, or `null` if nothing is promoted yet), `chargedUntil` (end of the period already billed hosting credits — advanced a month at a time, so hosting an app costs credits monthly; see [`cargo-billing`](../../cargo-billing/SKILL.md)). ## Worker (`hosting worker get` / items in `hosting worker list`) Identical to an app, with one difference: `promotedDeployment` is a **Worker Deployment** (carries `workerUuid` + `meta`, see below). The `uuid` is passed as `--worker-uuid` to deployment commands. ## Deployment (`hosting deployment get` / items in `hosting deployment list`) A deployment is a discriminated union on `kind` (`"app"` | `"worker"`). Shared fields: ```json { "uuid": "deployment-uuid", "kind": "app", "appUuid": "app-uuid", "workspaceUuid": "...", "status": "success", "url": "https://my-app.cargo.app", "sourceS3Path": "...", "bundleS3Path": "...", "buildLogS3Filename": "...", "errorMessage": null, "meta": {}, "userUuid": "...", "promotedAt": "2026-01-01T00:01:30Z", "promotedByUserUuid": "...", "finishedAt": "2026-01-01T00:01:10Z", "temporalWorkflowId": "...", "createdAt": "2026-01-01T00:00:00Z", "updatedAt": "2026-01-01T00:01:30Z" } ``` - **`kind: "app"`** carries `appUuid` and an empty `meta` (`{}`). - **`kind: "worker"`** carries `workerUuid` instead of `appUuid`, and `meta: { "bundleSha256": "...", "outboundAllowlist": ["..."] }`. **Key fields:** - `uuid` — pass to `deployment promote --uuid`. - `appUuid` / `workerUuid` — exactly one is set, matching `kind`. - **`status`** — one of `"pending"`, `"building"`, `"success"`, `"error"`, `"cancelled"`. **Terminal** at `success` / `error` / `cancelled`; only a `success` deployment is worth promoting. - `errorMessage` — populated when `status` is `error`; `buildLogS3Filename` points at the build log for diagnosing a failed build. - `promotedAt` / `promotedByUserUuid` — non-null once this deployment has been promoted to the live URL (this is how "is it live?" is represented — there is no separate `isPromoted` flag). - `finishedAt` — when the build reached a terminal state. ## get-promoted (`hosting deployment get-promoted`) Returns the currently-promoted Deployment for the given `--app-uuid` / `--worker-uuid` (same shape as above, with `promotedAt` set), or null/empty if nothing is promoted yet. Equivalent to reading `promotedDeployment` off the app/worker. ## env (`hosting app env`) Not JSON — `hosting app env <appUuid>` prints `.env.local` lines (Cargo OAuth client, workspace UUID, app UUID, `VITE_CARGO_DEPLOYMENT_UUID`, API URL) to stdout. Redirect into a file: `cargo-ai hosting app env <app-uuid> > .env.local`. ## init templates (`hosting app init <dir> --list-templates`) ```json [ { "slug": "blank", "description": "..." }, { "slug": "territories-overview", "description": "..." } ] ``` Workers list their own templates (`blank`, `custom-integration`) via `hosting worker init <dir> --list-templates`. Note `--list-templates` still requires the `<directory>` positional argument. -
troubleshooting.md 3.2 KB
# Hosting troubleshooting Common errors in the `hosting` domain and how to fix them. ## `unknown command 'hosting'` The `hosting` domain shipped in a recent CLI. If `cargo-ai hosting --help` errors, bump the CLI: `npm install -g @cargo-ai/cli@latest`. ## Slug already taken / `create` fails on `--slug` The `--slug` is the live subdomain (`<slug>.cargo.app`) and **must be globally unique within the hosting domain** — not just unique to your workspace. Pick a more specific slug and re-run `create`. ## I deployed but the URL still shows the old version `deployment create` only builds and uploads — it does **not** change the live URL. Promote the new deployment: ```bash cargo-ai hosting deployment get <deployment-uuid> # confirm the build is terminal/succeeded cargo-ai hosting deployment promote --uuid <deployment-uuid> cargo-ai hosting deployment get-promoted --app-uuid <app-uuid> # verify what's live ``` ## `deployment create` build fails The build runs server-side in a sandbox (`npm ci && vite build` for apps, entrypoint bundling for workers). A failed build usually means: - **`--source` points at the wrong directory.** Pass the **package root** (where `package.json` lives), not a pre-built `dist/`. - **`npm ci` can't resolve the lockfile.** Ensure `package-lock.json` is present and in sync with `package.json`, and that it isn't in the ignore list. - **Something needed got ignored.** The default ignore list is `node_modules,dist,build,.git,.next`. If you override `--ignore`, you replace the whole list — don't accidentally drop `node_modules` from the ignores (it should stay ignored; the sandbox installs deps itself) while keeping source files you need. When `status` is `error`, `deployment get <uuid>` exposes the cause: read `errorMessage`, and `buildLogS3Filename` points at the full build log. Fix the source and re-run `deployment create`. ## `--app-uuid` and `--worker-uuid` both passed (or neither) On `deployment create`, `deployment list`, and `deployment get-promoted` the two flags are **mutually exclusive** — pass exactly one. A deployment targets one app or one worker, never both. ## `folderNotFound` on `--folder-uuid` The folder UUID doesn't exist. Folders are managed by the [`cargo-workspace-management`](../../cargo-workspace-management/SKILL.md) skill — run `cargo-ai workspaceManagement folder list` to find valid UUIDs. To move a resource back to the workspace root, pass the literal string `null`: `--folder-uuid null`. ## `app env` writes the wrong API URL By default `hosting app env` points at `https://api.getcargo.io`. For a different environment, override it: `cargo-ai hosting app env <app-uuid> --api-url <url>`. Workers have no `env` subcommand — they receive config via the `env` argument to `fetch(request, env)` at runtime. ## Removing an app/worker took its deployments too That's by design — `app remove` / `worker remove` cascade to every deployment of that resource. There's no undo; recreate the slot and redeploy if needed. ## Still stuck File a report so the Cargo team can improve the CLI and these docs: ```bash cargo-ai workspaceManagement report create \ --title "<one-line summary>" \ --description "<exact command(s), errorMessage, expected vs actual, UUIDs involved>" ```
-
-
skill-metadata.json 1 KB
{ "$comment": "Generated by .github/scripts/skills-metadata.mjs — do not hand-edit. Regenerate with: node .github/scripts/skills-metadata.mjs --write .", "name": "cargo-hosting", "version": "1.0.2", "documents": [ { "path": "SKILL.md", "kind": "entrypoint", "title": "Cargo CLI — Hosting" }, { "path": "references/examples/apps.md", "kind": "example", "title": "App examples" }, { "path": "references/examples/deployments.md", "kind": "example", "title": "Deployment examples" }, { "path": "references/examples/workers.md", "kind": "example", "title": "Worker examples" }, { "path": "references/response-shapes.md", "kind": "reference", "title": "Hosting response shapes" }, { "path": "references/troubleshooting.md", "kind": "reference", "title": "Hosting troubleshooting" } ], "contentHash": "ad4c6518a0be45c6a713e9de33e572a226a353c872a769f8dd95707dd5b8c2c0" } -
SKILL.md 9.2 KB
--- name: cargo-hosting description: "Put something on the internet from Cargo — Vite single-page apps served at https://<slug>.cargo.app and serverless edge workers that answer HTTP requests, plus the deployments that build and promote them. Triggers: \"build me a dashboard for this\", \"host this app\", \"give me a URL to share\", \"deploy this\", \"I need a webhook endpoint\", \"make it live\", \"promote to production\", \"put it on cargo.app\", \"ship a UI for my team\". Skip when: the app or worker should be declared as committed workspace code — use cargo-project." version: "1.0.2" compatibility: Requires @cargo-ai/cli (npm). Sign in or create an account with `cargo-ai login --email` (emailed code, no browser), `--oauth`, or an API token homepage: https://github.com/getcargohq/cargo-skills metadata: author: getcargo openclaw: requires: bins: - cargo-ai install: - kind: node package: "@cargo-ai/cli@latest" bins: - cargo-ai homepage: https://github.com/getcargohq/cargo-skills --- # Cargo CLI — Hosting **Cargo Hosting** runs two kinds of workspace-scoped resources, plus the deployments that ship them: - **App** — a Vite single-page app served on `https://<slug>.cargo.app`, built on `@cargo-ai/app-sdk` (Vite + refine + shadcn primitives, with `getCargoEnv()` / `useCargoApi()` wired to the workspace). - **Worker** — a serverless HTTP handler that runs on the edge (`fetch(request, env)`), built on `@cargo-ai/worker-sdk` (auto OpenAPI 3.1 spec at `/openapi.json`, Swagger UI at `/docs`). - **Deployment** — one build+upload of a local source directory to an app or worker. A deployment is **not live until it's promoted**. > For organizing apps/workers into **folders**, use [`cargo-workspace-management`](../cargo-workspace-management/SKILL.md) (`folder …`). The `--folder-uuid` flags here consume those folder UUIDs. > See `references/examples/apps.md`, `references/examples/workers.md`, and `references/examples/deployments.md` for end-to-end walkthroughs. > See `references/response-shapes.md` for JSON response structures. > See `references/troubleshooting.md` for common errors and how to fix them. ## Bootstrap Already signed in (`cargo-ai whoami` returns a workspace)? Skip to the next section. ```bash npm install -g @cargo-ai/cli # no global install? prefix every command with `npx @cargo-ai/cli` cargo-ai login --email you@company.com # emailed code, no browser; creates the account on first use # alternatives: --oauth (browser) · --token <api-token> (CI) cargo-ai whoami # confirm the active workspace before any write ``` Every command prints JSON to stdout; failures exit non-zero with `{"errorMessage": "..."}`. Anything that creates a run or a batch is async — pass `--wait-until-finished` or poll the matching `get`. When the full skill bundle is installed, [`../cargo/references/prerequisites.md`](../cargo/references/prerequisites.md) adds the CLI version pin, token scopes, and the admin-only surface. ## The lifecycle Apps and workers follow the same shape — **scaffold → create slot → deploy → promote**: ``` init (local scaffold) → create (slot + slug) → deployment create (build+upload) → deployment promote (go live) ``` 1. **Scaffold** a local project from a template — `hosting app init <dir>` / `hosting worker init <dir>`. 2. **Create the slot** in the workspace — `hosting app create --name --slug` → `appUuid` (or `workerUuid`). The `--slug` becomes the subdomain and **must be globally unique within the hosting domain**. 3. **(apps, optional) Wire local dev** — `hosting app env <appUuid>` prints the `.env.local` lines a local copy needs (Cargo OAuth + workspace + app UUID + API URL). 4. **Deploy** — `hosting deployment create --app-uuid <uuid> --source <dir>` uploads the source; the backend runs `npm ci && vite build` (apps) or bundles the entrypoint (workers) in a sandbox. Returns a `deploymentUuid`. 5. **Promote** — `hosting deployment promote --uuid <deploymentUuid>` points the live URL at that build. Deploys build asynchronously — **poll `hosting deployment get <uuid>`** until the status is terminal before promoting (see [Async polling](#async-polling)). ## Apps ```bash # Discover cargo-ai hosting app list # all apps (filter with --folder-uuid <uuid>) cargo-ai hosting app get <uuid> # one app's details + URL # Scaffold locally (Vite + @cargo-ai/app-sdk) cargo-ai hosting app init ./my-app --list-templates # see available templates, then: cargo-ai hosting app init ./my-app --template blank --name "My App" # Create the slot (slug must be globally unique → it's the subdomain) cargo-ai hosting app create --name "My App" --slug my-app --folder-uuid <folder-uuid> # Print .env.local for local development cargo-ai hosting app env <app-uuid> cargo-ai hosting app env <app-uuid> --api-url https://api.getcargo.io # Update / remove cargo-ai hosting app update --uuid <app-uuid> --name "Renamed" cargo-ai hosting app update --uuid <app-uuid> --folder-uuid null # move to workspace root cargo-ai hosting app remove <app-uuid> # also removes its deployments ``` Templates: `blank` (minimal starting point) and `territories-overview` (read-only territories grid demoing `useCargoApi()` + react-query). Run `app init <dir> --list-templates` for the current list. ## Workers Same command shape as apps — substitute `worker` for `app`: ```bash cargo-ai hosting worker list # filter with --folder-uuid <uuid> cargo-ai hosting worker get <uuid> # Scaffold (edge fetch(request, env) handler on @cargo-ai/worker-sdk) cargo-ai hosting worker init ./my-worker --list-templates cargo-ai hosting worker init ./my-worker --template blank --name "My Worker" cargo-ai hosting worker create --name "My Worker" --slug my-worker --folder-uuid <folder-uuid> cargo-ai hosting worker update --uuid <worker-uuid> --name "Renamed" cargo-ai hosting worker remove <worker-uuid> # also removes its deployments ``` Templates: `blank` (auto OpenAPI spec + Swagger UI) and `custom-integration` (a Cargo Custom Integration — manifest / actions / extractors / autocompletes / dynamic schemas). Workers have **no `env` subcommand** — they read config from the `env` argument passed to `fetch` at runtime. ## Deployments A deployment belongs to exactly one app **or** one worker (`--app-uuid` and `--worker-uuid` are mutually exclusive). ```bash # List / inspect cargo-ai hosting deployment list --app-uuid <uuid> # or --worker-uuid <uuid> cargo-ai hosting deployment get <deployment-uuid> # status + metadata cargo-ai hosting deployment get-promoted --app-uuid <uuid> # what's currently live # Build & upload a local source directory (point at the package root, NOT dist/) cargo-ai hosting deployment create --app-uuid <uuid> --source ./my-app cargo-ai hosting deployment create --worker-uuid <uuid> --source ./my-worker # default ignores: node_modules,dist,build,.git,.next — override with --ignore "a,b,c" # Go live cargo-ai hosting deployment promote --uuid <deployment-uuid> ``` ## Critical rules - **`--slug` must be globally unique within the hosting domain** — it's the live subdomain (`<slug>.cargo.app`). A clash fails at `create`. - **Deploying ≠ going live.** `deployment create` builds and uploads; the URL only changes when you `deployment promote` that deployment. Use `deployment get-promoted` to see what's live now. - **`--source` is the package root, not `dist/`.** The build runs in a Cargo sandbox: `npm ci && vite build` for apps, entrypoint bundling for workers. Shipping a pre-built `dist/` will not work. - **Builds are async** — poll `deployment get` until terminal before promoting (see below). - **`--app-uuid` / `--worker-uuid` are mutually exclusive** on `deployment create`, `deployment list`, and `deployment get-promoted`. Pass exactly one. - **`remove` cascades** — removing an app or worker also removes all of its deployments. - **`update --folder-uuid null`** (literal string `null`) moves a resource back to the workspace root. - **Hosting consumes credits monthly per resource.** Each app/worker carries a `chargedUntil` that an hourly sweep advances a month at a time, so a live app or worker bills hosting credits on an ongoing basis — `remove` resources you no longer serve. Track consumption via [`cargo-billing`](../cargo-billing/SKILL.md). ## Async polling `deployment create` kicks off a sandboxed build. The deployment's `status` moves `pending → building → success` (or `error` / `cancelled`). Poll until terminal, then promote the `success` one: ```bash cargo-ai hosting deployment get <deployment-uuid> # poll ~2–5s until status is terminal ``` Terminal statuses are `success`, `error`, and `cancelled` — only promote a `success` deployment. On `error`, read the deployment's `errorMessage` (and `buildLogS3Filename`) to diagnose the build. For the general polling pattern (intervals, retries), see [`../cargo-orchestration/references/polling.md`](../cargo-orchestration/references/polling.md). ## Help Every command supports `--help`: ```bash cargo-ai hosting app create --help cargo-ai hosting deployment create --help ```
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.