Release notes
What is new in each version of aircloud, the newest first. When you upgrade with aircloud upgrade, it shows you these notes for every version you move past. To see whether a newer version is out, run aircloud changelog.
aircloud 0.1.12
Released 2026-10-30.
Your product's members get memberships, profiles, grants, groups and denies you manage from the CLI; every route and trigger without a signed-in user says which node it acts at; and aircloud authz explain tells you why a request was allowed or refused.
Needs your action
-
aircloud members update,aircloud members remove,aircloud members grants,aircloud members grantandaircloud members revokename a membership by its id, not a user: one person may now hold several memberships, each at its own node.aircloud members listshows each membership's id beside its user.What to do: Take the id from the membership column of
aircloud members list(or fromaircloud members membershipswith the person's user id) and pass it where you passed the user id. -
aircloud checkand every release refuse a public route to a function, an event trigger and a cron trigger that do not say which node of your organization tree they act at (route.org_path_required,trigger.org_path_required); nothing acts over your whole product unless it says so. A route to a container must not say one (route.org_path_not_invocation).What to do: Add
org_path = "/"to each such[[route]]inconfig/routes.tomland to each[[triggers.events]]and[[triggers.cron]]in afunction.tomlto keep acting over your whole product, or a lower node such asorg_path = "/org/acme"to act only there; removeorg_pathfrom routes to a container. -
aircloud checkand every release refuse a node your product names that it never creates (org.path_undeclared): anorg_pathor a route'satnames/, a node of[authenticate](admin_org_path,default_org_path, the[authenticate.workspaces]parent, the newnodeslist) or a node above one, or a node below the workspaces parent, which workspace signup creates. Each production activation creates the nodes of[authenticate]; a node you later remove fromnodesis not deleted.What to do: For each node
aircloud checknames, add it to[authenticate] nodes = ["/org/acme"]inconfig/routes.toml, or act at a node your product already declares. -
Generated tests use
@aircloudhq/testing2.0.4:invokenames the route or trigger a function runs through instead of the function's file, and refuses one your product does not declare, as the platform does; a public route is called with no signed-in user.What to do: When you move a product's tests to 2.0.4, replace each
invoke("app/functions/pets/index.js", request)withinvoke({ route: "/api/pets" }, request)naming the route yourconfig/routes.tomldeclares, and run the tests withnpm --prefix test test, which prepares your routes and triggers first. -
aircloud generate scaffoldwith--owneror--sharedputs the entity's routes and pages inside[authenticate], since its records belong to a signed-in user, and is refused in a product without it.What to do: Run
aircloud generate authenticationbefore you generate an owned or shared scaffold.
New
aircloud org nodeslists, creates, archives, unarchives and deletes the nodes of your organization tree: archiving a client's node suspends everything acting there until you unarchive it, and only an archived node is deleted.aircloud profilesmanages profiles, named sets of roles granted by reference;aircloud generate authenticationnow also writes your base profiles toconfig/profiles.toml, one per role, withadminholding every role.aircloud members grant,aircloud members grantsandaircloud members revokegive a membership a profile at a node, optionally until a time;aircloud members invite --profilegrants one at the new member's node, and--scopes tenant:orglets them manage the members below it.aircloud members updatechanges only the options you give, and--pathmoves a membership to another node.aircloud groupsshares grants among memberships, andaircloud deniesrefuses roles or operations at and below a node whatever any grant gives.aircloud members membershipslists one person's memberships,aircloud members blocksthe blocked addresses, andaircloud members reviewthe grants about to expire, the profiles nobody uses, the empty groups and who manages members.aircloud authz check,aircloud authz explainandaircloud authz whosay whether a member may act at a node, which rule decided, and who reaches a node with which roles; your coding agent asks the same through the dev MCP server'sauthz_check.--membershipon every command acts through one of your memberships when you hold several.aircloud checkknows the new declarations:config/profiles.toml,[authenticate.workspaces]for end users who create a company of their own,aton a session route,[[policy]]field rules on an entity, and[org] operationsand[[elevate]]aggregates in afunction.toml.- The generators write
org_path = "/"on every route and trigger they add, so the choice to act over your whole product is visible and yours to narrow. aircloud release showreports a profile removed fromconfig/profiles.tomlthat was kept because members still hold it, and a preview whose workspaces declaration differs from production's.- The generated AGENTS.md, the AI skill and the header of a generated function without a signed-in user say it acts at the node its
org_pathdeclares, reads every customer's records at or below that node and stores what it writes there; the skill and AGENTS.md also teach memberships, profiles, grants, denies, field rules, workspaces, narrowing and elevated aggregates. aircloud functions invoke --at <node>runs a function as if called at a node below yours, and is refused at a node outside it or archived; your coding agent passes the sameatto the dev MCP server'sfunction_invoke.aircloud generate scaffold --roles … --at <node>andaircloud generate function --roles … --at <node>write the node a session route acts at, which a product declaring[authenticate.workspaces]requires.aircloud org nodes create --seed <template> --environment <env>fills a new node with the seed records ofdb/seeds/<env>/nodes/<template>/, andaircloud org nodes listshows in its SEED column whether that seed was applied, refused or failed.test/principals.tomlgives a test principal grants — a profile at a node at or below its own, optionally until a time — so your integration and system tests act as a member holding them;aircloud checkrefuses a grant naming a profileconfig/profiles.tomldoes not declare or a node outside the principal's.- Nodes have a display name people see:
aircloud org nodes create --name "Acme Ltda"names a new node,aircloud org nodes renamechanges the name,aircloud org nodes listshows it in its NAME column, a workspace's node is named as its creator named it, and an[authenticate] nodesentry may be{ path = "/org/marcas", display_name = "Marcas" }— each production release sets that name. The generated members page shows each node by its name with its path as a hint.
Fixed
- The integration scenario of an owned or shared scaffold signs in as a customer and proves another one cannot read or delete the record, instead of acting as an admin who reads everything.
- The generated test for an owned entity no longer tries to change the owner field, which the platform refuses.
aircloud 0.1.11
Released 2026-10-28.
Products with many fields release again: aircloud release no longer sends a separate payment check that larger products were refused on, and the platform checks your plan when it receives the release instead.
Needs your action
-
aircloud release0.1.10 and earlier stop working against the platform, because the separate payment check they send before uploading has been removed.What to do: Update the CLI with
aircloud update(or your package manager) before your nextaircloud release.
Fixed
- A product with many fields across its entities (about 140 or more) could not release: the request was refused with
edge_request_refused. It now releases. - When your plan cannot pay for a release,
aircloud releasestill refuses it before anything is stored or built, naming each missing item, how much it needs and how much you have; the check now happens when the platform receives your release. - A request to your product's routes or functions with a large JSON body (more than 1000 values) is no longer refused for its size alone.
aircloud 0.1.10
Released 2026-10-26.
A release your plan cannot pay for is refused before any work, naming what is missing; a refusal while it is checked ends it at once with the reason; functions handle time zones without guessing; and every page of your site opens from any link.
New
- Before uploading,
aircloud releaseasks the platform whether your plan can pay for everything the release will use, and refuses with each missing item, how much it needs and how much you have, instead of finding out halfway through. aircloud release shownames the step a release is at while it is being checked.- In a function,
civilDateandinstantOffrom@aircloudhq/web/functiongive the date in a time zone and turn a local date and time into an instant, using the time zones your release carries. aircloud testruns your functions the way the platform does: with no built-in time zone data and in UTC, so a test that passes on your machine passes after release.- The generated AGENTS.md, the AI skill and the header of a generated function without a signed-in user (a public route, an event, a scheduled job or a webhook) say that it reads every customer's records and that what it writes is stored at your account's root, which staff can read only for shared entities, with the way to let staff change it.
Fixed
- A release that runs out of something your plan allows while it is being checked now fails at once with the reason and the item, instead of waiting until it times out.
- A link to any page under your site, including one whose last part has a dot (such as
/kiosk/p1.x), opens the page instead of answering not found; a missing file still answers not found. - A release that has already failed no longer leaves work running behind it.
aircloud 0.1.9
Released 2026-10-24.
Each folder works with its own account, invoking a function behaves like a real request, releases show their progress, and every release shows the day it came out.
Needs your action
-
The CLI now keeps one sign-in per account and region, and no longer reads a sign-in saved by an earlier version.
What to do: Run
aircloud loginonce after you upgrade. -
Your installed AI skill now follows the
aircloudthat installed it: only that one refreshes it, and anotheraircloudon your machine leaves it as it is and tells you. A skill installed by an earlier version is no longer refreshed on its own.What to do: Run
aircloud skill install --agent <agent>once after you upgrade, with theaircloudyou use. -
aircloud functions invokeexits by what your function answered: 0 for a 2xx or 3xx answer, 3 for a 4xx, 4 for a 5xx or a refusal by the platform before your function ran; 1 still means the CLI or the platform failed.What to do: If a script treats exit status 0 as success, check that it expects 3 and 4 for your function's error answers.
-
aircloud functions invokewithout--datasends your function no body and no content type, and--datawith--method GETorHEADis refused.What to do: Pass
--datawhen your function expects a body. -
A field written without a type, and the owner and label fields, are now
string: one line of at most 1024 bytes. Long or multi-line text istext.What to do: Declare each field that holds long or multi-line text as
name:text, then runaircloud check.
New
aircloud environments create <name>,aircloud environments listandaircloud environments destroy <name>manage preview environments;aircloud release activate <release> --env <name>puts a release in one.- Each folder acts as its own account and region:
aircloud newandaircloud products authorizewrite them into aircloud.toml, every command names on stderr the account it acts as, andaircloud accounts listandaircloud accounts use <account>show and choose your accounts. aircloud functions invoketakes--method,--pathand--header name=value, so you call a function the way its clients do.aircloud logs --response-status 4xx(or a single code such as 404) shows only the invocations your function answered that way, and--sourcekeeps only the event invocations from one source.aircloud functions listshows where each function is live: the environments whose active release holds it, or that it was removed.aircloud release showlists every part of a release with its progress, and--waitprints each change as it happens; a part waiting for build capacity shows its place in line, and a failed part shows why and the last lines of its log.aircloud login --timeout <duration>sets how long login waits for you, and the sign-in link or code is shown again every 30 seconds while it waits.- Fields use Rails' types:
stringis one line,textis multi-line and shows as a text area in generated pages. - Labels in your default language come from the command: a field's with
name:string:display_name=<label>, the entity's with--display-name <label>. aircloud generate scaffold --roles <roles>protects the pages as well as the API,--sharedlets end users also read the records of the organization above their own, andaircloud generate function --roles <roles>puts a function behind sign-in with those roles.- An entity can say who may change its records with
write_roles; a signed-in user without one of those roles is refused withflex.role_required. aircloud i18n missinglists the labels in your default language that nobody has written yet.- aircloud.toml carries your product's name, and your site's title is that name.
aircloud upgrade,aircloud changelogandaircloud versionshow the day each release came out, and so does the Release notes page.- Generated tests check each access rule an entity declares, against your product's own schema.
- A verification that runs out of time names the step and the test layer it stopped at, and keeps the report of what ran.
Fixed
- A request to invoke a function that is too large or names a method, path or header it may not carry is refused with the reason before the function is called, instead of ending with an unknown outcome.
- The time login waits for you now starts when the link or code is shown.
- A Rust function's
witfolder belongs to the platform: it is no longer generated into your product, committed or uploaded, so a release never fails over an outdated copy. - A header starting with
x-air-that a visitor sends never reaches your function or container. - Your React site's page language is your product's default language.
aircloud testlinks the components a function lists the same way a release builds them.
aircloud 0.1.8
Released 2026-10-21.
Secrets work again, you can delete them, and feedback that quotes your code goes through.
Needs your action
-
aircloud secrets setfrom version 0.1.7 or older is refused: the platform now accepts a secret's value only in the way 0.1.8 sends it.What to do: Run
aircloud upgrade, then set your secrets again withaircloud secrets set. -
aircloud release promotefrom version 0.1.7 or older is refused: the platform no longer accepts a body on a promote, and 0.1.8 sends none.What to do: Run
aircloud upgrade, then promote the release again withaircloud release promote.
New
aircloud secrets delete NAME --env <environment|ci>removes a secret. Deleting one that is not set does nothing.- When a request's body is of a type the route does not take, is larger than the route allows, or arrives too slowly, the platform now answers with an error that names the cause (415, 413 or 408) instead of cutting the request.
Fixed
aircloud secrets setwas refused for every value. It now stores the value you pipe in, exactly as you typed it, andaircloud secrets listshows it set.aircloud secrets set,listanddeletenow tell you at once when a name or an environment is not valid, before anything is sent.aircloud feedbackwas refused when your report quoted a file path, a line of code, a command's options or a URL. Those reports now go through.aircloud feedbackcould attach an option's value as if it were an option's name, when the value began with a dash. It now attaches only the names of the options you gave, and never a value.
aircloud 0.1.7
Released 2026-10-20.
Your site can use shadcn/ui, Radix and sonner, with your content policy kept strict.
Needs your action
-
app/site/src/main.jsxnow only starts your site: it imports@aircloudhq/web/csp-noncefirst, then./application.jsx, andaircloud checkrefuses anything else in it.What to do: Move the code that was in
app/site/src/main.jsxintoapp/site/src/application.jsx, then leavemain.jsxwith just those two imports.
New
- You can add shadcn/ui components: your site accepts its
components.json, andsrc/components/can hold subfolders, mirrored bytest/site/components/. - Libraries that add their own styles while your site runs, like Radix dialogs and sonner toasts, now work without loosening your content policy: every page load gets a fresh style nonce, set by
nonce_directivesinconfig/content_security_policy.toml. - Your site's system tests now fail when a page breaks your content policy, whether on load or after a click, so you see the problem before your users do.
- The docs have a shadcn/ui guide, and your AI coding assistant knows how to add components without breaking your content policy.
aircloud 0.1.6
Released 2026-10-20.
You can now see what changed in every version.
New
- When you run
aircloud upgrade, it shows what changed in each version you move past, and what to do if something you use changed. aircloud changelogtells you whether a newer version is out and what it brings.- Your AI coding assistant now checks for a newer version, upgrades and reads what changed before it writes code for you.
- The docs have a Release notes page in the main menu, and Homebrew and npm point to it.
aircloud 0.1.5
Released 2026-10-16.
Upgrading with Homebrew works as soon as a new version is out, and the install examples in the docs work.
Fixed
- If you installed with Homebrew,
aircloud upgradenow gives you the command that really upgrades:brew update && brew upgrade aircloud. On its own,brew upgradecould take a day to notice a new version. - The install examples in the docs used a version number that does not exist. They now use the current version.
aircloud 0.1.4
Released 2026-10-16.
npm now installs the latest version, like every other install method.
Fixed
npm install -g @aircloudhq/cliwas still installing 0.1.0. It now installs the current version.
aircloud 0.1.3
Released 2026-10-16.
Nothing changes for you: another fix to how new versions reach npm.
Fixed
- Another step toward npm offering the same version as the other install methods; it got there in 0.1.4.
aircloud 0.1.2
Released 2026-10-15.
Nothing changes for you: this version fixed how new versions reach npm.
Fixed
- npm kept offering 0.1.0 while the other install methods moved on. This version fixed part of that; npm caught up in 0.1.4.
aircloud 0.1.1
Released 2026-10-15.
Platform updates no longer make aircloud skill doctor say something is wrong.
Fixed
- After a platform update,
aircloud skill doctorsaid your setup was broken until you upgraded. Now it just tells you an update is available, and only reports a problem when your version can no longer work with the platform.
aircloud 0.1.0
Released 2026-10-15.
The first version of aircloud: create a product, check it, put it live and run it, all from your terminal.
New
aircloud newcreates a product.aircloud generateadds parts to it — a page, a data entity, a function — andaircloud destroyremoves them.aircloud checktells you what is wrong with your product before you release it, using the same rules the platform uses.aircloud testruns your tests.aircloud signupcreates your account andaircloud loginsigns you in.aircloud releaseputs a version of your product live.aircloud functions,logs,secretsandmemberslet you run it, see what happened and manage who uses it.aircloud skillteaches your AI coding assistant how to build on Air-Cloud, andaircloud feedbacksends us a problem or an idea.- Install it with the install script, Homebrew, npm or Docker.