Builder and Guard
The Mezair Builder turns a Cell project into inspectable output. Mezair Guard is the trust gateway before local runtime or preview deploy: it checks that Cell server code stays inside the declared contract instead of quietly reaching for provider APIs, process globals, or effects the manifest cannot explain.
Build pipeline
mezair cloud check and mezair cloud build share the same pipeline. check runs it without writing artifacts; build writes output.
Pipeline:
- Load
mezair.json. - Resolve server and client entrypoints.
- Run import and capability policy checks.
- Run TypeScript typecheck.
- Bundle the server entrypoint.
- Import the server bundle and extract the app manifest.
- Bundle the client entrypoint.
- Write manifest, generated client, generated types, and build metadata.
If any error-level diagnostic appears, the pipeline stops at the failing phase.
Output directories
.mezair/
dist/
client/
index.html
assets/
cell.client.js
server/
index.mjs
manifest.json
build-meta.json
generated/
api.d.ts
client.tsDiagnostics
Diagnostics include:
- code
- severity
- message
- file
- line and column where available
- hint where available
CLI JSON output keeps these shapes stable enough for scripts and agents.
Example:
{
"ok": false,
"phase": "import-policy",
"diagnostics": [
{
"code": "FORBIDDEN_IMPORT",
"severity": "error",
"message": "Import '@aws-sdk/client-s3' is not allowed in Cell server code.",
"file": "src/cell.server.ts",
"line": 1,
"column": 26,
"hint": "Use declared Mezair capabilities such as ctx.db or ctx.files."
}
],
"errors": [
{
"code": "FORBIDDEN_IMPORT",
"severity": "error",
"message": "Import '@aws-sdk/client-s3' is not allowed in Cell server code."
}
]
}errors is a compatibility alias for older automation. New code should read
diagnostics.
Import policy
Cell server code must stay statically inspectable. Current forbidden imports include:
| Import | Why |
|---|---|
fs, node:fs |
Use ctx.files for Cell-owned file storage. |
child_process, node:child_process |
Move background work into declared jobs. |
@aws-sdk/* |
Provider access belongs in the AWS adapter. |
aws-cdk-lib |
Cell code must not author provider infrastructure directly. |
sst, sst/* |
Provider tooling belongs inside deployment adapters. |
cdktf, @cdktf/* |
Terraform/CDKTF authoring belongs inside deployment adapters. |
pulumi, @pulumi/* |
Provider infrastructure belongs inside deployment adapters. |
Dynamic import is also forbidden in Cell server code.
Capability checks
Guard can detect some undeclared effects:
- global
fetchrequirescapabilities.outboundFetch - literal
fetch("https://...")hosts must matchcapabilities.outboundFetch.allow - fetch targets must be static absolute
httporhttpsURL literals so Guard can check the host - scheduled jobs require
capabilities.scheduledJobs ctx.dbrequirescapabilities.databasectx.filesrequirescapabilities.filesctx.eventsrequirescapabilities.eventsctx.jobsrequirescapabilities.jobsctx.workflowsandworkflow(...)requirecapabilities.workflowsservice(...)requirescapabilities.services- direct
process.envis rejected; usectx.env.get()orctx.env.require() - handler use of capabilities should match declared Cell capabilities where alpha can inspect it
Current direct environment checks catch straightforward static forms such as
process.env and process["env"]. Guard is not a perfect JavaScript sandbox;
it is a policy check for normal Cell code and a clear signal to reviewers.
This is not a perfect sandbox. It is a practical alpha control that narrows the contract and catches common ways app code escapes into provider-specific behavior.
Outbound fetch policy
Declare outbound fetch explicitly:
export default app({
capabilities: {
outboundFetch: { allow: ["api.example.test"] }
},
mutations: {
sync: mutation({
handler: async () => {
await fetch("https://api.example.test/sync");
return { ok: true };
}
})
}
});For now, Guard requires literal absolute http or https URL strings so it can
check the host. These are rejected:
const target = "https://api.example.test/sync";
await fetch(target);
await fetch("/internal");Literal URLs let Guard check every destination before deployment. Dynamic network targets cannot be verified this way.
Typecheck
The builder runs TypeScript against the Cell project. This catches app-code mistakes before bundle and manifest extraction.
Use:
mezair cloud check --jsonbefore:
mezair cloud build --jsonManifest extraction
After the server bundle is built, the builder imports it and verifies that the default export is an app() definition.
If manifest extraction fails, the builder returns SERVER_EXPORT_INVALID or MANIFEST_EXTRACTION_FAILED diagnostics.
Generated client output
The builder emits generated client metadata under .mezair/generated so browser code can call queries and mutations through stable names instead of hand-written string paths.
Read Generated client for client-side usage.
What to trust before deploy
Before preview deploy, inspect:
mezair cloud check --jsondiagnosticsmezair cloud build --jsonoutput.mezair/dist/manifest.json.mezair/generated/client.ts.mezair/dist/build-meta.json- deployment plan and CloudFormation template from
mezair cloud deploy --preview --json
If these disagree, fix the discrepancy before deploying.
Practical rule
If a Cell needs a new capability, declare it and add support in the runtime and adapters. Keep provider-specific access in the adapter so the deployment plan can account for it.