The --json protocol
What an everyapp command writes on stdout with --json (NDJSON events), how the run ends (exit codes 0, 1, 2, 130, 251, 252), and what an agent does with each event, action and error.
Every pnpm everyapp command that does work takes --json, except dev (long-running and for a person; dev --json is UNKNOWN_FLAG, exit 252). With it, stdout carries a stream of events an agent reads line by line, nothing prompts, and the exit code says how the run ended. This page is the protocol; the commands are on /docs/agent/cli, the error codes on /docs/agent/errors, and the handoffs setup makes on /docs/agent/setup. The source of truth is the header comment of packages/cli/src/lib/output/events.ts.
The stream
- One JSON object per line (NDJSON) on stdout. Every event is
{ "v": 1, "ts": "<ISO 8601>", "type": "<type>", … }:vis the protocol version,tsisnew Date().toISOString()at emit time (createNdjsonSinkinpackages/cli/src/lib/output/events.ts). - Nothing else lands on stdout. The lines a person would see are a filter over the same events (
createHumanSink), which--jsonreplaces;done'sdisplay(the table or lines drawn for a person) is set toundefinedbefore the line is serialized, so it is absent in--json; a script readsdatainstead. --jsonis read before any command parses its arguments:globalOptionsinpackages/cli/src/bin/cli.tsscans the arguments up to a--for--jsonand--no-color. So the sink exists before stricli runs, and what stricli refuses (an unknown command, a bad flag) is an NDJSONerrortoo, with stricli's own writes to stderr dropped (stderr: { write: () => true }). Arguments after--are the command's own.--no-coloris global: it is taken out of the arguments (no command declares it), turns chalk off, and setsNO_COLOR=1in everyapp's environment so cf and the other children it runs print without color too.NO_COLORin the environment does the same; so does a stdout that isn't a terminal, orTERM=dumb(colorEnabledinpackages/cli/src/lib/output/terminal.ts). Messages that a command builds from a table drawn for a person (secret list,email show) go throughstripVTControlCharactersfirst.- Child processes never write to stdout. The children everyapp runs itself (pnpm, the manifest's install and build commands, git, the Gateway's build from the checkout) write to a private log file,
$TMPDIR/everyapp/<name>-<time>-<pid>.log(mode0600, directory0700,namethe first two words of the command line), whose first lines are$ <command line>and# in <cwd>(runLoggedinpackages/cli/src/lib/childLog.ts). When one fails, the run ends with anerrorwhosecodeis the step's (COMMAND_FAILEDby default; the deploy's install step usesINSTALL_FAILED), whose message is<what> failed, then<command> exited with code <n>. Its last lines:and the last 20 non-blank lines of the child's output indented, thenFull log: <path>, and whosedatais{ command, exitCode, tail, log }(plusfixwhen the step has one). With--verbosethe same output also streams to stderr as it comes, each line dim and indented under$ <command line>. Without--verbose, nothing of it reaches stderr either:packages/cli/src/commands/deploy/stdout.test.tsruns a chatty install underdeploy --jsonand asserts stdout is only events and stderr is empty. - cf's own output never goes to the log: the runner keeps it in memory, and a
CfErrorcarries its message parsed from cf's error box and its last lines (packages/cli/src/lib/cf/errors.ts). - stderr under
--json: without--verbose, the one line everyapp itself writes there is the launcher's,Rebuilt the everyapp CLI from this checkout (<commit>)(dim), whichpackages/cli/bin/everyapp.jsprints after it rebuiltdist/because the checkout's CLI, SDK, perimeter or toolbus sources changed since the last build (<commit>is the checkout's short commit,git describe --always --exclude=*). It also prints on the first run after any command that ranpnpm installin the checkout (create,deploy,release), because the rootpostinstallrebuiltpackages/sdk/dist. A rebuild that fails writes the build output andeveryapp: couldn't rebuild from this checkout: …to stderr and exits1before any event. Every stdout line is JSON. - Help and the version are not events.
packages/cli/src/bin/cli.tsanswers a bare--help,-h(stricli's--help-alland-Hare read as--help, andhelp [<command>]as<command> --help),--version,-v, a bare group name and<group> --help(pnpm everyapp secret) with text on stdout before the sink exists;<command> --help(-hanywhere among a command's arguments) is stricli's help for that command, text on stdout too (stricli's scanner stops routing at the first help flag and prints the help of the command reached). - The runtime is checked before any command: under Bun, or a Node older than
22.18.0, the run is oneerrorwith codeUNSUPPORTED_RUNTIMEthrough the same sink (packages/cli/src/lib/runtime.ts).
Event types
Six type values. Each event has v and ts; the rest is per type.
type |
Fields | Meaning |
|---|---|---|
step |
step, status, message?, data? |
A named piece of work started, finished, was skipped or failed. |
progress |
step, message, data? |
A line while a step runs (a wait, a log line). |
warning |
code, message, step?, data? |
Something to know; the run goes on and the exit code is unchanged. |
action_required |
action, message, step?, data? |
Only a person can go on from here (see the actions below). |
error |
code, message, retryable, step?, data? |
The run failed; always the last event, exit 1. |
done |
message?, data? |
The run finished; always the last event, exit 0. display is never in --json. |
In every message, the first line is the headline and the lines after it are detail (a person sees them dim under it).
step
step is a dotted name (setup.auth, app.build, gateway.deploy, db.query); status is one of start, ok, skip, fail. fail says the step broke, before the run says why; it never sets the exit code by itself (EventSink.exitCode reads only error and action_required). Under --json it comes from create: create.install fail is followed by the error INSTALL_FAILED; create.types, migrations.local and create.git fail are followed by the warnings WORKER_TYPES_FAILED, MIGRATIONS_FAILED and GIT_FAILED and the run goes on to done (a create.git error that isn't GIT_FAILED is thrown instead). The other fail sites are everyapp dev's, which has no --json. A step's facts are in its data, on the ok (or skip) event. The ones an agent reads most:
step |
status |
data |
|---|---|---|
cloudflare.login (login) |
ok / skip |
{ email }; skip adds token (CLOUDFLARE_API_TOKEN is set) |
setup.auth (setup) |
ok |
{ email } |
setup.account |
ok |
{ id, name, email, gateway } (gateway: a live Gateway is there already) |
setup.plan |
ok / skip |
{ plan }, skip adds url |
setup.domain |
ok |
{ gatewayHost, appBaseDomain, zone } |
setup.gateway |
start |
{ change, release, releaseName, from, gatewayUrl, account }; change is install, resume, upgrade, repair or redeploy as GatewayChange names them |
setup.gateway |
ok / skip |
{ versionId, release, releaseName }; skip with upToDate: true when nothing was deployed |
setup.owner |
ok / skip |
{ email, organizationName } (ok: created by this run's link; skip: there already) |
app.register (deploy) |
ok |
{ appId, workerName, hostname, status, existingApp, firstDeploy, defaultAccess, deployerAccess, hasOwner, publicRoutes, scope, organizationId, organizationName, gatewayUrl } (who can open the app: below; publicRoutes: the manifest's public routes as [{ path, methods }]) |
app.migrations (deploy), gateway.migrations (setup, update) |
ok |
{ applied, fresh, restoreCommand?, rollbackCommand? } (D1; below); a Postgres app: { dialect: "postgresql", engine, applied? } |
app.live (deploy) |
ok |
{ hostname, url, waited? } |
app.live |
skip |
{ hostname, url, reason }; reason is outside-base, certificate or first-visit |
app.bind |
ok |
{ versionId, newHosts } |
app.access (deploy, delete) |
ok / skip |
{ appId, applicationId, changed, removed }; only when Cloudflare Access fronts the apps (syncAppsAccessAfter in packages/cli/src/lib/access/sync.ts, after app.live on a deploy, before app.delete on a delete): ok when the apps' Access application's destinations changed to match the app's public routes, skip when they matched already; removed: true on a delete |
gateway.access (update, setup) |
ok / skip |
{ changed: [application ids], gateway: { id, outcome } | null, apps: { id, outcome } | null, combined, missing: [hosts], appsWithRoutes, appsWithMcp }; only on a live self-hosted Gateway behind Cloudflare Access (keepAccessAfterGatewayDeploy in packages/cli/src/lib/access/applications.ts, after the Gateway upload or the up-to-date check, under the access lease): ok when an application was updated to what this release lets through (its bypass paths, its sign-in methods, the policy), skip when both matched already; missing names a host whose application is gone (warning ACCESS_APPLICATION_MISSING) |
gateway.upgrade |
start / ok |
{ from, to } / { to } |
app.release (release) |
ok |
{ tarball, shown, appId, version, sha256 } |
db.query |
start / ok |
{ database } |
db.restore |
ok |
{ appId, databaseId, bookmark, migrations, createdAt, createdBy } |
app.register on a deploy (packages/cli/src/commands/deploy/deployApp.ts) says who can open the app, the Access fact a person sees at the end of a first deploy (the human sink's reading is in packages/cli/src/lib/output/events.ts): scope: "shared" means every organization's members (no command sets it now; a redeploy keeps the scope the registry has: registerFromManifest in packages/cli/src/commands/appGateway.ts passes none, so register in packages/cli/src/lib/gateway/registry.ts keeps the row's, org for a new app); else defaultAccess: true means everyone in organizationName; else deployerAccess: false means owners and admins only, and true the deployer, owners and admins (changed at <gatewayUrl>/admin/apps). hasOwner: false means the Gateway has no owner yet and its first owner gets the app. firstDeploy is true until the app has been live once; existingApp says the registry had it already.
app.migrations and gateway.migrations ok (migrationEventData in packages/cli/src/lib/migrations/remote.ts): applied lists the migrations applied this run (empty when the database was up to date); fresh: true means the database had none of them before, so there was nothing to restore and no restore point was saved; whenever one was, restoreCommand is <CLI> db restore … as a person runs it and rollbackCommand cf's own command, the same rollbackCommand an error carries (see after a migration, below). A Postgres app (migrations.dialect: "postgresql") gets { dialect: "postgresql", engine: "drizzle" | "prisma", applied? } and never a restore point; applied only with Prisma, which names what it applied.
progress
Emitted while a step runs, with the step's name. A wait for a lease (app.lease, gateway.lease, db.lease; data: { holder }, packages/cli/src/lib/gateway/lease.ts), for a certificate (gateway.tls, packages/cli/src/lib/domains/certWait.ts, two shapes: { host } when one hostname's certificate arrived, message https://<host> has its certificate., which a person's sink doesn't show, and { hosts, waitedMs, waitingFor } while others wait, waitingFor a { "<host>": "tls" | "dns" | "other" } map of why each doesn't answer yet), for an app to go live (app.live, { hostname, waitedMs, answered } every 15 seconds, answered: true once the hostname answers over HTTPS and the wait is for the app itself rather than its certificate, packages/cli/src/commands/deploy/steps/waitForLive.ts), a release download (app.release), the mail routes being applied (app.email), everyapp dev's request and tool-call lines (dev.session, dev.mcp). On Ctrl-C the NDJSON sink emits one progress with step: "interrupt" whose message is built from what is running and registered (stoppingMessage in packages/cli/src/lib/interrupt.ts): stopping cf while cf children run, then each registered cleanup's label, joined and capitalized (Stopping cf and freeing <app> for other runs), or Stopping when nothing is registered; then the process exits (see the exit codes).
warning
code is stable, message is for a person, step names the step it came from when there is one. The sink writes a warning once per run per code and message pair: a check run for the app and then for the Gateway that raises the same words is written once (the emitter keys on `${code}\n${message}`). A warning's data can carry a next step the same way an error does: OWNER_NOT_CLAIMED has rerun: "<CLI> setup", rerunNote: "at a terminal" and needsTerminal: true (needsTerminal means the rerun is for a person at a terminal: hand it over; run with --json where CI is set, it raises the same warning again); ACCESS_NOT_CHECKED and ACCESS_SYNC_FAILED (step app.access, on a deploy or delete, syncAppsAccessAfter in packages/cli/src/lib/access/sync.ts) have appId and rerun: "<CLI> access on", the first with a rerunNote saying when; EMAIL_INBOUND_UNDECLARED (on a deploy) has rerun: "<CLI> email unset inbound"; MIGRATIONS_FAILED (on create) has rerun: "<CLI> db migrate"; WORKERS_PAID_UNVERIFIED has url and plan; GATEWAY_AT_ZONE_APEX has suggestedDomain; APP_NEEDS_SETUP (on a deploy, step app.secrets: <app> won't open until <names> is set, the first unmet setting's why under it) has setup, the AppSetup under done below, and the run's done.data.next carries its configure command. A warning never changes the exit code. CUSTOM_DOMAIN_OWNER_UNCHECKED is hidden from a person without --verbose but is always in the stream.
action_required
action is one of the eight values below. data fields:
| Field | Meaning |
|---|---|
url |
The page the person opens. |
code |
A one-time code to enter at url (device login). |
expiresAt |
ISO time after which url (or code) stops working. |
waiting |
true: the run waits for the action and goes on by itself once it is taken. Absent: the run stops here (exit 2). |
waitingFor |
What the wait is for, in words (Cloudflare login, the owner account (up to 15 minutes)); a person's spinner says Waiting for <it>. |
rerun |
The command to run once the action is taken: this same command, --json included when this run had it, unless the action says another or needsTerminal is set. Run it as it is. |
rerunNote |
Said after rerun (in a terminal, to finish). |
needsTerminal |
true: only a person at a terminal can do rerun, so it is built without --json. Hand it over as it is; never add --json (rerun_interactive; the warning OWNER_NOT_CLAIMED carries it too). |
choices |
Instead of rerun, when the way on is one of several commands: an array of { rerun, label, … }, one per choice. |
A stopping action always has rerun or choices. A waiting action has neither, because the run continues; if the wait runs out, the run ends: claim_owner with a last stopping action_required (exit 2), cloudflare_login with the error CLOUDFLARE_LOGIN_FAILED (exit 1). Action-specific keys (accounts, zone, plan, workerName, …) are listed per action below, and rollbackCommand is added after a migration (see below).
error
code is stable (the codes are on /docs/agent/errors), message is for a person, retryable says whether running the same command again can succeed with nothing changed. data fields:
| Field | Meaning |
|---|---|
fix |
A remedy in words, not a command (use a name with lowercase letters, digits and dashes). |
rerun |
The command to run next, where one helps (see the rules below). |
rerunNote |
Said after rerun (once it's done, for a stack trace to report). |
authorize |
true: rerun takes something over (a flag like --force-dns, --yes). Show it and ask; never run it on your own. |
url |
A page that helps (ZONE_NOT_FOUND, from gatewayZone in packages/cli/src/commands/setup/deployGateway.ts, carries the Cloudflare page to add a domain). |
stack |
The thrown error's stack, on UNEXPECTED. |
rollbackCommand |
cf's own command that puts a database this run migrated back to its restore point. |
didYouMean |
A close match to what was typed (argument errors). |
usage |
The command's usage line (argument errors). |
help |
The --help command to run (argument errors). |
Plus what the error raised with: command, exitCode, tail and log on a failed child; accounts on GATEWAY_NOT_FOUND and install_gateway; holder on LEASE_HELD; zones on ZONE_NOT_FOUND and DOMAIN_REQUIRED (with choices when there are several zones); url and cloudflare on CF_EMAIL_UNVERIFIED; domains and commands on EMAIL_ROUTING_DISABLED; live and candidate on DOWNGRADE_REFUSED.
done
The run's last event on success. data always has durationMs, the milliseconds since the sink was created (the emitter adds it). Two conventions across commands:
next: what to run next, an array whose items are a command string or{ command, note }(setup,create,deploy,install,release,configure,email show,secret list,mcp add,mcp on,mcp list,mcp show);statusaddscodeandwhyto each and may give a page to open asurlinstead of a command ({ code, command?, url?, note, why }, under status --json).facts: what a person sees as labelled lines, an array of{ label, value, note? }(setup'sGatewayandAdmin).
The rest is the command's result (see the commands below).
Two commands carry an app's setup state as setup, an AppSetup (packages/sdk/src/internal/appSettings.ts; in status it is null when the app declares nothing to set, is still pending or its Worker is gone): status as data.apps[].setup, secret list as data.app.setup.
{ ready: boolean,
settings: Setting[], // every setting, manifest order
unmet: Setting[], // the ones that keep the app closed
groups: [{ group, met, members: string[] }],
command: { command } | null } // "pnpm everyapp configure <app>"; null once ready
Setting = { kind: "provider" | "capability" | "secret" | "ai-routes", id, label,
holder: "gateway" | "app", names: string[],
need: { kind: "required" | "optional" | "anyOf", group? },
set: true | false | null, // null: the app Worker's names were never recorded; never blocks
blocking: boolean, why?, hint?, docs?, setup? }
// hint: what the key is and where it comes from, from the provider's entry (its hint, then each setting's own)
// setup: the guide, "setup/<name>.md" in the everyapp skill; none for a provider registered on the GatewayAn agent reads unmet, shows each setting's why, hint, docs and setup guide (a provider registered on the Gateway has no guide: pnpm everyapp provider show <id> prints its spec, /docs/agent/providers), and gets the values in without one passing through the chat: the person runs pnpm everyapp configure <app> in their own terminal; or NAME=value lines a command or a file produced are piped into pnpm everyapp configure <app> --json; or the person exported them under the settings' own names before the agent started and the agent runs pnpm everyapp configure <app> --from-env --json (one name: secret set NAME --from-env NAME --json). It never asks for, prints or repeats a value. configure ends with data.app.setup read again; deploy ends with one next entry carrying the same command (note asks for each; <app> opens once they are set) when the app it deployed needs setup, beside its APP_NEEDS_SETUP warning. An MCP app (mcp on), which has nothing to configure, carries pnpm everyapp secret set <KEY> instead.
Exit codes
| Code | When |
|---|---|
0 |
The run ended with done. |
1 |
An error was emitted, whatever came before it (a waiting action that was taken, steps that succeeded). |
2 |
The run stopped on an action_required without waiting, or ended while still waiting for one. Do the action, then run data.rerun (or one of data.choices). |
130 |
Ctrl-C (SIGINT) while cf children or cleanups were registered (packages/cli/src/lib/interrupt.ts). |
143 |
SIGTERM, the same way. |
251 |
stricli found no command for the arguments (UNKNOWN_COMMAND). |
252 |
stricli refused the arguments (UNKNOWN_FLAG, INVALID_VALUE, MISSING_ARGUMENT, MISSING_FLAG_VALUE, TOO_MANY_ARGUMENTS, REPEATED_FLAG). |
The sink computes 0, 1 and 2 (EventSink.exitCode): 1 once an error was emitted; else 2 once the run stopped on an action, or while it waits for one (until done clears it); else 0. runReported in packages/cli/src/lib/output/run.ts sets it with setExitCode, and packages/cli/src/bin/cli.ts re-applies it after stricli's run(), which would otherwise reset process.exitCode. 251 and 252 are stricli's own and stay. stricli's ExitCode values (@stricli/core) are negative, UnknownCommand: -5, InvalidArgument: -4, ContextLoadError: -3, CommandLoadError: -2, InternalError: -1 (and CommandRunError: 1), and reach the shell as 256 plus the value: 251, 252, 253, 254, 255. 254 is COMMAND_FAILED from a command loader that failed (below). 253 (ContextLoadError) is returned only when a context loader stricli calls fails, and packages/cli/src/bin/cli.ts hands run() a context already built (buildContext), so it cannot occur; 255 (InternalError) is in the table and returned nowhere in @stricli/core 1.3.0. Neither has an everyapp event.
Ctrl-C (packages/cli/src/lib/interrupt.ts): the first SIGINT or SIGTERM forwards the signal to every running cf child (its process group), waits up to 3 seconds for them, kills what's left, runs the synchronous cleanups (temp directories, secrets files), then the asynchronous ones for up to 10 seconds (recording an upload, releasing the deploy lease, last registered first), and exits 130 (143 for SIGTERM). A second Ctrl-C exits at once; a SIGTERM after the first signal (a CI runner following its SIGINT up) lets the cleanup go on. With nothing registered, Node's default handling applies. everyapp dev stops its own cf dev through a cleanup and exits 130 too.
Argument errors (exit 251 and 252)
What stricli's parser and router refuse is reported as an error event with retryable: false and a code from ArgumentErrorCode (packages/cli/src/argumentErrors.ts), the exit code staying stricli's.
code |
Exit | When | data |
|---|---|---|---|
UNKNOWN_COMMAND |
251 |
No route for the input; message lists the group's commands. | didYouMean (a full command, when a visible name is within two edits), help (<CLI> <group> --help) |
UNKNOWN_FLAG |
252 |
--flag or -x the command doesn't declare. |
didYouMean (--<flag>, within two edits), help |
INVALID_VALUE |
252 |
An enum flag given another value; a value its parser refused; a value given to a switch. | didYouMean (the enum value), usage (a positional), or fix (use --flag or --no-flag) |
MISSING_ARGUMENT |
252 |
A required positional is missing (Missing the SQL to run, Name at least one …). |
usage |
MISSING_FLAG_VALUE |
252 |
--flag needs a value when the flag was typed without one; <command> needs --flag <value> when a required flag wasn't given. |
usage (required flags shown in it), help |
TOO_MANY_ARGUMENTS |
252 |
More positionals than the command takes. | usage |
REPEATED_FLAG |
252 |
A flag given more than once. | help |
COMMAND_FAILED |
254 / 1 |
stricli's exit code: 254 when the command's loader failed (exceptionWhileLoadingCommandFunction, CommandLoadError), 1 when its body threw or returned an Error outside runReported (exceptionWhileRunningCommand, commandErrorResult, CommandRunError). |
help |
usage reads <CLI> <command path> [<arg>] [flags] (pnpm everyapp create [<name or path>] [flags]). <CLI> is how this run was started: pnpm everyapp under pnpm, npx everyapp under npm, yarn everyapp under yarn, else everyapp (invocation in packages/cli/src/lib/output/command.ts, from npm_config_user_agent).
Actions a person must take
RequiredAction (the REQUIRED_ACTIONS array in packages/cli/src/lib/output/events.ts) has eight values: cloudflare_login, register_workers_subdomain, claim_owner, upgrade_workers_paid, rerun_interactive, add_domain, choose_account, install_gateway. For each: who raises it, what the person does, what data carries, and whether the run waits.
cloudflare_login
cf isn't logged in to Cloudflare and CLOUDFLARE_API_TOKEN isn't set. Raised by every command that reaches Cloudflare (ensureCfAuth in packages/cli/src/lib/cf/account.ts).
- Under
--json, a command that hands the device login on (login,setup,update,status,deploy,install,delete,secret,email,access,provider,db query,db restore) runscf auth login --no-browserpiped and, as soon as cf prints its link and code, emitsaction_requiredwithaction: "cloudflare_login",stepthe command's login step (cloudflare.login,setup.auth,gateway.login,app.login,db.login,login), messageLog in to Cloudflare: open this link and enter the code, anddata: { url, code, expiresAt, waiting: true, waitingFor: "Cloudflare login" }.expiresAtis 5 minutes from then, the time cf gives (its own cap). The run waits: passurlandcodeto a person and keep reading. Approved in time, the login step endsokwith{ email }and the run goes on. Not approved, the run ends witherrorCLOUDFLARE_LOGIN_FAILED(retryable: true,rerun: "<CLI> login", messageCloudflare login timed out after …withOr set CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID.). - A path that doesn't hand the login on stops instead:
action_required cloudflare_loginwith nowaiting, messageLog in to Cloudflare with <CLI> login/Unattended? Set CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID instead.,rerunthis command. CLOUDFLARE_API_TOKENset but refused is not an action:errorCLOUDFLARE_TOKEN_REJECTEDwithfix.
register_workers_subdomain
cf refused an upload because the Cloudflare account has no workers.dev subdomain yet (cf error kind subdomain_missing, explainDeployFailure in packages/cli/src/lib/cf/deploy.ts). Raised by whatever uploads a Worker: deploy, setup, update, and the Gateway rebind delete runs. Message Choose a workers.dev subdomain for this Cloudflare account / Cloudflare needs one before an account's first Worker. Apps never use it. data: { url, rerun }: url is the dashboard link in cf's message, else https://dash.cloudflare.com/<accountId>/workers/onboarding; rerun this command. Does not wait.
claim_owner
The Gateway has no owner yet, and this run minted the one-time setup link that creates one (ensureOwner in packages/cli/src/commands/setup/runSetup.ts, packages/cli/src/lib/gateway/setup-link.ts). Raised by setup, and by deploy when it installs a Gateway (installGateway includes it).
- First,
action_requiredwithaction: "claim_owner",step: "setup.owner", messageOpen this link to create the owner account/Works once and expires in 24h. Treat it like a password.(orOpen this new link …/The link shown before no longer works. …whenreplaced), anddata: { url, expiresAt, replaced, waiting: true, waitingFor: "the owner account (up to 15 minutes)" }.urlis<gatewayUrl>/setup#token=est_…: the secret is in the fragment, only its SHA-256 is in the Gateway's D1, and opening it makes that person the Gateway's owner. Hand it to the person; never log it.expiresAtis 24 hours from minting. The run waits: it reads the link's row in D1 every 5 seconds for up to 15 minutes. Claimed,setup.ownerendsokwith{ email, organizationName }and the run goes on todone. - Nobody opened it in 15 minutes: a last
action_required claim_ownerwith messageOpen the setup link above to create the owner account/Nobody opened it within …. It still works for …; running setup before it's opened replaces it.,data: { setupUrl, expiresAt, rerun: "<CLI> setup --json", rerunNote: "to finish" }(thererunis<CLI> setup, with--jsonwhen this run had it); exit2. - The link stopped working (setup ran again elsewhere, or it expired):
action_required claim_owner, messageUse the newer setup link, or get a new one,rerun: "<CLI> setup --json"(the same rule),rerunNote: "for a new link". - The link is shown to a person at the terminal or through
--json(maySetupLinkBeShown:relayed), never whenCIis set: then the run endsdone(exit0) withdata.owner: nulland the warningOWNER_NOT_CLAIMED(rerun: "<CLI> setup",rerunNote: "at a terminal",needsTerminal: true): handrerunto the person; run again with--jsonwhereCIis set, it ends the same way. - Before the link, a plain request to the Gateway can warn
GATEWAY_UNREACHABLE(data: { kind, reason }; the link works as soon as it answers) orACCESS_IN_FRONT(Cloudflare Access protects it; whoever opens the link signs in to Access first).
upgrade_workers_paid
The account is on Cloudflare's Free plan; EveryApp needs Workers Paid. Three sources, none waits, rerun is always this command:
setupon a new install reads the plan before anything is created (checkPlaninpackages/cli/src/commands/setup/runSetup.ts): messageSubscribe this account to Workers Paid/It's on the Free plan. …,data: { plan, url, rerun }withurlhttps://dash.cloudflare.com/<accountId>/workers/plans. A plan that can't be told is the warningWORKERS_PAID_UNVERIFIEDinstead; one cf couldn't read is the stepsetup.planskip.- cf refused an upload for the plan (cf error kind
free_plan,packages/cli/src/lib/cf/deploy.ts):data: { workerName, cloudflare, url, rerun },cloudflarebeing cf's message. - Any other cf call refused for the plan (
packages/cli/src/lib/output/report.ts): messageCloudflare refused, for the Free plan: <cf's message>/EveryApp needs Workers Paid ($5 a month, then usage). Subscribe, then run this command again.,urlhttps://dash.cloudflare.com/?to=/:account/workers/plans.
rerun_interactive
A Worker's live version wasn't deployed by everyapp (changed in the dashboard, through the API, or by an interrupted deploy), and Cloudflare won't replace it unattended; only a person at a terminal can confirm. Raised by whatever changes a Worker (assertReplaceable and explainDeployFailure in packages/cli/src/lib/cf/deploy.ts): deploy for the app's Worker (packages/cli/src/commands/deploy/deployApp.ts), secret set and secret unset for each Worker they change (packages/cli/src/commands/secret/index.ts), and for the Gateway's Worker setup, update and the rebind a deploy or delete runs (reconcileGateway in packages/cli/src/lib/gateway/reconcile.ts, then applyGateway in packages/cli/src/lib/gateway/apply.ts).
- Before anything changes: message
<Worker> was changed outside everyapp; confirm in a terminal/Its live version wasn't deployed by everyapp, and Cloudflare won't replace it unattended. Nothing changed.,data: { workerName, versionId, rerun, rerunNote: "in a terminal", needsTerminal: true }. - At the upload (cf's strict mode aborted, kind
strict_conflict): message<Worker> was changed outside everyapp; confirm in a terminal/It was last changed in the Cloudflare dashboard or through the API, so cf won't overwrite it unattended.,data: { rerun, rerunNote: "in a terminal, and confirm cf's prompt", needsTerminal: true }(noworkerNameorversionId).
Does not wait. rerun is this same command with --json left out (thisCommand([], { terminal: true }) in packages/cli/src/lib/output/command.ts: the one rerun built for a terminal), and --yes never skips it (packages/cli/src/commands/flags.ts). data.needsTerminal: true is the field to key on, not the action name: it means only a person at a terminal can do the rerun (needsTerminal in ActionData, packages/cli/src/lib/output/events.ts; the warning OWNER_NOT_CLAIMED carries it the same way). Hand rerun to the person as it is: an agent that adds --json back gets this same action_required again, every time, because only a person at a terminal can answer the confirmation.
add_domain
The Cloudflare account has no active zone a Gateway can live under. Raised by setup (and deploy installing a Gateway) from activeZones in packages/cli/src/commands/setup/runSetup.ts and gatewayZone in packages/cli/src/commands/setup/deployGateway.ts:
- A zone exists but isn't active: message
Finish activating <zone> on Cloudflare/Its nameservers don't point at Cloudflare yet.,urlis the zone's dashboard page,https://dash.cloudflare.com/<accountId>/<zone>(zoneUrlinpackages/cli/src/lib/domains/zones.ts); fromgatewayZone(the zone of--domain)dataadds{ zone, status }. - No zone at all: message
Add a domain to this Cloudflare account/EveryApp needs one. Buy one in the dashboard (about $10 a year for a .com, ready in minutes),/or point a domain you own at Cloudflare's nameservers.,urlis the account's domains page,https://dash.cloudflare.com/<accountId>/domains/overview(registerDomainUrlinpackages/cli/src/lib/domains/zones.ts).
rerun this command; does not wait.
choose_account
The login sees several Cloudflare accounts and nothing picked one (no --account-id, no CLOUDFLARE_ACCOUNT_ID, no hostname that singles one out). No single rerun fits: the action is thrown with rerun: null, which reportFailure leaves out, so the event has no rerun and data.choices lists one command per choice. Pick one choice (or let the person) and run its rerun as it is: every choices[].rerun is built by thisCommand (packages/cli/src/lib/output/command.ts) like a plain rerun, so it carries --json when this run had it, and --json given twice is the error REPEATED_FLAG. Does not wait.
- Installing a Gateway (
resolveAccountinpackages/cli/src/lib/cf/account.ts): messageChoose the Cloudflare account to install in/<email> can use <n> accounts. Run one of:; each choice is{ accountId, accountName, label, rerun }withrerunthis command plus--account-id <id>. - Several accounts have a Gateway (
discoverGatewayinpackages/cli/src/lib/gateway/discover.ts): messageChoose which Gateway to use/<email> sees a Gateway in <n> Cloudflare accounts. Run one of:; each choice is{ accountId, accountName, gatewayUrl, label, rerun }.rerunis this command plus--account-id <id>, or forsetupthis command with--domain <gatewayHost>in place of its--domain.
install_gateway
No account the login sees has a Gateway, and the command needs one. Two raisers; does not wait.
status(existingGatewayinpackages/cli/src/lib/gateway/connect.ts): messageNo Gateway in <account>'s Cloudflare account (logged in as <email>)/Gateway in another account? Log in to it: <CLI> login,data: { accounts, rerun: "<CLI> setup", rerunNote: "installs one" },accountsbeing the{ id, name }of every account asked. Thatrerunnames another command, so add--jsonto it yourself; it has no--domain, and under--jsonthesetupit names ends with the errorDOMAIN_REQUIRED(pickDomaininpackages/cli/src/commands/setup/runSetup.ts): messageChoose the Gateway's address with --domain/It must be under one of this account's domains: <zones>. A subdomain works best.,data.zones(the account's active zones), and a way on shaped aschoose_account's. With one zone:rerunis this command with--domain apps.<zone>added (<CLI> setup --domain apps.<zone>),rerunNote: "or another name under <zone>",fix: "add --domain apps.<zone>, or another name under <zone>"; rundata.rerunas it is (thisCommandbuilt it, so it carries--jsonwhen the run had it). With several: norerun,data.choicesis one{ label: "<zone>", rerun: "<CLI> setup --domain apps.<zone>" }per zone, andfix: "add --domain apps.<first zone>, or another name under <zone>, <zone> or <zone>"; pick one choice (or let the person) and run itsrerunas it is (built the same way).deploy(offerGatewayinpackages/cli/src/commands/deploy/steps/offerGateway.ts): at a terminal it offers to install one atapps.<zone>; under--jsonit stops with messageInstall a Gateway first: <account> has none yet/Apps deploy behind one. Setup needs a person once, to create the owner account.,rerun<CLI> setup --domain <apps.<first active zone>> [--account-id <id>](--domain <hostname>when no zone could be read),data: { accounts, domain? }. The deploy comes after the setup.
Every other command that needs the Gateway (secret, email, db, access, provider, delete) connects through connectToGateway and requireGateway (packages/cli/src/lib/gateway/connect.ts, packages/cli/src/lib/gateway/discover.ts) and fails with the error GATEWAY_NOT_FOUND instead: no Gateway in any account the login sees gives rerun: "<CLI> setup --domain <hostname>" and rerunNote: "to install one"; none in the account --account-id or CLOUDFLARE_ACCOUNT_ID named, or a login that lists no accounts, gives a fix naming --account-id; data.accounts always.
What to do next: fix, rerun, authorize
The rules are in packages/cli/src/lib/errors.ts. Every problem says what to do next its own way, never "the command that just failed" by default:
fixis a remedy that isn't a command. A validation error says what's wrong and how to fix it, with norerun.rerunis a command to run,rerunNotethe words after it. It defaults to this same command only where running it again can help: anaction_required(do the action, then run it again), aretryableerror, and a takeover (the command with its flag,authorized). An error can name another command (<CLI> login,<CLI> deploy,<CLI> setup).- "This same command" is
thisCommand: the arguments as given,--jsonincluded when this run had it (so an agent runs the rerun as it is), each quoted for a POSIX shell, prefixed by<CLI>. Some reruns drop a flag (thisCommandWithout("--domain")) or add one. A rerun only a person at a terminal can do (thisCommand([], { terminal: true }): every event withneedsTerminal: true) leaves--jsonout.
Takeover flags
An error whose way on is a flag that takes something over (replaces a DNS record, deletes data, skips a confirmation) gets rerun: "<this command> <flag>" and authorize: true. Show it and ask; never retry with the flag on your own. The table (TAKEOVER_FLAGS):
code |
Flag | Raised when |
|---|---|---|
DNS_RECORD_CONFLICT |
--force-dns |
A DNS record answers a hostname about to be published (packages/cli/src/lib/domains/preflight.ts); fix says to delete it or use another name. |
DNS_UNREADABLE |
--force-dns |
The login can't read the zone's DNS records (a token without Zone DNS Read). |
CAA_BLOCKS_ISSUANCE |
--force-dns |
In the table; nothing raises it in this checkout. |
DURABLE_OBJECT_REMOVED |
--allow-delete-durable-object-data |
everyapp.config.ts dropped a Durable Object class the last deploy had (packages/cli/src/commands/deploy/deployApp.ts). |
WORKFLOW_REMOVED |
--allow-delete-workflows |
It dropped a Workflow the last deploy had. |
EMAIL_ROUTING_DISABLED |
--enable-email-routing |
An inbound address's domain has Email Routing off (packages/cli/src/lib/app/emailRoutes.ts); data: { domains, commands }. |
CONFIRMATION_REQUIRED |
--yes |
A confirmation nobody could answer (see prompts below). |
DOWNGRADE_REFUSED sets its own (downgradeRefused in packages/cli/src/lib/gateway/apply.ts; the Gateway always comes from this checkout, checkoutGateway in packages/cli/src/lib/gateway/checkoutRelease.ts): setup and update (a hidden flag there) take --allow-downgrade; both reach the refusal through installGateway in packages/cli/src/commands/setup/runSetup.ts with allowDowngradeFlag: true, so the error carries rerun this command with --allow-downgrade, authorize: true and fix: "git pull, then run setup again" (that text from update too). The rebind a deploy or delete runs has no flag (refuseOlderCheckout, same file as downgradeRefused): fix: "git pull" with rerun this command and rerunNote: "after that". data: { live, candidate }.
CANCELLED
code: "CANCELLED" is a person declining a prompt, or pressing Ctrl-C at one: nothing went wrong, so it has no fix or rerun, its message says what was left as it was (Cancelled. Nothing changed., Cancelled. Nothing deleted.), and the run still exits 1. Under --json nothing prompts, so it comes only from runs a person attends.
retryable
retryable: true means running rerun again can succeed with nothing changed. rerun defaults to this same command (EveryAppError in packages/cli/src/lib/errors.ts) but is not always it: run data.rerun, never a command you rebuilt. rerunNote says when (once the other deploy finishes, in a few minutes). The errors raised with it:
code |
rerun |
Raised when |
|---|---|---|
CF_TIMEOUT |
this command | A cf call passed its time limit. |
NETWORK_ERROR |
this command | The network failed (see how a thrown error becomes an event). |
CF_EMAIL_UNVERIFIED |
this command | The Cloudflare account's email address isn't verified (Cloudflare API code 10034), so Cloudflare refuses to create anything; data.url is the profile page, https://dash.cloudflare.com/profile, data.cloudflare cf's message (see how a thrown error becomes an event). |
LEASE_HELD |
this command | Another run holds the lease after the wait; data.holder names it; rerunNote once the other deploy finishes on a deploy, else once it's done (<CLI> status shows it) (packages/cli/src/lib/gateway/lease.ts). |
LEASE_LOST |
this command | This run's hold expired, so it stopped before its next change to avoid overlapping another run. |
APP_CHANGING |
this command | The app's registry row kept changing while the deploy recorded its upload; the upload is kept (packages/cli/src/lib/gateway/registry.ts). |
APP_NOT_LIVE |
<CLI> status |
The hostname answers but the app isn't live after 10 minutes; rerunNote: "then deploy again" (packages/cli/src/commands/deploy/steps/waitForLive.ts). |
APP_NOT_FOUND (from the live wait) |
this command | The app was deleted from the Gateway while the run waited for it; rerunNote: "to put it back". |
RELEASE_DOWNLOAD_FAILED |
this command | A release URL timed out or couldn't be fetched (packages/cli/src/lib/release/github.ts). |
EMAIL_ROUTES_PARTIAL |
this command | The inbound addresses are saved, routing them stopped part-way; rerunNote again, or <CLI> deploy, to finish; data: { saved, cause }. |
SECRETS_PARTIALLY_APPLIED |
<CLI> secret set <the names left> (or unset; with --app <id> when it ran by --app and one of the app's own is left); from configure, <CLI> configure <app> (rerunNote to set what is left; before the first deploy <CLI> configure, in the app's directory, to set what is left) |
Some Workers took the change before Cloudflare refused one; data: { applied, left } (packages/cli/src/commands/secret/index.ts). |
CLOUDFLARE_LOGIN_FAILED |
<CLI> login |
The device login timed out or didn't complete. |
retryable: false with a rerun means something must happen first (rerunNote, fix, or an action).
After a migration: rollbackCommand
A deploy or Gateway upgrade saves a Time Travel restore point before it migrates a database that has data (packages/cli/src/lib/migrations/remote.ts). When the run fails after that, afterMigration attaches the restore point to the thrown error and reportFailure adds to the last event, error or action_required alike: a line The database stays migrated. To roll it back: <CLI> db restore … at the end of the message, and data.rollbackCommand, cf's own command for a script: CLOUDFLARE_ACCOUNT_ID=<id> npx cf@<pinned version> d1 time-travel restore <databaseId> --bookmark <bookmark> --force (a PowerShell variant on Windows without SHELL; restoreCommand in packages/cli/src/lib/cf/d1.ts). --force is there because cf, where nobody can type, answers its own confirmation "no". MIGRATION_FAILED itself (the migration broke, nothing uploaded) carries rollbackCommand in data the same way, with fix: "correct the migration". A run that succeeds says the same restore point on the migration step's ok event (restoreCommand and rollbackCommand in app.migrations or gateway.migrations, above), so a deploy that went through can be undone from the stream too.
How a thrown error becomes an event
reportFailure in packages/cli/src/lib/output/report.ts turns whatever a command threw into its last event, in this order:
| Thrown | Event |
|---|---|
ActionRequiredError |
action_required with its action, data, and url, rerun, rerunNote when set (rerun: null is omitted: choices carries the commands). |
CfError of kind free_plan |
action_required upgrade_workers_paid (see above). |
EveryAppError |
error with its code, retryable, data, and fix, rerun, rerunNote, authorize: true when set. |
CfError of kind email_unverified (Cloudflare API code 10034, packages/cli/src/lib/cf/errors.ts) |
CF_EMAIL_UNVERIFIED: message Verify your Cloudflare account's email address first / Cloudflare refuses to create anything until the address on the account is verified. Open the message Cloudflare sent you, then run this command again., retryable: true, rerun this command, data: { url: "https://dash.cloudflare.com/profile", cloudflare }, cloudflare being cf's message. |
CfError (any other kind) |
error with code CF_<KIND> in upper case: CF_AUTH, CF_NOT_FOUND, CF_ALREADY_EXISTS, CF_ABORTED, CF_STRICT_CONFLICT, CF_SUBDOMAIN_MISSING, CF_R2_NOT_ENABLED, CF_ACCESS_NOT_ENABLED, CF_D1_ID_REJECTED, CF_UNKNOWN; retryable: false; cf's message. |
CfTimeoutError (a cf call past its time limit) |
CF_TIMEOUT, retryable: true, rerun this command. |
CfOutputError (cf succeeded but printed something other than the expected JSON) |
CF_OUTPUT, retryable: false. |
ManifestError (from @every-app/perimeter/manifest) |
INVALID_MANIFEST, retryable: false. |
An error (or its cause) with a Node network code: ECONNREFUSED, ECONNRESET, ENOTFOUND, EAI_AGAIN, ETIMEDOUT, UND_ERR_CONNECT_TIMEOUT, UND_ERR_SOCKET; or a TypeError fetch failed |
NETWORK_ERROR, message The network failed (<code>) then the error's message (the TypeError: The network failed / fetch failed, no code), retryable: true, rerun this command. |
Any other error with an upper-case code (ENOENT, EACCES) |
SYSTEM_ERROR, retryable: false. |
| Anything else | UNEXPECTED: message everyapp hit an unexpected error / <name>: <message> / This is a bug in everyapp, not something you did.; data.stack; and, since the NDJSON sink is never verbose, rerun this command with --verbose added (if not there) and rerunNote: "for a stack trace to report". Under --json the stack is in data already; the rerun is for a person's screen. |
step is set on the event when the caller named the step that failed. CF_ABORTED is cf answering its own confirmation "no" where no one could type (it prints Aborted. and exits 0, which everyapp treats as a failure).
Prompts under --json
Every question everyapp asks goes through packages/cli/src/lib/output/prompt.ts, and canPromptInTerminal(json) is the gate: stdin and stderr must be terminals, --json must be off, and CI must be unset. Under --json nothing prompts; each question becomes an event:
- A yes/no confirmation (
confirmUnlessYes):--yesskips it; without it the run ends witherrorCONFIRMATION_REQUIRED, its message theunattendedtext (Deleting an app needs confirmation at a terminal, or --yes;This SQL can change <app>'s production database/A person at a terminal confirms it first, or --yes does.;Removing secrets needs confirmation, and there's no terminal to ask in;Turning Access off needs confirmation at a terminal, or --yes;Restoring <db> needs a person at a terminal to confirm, or --yes/It undoes …; anything written to it since is lost too.),rerunthis command with--yes,authorize: true, anddatawhen the command has it (db restore:{ appId, databaseId, bookmark, migrations, createdAt, createdBy }). Where:delete(with--purge, a person at a terminal types the app id instead; unattended it is the same--yes),db querywriting to production (anything that isn'tSELECT,EXPLAIN,VALUES, a read-onlyWITHor aPRAGMAthat sets nothing,readsOnlyinpackages/cli/src/commands/db/queryOutput.ts),db restore,secret unset,access off(turnAccessOffinpackages/cli/src/commands/access/index.ts; nothing to confirm when Access isn't in front:donewith{ removed: false }). teardown's confirmation is the account id, never--yes: typed at a terminal, or--confirm <id>(the same id as--account-id). Under--jsonwithout it:errorTEARDOWN_CONFIRMATION_REQUIRED(Tearing down <id> needs its id typed at a terminal, or --confirm <id>),rerunthis command with--confirm <id>added,authorize: true,data: { accountId, plan }. Only for a dedicated test account.- A choice (which account, which Gateway, which zone):
choose_accountwithchoices, or forsetupwithout--domainthe errorDOMAIN_REQUIRED(data.zones, andrerunorchoicesas underinstall_gatewayabove). - A secret's value (
secret set): never from the command line;--from-env <VAR>or stdin when something is piped in (packages/cli/src/lib/secretValue.ts). With neither,errorSECRET_VALUE_REQUIRED(Can't ask for <NAME>'s value without a terminal/Or pipe it in: echo "$<NAME>" | <CLI> secret set <NAME>),rerun: "<CLI> secret set <NAME> --from-env <NAME>".--from-envand stdin hold one value: several names areSECRET_SEVERAL_NAMES. - An app's settings (
configure <app>):NAME=valuelines on stdin (one per line; blank lines and#lines skipped, anexportprefix allowed, one pair of quotes around a value dropped, the value otherwise as it is; a later line for a name wins) or--from-env(each unset setting from the environment variable of its own name; a set name is never replaced, and stdin isn't read), never both; a value after the verb isVALUE_ON_COMMAND_LINE(a second argument or--from-env=<value>is refused by the argument parser first,TOO_MANY_ARGUMENTSorINVALID_VALUE, the value never shown), a line that isn'tNAME=valuePIPED_LINE_INVALID(never echoed), a piped name the manifest doesn't declareSECRET_NOT_DECLARED(echoed only when it looks like a setting name), a blank piped valueSECRET_EMPTY, each before anything is written. With nothing read and a required setting unset,errorSECRET_VALUE_REQUIRED(Can't ask for <app>'s settings without a terminal/<app> needs <names>. Run this at a terminal, pipe NAME=value lines in (one per line), or export them under those names and add --from-env (which also takes the variable of any unset optional setting).),data.namesthe names still missing,rerun: "<CLI> configure <app> --from-env"(rerunNotewith the variables exported) once deployed; before the first deploy, in the app's directory,rerun: "<CLI> configure --from-env"(in the app's directory, with the variables exported). - Turning Email Routing on for a domain:
EMAIL_ROUTING_DISABLEDwith--enable-email-routing(a takeover). - Replacing a Worker changed outside everyapp:
rerun_interactive;--yesdoesn't cover it. - cf's own questions: cf runs piped and can't ask; its strict-mode abort is
rerun_interactive, and anything else it aborts isCF_ABORTED.
Commands whose result is the done event
For these the done event is the answer; a person sees a table (display), a script reads data.
db query --json
The flag is resultJsonFlag (packages/cli/src/commands/flags.ts, brief Print the result as an NDJSON event), which db query declares with its own brief Print one NDJSON done event, its rows in data.results, instead of a table (packages/cli/src/commands/db/command.ts). data:
{ "database": "production" | "local", "results": [[{ "<column>": <value> }, …], …], "meta": [{ "duration": <ms>, "changes": <n> }, …], "durationMs": <ms> }results has one array per statement (the SQL is split on ;), each an array of row objects keyed by column; meta has one { duration, changes } per statement, D1's own numbers. A write with no rows back shows as changes > 0. Before it, step db.query start and ok with { database }. A statement D1 refuses is error QUERY_FAILED with the SQLite code in the message. Writes to production need --yes under --json (CONFIRMATION_REQUIRED otherwise).
status --json
data is the whole report (reportStatus in packages/cli/src/commands/status/index.ts): deployed, installed, gatewayUrl, accountId, mode (the install row's deploymentMode: self_hosted, hosted, or null when no upload recorded one, packages/cli/src/lib/gateway/install.ts), release: { version, sha256 }, versionId (the Worker serves), recordedVersionId (the install row names), owner: { email, organizationName } | null, claimed, apps (each { id, hostname, workerName, status, bound, deployedBy, email: { senders, inbound, routed, declaresInbound }, publicRoutes, mcp, setup }; setup is the AppSetup above, null when the app declares nothing to set, is still pending or its Worker is gone), desiredApps, liveApps, appBaseDomain, domains, liveDomains, inSync, upToDate, checkout: { version, treeSha256 } | null, tls, certificates: [{ host, ready }] | null, access: { on, teamDomain, drift, driftUnread } | null (whether Cloudflare Access fronts the Gateway, read from the Gateway Worker's settings and the D1 record by accessStateOf in packages/cli/src/lib/access/settings.ts, and with on, whether it is in step with this release: drift: { paths: [hosts], signIn: [hosts], missing: [hosts], settings: boolean } from Zero Trust, the live applications against what this release wants (accessDrift in packages/cli/src/lib/access/plan.ts; empty lists and settings: false mean in step, otherwise the problem ACCESS_DRIFT names pnpm everyapp access on), or drift: null with driftUnread: { permission, error } when Zero Trust couldn't be read (permission: true for a login without the Access permissions, said on the row and never a problem; otherwise the problem ACCESS_DRIFT_UNKNOWN); off, both are null; the whole is null for a hosted Gateway, before the first upload, or when cf couldn't read the settings), leases, fixes and next (below). message is one line: Gateway <url>: <n> apps live, nothing to fix or … <n> problems to fix, counting error and warning problems only. A Gateway database with no install row gives { deployed: true, installed: false, accountId, fixes: [<GATEWAY_NOT_INSTALLED>] }.
Each apps[] entry carries publicRoutes: [{ path, methods }], the routes its stored manifest opens to the internet (storedPublicRoutes in packages/cli/src/lib/app/publicRoutes.ts: methods upper-cased, ["GET"] for a route that names none, as the perimeter matches them; an empty array when the manifest has no public), and mcp: { by, why } | null, its stored manifest's mcp (storedMcp; the app's host answers /mcp, by the Gateway's ToolBus or the app's own server); a person sees both as the APP table's PUBLIC column (GET /t/*, POST /t/e, GET /health +2 more · MCP /mcp (gateway)).
fixes is what is off and what to do, one { code, severity, message, run, note?, fix? } per problem (fixData): severity is error, warning, info or settling; message is the headline and its detail lines joined with newlines; run the command that fixes it (null when none) and note the words after it (updates it now, asks for the hostname again, redeploys <version>, asking first); fix a remedy in words when there is one. Every problem is listed, the ones that settle by themselves included, info ones last. The codes (packages/cli/src/commands/status/problems.ts):
code |
Severity | Means | run |
|---|---|---|---|
CHECKOUT_BEHIND |
warning | This checkout's Gateway is older than the live one; deploys from here are refused. | git pull |
GATEWAY_OUTDATED |
info | This checkout's Gateway is newer than the live release (Your every-app folder has a newer Gateway than the one online); the next new app's deploy updates it too. |
<CLI> update (note: "updates it now") |
NO_OWNER |
warning | Nobody can sign in yet. | <CLI> setup |
GATEWAY_NOT_INSTALLED |
warning | The database exists, the install row doesn't. | <CLI> setup |
GATEWAY_NOT_UPLOADED |
warning | The install stopped before its first upload. | <CLI> setup |
GATEWAY_CHANGED |
warning | The Gateway Worker serves a version setup didn't upload. | <CLI> setup |
BINDINGS_DIFFER |
warning | The live Gateway doesn't bind or publish what its registry lists. | <CLI> setup |
APP_WORKER_MISSING |
error | An app's Worker no longer exists. | <CLI> deploy from <app>'s directory, or <CLI> delete <app> |
APP_NOT_BOUND |
error | The Gateway can't bind the app (its Worker's name is wrong). | <CLI> delete <app> |
APP_NOT_UPLOADED |
warning | Registered, no deploy finished. | <CLI> deploy from the app's directory, or <CLI> delete <app> |
APP_BINDING |
settling | Goes live on its first visit. | none |
APP_NEEDS_SETUP |
warning | A required setting of the app is unset (<app> needs setup; the detail names each unmet setting and its guide). |
<CLI> configure <app> (setup.command, no note: it asks which member of an any-of group) |
SETTINGS_UNKNOWN |
warning | cf couldn't list a Worker's secrets (Couldn't list the Workers' secrets); the settings it holds read set: null in apps[].setup.settings[], never blocking. |
none |
EMAIL_ROUTES_UNKNOWN |
warning | Cloudflare didn't list the Email Routing rules. | none |
EMAIL_INBOUND_UNDECLARED |
warning | Inbound addresses stored, but the deployed config doesn't turn inbound mail on. | none; fix names the config change or <CLI> email unset inbound |
EMAIL_ROUTE_PENDING |
warning | An inbound address isn't routed yet. | <CLI> deploy from <app>'s directory |
EMAIL_ROUTE_MISSING |
warning | A routed address gets no mail. | <CLI> deploy from <app>'s directory |
CERTIFICATES_UNKNOWN |
warning | Cloudflare didn't list the zone's certificates. | none |
CERT_PENDING |
settling | A hostname's certificate hasn't come yet. | none |
ACCESS_UNKNOWN |
warning | Cloudflare didn't say whether Access is on (the Gateway Worker's settings couldn't be read). | none |
ACCESS_DRIFT |
warning | Access is on, and Zero Trust has other paths let through, other sign-in methods, a missing application, or settings naming other applications than this release wants (access.drift). |
<CLI> access on (note: brings Access in step with this Gateway) |
ACCESS_DRIFT_UNKNOWN |
warning | Access is on, and Zero Trust refused the read that says whether it is in step (access.driftUnread.error). |
none |
DEPLOY_RUNNING |
settling | A deploy holds a lease right now. | none |
next is what isn't done yet, at most four { code, command?, url?, note, why } (nextStepsFor in packages/cli/src/commands/status/next.ts; the rules are docs/design/2026-10-proactive-next-steps.md): command is the <CLI> … to run or url the page to open (one of the two), note what it does, why the state behind it (an app id, a setting name, a count). A step is a function of state: it goes when the state changes, nothing is stored to dismiss it, and a step never repeats a fix (a key APP_NEEDS_SETUP names is not suggested again, and a step whose command a fix's run already gives is dropped). A person sees them as a Next: block after the fixes, each as its command or URL and its note. The codes, in the order they come:
code |
When | command or url |
|---|---|---|
AI_KEY |
None of OPENAI_API_KEY, OPENROUTER_API_KEY, WORKERS_AI_API_TOKEN is set on the Gateway while an app lists an AI provider it runs without (optional); the names were read |
<CLI> secret set <the keys the apps name> (note AI for <apps>) |
PROVIDER_OFFER |
An MCP app's key is set (DATAFORSEO_API_KEY) while the app is off, on an uploaded Gateway, and no deployed app lists its capability (OpenSEO lists dataforseo: the key is that app's) |
<CLI> mcp on <id> (note says each call spends the provider's credit) |
PROVIDER_KEY |
An MCP app is on and its key isn't set | <CLI> secret set <key> (an MCP app has no Worker, so configure <id> refuses it; this is its setup.command) |
ACCESS_OFF |
Self-hosted, uploaded, the owner has claimed, access.on is false (before the claim access on refuses, ACCESS_NOBODY_ALLOWED, and NO_OWNER says setup) |
<CLI> access on |
INVITE |
The owner is the only member of the install organization, no invitation is pending, and an app is up | https://<gateway>/admin/users |
CONNECT_AI |
No AI connection and no live personal token in the install organization, while an app serves tools | https://everyapp.com/docs/connect-ai, the connector steps (note names https://<gateway>/mcp, which answers a GET with 405: it is for the client, not a browser) |
CREATE_APP |
Uploaded, no apps | <CLI> create my-app |
EMAIL_UNSET |
EMAIL_FROM isn't set (the name may be inside it, so EMAIL_FROM_NAME alone decides nothing) while there is more than one member or an app lists email |
<CLI> secret set EMAIL_FROM EMAIL_FROM_NAME |
The reads behind them, all under the operator's credentials and never over HTTPS: the Gateway Worker's secret names (names only, listed once for Access, each app's settings and these), the MCP app rows of the registry (tier provider, from the same listApps the report makes), and one cf d1 query batch of five counts in the install organization (readOrganizationCounts in packages/cli/src/lib/gateway/counts.ts: members, invitations pending and not expired, mcp_connections not revoked, user_access_tokens not revoked and not expired, app_tool_catalogs serving tools). A read that fails skips the rules that need it (an older Gateway without one of the tables, cf down) and raises nothing. Before the owner claims (owner: null) no counts are read, so no INVITE or CONNECT_AI, and no ACCESS_OFF; a hosted Gateway never gets ACCESS_OFF; nothing is suggested before the first upload except what fixes says. The commands are Gateway-wide (secret set NAME, access on, mcp on): the one command that opens an app, <CLI> configure <app>, is the APP_NEEDS_SETUP fix's, never repeated here.
secret list --json
listSecrets in packages/cli/src/commands/secret/index.ts. Names only, never values. With no app named, outside an app directory: { gateway: { workerName: "every-app-gateway", names, settable, mcpCredentials }, apps: [{ id, setup }] } (names set on the Gateway Worker, settable what can be set there, mcpCredentials each remote MCP app credential name as { name, apps, set }, setup each app's AppSetup; an MCP app is in apps only while it needs setup). For one app (<app> from anywhere, or the directory's): { app: { id, deployed, workerName, declared, workers: [{ workerName, names, missing }], secretNames, settings, setup }, gateway: { workerName, names, needed: [{ name, required, set }], missing, settable }, next? }; workers is the app's Worker then each helper, missing the manifest's secrets nobody set, needed the Gateway settings the app reads (set says the Gateway Worker has it), settings every setting with its state, setup the AppSetup above. next mixes { command, note } objects and command strings: once deployed, setup.command.command (<CLI> configure <app>) while something is unmet; before the first deploy, { command: "<CLI> configure", note: "in the app's directory" } while something is unmet, then <CLI> deploy; absent when nothing is missing.
email show --json
showEmail in packages/cli/src/commands/email/index.ts. { app: { id, workerName, status, deployed }, declares: { sends, receives }, senders, inbound, routed, next? }: senders and inbound are the installation's lists on the Gateway, routed the inbound addresses with an Email Routing rule, declares what everyapp.config.ts says the app does. next is an array of { command, note }: first the list's own fix when there is one ({ command: "<CLI> email unset inbound", note: "clear the stored address" } when addresses are stored but the config no longer declares inbound mail, else { command: "<CLI> deploy", note: "route the list as shown" } when an inbound address isn't routed yet or a removed one still is), then { command: "<CLI> email set --sender '*@<domain>'", note: "send as your own domain" } when senders can be set (the config declares sending and the Gateway isn't hosted) and none is stored, then { command: "<CLI> email set --inbound <address>", note: "receive mail" } when the config declares inbound mail and none is stored; absent when empty. With nothing stored at all, next is those email set entries alone. Not deployed: { app: { id, deployed: false }, declares, next: ["<CLI> deploy"] }.
Other done data
| Command | data |
|---|---|
deploy |
{ url, workerName, versionId, live, organization, publicRoutes, mcp, next? } (liveDone in packages/cli/src/commands/appGateway.ts); mcp is the manifest's mcp as { by, why } (the app's host answers /mcp; a person sees it as the MCP fact, Serves /mcp on its own host (<by>): <why>), null when the manifest sets none; publicRoutes is [{ path, methods }] from the manifest's public (publicRoutesOf in packages/cli/src/lib/app/publicRoutes.ts: in manifest order, methods upper-cased, ["GET"] when a route names none, [] when there is no public), which a person sees as the Public fact after Access (Open to the internet without sign-in: GET /hooks/*, POST /collect, the first six routes, then … and N more (everyapp.config.ts public)); next is { command, note } entries (packages/cli/src/commands/deploy/deployApp.ts): { command: "<CLI> email set --inbound <address>", note: "routes mail to <app>" } when the config declares inbound mail and no address is stored, and { command: "<CLI> email set --sender '*@<domain>'", note: "lets <app> send as your domain" } when the config declares sending, the Gateway isn't hosted (app senders can be set) and none is stored; both can be present. When the app needs setup, { command: "<CLI> secret set <names> [--app <id>]", note: "<app> opens once these are set" } comes too, beside the APP_NEEDS_SETUP warning. |
release |
{ tarball, shown, version, sha256, next }, next <CLI> install <shown>. |
setup, update |
{ gatewayUrl, adminUrl, organizationName, owner, release, mode, gateway, accessOn, facts?, next? }; mode is self_hosted or hosted; gateway is installed, upgraded, repaired or up-to-date; accessOn is true when interactive setup turned Cloudflare Access on (its done is the step setup.access; the facts then carry Access on and next has no access on), false when declined or failed (ACCESS_SETUP_SKIPPED), null when not asked (--yes, --json, update, hosted); next on a newly installed Gateway or a newly created owner is nextAfterInstall in packages/cli/src/commands/setup/index.ts, each entry { command, note }: self-hosted [<CLI> create my-app, <CLI> access on, <CLI> secret set OPENAI_API_KEY, <CLI> secret set EMAIL_FROM EMAIL_FROM_NAME] (notes start your first app, put Cloudflare Access in front of your Gateway (recommended), AI for apps (or OPENROUTER_API_KEY, WORKERS_AI_API_TOKEN), email invites and password resets; needs Cloudflare Email Sending); hosted [<CLI> create my-app, <CLI> secret set OPENAI_API_KEY, <CLI> secret set EMAIL_FROM] (no Access line: access on refuses a hosted Gateway); on an up-to-date one [{ command: "<CLI> status", note: "see apps, domains and certificates" }]; none after a repair, or when nobody could claim the owner. |
create |
{ appId, dir, next }; dir is the new app's absolute path; next is [{ command: "cd <path>" }, { command: "pnpm dev", note: "run it locally" }, { command: "pnpm run deploy", note: "put it live" }], <path> being what to type from where create ran (../my-app for pnpm everyapp create ../my-app; the whole path when it was given absolute or from ~). |
delete |
{ appId, workerName, alreadyDeleted, purged, removed, kept }. |
db restore |
{ appId, databaseId, bookmark, migrations, createdAt, createdBy }. |
email set, email unset |
{ app: { id, workerName, status }, senders: { value, changed }, inbound: { value, changed, routed, removed }, next? }. |
secret set, secret unset |
{ gateway?: { names, versions, pinned? }, app?: { id, workerName, names, versions } }, versions the new Worker version per Worker; pinned each remote MCP credential set, { name, origin }, with the one origin the Gateway sends it to; unset of names nobody holds is { removed: false }. |
configure |
{ app: { id, deployed, setup }, set: string[], changed?: { gateway?: { names, versions }, app?: { id, workerName, names, versions } }, next? }: setup the AppSetup above, read again after the change; set the names set, in manifest order; changed as secret set's data, absent when nothing was set; next is [{ command: "<CLI> configure <app>", note: "at a terminal, with NAME=value lines on stdin, or with --from-env" }] when the app still needs setup (message Set A. <app> still needs X, the names still missing, beside the APP_NEEDS_SETUP warning; before the first deploy { command: "<CLI> configure", note: "in the app's directory: at a terminal, with NAME=value lines on stdin, or with --from-env" }), or before the first deploy [{ command: "<CLI> deploy", note: "then <CLI> configure <app> for X and Y" }] (message <app>'s Gateway settings are set; its own X and Y come after its first deploy; note in the app's directory when it has no secrets of its own); absent when the app is ready (Set A, B and C. <app> is ready, or <app> is ready). |
access on |
{ team: { domain, created, sessionSet, globalSession }, signInMethods: [{ id, type, name, allowed, restrictToAccountMembers? }], identityProviders: { oneTimePinAdded, cloudflareAdded }, policy, applications: { gateway, apps, combined }, settings: { names, outcome, reason }, signIn: { url, pending, first }, next } (turnAccessOn in packages/cli/src/commands/access/index.ts); each application carries allowedIdps and signInAdded; settings.outcome is set or kept, signIn.first pin, idp or both, next the secret set commands that follow. |
access off |
{ removed: true, settings, applications: { deleted, trimmed, kept } }; { removed: false } when Access wasn't in front. |
access show |
{ on, hosted, team, policy, signIn: { methods, cloudflare, pin, openToAnyCloudflareAccount } | null, applications: { gateway, apps, combined }, desired, drift: { paths, signIn, missing, settings }, settings: { names, current }, linkPending, fixes? } (each application with allowedIdps and signInInSync); nothing changes. |
install |
The same as deploy (deployDone): the installed release is deployed. |
mcp add |
{ id, name, url, auth: { kind, secret?, header? }, risk, on: true, was, organization: { id, name }, probe, key, mcp: { url, toolPrefix }, granted, next }; was is new or revived; probe what the one look at the URL found (outcome reachable, needs-credential, redirected or unreachable); key null for a server that takes no credential, else { name, set, bound, boundOrigin } (/docs/agent/mcp). |
mcp on |
{ id, name, kind, on: true, was, organization: { id, name }, key, mcp: { url, toolPrefix }, granted, next? }; kind is builtin or remote; was is new, revived (a removed row brought back), off (served again, access kept) or existing; next the secret set for the key or credential when it isn't set. |
mcp off |
{ id, name, kind, on: false, wasOn, key }: the row is disabled, its access, tokens and snapshot kept. |
mcp remove |
{ id, name, kind, removed, key }: the tombstone (mcp off until 2026-10-25). |
mcp list |
{ apps: [{ id, name, kind, status, on, url?, auth?, supported?, tools, key, lastListedAt?, lastError? }], mcp, next? } (providers until 2026-10-25); status is on, off, needs setup or not added; mcp the Gateway's /mcp URL; next lists <CLI> mcp on <id> and <CLI> secret set <key> for what is not added or unset. |
mcp show |
{ id, name, kind, status, on, url?, auth?, supported?, risk?, rev?, overrides?, addedBy, addedAt, key, snapshot, tools, mcp, next? }; each of tools is { name, serverName, title, risk, source, on, problem }. |
mcp refresh |
{ id, name, kind, refreshed, dropped }. |
mcp tool |
{ id, tool: { serverName, name, inListing }, before, override, rev }. |
teardown |
{ accountId, dryRun, removed, kept, plan }; with --dry-run nothing is removed and plan says what would be. |
provider … |
add (--oauth included), list, show, presets, connections and disconnect: on the providers page, with what each command does. |
login, db migrate |
Only durationMs; the facts are on their steps. |
The loop an agent runs
Read stdout line by line and act on type:
stepandprogress: keep reading; keep a step'sdatawhen it carries a fact you need (app.live'surl,setup.owner'semail).warning: keep reading. Show it to the person after the run, with itsrerunorurlif it has one; arerunwithneedsTerminal: trueis theirs to run, not yours.action_requiredwithdata.waiting: true: handurl(andcode) to the person at once and keep reading; the run goes on by itself when the action is taken, and endsdoneorerrorlike any run; a wait that runs out endsclaim_ownerwith a last stoppingaction_required(exit2) andcloudflare_loginwith the errorCLOUDFLARE_LOGIN_FAILED(exit1).action_requiredwithoutwaiting: the run is over, exit2. Showmessage,urlandcode; once the person has done it, rundata.rerunas it is (it carries--jsonwhen this run had it), or let them pick fromdata.choicesand run thatrerunas it is too (it is built the same way); arerunwithdata.needsTerminal: true(rerun_interactive) goes to the person as it is.error: the run is over, exit1. Showmessageanddata.fix. Ifdata.authorizeistrue, showdata.rerunand ask before running it. Otherwise, ifdata.retryableistrue, wait for whatrerunNotesays and rundata.rerun; ifrerunnames another command (<CLI> login,<CLI> setup), run or show that, with--jsonadded; if there is aurl, open it; if there isrollbackCommand, show it besidemessage's restore line.UNEXPECTEDis a bug: reportdata.stack.done: exit0. Readdata(anddata.nextfor what to do after).
run: pnpm everyapp <command> … --json
for each line on stdout:
event = parse(line)
switch event.type:
"step", "progress": continue
"warning": remember(event) ; continue
"action_required":
if event.data.waiting: tell person(event.data.url, event.data.code) ; continue
else: stop = event # exit code will be 2
"error": failure = event # exit code will be 1
"done": result = event.data # exit code will be 0
wait for exit code
if exit == 2: show stop.message, stop.data.url, stop.data.code
if stop.data.needsTerminal: hand stop.data.rerun to the person as it is # rerun_interactive
else, after the person is done: run stop.data.rerun as it is (or one of stop.data.choices[].rerun, as it is)
if exit == 1: show failure.message, failure.data.fix
if failure.data.authorize: ask, then run failure.data.rerun as it is
else if failure.data.rerun: run it (after what rerunNote says, if retryable)
if exit == 251 or 252: show failure.message, failure.data.didYouMean / usage / help
if exit == 130: the run was interrupted; nothing to parse after the "interrupt" progress lineTwo cautions. A rerun that is this same command, and every choices[].rerun, carries --json when this run had it (thisCommand builds them all), so run it as it is: --json twice is the error REPEATED_FLAG. Only a rerun that names another command (<CLI> login, <CLI> setup, <CLI> setup --domain <hostname>, <CLI> deploy) is written without it; add --json to those. A rerun whose event carries needsTerminal: true (rerun_interactive, the warning OWNER_NOT_CLAIMED) is built without it: it is for a person at a terminal, and with --json it ends the same way again. And a claim_owner or cloudflare_login url is a credential for whoever opens it: pass it to the person, don't write it anywhere that persists.
everyapp dev has no --json
everyapp dev is the exception: a long-running, human-facing command. Its flags are --port, --host, --mode, --gateway, --base-host (declared baseHost; --help prints the kebab form and the parser takes both, stricli's caseStyle in packages/cli/src/app.ts) and --skip-migrations, with no --json (packages/cli/src/commands/dev/command.ts), and it always writes for a person (eventSink(false) in packages/cli/src/commands/dev/index.ts): the ready line, how to reach the app, then its request and tool-call lines (dev.session, dev.mcp) as they come. Ctrl-C stops the app's dev server and exits 130. Drive it from an agent as a background process and read its text; use /docs/agent/dev for what it prints.
The event log: EVERYAPP_EVENT_LOG
A dormant seam for test harnesses and bug reports, never for an agent's own use. With EVERYAPP_EVENT_LOG=<path> in the environment, every everyapp process appends to that file, one JSON object per line, whether or not it was run with --json: { "type": "invocation", "pid", "ts", "argv", "cwd", "json", "isatty": { "stdin", "stdout", "stderr" }, "ci" } once at start, then each event as the run's sink emitted it (the same object its --json line carries, plus pid; a warning once, done with durationMs and no display), then { "type": "exit", "pid", "ts", "code", "ms" }. What a command never emits is not there either: setup mints its owner link only when maySetupLinkBeShown allows (packages/cli/src/lib/gateway/setup-link.ts), so the link is absent from the log exactly when a person would not have seen it. Each line is one fs.appendFileSync (O_APPEND), so the processes that share a file (pnpm run deploy running everyapp, npx everyapp) interleave whole lines, told apart by pid. The file is created readable by the user only (mode 600), because the owner link in it is a password. A path that can't be written is said once on stderr and the run goes on (packages/cli/src/lib/output/eventLog.ts). Unset, nothing is written. It is how the onboarding loop (docs/design/2026-10-onboarding-loop.md) times a harness's everyapp runs and claims the owner link from outside the harness, and what to ask for in a bug report: EVERYAPP_EVENT_LOG=/tmp/everyapp-events.ndjson pnpm everyapp setup …, then attach the file after reading it for anything secret (an owner link, est_…, is a password).
Sources
packages/cli/src/lib/output/events.tspackages/cli/src/lib/output/eventLog.tspackages/cli/src/lib/output/report.tspackages/cli/src/lib/output/prompt.tspackages/cli/src/lib/output/run.tspackages/cli/src/lib/output/command.tspackages/cli/src/lib/output/terminal.tspackages/cli/src/lib/output/text.tspackages/cli/src/lib/errors.tspackages/cli/src/lib/exit-code.tspackages/cli/src/lib/interrupt.tspackages/cli/src/lib/childLog.tspackages/cli/src/lib/runtime.tspackages/cli/src/lib/secretValue.tspackages/cli/src/lib/cf/account.tspackages/cli/src/lib/cf/deploy.tspackages/cli/src/lib/cf/errors.tspackages/cli/src/lib/cf/d1.tspackages/cli/src/lib/cf/schemas.tspackages/cli/src/lib/migrations/remote.tspackages/cli/src/lib/gateway/setup-link.tspackages/cli/src/lib/gateway/connect.tspackages/cli/src/lib/gateway/discover.tspackages/cli/src/lib/gateway/apply.tspackages/cli/src/lib/gateway/change.tspackages/cli/src/lib/gateway/lease.tspackages/cli/src/lib/gateway/registry.tspackages/cli/src/lib/gateway/install.tspackages/cli/src/lib/gateway/reconcile.tspackages/cli/src/lib/access/sync.tspackages/cli/src/lib/access/settings.tspackages/cli/src/lib/release/github.tspackages/cli/src/lib/domains/zones.tspackages/cli/src/lib/domains/certWait.tspackages/cli/src/lib/domains/https.tspackages/cli/src/lib/domains/preflight.tspackages/cli/src/lib/app/emailRoutes.tspackages/cli/src/argumentErrors.tspackages/cli/src/app.tspackages/cli/src/bin/cli.tspackages/cli/src/commands/flags.tspackages/cli/src/commands/appGateway.tspackages/cli/src/commands/setup/runSetup.tspackages/cli/src/commands/setup/deployGateway.tspackages/cli/src/commands/setup/index.tspackages/cli/src/commands/deploy/index.tspackages/cli/src/commands/deploy/command.tspackages/cli/src/commands/deploy/deployApp.tspackages/cli/src/commands/release/bundleApp.tspackages/cli/src/commands/deploy/stdout.test.tspackages/cli/src/commands/deploy/steps/offerGateway.tspackages/cli/src/commands/deploy/steps/waitForLive.tspackages/cli/src/commands/create/index.tspackages/cli/src/commands/delete/index.tspackages/cli/src/commands/login/index.tspackages/cli/src/commands/login/command.tspackages/cli/src/commands/db/index.tspackages/cli/src/commands/db/command.tspackages/cli/src/commands/db/queryOutput.tspackages/cli/src/commands/db/restore.tspackages/cli/src/commands/status/index.tspackages/cli/src/commands/status/command.tspackages/cli/src/commands/status/problems.tspackages/cli/src/commands/secret/index.tspackages/cli/src/commands/email/index.tspackages/cli/src/commands/email/command.tspackages/cli/src/commands/access/index.tspackages/cli/src/commands/dev/command.tspackages/cli/src/commands/dev/index.tspackages/cli/bin/everyapp.jspackages/sdk/src/internal/gatewaySettings.tspackages/perimeter/src/manifest/manifest.tslanding-page/src/lib/source.ts
CLI reference
Every everyapp command with its arguments, flags, defaults and help text, generated from the CLI itself. Exit codes and the global flags are here too.
Error codes
Every code an everyapp command can end with (errors, the reporter's and cf's, argument errors), the codes the Gateway's deploy API and browser install answer, every warning, and every problem status reports, each with what it means and how to fix it.