Claude Cursor Skill

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

LLM Mart · 0 points · 18 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download getcargohq-cargo-skills-cargo-hosting-addc862.zip · 11 KB
Part of getcargohq/cargo-skills — 22 skills

Install

skills CLI npx skills add https://github.com/getcargohq/cargo-skills/tree/main/cargo-hosting
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install getcargohq-cargo-skills@llmmart
Git 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, 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 (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.

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)
  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).

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

  • --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.

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.

No comments yet.

Reviews (0)

No reviews yet.

Related