CLI & Deploy

CLI

bun run pramen help
bun run pramen init my-app                        # scaffold app.ts + oblaka.ts
bun run pramen token alice author --tenant acme   # mint a dev JWT
bun run pramen schema sql                         # CREATE TABLE for the schema
bun run pramen schema snapshot                    # baseline in .pramen/schema.json
bun run pramen schema diff                        # additive vs destructive changes
bun run pramen schema status --tenant acme        # is a deployed tenant caught up?

Configuration: oblaka

Cloudflare topology is declared in oblaka.ts (the source of truth) — the Worker, the PRAMEN Durable Object, its SQLite migration, vars, and observability. oblaka generates wrangler.jsonc from it (git-ignored; never edit by hand).

Each project sets a unique PROJECT in oblaka.ts, which names the Worker, the DO, and the KV namespace — so multiple projects in one Cloudflare account never collide.

Deploy

bun run config         # oblaka oblaka.ts          -> generate wrangler.jsonc (local)
bun run dev            # regenerate + lopata dev (local runtime)
bun run dev:wrangler   # regenerate + wrangler dev (workerd-parity check)
bun run plan           # oblaka --remote --dry-run  -> preview remote changes

# Real deploy: provision resources via oblaka, then ship the code via wrangler.
export CLOUDFLARE_ACCOUNT_ID=... CLOUDFLARE_API_TOKEN=...
wrangler secret put AUTH_SECRET     # production auth secret (overrides the dev var)
bun run deploy --env production     # oblaka --remote (provision) && wrangler deploy

oblaka --remote provisions the Worker + Durable Object (and the SQLite DO migration) on Cloudflare and writes the config; wrangler deploy bundles and uploads the Worker entry (worker.ts, your createPramen(app) call).

Testing

bun test generates the config from oblaka.ts, boots a single wrangler dev against fresh local state, and runs every suite (each on its own tenant) — ACL, cell-level ACL, relations, live-query invalidation, pagination, aggregates, auth, migrations, and more. CI runs typecheck + bun test on every push/PR; no Cloudflare credentials are needed (miniflare).