# Userland full docs context # Userland agent context Userland publishes apps to immutable app origins at https://.apps.userland.fun/. Use the control-plane API or CLI from a server-side tool with USERLAND_API_KEY in the environment. Do not expose USERLAND_API_KEY or app secrets in frontend code. Do not invent platform internals for app code. Use manifest.userland.json and the Userland runtime ctx APIs. Core URLs: - API: https://api.userland.fun - Examples: https://github.com/dwrtz/userland-public - Public CLI source: https://github.com/dwrtz/userland-public/tree/main/cli - Runtime types: https://docs.userland.fun/types/runtime-context-v0.d.ts - Manifest schema: https://docs.userland.fun/schemas/resource-manifest-v0.schema.json - OpenAPI: https://docs.userland.fun/openapi.json Recommended flow: 1. Read /start, /quickstarts/full-stack-app, /reference/resource-manifest, /reference/runtime-ctx, /reference/api, and /reference/cli. 2. Create manifest.userland.json, public assets, and server/index.js when dynamic behavior is needed. 3. Validate secrets, resources, runtime fallback, and file paths before publishing. 4. Publish with the CLI or PUT /v0/apps. 5. Report app_id, origin, release_id, activation status, and rollback instructions. Docs routes: - https://docs.userland.fun/start: The shortest path for a coding agent to build and publish a Userland app. - https://docs.userland.fun/agents: Operational rules for autonomous and supervised coding agents using Userland. - https://docs.userland.fun/skills: How Userland repo-scoped Codex skills fit into the agent workflow. - https://docs.userland.fun/prompts: Copyable prompts for handing a Userland app build to a coding agent. - https://docs.userland.fun/quickstarts/static-app: Publish a static Userland app with only public assets. - https://docs.userland.fun/quickstarts/server-app: Publish a dynamic app with a Userland server entrypoint. - https://docs.userland.fun/quickstarts/full-stack-app: Build a Userland app with static UI, server routes, auth, data, and secrets. - https://docs.userland.fun/quickstarts/from-example: Start from a public Userland example and adapt it safely. - https://docs.userland.fun/concepts/apps-and-releases: How Userland app identity, immutable releases, activation, and rollback work. - https://docs.userland.fun/concepts/resources-and-state: How managed resources relate to durable app state. - https://docs.userland.fun/concepts/runtime-routing: Request routing order for static files, reserved paths, and server fallback. - https://docs.userland.fun/concepts/security-boundaries: Userland control-plane, product, and app-runtime trust boundaries. - https://docs.userland.fun/guides/data: Declare and use app-scoped data collections. - https://docs.userland.fun/guides/auth: Add app-user auth, roles, invites, and sessions. - https://docs.userland.fun/guides/files: Declare file stores and generate runtime file URLs. - https://docs.userland.fun/guides/secrets: Declare, set, and read app secrets safely. - https://docs.userland.fun/guides/jobs: Declare manual and scheduled jobs for server-side background work. - https://docs.userland.fun/guides/webhooks: Declare provider webhooks and handle verified deliveries. - https://docs.userland.fun/guides/rollback: Move an app live pointer back to a compatible release. - https://docs.userland.fun/guides/resource-migrations: Change resources safely under Userland v0 monotonic resource rules. - https://docs.userland.fun/guides/troubleshooting: Debug publish, activation, runtime, job, webhook, secret, and rollback failures. - https://docs.userland.fun/reference/api: Userland v0 control-plane endpoints and request patterns. - https://docs.userland.fun/reference/resource-manifest: The app metadata, runtime, resource, and release file contract. - https://docs.userland.fun/reference/runtime-ctx: The server-side Userland runtime context available to app modules. - https://docs.userland.fun/reference/cli: Userland CLI command surface for publishing and operations. - https://docs.userland.fun/reference/agent-skills: Reference for Userland repo-scoped Codex skills and expected coverage. - https://docs.userland.fun/reference/errors: Error response format and common status codes. - https://docs.userland.fun/reference/limits: Current v0 release and runtime limits agents should validate before publishing. - https://docs.userland.fun/examples: Public examples catalog agents can copy from. - https://docs.userland.fun/changelog: Human and agent-visible notes for docs, API, runtime, examples, skills, and CLI changes. ## Start > **For agents:** Read `llms.txt`, create `manifest.userland.json`, add `public/` files, add `server/index.js` only when dynamic routes are needed, then publish with a server-side CLI or API call using `USERLAND_API_KEY`. ## Goal Build a valid Userland app bundle and publish it to an immutable app origin. ## Inputs - App idea and expected user workflow. - `USERLAND_API_KEY` in the local environment. - Optional examples from the public examples repo. ## Outputs - `manifest.userland.json`. - Static files under `public/`. - Optional server module at `server/index.js`. - Published `app_id`, `origin`, `release_id`, and activation status. ## Commands ```bash npm run userland -- apps publish . ``` ## Generated artifacts - [`/llms.txt`](/llms.txt) for compact agent context. - [`/openapi.json`](/openapi.json) for the control-plane API. - [`/schemas/resource-manifest-v0.schema.json`](/schemas/resource-manifest-v0.schema.json) for `manifest.userland.json`. - [`/types/runtime-context-v0.d.ts`](/types/runtime-context-v0.d.ts) for server runtime code. Do not put API keys, app secrets, or platform internals into app frontend code. ## Agents > **For agents:** Treat Userland as the platform boundary. Use the manifest, runtime `ctx`, CLI, and API exactly as documented instead of guessing infrastructure internals. ## Agent Contract 1. Read `/llms.txt` before generating files. 2. Prefer a complete quickstart or example over ad hoc scaffolding. 3. Declare managed resources in `manifest.userland.json`. 4. Use `ctx.data`, `ctx.auth`, `ctx.files`, `ctx.secrets`, `ctx.jobs`, and `ctx.webhooks` from server code. 5. Publish only from a trusted local or server-side tool with `USERLAND_API_KEY`. ## Never Do - Never expose `USERLAND_API_KEY` in browser code. - Never print secret values. - Never invent platform internals or raw resource names. - Never serve app content from `userland.fun`; runtime apps use `https://.apps.userland.fun/`. ## Machine-readable inputs - [`/llms.txt`](/llms.txt) - [`/llms-full.txt`](/llms-full.txt) - [`/openapi.json`](/openapi.json) - [`/schemas/resource-manifest-v0.schema.json`](/schemas/resource-manifest-v0.schema.json) - [`/types/runtime-context-v0.d.ts`](/types/runtime-context-v0.d.ts) - [`/examples/catalog.json`](/examples/catalog.json) - [`/skills/catalog.json`](/skills/catalog.json) ## Skills > **For agents:** When working inside `userland-public`, load the relevant `.agents/skills/*/SKILL.md` workflow before implementing manifests, runtime code, publishing, or debugging. ## Distribution Launch uses repo-scoped skills in the public examples repo. Plugin packaging is deferred until the workflows stabilize. Public repo: `https://github.com/dwrtz/userland-public` CLI source: `https://github.com/dwrtz/userland-public/tree/main/cli` ## Skill Areas - `userland-build-app` for end-to-end app generation. - `userland-manifest-resources` for resource declarations. - `userland-runtime-code` for server handlers and `ctx`. - `userland-publish-operate` for CLI/API publishing, secrets, events, and rollback. - `userland-debug-migrate` for activation and resource-change failures. - `userland-adapt-examples` for copying examples into new apps. See `/skills/catalog.json` for a machine-readable list. ## Prompts > **For agents:** Use the full prompt as an operating contract. Report files created, commands run, app identity, activation status, and rollback notes. ## App Build Prompt ```text Read https://docs.userland.fun/llms.txt and build a Userland app for this idea: . Create manifest.userland.json, public files, and server/index.js only when dynamic routes are needed. Use Userland managed resources and runtime ctx APIs. Do not expose USERLAND_API_KEY or app secrets in frontend code. Do not invent platform internals. Publish with USERLAND_API_KEY from the environment using the public Userland CLI or documented API. Report app_id, origin, release_id, activation status, and rollback instructions. ``` ## Static App > **For agents:** Create a manifest with `runtime.static_root: "public"` and `fallback: "index.html"`, then publish the directory. ## Files ```text manifest.userland.json public/index.html ``` ## Manifest ```json { "app": { "name": "Hello Static", "visibility": "public" }, "runtime": { "static_root": "public", "fallback": "index.html" }, "resources": {} } ``` ## Publish ```bash npm run userland -- apps publish . ``` ## Server App > **For agents:** Add `runtime.server_entry`, set `fallback` to `server`, and export a default server module with `fetch(request, ctx)`. ## Files ```text manifest.userland.json public/index.html server/index.js ``` ## Server ```js export default { async fetch(request, ctx) { const url = new URL(request.url); if (url.pathname === "/api/health") { return Response.json({ ok: true, app_id: ctx.app.app_id }); } return new Response("not found", { status: 404 }); } }; ``` ## Full Stack App > **For agents:** Model durable needs in `resources`, keep secret reads in server code, and use `ctx` helpers instead of direct platform APIs. ## File Structure ```text manifest.userland.json public/index.html public/assets/app.js public/assets/app.css server/index.js ``` ## Resource Shape Declare `auth`, `data`, and `secrets` before writing runtime code that depends on them. If activation returns `pending_secrets`, set the missing secrets and republish or inspect the release state. ## Manifest ```json { "app": { "name": "Team Notes", "summary": "A private notes app with admin-managed access.", "visibility": "public" }, "runtime": { "static_root": "public", "server_entry": "server/index.js", "fallback": "server" }, "resources": { "auth": { "mode": "app_users", "roles": ["admin", "editor"], "public_signup": false }, "data": { "collections": { "notes": { "fields": { "title": "string", "body": "richtext", "status": { "type": "enum", "values": ["draft", "published"] } }, "indexes": [{ "name": "by_status", "fields": ["status"] }], "access": { "read": "authenticated", "write": "role:editor" } } } }, "secrets": { "required": ["OPENAI_API_KEY"] } } } ``` ## Server entry ```js export default { async fetch(request, ctx) { const url = new URL(request.url); const notes = ctx.data.collection("notes"); if (url.pathname === "/api/notes" && request.method === "GET") { await ctx.auth.requireRole(request, "editor"); return Response.json(await notes.list({ limit: 50 })); } if (url.pathname === "/api/notes" && request.method === "POST") { await ctx.auth.requireRole(request, "editor"); const input = await request.json(); const note = await notes.create({ title: input.title, body: input.body, status: "draft" }); return Response.json({ note }, { status: 201 }); } return new Response("not found", { status: 404 }); } }; ``` ## Publish and operate ```bash npm run userland -- apps publish . --message "Initial Team Notes release" printf '%s' "$OPENAI_API_KEY" | npm run userland -- apps secrets set "$APP_ID" OPENAI_API_KEY npm run userland -- apps events "$APP_ID" --severity error --limit 25 ``` ## Verification - Static files are under `runtime.static_root`. - Server routes return JSON errors without stack traces. - Browser code never contains secret names with values. - Publish output includes `activation_status=live`. ## From Example > **For agents:** Clone or copy an example, preserve the manifest/runtime shape, then replace product-specific UI and data fields deliberately. ## Flow 1. Open `/examples/catalog.json`. 2. Choose the closest example by capability. 3. Copy the example directory. 4. Rename the app metadata and data collections. 5. Run tests when present. 6. Publish with the CLI. ## Source The canonical public examples repo is `https://github.com/dwrtz/userland-public`. ## Apps And Releases > **For agents:** Treat `app_id` as stable identity and release ids as immutable deployment snapshots. Rollback moves the live pointer only. ## Model Publishing creates an app or release. The runtime origin is always `https://.apps.userland.fun/`. App names and summaries are mutable metadata. They are not routing identity. ## Activation Activation can be `live`, `pending_secrets`, or `requires_migration`. Non-live releases are stored but do not replace the live pointer. ## Resources And State > **For agents:** Declare capabilities at the product level. Do not expose platform storage, routing, or execution internals in app code. ## Resources Userland v0 supports static files, server entrypoints, data collections, app-user auth, file stores, secrets, jobs, webhooks, events, release history, and rollback. ## State State is app-scoped and retained across compatible releases. Publishing is non-destructive in v0. ## Runtime Routing > **For agents:** Reserved `/_userland/*` paths win, static files are checked next, then fallback decides between `index.html`, `server`, or `404`. ## Routing Order 1. Platform reserved paths under `/_userland/*`. 2. Static release file lookup under `runtime.static_root`. 3. Directory `index.html` lookup. 4. Runtime fallback. Apps cannot publish files under `_userland/`. ## Security Boundaries > **For agents:** Keep control-plane credentials outside app code. App-user auth uses host-bound runtime cookies and reserved platform routes. ## Planes - `api.userland.fun` is the control plane for API keys. - `userland.fun` is the product home page. - `*.apps.userland.fun` is the app runtime plane. - `docs.userland.fun` is public documentation. Runtime dispatch strips platform headers, ordinary cookies, internal headers, and control-plane credentials before app server code runs. ## Data > **For agents:** Put collection declarations in the manifest and use `ctx.data.collection(name)` from server code. ## Server Use ```js const posts = ctx.data.collection("posts"); const post = await posts.create({ title: "Hello", slug: "hello" }); const page = await posts.list({ where: { slug: "hello" }, limit: 10 }); ``` Creates and updates accept declared fields only. Unique indexes are enforced per app. ## Auth > **For agents:** Declare `auth.mode: "app_users"` and roles, then call `ctx.auth.currentUser(request)` or `ctx.auth.requireRole(request, role)`. ## Reserved Routes App-user signup, login, logout, session lookup, and invite acceptance live under `/_userland/auth/*`. Create admin invites through the control-plane API or CLI after publishing an app that declares the target roles. ## Files > **For agents:** Declare file stores in `resources.files`, enforce content type and size expectations, and upload only through `ctx.files`. ## Server Use ```js const media = ctx.files.store("media"); const file = await media.createUpload(bytes, { filename: "hero.png", content_type: "image/png" }); const url = await media.getPublicUrl(file.file_id); ``` Private stores require an authenticated user or signed URL. ## Secrets > **For agents:** Declare required secret names, set values through the CLI/API, and read them only from server code with `ctx.secrets`. ## CLI ```bash printf '%s' "$CHECKOUT_SECRET_KEY" | npm run userland -- apps secrets set "$APP_ID" CHECKOUT_SECRET_KEY ``` Secret values are encrypted at rest, never returned by the API, and must not be embedded in static assets. ## Jobs > **For agents:** Declare jobs in the manifest, enqueue manual jobs with `ctx.jobs.enqueue`, and implement `job(event, ctx)` in the server module. ## Server Use ```js await ctx.jobs.enqueue("send-digest", { user_id: "appusr_123" }, { delay_seconds: 60 }); ``` Scheduled jobs use `every_15_minutes`, `hourly`, or `daily` in v0. ## Webhooks > **For agents:** Declare webhook providers in the manifest and handle deliveries with `webhook(event, ctx)` or route them to a job. ## Runtime URL ```text https://.apps.userland.fun/_userland/webhooks/:name ``` Signature headers are verified by Userland and redacted before app-visible events reach server code. ## Rollback > **For agents:** List releases, choose a retained compatible release, then call rollback. Do not expect rollback to delete durable state. ## CLI ```bash npm run userland -- apps releases "$APP_ID" npm run userland -- apps rollback "$APP_ID" "$RELEASE_ID" ``` Rollback moves the live pointer only. Data, users, sessions, files, secrets, queued jobs, webhook history, and events are retained. ## Resource Migrations > **For agents:** Add new resources and backfill deliberately. Do not redefine same-name resources incompatibly in v0. ## Policy Publish is non-destructive. Release manifests are release-local views over durable app state. Provisioned resources are monotonic in v0. For incompatible changes, add a new collection, field, store, or job name, backfill through server code, then hide old UI paths. ## Troubleshooting > **For agents:** Start with publish output, activation status, missing secrets, release resources, and owner-visible app events. ## Checks 1. Confirm `USERLAND_API_KEY` is set only in the local environment. 2. Validate `manifest.userland.json`. 3. Check activation status for `pending_secrets` or `requires_migration`. 4. Read app events with `npm run userland -- apps events "$APP_ID" --severity error`. 5. Roll back only to a compatible retained release. ## First Commands ```bash npm run userland -- apps events "$APP_ID" --limit 25 npm run userland -- apps releases "$APP_ID" npm run userland -- apps secrets set "$APP_ID" SECRET_NAME --value "$VALUE" npm run userland -- apps rollback "$APP_ID" "$RELEASE_ID" ``` ## Publish failures - `invalid_bundle`: every release needs a non-empty `files` array. When using the CLI, confirm the app directory is not empty. - `invalid_path`: release paths must be relative, must not contain `..`, and must not publish under `_userland/`. - `missing_static_root`: `runtime.static_root` must contain at least one release file. - `missing_server_entry`: `runtime.server_entry` must point to a file in the release. - `bundle_too_large`: v0 accepts up to 1000 files, 20 MiB per file, and 100 MiB total decoded bytes. ## Activation failures `pending_secrets` means the release is stored but not live. Set each missing secret: ```bash printf '%s' "$VALUE" | npm run userland -- apps secrets set "$APP_ID" SECRET_NAME ``` `requires_migration` means the release changes durable resources in a way v0 will not apply automatically. Use an add/backfill/hide approach: add a new resource name, backfill in runtime code or an admin path, then stop using the old resource. ## Runtime failures Read recent error events: ```bash npm run userland -- apps events "$APP_ID" --severity error --limit 25 ``` Check that dynamic routes are reachable only when `fallback` is `server`, that the server module exports `fetch`, and that frontend code calls your app origin rather than the control-plane API. ## Job and Webhook Failures Check events for the job or webhook name, then compare the manifest with `server/index.js`: ```bash npm run userland -- apps events "$APP_ID" --type job --limit 25 npm run userland -- apps events "$APP_ID" --type webhook --limit 25 ``` Job names must match exactly. Webhooks that deliver to jobs must reference a declared job and a required secret that has been set for the app. ## API > **For agents:** Use bearer auth for owner reads and mutations. Send JSON. Handle structured `{ "error": { "code", "message" } }` responses. ## Base URL ```text https://api.userland.fun ``` All owner reads and mutations use: ```http Authorization: Bearer ap_live_... Content-Type: application/json ``` ## Endpoints - `POST /v0/accounts` - `POST /v0/auth/token` - `GET /v0/apps` - `PUT /v0/apps` - `GET /v0/apps/:app_id` - `PUT /v0/apps/:app_id` - `DELETE /v0/apps/:app_id` - `GET /v0/apps/:app_id/releases` - `POST /v0/apps/:app_id/rollback` - `GET /v0/apps/:app_id/resources` - `GET /v0/apps/:app_id/events` - `GET /v0/apps/:app_id/secrets` - `PUT /v0/apps/:app_id/secrets/:NAME` - `DELETE /v0/apps/:app_id/secrets/:NAME` - `POST /v0/apps/:app_id/admin-invites` Use `/openapi.json` for the machine-readable API contract. ## Publish request `PUT /v0/apps` creates an app and first release. `PUT /v0/apps/:app_id` publishes another release for an existing app. ```json { "app": { "name": "Hello App", "visibility": "public" }, "runtime": { "static_root": "public", "fallback": "index.html" }, "resources": {}, "files": [ { "path": "public/index.html", "content_type": "text/html; charset=utf-8", "content_base64": "PCFkb2N0eXBlIGh0bWw+PGgxPkhlbGxvPC9oMT4=" } ], "message": "Initial release", "provenance": { "source": "agent" } } ``` The response includes `status`, `app_id`, `release_id`, `origin`, `previous_release_id`, and `activation`. ## Activation - `live` means the release is serving. - `pending_secrets` means required secrets are missing. - `requires_migration` means the release was stored but did not become live because a resource change needs an explicit migration plan. ## Events and rollback Use `GET /v0/apps/:app_id/events?severity=error&limit=25` to inspect owner-visible failures. Use rollback only with a compatible retained release. ## Resource Manifest > **For agents:** Create `manifest.userland.json` with `app`, `runtime`, and optional `resources`. The CLI adds release `files` when publishing a directory. ## Minimal Manifest ```json { "app": { "name": "Recipe Box", "visibility": "public" }, "runtime": { "static_root": "public", "server_entry": "server/index.js", "fallback": "server" }, "resources": {} } ``` Do not expose raw platform resource configuration in this manifest. ## Top-level fields - `app` is required. It contains mutable display metadata and does not affect the app origin. - `runtime` is required. It tells Userland where static files live and whether dynamic requests go to a server module. - `resources` is optional. It declares durable managed capabilities for the release. When publishing with the CLI, `manifest.userland.json` does not include release files. The CLI reads the directory, builds the `files` array, infers content types, and sends a publish request to the API. ## App ```json { "name": "Recipe Box", "summary": "A recipe CMS with a public site and admin editor.", "visibility": "public", "tags": ["recipes", "cms"] } ``` - `name` is required and must be non-empty. - `summary` is optional text for humans and agents. - `visibility` is `public` or `private`; v0 defaults to `public`. - `tags` use the same lowercase resource-name shape as other author-defined names. ## Runtime ```json { "static_root": "public", "server_entry": "server/index.js", "fallback": "server" } ``` - `static_root` is required and must point to at least one release file. - `server_entry` is required when `fallback` is `server`; it must point to a release file. - `fallback` is `server`, `index.html`, or `404`. - Paths are relative, slash-separated, and cannot use empty, dot, parent, or reserved `_userland` segments. ## Resources ```json { "auth": { "mode": "app_users", "roles": ["admin", "editor"] }, "data": { "collections": { "posts": { "fields": { "title": "string", "slug": "string", "status": { "type": "enum", "values": ["draft", "published"] } }, "indexes": [{ "name": "by_slug", "fields": ["slug"], "unique": true }], "access": { "read": "public", "write": "role:editor" } } } }, "secrets": { "required": ["OPENAI_API_KEY"] }, "jobs": { "send-digest": { "trigger": "manual", "max_attempts": 3 } }, "webhooks": { "github": { "provider": "github", "secret": "GITHUB_WEBHOOK_SECRET", "deliver_to": "server" } } } ``` Use `/schemas/resource-manifest-v0.schema.json` as the machine-readable schema for `manifest.userland.json`. ## Runtime Ctx > **For agents:** Server code receives only `request` and scoped `ctx`; use those helpers instead of platform internals. ## Shape ```ts ctx.app.app_id ctx.app.origin ctx.app.release_id ctx.auth ctx.data ctx.files ctx.secrets ctx.jobs ctx.webhooks ctx.log ``` Server modules can export `fetch`, `job`, and `webhook` handlers. ## Server module ```js export default { async fetch(request, ctx) { return Response.json({ app_id: ctx.app.app_id }); }, async job(event, ctx) { ctx.log.info("job received", { name: event.name }); }, async webhook(event, ctx) { return Response.json({ received: true }); } }; ``` ## Request handling `fetch(request, ctx)` handles dynamic HTTP requests when static routing does not match and `runtime.fallback` is `server`. Use standard Web APIs: `Request`, `Response`, `URL`, `Headers`, and `Response.json`. ## Data ```js const posts = ctx.data.collection("posts"); const post = await posts.create({ title: "Hello", slug: "hello" }); await posts.update(post.id, { title: "Hello world" }); const page = await posts.list({ where: { slug: "hello" }, limit: 10 }); ``` Rows are scoped to the app and expose declared fields plus `id`, `created_at`, and `updated_at`. ## Secrets ```js const apiKey = await ctx.secrets.require("OPENAI_API_KEY"); const optional = await ctx.secrets.get("OPTIONAL_TOKEN"); ``` Secret values are available only to server runtime code. ## Auth ```js const user = await ctx.auth.currentUser(request); const admin = await ctx.auth.requireRole(request, "admin"); ``` Auth helpers work when the app declares `auth.mode: "app_users"`. ## CLI > **For agents:** Use `USERLAND_API_KEY` from the environment. Do not advertise `npx @userland/cli` until the package is published. ## Local Command ```bash npm run userland -- apps publish . npm run userland -- apps list npm run userland -- apps releases "$APP_ID" npm run userland -- apps rollback "$APP_ID" "$RELEASE_ID" npm run userland -- apps events "$APP_ID" --severity error --limit 25 npm run userland -- apps secrets set "$APP_ID" SECRET_NAME --value "$VALUE" ``` The launch public CLI source is under `userland-public/cli`. ## Distribution For launch, the public CLI is run from source in `https://github.com/dwrtz/userland-public/tree/main/cli`. The package name is reserved as `@userland/cli`, but npm installation is deferred until a real package release exists. ## Sync Policy `userland-public/cli` is the public CLI source of truth during this phase. CLI changes should update the public CLI source, public CLI README, this reference page, command tests, and changelogs together. Validate with: ```bash npm run typecheck npm run cli:test npm test ``` ## Agent Skills > **For agents:** Select the narrowest Userland skill that matches the task and follow its workflow before generating or changing files. ## Coverage - Build app from idea. - Model resource manifest. - Write runtime code. - Publish and operate apps. - Debug activation, runtime, job, webhook, and migration issues. - Adapt examples. The machine-readable catalog is available at `/skills/catalog.json`. The public skill source is `https://github.com/dwrtz/userland-public/tree/main/.agents/skills`. When a task includes publishing, secrets, events, rollback, or CLI usage, pair the selected skill with `/reference/cli` and `/guides/troubleshooting`. ## Errors > **For agents:** Parse `error.code` and `error.message`, report both, and use events for owner-visible runtime detail. ## Shape ```json { "error": { "code": "invalid_path", "message": "Release path must be relative." } } ``` Common statuses are `400`, `401`, `403`, `404`, `409`, `413`, and `429`. ## Common Codes - `invalid_path`: a release file path is absolute, contains `..`, or targets `_userland/`. - `missing_static_root`: `runtime.static_root` does not match any published file. - `missing_server_entry`: `runtime.server_entry` does not match a published server file. - `invalid_resource_manifest`: resource declarations failed validation. - `pending_secrets`: activation is blocked until required app secrets are set. - `requires_migration`: durable resource changes need an explicit migration plan. ## Recovery Use the CLI to inspect and recover: ```bash npm run userland -- apps events "$APP_ID" --limit 25 npm run userland -- apps releases "$APP_ID" npm run userland -- apps rollback "$APP_ID" "$RELEASE_ID" ``` See `/guides/troubleshooting` for the full debug path. ## Limits > **For agents:** Check file count, decoded file sizes, paths, MIME types, and supported schedules before publish. ## Release Limits - Max files: `1000`. - Max single decoded file: `20 MiB`. - Max total decoded files: `100 MiB`. - File paths must be relative and cannot use empty, dot, or parent segments. - Scheduled jobs support `every_15_minutes`, `hourly`, and `daily`. ## Platform Limits - Production server apps run as Workers for Platforms User Workers behind the Userland app gateway. - v0 uses one shared Userland-managed D1 database. Apps do not get a dedicated D1 database. - App data is scoped by `app_id`; large or high-write apps may be moved to app-data shards later. - Current operational tripwires: shared D1 storage near `7 GB`, D1 queueing/user-visible SQL latency, or one tenant degrading unrelated apps. ## Examples > **For agents:** Choose examples by capabilities, copy the full directory, then update manifest metadata, resource names, UI, and tests together. Clone `https://github.com/dwrtz/userland-public`, choose the closest example by capability, and adapt the whole example directory rather than copying isolated snippets. The monorepo `examples/` directory contains platform test fixtures only. User-facing examples live in the public repo. ## Required Files Each public example includes: - `README.md` for humans supervising the agent. - `AGENT.md` with adaptation notes. - `example.json` metadata. - `manifest.userland.json`. - `public/` assets. - `server/index.js` when dynamic runtime behavior is required. ## Public Catalog Use `/examples/catalog.json` for machine-readable example metadata. The canonical public repo is `https://github.com/dwrtz/userland-public`. ## Changelog > **For agents:** Check this page when generated examples, manifests, or CLI commands no longer match the current docs. ## Unreleased - Added a content-driven docs site foundation. - Added machine-readable `llms.txt`, `llms-full.txt`, examples catalog, and skills catalog outputs. - Moved public examples, repo-scoped skills, and public CLI source into `https://github.com/dwrtz/userland-public`. - Added launch QA checklist for docs, home page, public examples, skills, CLI, artifacts, and smoke tests. - Added generated artifact freshness checks and documented the public repo duplication policy. - Added command-level public CLI tests and launch CLI sync policy notes. - Kept npm publication for `@userland/cli` deferred until an actual package release exists.