Reference
Changelog
What changed in each release of the CLI, SDK, runtime, and Starbase.
Newest first. Starbase changes go live when they merge. The packages (robodev, @robodev-ai/sdk, @robodev-ai/runtime, @robodev-ai/client) are published to npm; robodev, the SDK and the runtime each ship their own CHANGELOG.md. Hosted projects always run Starbase's own SDK and runtime, so a new package version matters for robodev dev and for local typings.
2026-10-22 — Starbase (hosted)
- Replacing a unique constraint on a table that has rows (for example a column's .unique() swapped for a composite unique(...).on(a, b)) now deploys without --force. It used to fail with a misleading schema_change_ambiguous "looks like a rename" error. Dropping a constraint or an index no longer counts as destructive; dropping a table or column, changing a column type, SET NOT NULL and dropping a primary key still need --force.
- If existing rows break a new unique constraint, the deploy answers 409 schema_change_conflicts_with_data naming the constraint, the table and the duplicated key. The whole schema change is rolled back and the previous deployment keeps serving. Remove or merge the duplicate rows, then deploy again.
2026-10-22 — runtime 0.30.0 / client 0.10.0 / robodev 0.78.0
- Native Sign in with Apple for iOS apps: POST /api/user/auth/apple/native with Apple's identityToken and the raw nonce returns { accessToken, refreshToken }. @robodev-ai/client 0.10.0 adds api.auth.signIn.appleNative(...). Native and web Apple users are the same users. See Auth (/docs/auth#apple-native).
- Account self-delete: DELETE /api/user/me (Bearer) on deployed projects and in robodev dev, and api.auth.deleteAccount() in the client. It fires user.deleted. See Auth (/docs/auth#delete-account).
- robodev dev verifies native Apple identity tokens when APPLE_BUNDLE_IDS is set in the project .env; web Apple stays hosted-only.
- robodev auth-settings set --apple-bundle-ids and the MCP update_auth_settings argument apple_bundle_ids set the project's iOS bundle IDs. get shows web and iOS Apple status separately.
- OpenAPI: POST /api/user/auth/apple/native (UserAuthAppleController_native) and DELETE /api/user/me (UserMeController_delete).
Starbase (hosted), released together with 0.78.0:
- The Auth page's Apple card is an accordion: Apple Developer key (Team ID, Key ID, .p8), Web sign-in (Services ID, Return URL) and iOS app (bundle IDs), each with a one-line summary and a status badge. The first missing group opens by default, and a save error opens the group to fix. The Services ID is no longer required when bundle IDs are set. The Start URLs card adds the Apple native URL.
- When the iOS app sends authorizationCode, Starbase stores the Apple refresh token encrypted and revokes it when the user is deleted (self-delete, dashboard or MCP), as App Store guideline 5.1.1(v) requires.
- GET /v1/projects/:id/auth adds appleBundleIds, appleWebActive and appleNativeActive; appleActive now means web or native is on.
2026-10-21 — runtime 0.29.0 / robodev 0.77.0
- robodev members list | add | role | remove manages who has access to the project. add gives a verified Robodev account access at once (developer by default, which can deploy) and invites anyone else. Always uses the robodev auth login; deploy keys cannot list or manage members. See CLI reference (/docs/cli#members-list).
- robodev mcp has list_project_members, add_project_member, update_project_member and remove_project_member (signed-in user only). @robodev-ai/runtime adds the shared tool schemas, formatProjectAccess and the member result texts.
Starbase (hosted), released together with 0.77.0:
- The hosted Robodev connector has the same four member tools; audit rows from it are marked · MCP.
- POST /v1/projects/:id/members adds a registered user with a verified email at once (audit Project member added) and invites anyone else. GET /v1/projects/:id/access lists direct members, and for admins pending invites and organization access.
- The Share page adds people directly or invites them, says which happened, and lists Organization access read-only for admins.
- Every project members and invites route answers a deploy key with 403 user_required (was 401).
2026-10-21 — runtime 0.28.0 / robodev 0.76.0
- robodev auth-settings get | set reads and changes the project's Robodev Auth settings (sign-in methods, self sign-up, Google and Apple keys). Secrets come only from a file, stdin or a hidden prompt. Needs robodev auth; a deploy key alone is refused.
- robodev mcp has get_auth_settings and update_auth_settings (signed-in user only). @robodev-ai/runtime adds the shared tool schemas, parseAuthSettingsUpdate and formatAuthSettings.
Starbase (hosted), released together with 0.76.0:
- The hosted Robodev connector has get_auth_settings and update_auth_settings.
- PATCH /v1/projects/:id/auth needs a project admin (403 admin required for developers). Developers see the Auth page read-only. Every change writes an Auth settings updated audit row; secrets are recorded only as set or cleared.
2026-10-20 — robodev 0.75.0
- robodev artifacts deploy [dir] [--name <name>] [--json] publishes a folder of static files as a Robodev Lite artifact at https://<name>.robodev.povio.dev, outside any project (index.html at the root required; .git, node_modules, .robodev, dotfiles and symlinks skipped, .well-known/ kept). Prints the URL and says when the name was taken and suffixed.
- robodev artifacts list [--json] and robodev artifacts delete <id|name>... [--yes] [--json] (TTY confirmation listing the hosts; refuses without --yes when stdin is not a TTY; several targets are one batch delete).
- Credentials as for robodev deploy: ROBODEV_DEPLOY_KEY, then the folder's deployToken, then robodev auth. A deploy key acts as the user who created it; no link and no --project. Against an older Starbase the commands print This Starbase does not support artifacts yet.
Starbase (hosted), released together with 0.75.0:
- Artifacts: a per-user static site at https://<name>.robodev.povio.dev deployed from the dashboard (/artifacts: folder upload, table, single and batch delete with confirmation), REST (/v1/artifacts), the CLI, or the hosted MCP connector. Names share the namespace with project slugs; a taken name becomes <name>-YYYYMMDD-xxxx; deleting frees the name. See Artifacts (/docs/artifacts).
- Hosted MCP connector tools deploy_artifact, list_artifacts and delete_artifact (no project_id; files as UTF-8 text or base64; under 30 MB per call). robodev mcp is unchanged.
- The artifact routes accept a project deploy key (rdb_…) as the user who created it, so CI and headless agents can manage that user's artifacts; a revoked key gets 401, a key without a creator on record gets 403 deploy_key_no_creator.
2026-10-20 — Starbase (hosted)
- The hosted Robodev MCP connector (https://robodev.povio.dev/mcp) adds start_security_review, list_security_reviews and get_security_review: an organization admin can start a security and scalability review of the project's latest deployed source, list the reviews and read one review's findings. Other members get a refusal naming the organization admin requirement. robodev mcp is unchanged.
2026-10-20 — sdk 0.22.0 / runtime 0.27.0 / client 0.9.0 / robodev 0.74.0
- Sign in with Apple for project end users on deployed projects. GET /api/user/auth/apple?redirect_uri= (or api.auth.signIn.apple() in @robodev-ai/client 0.9.0) starts it; tokens come back as query accessToken and refreshToken, like Google. See Auth (/docs/auth#apple).
- Apple uses only your project's own Apple keys (Team ID, Key ID, Services ID, .p8). Register <PUBLIC_URL>/internal/auth/apple/callback as a Return URL on the Services ID.
- robodev dev does not run Apple: GET /api/user/auth/apple answers 503 apple_oauth_unavailable_locally. Starters with a Google button also get an AppleLoginButton.
- hooks/auth.ts: provider can be apple, and auth.failed has the reason apple_oauth_failed.
- OpenAPI: GET /api/user/auth/apple (operationId UserAuthAppleController_login) replaces the old GET /api/user/auth/apple/callback 503 stub.
Starbase (hosted), released together with 0.74.0:
- The project Auth page takes your Apple Team ID, Key ID, Services ID and .p8 key (stored encrypted, never shown again) whenever OAuth is Robodev or Custom. Apple is on when those keys are complete, independent of the Google keys choice. Apple's Return URL is {PUBLIC_URL}/internal/auth/apple/callback.
- The Auth page shows Google and Apple status separately, plus the Apple redirect and start URLs. The Users table shows one badge per sign-in method; the users API adds methods: [email, google, apple]. The single method field (password, google, both, or apple) is deprecated and kept for robodev 0.73 and older.
- GET /api/user/auth/apple/callback on a project host is now a plain 404 (it was 503 not_implemented).
2026-10-19 — robodev 0.73.0 / runtime 0.26.0
- robodev secrets set / delete print The running worker restarts automatically within a few seconds to pick it up. when Starbase scheduled the restart. --restart is deprecated: it is accepted, calls nothing against a current Starbase, and prints a note to stderr. See CLI reference (/docs/cli#secrets-set).
- robodev secrets list and the list_secrets MCP tool report a failed automatic restart and how to retry it.
- robodev mcp: set_secret / delete_secret accept the deprecated restart: true and ignore it; the tool descriptions and instructions say restarts are automatic.
- @robodev-ai/runtime adds RESTART_SCHEDULED_MESSAGE, RESTART_FLAG_DEPRECATED_MESSAGE, formatAutoRestartFailure and the AutoRestartState type; formatSecretChange takes restartScheduled.
Starbase (hosted), released together with 0.73.0:
- Changing a secret restarts the project's running isolated worker automatically, from every surface (dashboard, robodev secrets, robodev mcp, the hosted connector, the REST API). The restart runs in the background about 5 seconds after the last change (at most 30 seconds after the first), waits for a running deploy, and keeps the old worker serving until the new one is healthy. See Secrets (/docs/secrets).
- PUT / DELETE /v1/projects/:id/secrets answer restartScheduled; restartNeeded is false whenever a restart was scheduled, so robodev 0.71 and 0.72 print Handlers read it on the next request. GET /v1/projects/:id/secrets and GET /v1/projects/:id/worker (.restart.autoRestart) add autoRestart.
- Settings → Secrets: saving or deleting shows Saved — restarting worker… and the Live worker strip follows the restart on its own. The inline Restart worker button after a save is gone; Changes not applied shows only after an automatic restart failed, next to Restart failed with View log and Retry.
2026-10-19 — robodev 0.72.0 / @robodev-ai/client 0.8.0
- @robodev-ai/client works in React Native and Expo: createClient({ url, storage }) takes a sync or async token storage (AsyncStorage, an expo-secure-store adapter), auth.ready() resolves once stored tokens are loaded, and Google sign-in from an in-app browser session uses auth.signIn.googleUrl({ redirectUri }) and auth.completeFromUrl(url). Without storage the browser behavior is unchanged. See React Native and Expo (/docs/dev#react-native).
- robodev dev --tunnel: Google sign-in started through the tunnel URL finishes on the device. Requests through the tunnel use the tunnel's https callback; localhost keeps the loopback callback. With your own Google client, register the tunnel callback too. See Google (/docs/dev#google).
Starbase (hosted), released together with 0.72.0:
- The local-dev Google broker accepts https://<id>.tunnels.robodev.povio.dev/api/user/auth/google/callback as a callback, but only while that tunnel is connected (409 tunnel_offline otherwise) and only after the user presses Continue on a page that names the tunnel host. The Google round-trip is bound to the browser that pressed Continue (a __Host- cookie); a copied Google link returns error=access_denied. If the tunnel drops before Google returns, the app's redirect_uri gets error=tunnel_offline. Loopback callbacks are unchanged.
2026-10-19 — runtime 0.25.0 / robodev 0.71.0
- robodev secrets list | set NAME | delete NAME manages the project's Secrets from a terminal or CI. set reads the value from --value-file, piped stdin, or a hidden prompt and refuses values on the command line. --restart restarts the worker after the change. Works with ROBODEV_DEPLOY_KEY, file deployToken, or robodev auth. See CLI reference (/docs/cli#secrets).
- robodev mcp has new tools: set_secret, list_secrets, delete_secret, restart_worker, plus list_auth_users and delete_auth_user (these two need robodev auth, not a deploy key). Secret values are write-only and never appear in a result.
- @robodev-ai/runtime exports the shared tool schemas and result wording (formatSecretChange, formatSecretList, formatRestartResponse, formatAuthUserList and friends).
Starbase (hosted), released together with 0.71.0:
- GET / PUT /v1/projects/:id/secrets and DELETE /v1/projects/:id/secrets/:name accept the project's own deploy key as well as members; a key for another project gets 403. PUT and DELETE answer restartNeeded. Values are still never returned. See Secrets (/docs/secrets#agents).
- Every secret set and delete is on the organization Audit page as Secret set / Secret deleted, with the deploy key prefix or MCP when they made it.
- The hosted Robodev connector has set_secret, list_secrets, delete_secret, restart_worker, list_auth_users and delete_auth_user. Its instructions no longer send agents to the dashboard for secrets.
2026-10-16 — runtime 0.24.0 / robodev 0.70.0 / robodev-be 0.8.0
- Per-file caps from before 0.59 are back, with blob storage for media: source and API files up to 1MB ("File must be under 1MB: <path>"); built frontend files (index.html, public/, root static) up to 8MB ("File must be under 8MB: <path>"); images incl. SVG, fonts, video, audio and PDF under public/ up to 50MB, uploaded separately and only when changed. Lockfiles are exempt from the 1MB and 8MB caps. robodev and robodev-be check before anything is uploaded; Starbase rejects the same with 400 invalid_file. Still no total size or file count limit. See Deploy (/docs/deploy).
Starbase (hosted), released together with 0.70.0:
- A blob PUT over 50MB gets 413 and the connection is closed instead of the body being read to the end. GET of a deploy blob is sent as an attachment with X-Content-Type-Options: nosniff. A HEAD that finds a blob marks it in use for 24 hours, so a file the CLI skipped as unchanged is never garbage-collected before its deploy commits.
2026-10-16 — runtime 0.23.0 / robodev 0.69.0
- Deploys take video (.mp4 .webm .mov), audio (.mp3 .wav .ogg) and PDFs under public/. robodev deploy uploads every public/ binary as a content-addressed blob before the deploy and skips files that did not change. See Deploy (/docs/deploy#media).
- Every deploy file is capped at 50MB ("File must be under 50MB: <path>", checked before any upload). There is still no total size or file count limit.
- @robodev-ai/runtime/server static hosting streams files from disk and answers HTTP Range requests (206 / 416), with media Content-Types.
Starbase (hosted), released together with 0.69.0:
- New HEAD / PUT / GET /v1/projects/:id/deploy-blobs/:sha256 (PUT and HEAD take a deploy key). POST /deploy accepts { path, sha256, size } for a public/ binary; inline base64 from older clients still works. Blobs no deployment references are deleted after 24 hours, and all of a project's blobs when it is deleted.
- The project host streams frontend files instead of buffering them, sends Accept-Ranges and Content-Length, and serves Range requests, so videos play and seek on the project host and custom domains.
2026-10-14 — robodev 0.68.0
- robodev restart restarts the hosted project's worker so it picks up secret changes. Auth is ROBODEV_DEPLOY_KEY, then file deployToken, then robodev auth. See CLI reference (/docs/cli).
Starbase (hosted), released together with 0.68.0:
- Restart worker on Settings → Secrets and on the new Deployments → Live worker strip boots a fresh worker with the current secrets; the old one keeps serving until it is healthy. Secrets shows Changes not applied while a running worker predates the latest secret change. Failed restarts are listed on Deployments. See Secrets (/docs/secrets).
- Correction: isolated workers read secrets when they start, not on every request. A saved secret applies on the next deploy or worker restart. In-process projects still read secrets on every request.
2026-10-14 — sdk 0.21.0 / runtime 0.22.0 / robodev 0.67.0
- Push device registry: ctx.push.registerDevice({ token, platform, userId?, label? }) and ctx.push.unregisterDevice({ token }) keep an optional list of devices per project. Push → Devices lists them with search and a platform filter, and sends a test notification to any one of them. Tokens FCM reports as dead are pruned on send. See Push (/docs/push).
2026-10-09 — runtime 0.21.1 / robodev 0.66.1
- Postgres 18: the schema push no longer drops and re-adds unchanged multi-column UNIQUE constraints on every run. Postgres 18 stores NOT NULL as constraint rows, which drizzle-kit misread; the drop made the plan destructive, so robodev dev skipped it and a self-hosted server refused to boot. A pair is now dropped only when the live definition already matches. See Self-host (/docs/self-host).
2026-10-09 — runtime 0.21.0 / robodev 0.66.0
- @robodev-ai/runtime/server runs a project outside hosted Starbase: createProjectServer loads a build, pushes the schema under an advisory lock (refusing data loss), and returns a fetch handler for Bun, Deno, or Node (serveNode) that serves the file routes, Robodev Auth with mailed codes, storage, and an optional SPA. S3 storage and SMTP email are the optional subpaths /server/s3 and /server/smtp. See Self-host (/docs/self-host).
- robodev 0.66.0 requires @robodev-ai/runtime 0.21.0. No CLI behavior changes.
2026-10-08 — sdk 0.20.0 / runtime 0.20.0 / robodev 0.65.0
- defineMcp({ title, websiteUrl, icons }) sets the display name, home page, and icons MCP clients show for a project's MCP server. They are sent in serverInfo on initialize and on server/discover. A /path resolves against the host the MCP client used. An invalid value fails deploy with 400 invalid_mcp_config. See MCP (/docs/mcp#server-identity).
- robodev 0.65.0 requires @robodev-ai/sdk 0.20.0 and @robodev-ai/runtime 0.20.0.
2026-10-08 — robodev 0.64.0
- robodev dev detects the Codex sandbox (CODEX_SANDBOX, CODEX_SANDBOX_NETWORK_DISABLED) and exits 1 before starting Postgres, telling the agent to rerun with escalated permissions or ask the user, to use robodev openapi for the spec, and, with network on, --database-url. --database-url with network on is not blocked. See Offline dev (/docs/dev).
- Starters ship guidance for running robodev dev from coding-agent sandboxes: a new always-apply .rulesync/rules/robodev-local-dev.md in the rulesync starters and a local-only Local dev with a coding agent section in every ROBODEV.md. Existing projects: run rules:gen after copying the files in, since projects created earlier do not have them.
2026-10-08 — robodev 0.63.1
- robodev dev now exits 0 on Ctrl-C, SIGTERM or a closed terminal, instead of crashing with terminating connection due to administrator command (57P01) and exit 1. The embedded Postgres is stopped, not left running.
- Postgres connection errors on idle clients no longer crash robodev dev. An admin shutdown (57P01, for example pg_terminate_backend) is silent; other errors print one warning line, and the next query reconnects.
2026-10-08 — robodev 0.63.0
- robodev openapi [--out <file>] prints the OpenAPI spec robodev dev serves at /openapi.json without starting a database, logging in, or touching the network. Use it to refresh a committed OpenAPI snapshot in a sandbox where Postgres cannot run. See CLI (/docs/cli).
- The robodev dev embedded Postgres now starts with dynamic_shared_memory_type=mmap on macOS and Linux, for new and existing clusters, so it starts in sandboxes that deny POSIX shared memory. Postgres keeps those segments as files under the data folder's pg_dynshmem/.
- When Postgres fails because the sandbox denies shared memory, robodev dev now adds a hint naming the cause and the ways out: run outside the sandbox, pass --database-url, or use robodev openapi.
Known limitations:
- A sandbox that denies SysV shared memory (shmget) still cannot run the embedded Postgres; no setting avoids it. Use --database-url or robodev openapi.
2026-10-07 — sdk 0.19.0 / runtime 0.19.0 / robodev 0.62.0
Behavior change: code shared between API files is now bundled once. Module-level state in a shared helper, such as const cache = new Map() in robodev/api/_lib.ts, is one instance per process, shared by every route, job, socket and hook that imports it. Before, each route had its own copy. This applies to hosted deploys and to robodev dev 0.62.0.
- Helper files. A file under robodev/api/ with any path segment starting with _ (api/_lib.ts, api/_lib/**, api/users/_shared.ts) is a helper: it gets no route and is bundled only through the files that import it. It is still deployed as source and returned by robodev load. Jobs, hooks and sockets can import it too. See API routes (/docs/api).
- A _ file that still exports a handler (get, post, put, patch, del or delete, including export { x as get }, export { get } from and export * from) stays a route at the same path. Deploy, the deploy log and robodev dev print: Warning: api/_health.ts exports get, but files starting with "_" are helper modules. Rename it (for example api/health.ts) to keep it a route; it is still served for now.
- Code splitting. The API build emits shared code once under _chunks/<buildId>/, and a dynamic import() becomes a lazily loaded chunk. Chunk paths are unique per build, so a redeploy never serves a stale chunk. Smaller bundles also keep worker boot well inside the 30s budget.
- Blocking auth hooks. defineAuthHook({ blocking: true }) makes onUserCreated and onUserSignedIn finish, or hit timeoutMs (default 10s, max 30s), before register, login, the MCP consent page, the magic-link callback and the Google callback respond. A throw or a timeout is logged and Auth still returns its normal 200/201/302. Other events stay fire-and-forget. A non-boolean blocking fails deploy with 400 invalid_auth_hook. Under robodev dev this needs @robodev-ai/sdk 0.19.0; an older SDK drops the key and the hook stays fire-and-forget. See Auth (/docs/auth).
- OpenAPI names. namedSchema("OrderStatus", schema) emits one components.schemas.OrderStatus and a $ref at every use site. defineApi({ operationId: "listOrders" }) replaces the default <method>_<path>. Deploy fails with 400 on invalid_schema_name, reserved_schema_name, schema_name_conflict, invalid_operation_id and duplicate_operation_id. Without either option /openapi.json does not change. See OpenAPI names (/docs/api).
- robodev dev prunes old chunk directories after each reload, keeping the current build and the one before it.
- Runtime exports: isApiHelperPath, isApiHelperFile, withoutApiHelpers, apiSourceExportsHandler, compileApiBuild, newBuildId, CHUNKS_DIR, collectOpenApiNames, defaultOperationId, RESERVED_SCHEMA_NAMES, RESERVED_OPERATION_IDS. AuthEventSink may return a promise and emitAuthEvents is async.
- robodev 0.62.0 requires @robodev-ai/sdk 0.19.0 and @robodev-ai/runtime 0.19.0.
Known limitations:
- A named schema is not always a $ref. .nullable() on a named plain z.string(), z.number() or z.boolean() is inlined, and so is a z.union of only named enums, only named literals or only named primitives. .optional(), z.array(), object properties, .refine(), .default(), and .nullable() on a named enum, literal or object keep the $ref.
- On hosted Starbase, a blocking hook's timeoutMs starts after the project's environment (ctx.env) is loaded; that load is not counted in the budget.
2026-10-07 — robodev 0.61.0
- robodev logs prints the hosted project's request logs with --limit, --status 2xx|4xx|5xx, --json, --follow and --project. robodev logs --deploy [logId] prints a deploy's header and transcript, and --follow streams a running deploy. Auth is ROBODEV_DEPLOY_KEY, then file deployToken, then robodev auth. See CLI reference (/docs/cli).
- Readable CLI errors: Starbase returned 502 Bad Gateway (request id: req_…): <start of the body> for a non-JSON answer, (request id: …) on JSON errors of 500 and above, and Could not reach <url>: <reason> when the server is unreachable. ROBODEV_DEBUG=1 adds the stack and the cause chain.
- robodev deploy adds The deploy may still have finished on the server. Check with: robodev logs --deploy after a network failure or a 5xx.
- robodev dev prints the port, the data directory and the last 40 lines of Postgres output when the embedded Postgres fails to init or start, plus a postmaster.pid or port hint.
- Role parity: robodev dev app queries run as the restricted robodev_app role, like the hosted project role, so TRUNCATE on a public table fails locally as it does hosted. --db-superuser opts out; --database-url skips role handling. See Offline dev (/docs/dev).
Starbase (hosted), released together with 0.61.0:
- A deploy boots the new worker before it reports success. If the worker cannot boot within 30 seconds (WORKER_BOOT_MS), the deploy fails with 422 worker_boot_failed, worker_boot_timeout or worker_compile_failed, and the previous version keeps serving. See Deploy (/docs/deploy).
- Every response carries x-request-id: req_<32 hex>, and platform JSON errors include requestId. Quote it when you report a problem.
- Deploys to one project run one at a time. A deploy key can read its own project's request and deploy logs.
- On shutdown, Starbase drains in-flight requests before it exits.
Clarification: email change
Since @robodev-ai/runtime 0.14.0 / robodev 0.56.0 (hosted Starbase since 2026-09-28), PUT /api/user/me requires currentPassword to change the email of a user with a password (missing: 400 current-password-required, wrong: 403 invalid-credentials). A user without a password (Google or magic-link only) gets 202 with pendingEmail, and the change completes through POST /api/user/auth/email-change/callback with the emailed code. This shipped without a changelog entry. See Auth (/docs/auth).