spfn 0.3.0-beta.4 → 0.3.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +50 -1
  2. package/dist/index.js +1258 -19
  3. package/package.json +2 -1
package/README.md CHANGED
@@ -54,7 +54,8 @@ with `--pm`. In a pnpm workspace, `create` installs from the workspace root.
54
54
  ## Commands
55
55
 
56
56
  Registered top-level commands: `create`, `init`, `add`, `dev`, `build`, `start`,
57
- `provision`, `codegen`, `contract`, `key`, `setup`, `db`, `env`, `ops`, `secret`.
57
+ `provision`, `codegen`, `contract`, `key`, `setup`, `db`, `env`, `ops`, `secret`,
58
+ `cloud`.
58
59
 
59
60
  ### `spfn create <name>`
60
61
 
@@ -384,6 +385,31 @@ Schema-driven: a secret declared with `envSecret({ generate: 'base64url32' })` c
384
385
  minted/rotated automatically (`secret generate`/`rotate`); one without `generate` is an
385
386
  external value you paste in (`secret set`).
386
387
 
388
+ ### `spfn cloud`
389
+
390
+ Free-tier management for apps deployed to your own **Vercel Hobby + Supabase Free**
391
+ accounts: see the plan limits, watch live usage against them, keep the Supabase
392
+ project from pausing, and sync env vars/API keys. Account tokens and key values live
393
+ in the OS keychain and never appear in command output.
394
+
395
+ | Subcommand | Description |
396
+ |------------|-------------|
397
+ | `cloud link` | Connect accounts: Vercel access token + Supabase personal access token (masked prompt or `VERCEL_TOKEN`/`SUPABASE_ACCESS_TOKEN` env), pick the project on each side. Identifiers land in gitignored `.spfn/cloud.json`; tokens go to the keychain |
398
+ | `cloud limits` | The free-plan limits (constants verified against the official docs, date shown) — works before `link` |
399
+ | `cloud usage` | Current usage: Vercel billing feed (rolling 30 days), Supabase DB size + last-24h API requests |
400
+ | `cloud status` | Usage measured against the limits on one screen; items at ≥80% get a migration warning |
401
+ | `cloud keepalive` | Daily cron hitting `/api/backend/_core/health?detailed=true` (the detailed check runs a DB query, which is what prevents the ~7-idle-day pause). Vercel cron by default; `--github-actions --url <deployed-url>` for a workflow instead |
402
+ | `cloud env pull` | Supabase keys → local: project URL + anon key into `.env.local`, service-role key into the keychain (`.env.server` gets a reference). `--db-url` also composes `DATABASE_URL` (prompts for the DB password) |
403
+ | `cloud env push KEY…` | Push local env values to the Vercel project env by name. Values resolve from `.env`/`.env.local`/`.env.server`+keychain; everything is sent encrypted except `NEXT_PUBLIC_*` |
404
+
405
+ Free-tier behavior worth knowing (also printed by `cloud limits`): Vercel Hobby
406
+ allows one cron at most once per day and pauses a capability when its rolling
407
+ 30-day limit is hit (it never bills); Supabase Free quota is summed per
408
+ organization (except DB size), and org totals like egress/MAU have no public API —
409
+ `cloud status` shows per-item numbers and points at the dashboard for the rest.
410
+ Hobby is limited to personal, non-commercial use — a monetized app needs Vercel Pro
411
+ or a migration off the free tier.
412
+
387
413
  ### `spfn setup icons`
388
414
 
389
415
  Install and configure SVGR for SVG-as-component imports (Next.js only).
@@ -418,6 +444,29 @@ listSignups GET /_ops/signups
418
444
  Add `--json` for the raw JSON Schema. The server still validates every call — `--describe`
419
445
  reports what it will accept, and the app's answer decides.
420
446
 
447
+ #### Capability modules
448
+
449
+ An app can also mount ops commands a package described, with
450
+ [`defineOpsModule`](../core/README.md#can-a-package-ship-ops-commands). Those commands are
451
+ named `<module>.<command>` and carry a summary, an effect and their scopes, so the CLI can
452
+ group them and say what each one does. From **0.3.0-beta.5**:
453
+
454
+ ```bash
455
+ spfn ops modules # what is mounted, and from where
456
+ spfn ops modules --json # same, machine-readable
457
+ spfn ops list --module ledger # just that module's commands
458
+ spfn ops call ledger.compact --yes # effect=destructive needs this
459
+ ```
460
+
461
+ `spfn ops call` refuses a command the app declared `effect: destructive` unless `--yes` is
462
+ given. It refuses the same way when the app announced module metadata this CLI could not
463
+ validate: the effect is then unknown rather than absent, and an unknown effect is not
464
+ treated as a safe one. The command still lists — an operator reading a short list would
465
+ otherwise take it for the app's whole surface — and the warning names what was dropped.
466
+
467
+ Everything in the manifest is the app's own text written to your terminal, so control
468
+ characters in it are replaced before anything is printed.
469
+
421
470
  The app URL comes from `--app` or `SPFN_OPS_APP`, and it must be **https** — every one of
422
471
  these commands carries a secret, and `token issue` carries an administrator's password.
423
472
  `http` is accepted only against `localhost`, `127.0.0.1` and `::1`, where there is no