CLI reference
Every spky command, grouped by what you're trying to do. Run spky <command> --help for full flags.
Commands read sp00ky.yml from the current directory. Pass --path <dir> to point at a project
somewhere else, and spky <command> --help for the flags of any single command.
Project & dev loop
| Command | What it does |
|---|---|
spky init | Scaffold a new project: schema, app, config, first migration. |
spky dev | Start the local stack: SurrealDB, SSP, scheduler, your apps. With sync.queryAllowlist on, passes the mode to the SSP and publishes the allowlist JSON as version dev on every start. Docs |
spky generate (gen) | Generate client types from sp00ky.yml, or a single file via --input/--output. --format json|typescript|dart|surql, --all, --append, --no-header, --mode, --endpoint, --secret, --modules-dir. For a typescript entry with queries, also records the query allowlist by running the query module through @spooky-sync/query-allowlist (the app’s node_modules/.bin/spooky-query-allowlist, else npx) and writes <queries>.allowlist.json; commit it. Docs |
spky migrate | Database migrations: create, apply, prod, status, fix. prod migrates the cloud deployment without deploying. Docs |
spky lint | Validate sp00ky.yml. |
spky doctor [--json] | Project health: config, codegen freshness, migrations, Docker. Docs |
spky verify [--fix] | Check the SSP/scheduler snapshot against upstream SurrealDB and print the scheduler’s own drift verdict; --fix re-clones the replica when its counts are off, else forces every SSP to re-bootstrap. |
spky query [sql] | Run SurrealQL once, or open a REPL. --cloud targets the deployment, --json prints raw JSON instead of a table. |
spky version | Print version information. |
Adding things to a project
| Command | What it does |
|---|---|
spky api add | Register a backend and generate its outbox table. Docs |
spky bucket | add a file bucket, or configure its storage backend. Docs |
spky flag | Feature flags: list, create, get, delete, enable, disable, set, unset, eval. set adds a targeting rule, eval dry-runs one user. Docs |
spky admin | Operator roster (_00_admin): list (ls), add <user>, remove <user>. Grants access to the feature-flag editor and the admin dashboard. Root-only, so nobody promotes themselves. |
spky recipe <name> | Render a cookbook snippet (live-list, optimistic-mutation, crdt-text-field). spky recipe list for the index. |
spky agents init | Generate AGENTS.md, parameterized by your schema. Docs |
spky mcp | MCP server for editors and agents: serve, token, tokens, revoke, install. Docs |
Running unattended: -y / --yes
Every subcommand accepts -y / --yes, and SPKY_YES=1 does the same from the environment.
It answers confirmation prompts without asking, so a command never sits waiting for a keypress.
This is the flag a CI job or a coding agent should pass. A pipe is easy for the CLI to detect, but an agent usually runs commands on a pseudo-terminal, where the prompt renders normally and then waits forever for input nothing can send.
The two kinds of question get different answers, because “yes to everything” is not what anyone means:
| Question | Example | With --yes | No terminal, no --yes |
|---|---|---|---|
| Consent to something consequential | Apply to PRODUCTION? Restart SurrealDB? Overwrite this directory? | Yes, and the log says so | Refuses, naming the flag |
| Preference with a default | Initialize git? Cache the vault key? Create a backup first? | The default | The default |
| Irreversible | Destroy the project. Reset its database. | Not covered | Refuses |
The last row is deliberate. --yes is the flag that gets added to every command by reflex, which
makes it the wrong thing to arm “delete everything” with. Those two take the project’s name instead:
--yes also switches the guided flows (spky login, picking or creating a project, billing setup)
to their unattended path. They lead into pickers and browser logins that no flag can answer, so
instead of opening one they stop with the exact command or environment variable to use.
Consent without a terminal used to be inconsistent: some commands hung, some failed with a bare
“Failed to read confirmation”, and spky migrate prod and spky link disconnect skipped the
question and went ahead. They now refuse like everything else. If a script relied on that,
add --yes to it.
Operating a running system
| Command | What it does |
|---|---|
spky jobs | Background jobs: list, get, kill, retry, clear. clear -A/--all also drops queued jobs; running ones are never deleted. No subcommand opens the interactive dashboard. Docs |
spky schedules | Server-side schedules: list, get, pause, resume, trigger, release, runs, sync. release <name> <key> lets a quarantined forEach key fire again. Docs |
spky workflows | Workflow DAGs: list, show, watch, runs, kill. show renders the graph, watch follows a run live. Docs |
spky logs | Tail or browse logs. --filter, --split, --since, --until, --grep, -i/--interactive (TUI), -F/--follow. Docs |
spky stats | Live CPU, memory, disk and network graphs. --window 1h, --filter backend,surrealdb. |
spky status | Deployment version, status and running VMs. |
spky restart [TARGET...] | Restart deployment containers. With no target: the scheduler and SSPs. Flags |
spky scale ssp <n> | Scale SSP instances. |
Cloud
| Command | What it does |
|---|---|
spky login, spky logout | Authenticate with Sp00ky Cloud. |
spky project | Manage cloud projects: create, list, credentials, destroy. credentials --raw prints just the password, for piping. Docs |
spky deploy | Build, upload, provision, migrate, deploy. With sync.queryAllowlist on, also publishes the committed allowlist JSON as _00_query_allowlist:<app>__<version> (the frontend’s package.json version) and keeps the previous version’s row; under enforce, a missing or stale JSON (sourceHash no longer matches the query module) fails the deploy, under warn it warns. Docs |
spky push | Push schema to a free (Cloudflare) project’s SSP node. Paid plans apply schema during deploy. |
spky release <app> | Announce a new version to running clients without deploying. --mandatory, --cache-bust. Also publishes the app’s allowlist JSON under the announced version, so a regenerated query allowlist goes live without a restart. |
spky env | Encrypted variables and the vault: set, list, rm, pull, import, unlock, passphrase, share-ci, reset. set --file <path> reads a multi-line value (a PEM key) from disk, scoped with --dev or --prod. reset takes request, approve <email>, complete, list. Docs |
spky domain | Custom domains: add, list, remove. add --app <name> picks which app serves it (a frontend, an exposed backend, or a backend on a dedicated machine), add --status attaches it to the public uptime page. |
spky backup | Database backups: list, create, restore, delete, configure, reset. Docs |
spky link | GitHub push-to-deploy: connect, status, settings, disconnect, trigger, runs. Docs |
spky token | API tokens for CI: create, list, revoke. |
spky team | Members and invitations: list, invite, invites, revoke, remove, rename. Docs |
spky billing | Billing: usage, plan. No subcommand opens the portal. |
spky notice [message] | Post a notice to the public uptime page. list and remove manage existing ones. |
Restarting containers
spky restart recreates containers in place. With no target it restarts the scheduler and its
SSPs, leaving backends, frontends and SurrealDB running.
| Input | What it does |
|---|---|
TARGET... | Roles (db or surrealdb, scheduler, ssp, frontend) or the name of a single app from sp00ky.yml. Several may be given at once. |
--all-backends | Restart every backend app. |
--upgrade | Move the scheduler and SSP to the newest published build before restarting. A role that sp00ky.yml pins to an exact version restarts on its pin instead, with a warning. |
--clean | Also wipe the scheduler’s persistent volume, its replica and write-ahead log. SurrealDB data is untouched. |
--surreal (--db) | Also restart SurrealDB. A process restart rather than a wipe, so data on the volume survives, but the whole deployment is briefly unavailable. Equivalent to adding db to the targets. |
-y, --yes | The global flag: confirms the prompt a SurrealDB target triggers. Without it, and without a terminal, the restart is refused. |
What --upgrade, --clean and --surreal do at the container level is spelled out in
Admin dashboard, which offers the same three actions from a
browser.
Migrating a deployment
spky migrate prod applies pending migrations plus the internal Sp00ky schema to your cloud
deployment, without deploying anything else. It resolves the SurrealDB URL and root password from
your login and the slug in sp00ky.yml, and reads the mode, namespace and database from
sp00ky.yml too, so there are no connection flags to pass.
| Flag | What it does |
|---|---|
-y, --yes | The global flag: confirms applying to production. Without it, and without a terminal, the migration is refused rather than run unasked. |
--force-schema | Re-apply the internal schema and remote functions even when unchanged, bypassing the schema-hash skip. Also accepted by spky migrate apply. Use it for drift recovery. |
--migrations-dir <dir> | Override the migrations directory from sp00ky.yml. |
--endpoint <url>, --secret <s> | Override the SSP or scheduler endpoint and auth secret used for the internal schema. |
--config <path> | Point at a sp00ky.yml somewhere else. |
Raise SPKY_DB_HTTP_TIMEOUT_SECS when a large migration exceeds the 120 second per-request
deadline. Migrations
Flags worth memorising
spky doctor --json is the designed integration point for scripts and AI agents: a stable list of
checks, each with a severity and a fix command. See
AI coding agents.