Repository navigation
v2.0.0 — Unified Apply
Unified Apply
This is the v1.48 destructive cutover landing in the public packages.
The shape
- One write engine —
r.project(id).apply(spec)atomically lands any combination of release slices (database / functions / site / subdomains / routes / checks) and an asset slice (assets.put / .delete / .sync). Same plan / commit / idempotency / retry / event envelope as before;assetsis just a new slice on the existing spec. - One namespace for blobs —
r.project(id).assetsreplaces the legacyr.blobs. New Node-only helpers:uploadDir(additive),syncDir(destructive only with explicitprune: true+ confirmation token),prepareDir(returns{ manifest, applySlice }so HTML can be rendered against resolved URLs before the apply lands). - One endpoint —
/apply/v1/*. Legacy/deploy/v2/*and/storage/v1/uploads*return 404. - Sync-prune drift is a first-class commit outcome: plan computes
base_revision+delete_set_digest, commit re-reads inventory and rejects with HTTP 409ASSET_SYNC_DRIFTif the prefix changed mid-flight. The SDK auto-re-plans. - Immutable URLs survive key mutation —
internal.asset_versionsretains every(project, key, sha)triplet so re-uploadinglogo.pngdoesn't break older content-hashed CDN URLs.
Removed surfaces (this is a breaking release)
r.blobs,r.deploy.apply,r.assets.apply, barer.apply— gone. User.project(id).applyfor writes andr.project(id).assetsfor blob operations.run402 blobCLI — gone. Userun402 assets(upload,sync,put,prepare,ls,rm,sign,diagnose).blob_putMCP tool — gone. Useassets_put,assets_upload_dir,assets_sync_dir,assets_prepare_dir,assets_put_many.POST /deploy/v2/plansandPOST /storage/v1/uploads— return 404.
What also changed
- CI bindings gain
asset_key_scopesfor per-key write authorization. The release-slice allowlist (secrets,subdomains,routes,checksforbidden for CI sessions) is enforced on/apply/v1/plansas hard errors. - Plan response carries
asset_entries[](one resolvedAssetRefper assetputentry, pre-commit),asset_sync(destructive confirmation block when sync-prune is declared), and acostpreview (storage_bytes_added,asset_keys_added/removed/after_commit,payment_required,quota_before/after). AssetRef.scriptTag()/linkTag()/imgTag()emitters carry SRI + crossorigin + MIME-param parsing + attribute escaping.
Upgrade
Lockstep across SDK, CLI, MCP, and Functions — all at 2.0.0. See openspec/changes/unified-apply (private repo) for the per-task ledger and design rationale.