naro-cli 0.18.0 → 0.19.0

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.
package/README.md CHANGED
@@ -62,6 +62,7 @@ naro usage Team usage this month: requests, builds and c
62
62
  naro usage --month 2026-09 --team acme Another UTC month, another team
63
63
 
64
64
  naro deploy [--prod] Build locally and deploy
65
+ naro deploy --env qa Deploy to a named environment (<subdomain>--qa) instead of the preview; not with --prod
65
66
  naro deployments List deployments
66
67
  naro inspect <deployment-id> One deployment + build logs
67
68
  naro cancel <deployment-id> Stop a build that is still running
@@ -86,10 +87,24 @@ naro protection Preview protection: on or off, and whether a
86
87
  naro protection enable | disable Protect the preview URL (members only) or open it to anyone with the link (disable asks first; --yes in CI)
87
88
  naro protection bypass [remove] Create (shown once) or remove the secret automation sends as x-naro-protection-bypass (replacing or removing asks first; --yes in CI)
88
89
 
89
- naro env list [--reveal] Secrets masked unless --reveal
90
+ naro env list [--reveal] Secrets masked unless --reveal; an environment's value shows its name
90
91
  naro env add DATABASE_URL production
91
- naro env remove DATABASE_URL
92
- naro env pull [.env.local]
92
+ Target: production, preview, all (the default) or an environment name (qa)
93
+ naro env remove DATABASE_URL The production, preview and all values; an environment's only with its name
94
+ (naro env remove DATABASE_URL qa)
95
+ naro env pull [.env.local] Preview's values by default; --env production, or --env qa for an environment
96
+ (its own value wins over all; an unknown name fails before anything is written)
97
+ naro env import .env.qa qa Upload every variable in a dotenv file to one target (all by default; asks first,
98
+ --yes in CI; invalid keys or values over 5 KB stop it before any request)
99
+
100
+ naro environments List the project's environments: address, branch, protection, and how many the plan allows
101
+ naro environments create qa --branch qa
102
+ A QA or staging surface served at <subdomain>--qa; --copy-env preview|production|none
103
+ picks where its variables start, --database schema|empty how its database does
104
+ naro environments set qa --no-branch --protection off
105
+ Change the branch whose pushes deploy here (--branch <b>, or --no-branch for none)
106
+ and who can open it (--protection on|off; off asks first, --yes in CI)
107
+ naro environments delete qa Delete it with its worker and protection key (asks first; --yes in CI)
93
108
 
94
109
  naro domains list
95
110
  naro domains add www.example.com Prints the CNAME to create; naro connects
@@ -310,16 +325,14 @@ point at its table's primary key or a unique column. `--owner user_id` adds
310
325
  four actions; any other new table is closed to the Data API until you give it
311
326
  a policy (`CREATE POLICY` in a migration, or `naro policy create` or
312
327
  `naro policy set`; the command says so).
313
- Policies are kept by table name: a drop removes the table's policies whenever
314
- the project has a backend, on or off (the command says so). A rename leaves
315
- them under the old name, where they apply to no table — the command prints
316
- what to run to move them. Move them then: the next time `naro db table`
317
- creates a table as that name or renames one to it, renaming the table back
318
- included, the policies stored under the name are removed first, so a new
319
- table never inherits an earlier one's (except, on a project without a
320
- backend, one changed through `naro db table`, the table editor or MCP) — and
321
- neither does a table made by `naro db push` or `naro db query`. Whatever a command removes it prints
322
- so it can be made again: as `CREATE POLICY` statements, which
328
+ Policies go with their table, as in Postgres and as `naro db push` does it,
329
+ in the same migration: a drop removes the table's policies, and a rename
330
+ moves them to the new name and rewrites the policies of other tables that
331
+ read it (the command says which). A rename such a policy cannot follow is
332
+ refused before anything runs. A table the command creates, or renames onto a
333
+ name, never inherits what an earlier table of that name left there: that is
334
+ removed first. A change that fails changes no policy. Whatever a command
335
+ removes it prints so it can be made again: as `CREATE POLICY` statements, which
323
336
  `naro policy create` takes back, and — for owner rules, whose owner column
324
337
  `CREATE POLICY` cannot say — as the `naro policy set <table> … --owner <column>`
325
338
  command that sets them again. A statement that cannot be shown as it is (a
@@ -585,8 +598,10 @@ SQLite changes a column by building the table again — `CREATE TABLE
585
598
  __new_x`, copy the rows, `DROP TABLE x`, `ALTER TABLE __new_x RENAME TO x` — so
586
599
  the drop removes `x`'s policies and the rename does not bring them back. Write
587
600
  the `CREATE POLICY` statements again after the rename, in the same migration.
588
- A plain `ALTER TABLE a RENAME TO b` does not move them either: they stay under
589
- `a`, and `b` has none until you create them again.
601
+ A plain `ALTER TABLE a RENAME TO b` in a migration moves `a`'s policies to `b`,
602
+ and a policy of another table that reads `a` is written to read `b` — do not
603
+ create them again on `b`: a policy of the same name already there is refused.
604
+ `naro db table`, the table editor and MCP do the same.
590
605
  The answer's `warnings` lists the policies a migration removed, with SQL you
591
606
  can paste; it also says when the project has no backend yet (the policies are
592
607
  saved and apply once `naro backend enable` turns it on) and when a policy was
@@ -743,7 +758,10 @@ into named policies; it also turns a backend that is off back on, so run
743
758
  `naro backend disable` again afterwards if it should stay off. `naro policy
744
759
  list` and `naro policy remove` work in the meantime. A migration or a query
745
760
  that holds a `CREATE POLICY` or `DROP POLICY` gets the same answer before
746
- anything runs; SQL without one runs as before.
761
+ anything runs, and so does any change that creates, drops or renames a table —
762
+ in SQL, `naro db table`, the table editor or MCP, with the backend on or off:
763
+ the stored rules apply by table name, and only `naro backend enable` clears
764
+ them. Other SQL runs as before.
747
765
 
748
766
  `naro policy set` refuses with `409 POLICY_EXISTS` when the table's `naro_<action>` policy is not one it wrote (for example one made with `naro policy create`): `Policy <name> on <table> is not one naro policy set wrote. Change it with naro policy create, or drop it first: naro policy drop <name> --table <table>.` A `naro_<action>` policy that cannot be read as stored (the table answers `500 POLICY_INVALID`) is not refused: setting a rule replaces it, and `none` drops it.
749
767
 
@@ -808,6 +826,164 @@ An `--update-check` you give replaces the default: without
808
826
 
809
827
  ## Release notes
810
828
 
829
+ ### 0.19.0
830
+
831
+ - `naro environments` manages a project's named environments, QA or staging
832
+ surfaces served at `https://<subdomain>--<slug>.naro.sh` beside production
833
+ and the preview. While the control plane has them switched off, every
834
+ sub-command fails with the server's `404 NOT_FOUND "Not found."`.
835
+ - `naro environments` (also `list`, `ls`) prints
836
+ `slug url branch protection` and one row per environment (`—` when no
837
+ branch deploys there, protection `on` or `off`), then
838
+ `2 of 3 environments`, or `2 environments` (`1 environment`) on a plan
839
+ with no limit. With none it prints
840
+ ``No environments. Create one with `naro environments create qa`.``
841
+ first. `--json` prints `{ projectId, environments, limit }`.
842
+ - `naro environments create qa [--branch qa] [--copy-env preview|production|none] [--database schema|empty]`
843
+ prints `✅ Created environment qa → https://<subdomain>--qa.naro.sh`. A
844
+ flag left out leaves the server's default: no branch, the preview's
845
+ variables, the database seeded with the schema. `--copy-env none` copies
846
+ nothing. Other values fail before any request with
847
+ `--copy-env must be preview, production or none.` and
848
+ `--database must be schema or empty.`
849
+ - `naro environments set qa [--branch <b> | --no-branch] [--protection on|off]`
850
+ prints `✅ Updated environment qa`. Before any request it refuses
851
+ `--branch and --no-branch cannot be used together.`,
852
+ `--protection must be on or off.` and
853
+ `Nothing to change: pass --branch, --no-branch or --protection.`
854
+ `--protection off` asks
855
+ `Turn off protection for qa? Anyone with the link can open it.` first,
856
+ like `naro protection disable`; with `--json` or without a terminal it
857
+ needs `--yes` (`CONFIRMATION_REQUIRED`).
858
+ - `naro environments delete qa` asks
859
+ `Delete environment qa? Its worker and protection key are removed.`,
860
+ then prints `✅ Deleted environment qa` (`--json`:
861
+ `{ projectId, slug, deleted: true }`).
862
+ - A slug the project does not have fails `ENVIRONMENT_NOT_FOUND`
863
+ `Environment not found.` and changes nothing. The server's refusals
864
+ come through with their code and message, such as `ENVIRONMENT_EXISTS`
865
+ `An environment with this name already exists.` and
866
+ `ENVIRONMENT_BRANCH_TAKEN`
867
+ `Another environment already deploys this branch.`
868
+ - New options `--no-branch`, `--copy-env <source>`, `--database <seed>`
869
+ and `--protection <on|off>`. `--branch <b>` is in `naro help` now, and
870
+ says what it does: for `naro environments create` and `set`, the branch
871
+ whose pushes deploy to that environment; for `naro deploy`, the default
872
+ branch of a project the deploy creates or updates. A deploy's own branch
873
+ follows where it goes.
874
+ - `naro deploy --env qa` deploys to a named environment instead of the
875
+ preview. It prints `✅ Deployment ready (qa)`, and `--json` has
876
+ `"target": "qa"` and `"environment": "qa"` (`null` for production and
877
+ preview). When the server gives no URL the CLI builds
878
+ `https://<subdomain>--qa.<host>`. `--env production` is `--prod` (and asks
879
+ `Deploy to production?` in a terminal the same way); `--env preview` is a
880
+ plain deploy. `--env` with `--prod` fails before anything is asked or sent:
881
+ `VALIDATION_FAILED` `--env and --prod cannot be used together.`, and
882
+ `--env ""` with `--env must be production, preview or an environment name.`
883
+ In a linked directory the environment is looked up before a missing key is
884
+ read, asked for or sent, and nothing is asked, sent or built when that
885
+ fails: a name the project has no environment for fails
886
+ `ENVIRONMENT_NOT_FOUND` `Environment not found.`, and while the control
887
+ plane has named environments switched off the deploy fails with their
888
+ `404 NOT_FOUND "Not found."`. Not yet linked, an environment deploy asks
889
+ for no missing value and sends none (the hint names the environment), and
890
+ the server answers `404 ENVIRONMENT_NOT_FOUND "Environment not found."`
891
+ for a name the project does not have.
892
+ - Release order: deploy web with named environments 1b-2 before relying on
893
+ `naro deploy --env`. The deploy route of an older control plane ignores
894
+ the name and deploys a preview (the result says `(preview)`), saving the
895
+ values sent with it for `all`, which production builds read. In a linked
896
+ directory the environments route's 404 stops the deploy before that, and
897
+ an unlinked one sends no values.
898
+ - `deployDirectory`, the library export the MCP server uses, refuses
899
+ `environment: "production"` and `environment: "preview"` (without
900
+ `production: true`) with `VALIDATION_FAILED`
901
+ `Pass production: true for production; preview is the default.` With
902
+ `production: true` the control plane answers
903
+ `environment and production cannot be used together.`
904
+ - `naro deploy` counts the env vars a deploy is missing from the values that
905
+ deploy gets. A production deploy now lists a key set only for preview as
906
+ missing, and a preview deploy one set only for production; an environment
907
+ deploy counts the `all` values and that environment's own. On an
908
+ environment deploy, the values typed at the env prompt are saved for that
909
+ environment alone, so a developer, who cannot change `all`, has them saved
910
+ instead of listed under `⚠ skipped env:`. Production and preview deploys
911
+ still save them for `all`. The hint names the environment too:
912
+ `npx naro-cli env add DATABASE_URL qa`.
913
+ - `naro env add` and `naro env remove` take an environment's slug as the
914
+ target: `naro env add DATABASE_URL qa`. A target that is none of
915
+ `production`, `preview`, `all` or a slug fails with
916
+ `Target must be production, preview, all or an environment name.` (it was
917
+ `Environment must be production, preview or all.`), and the usage reads
918
+ `Usage: naro env add KEY [production|preview|all|<environment>]`.
919
+ `naro env list` shows an environment's value under its slug.
920
+ - `naro env remove KEY` with no target removes the `production`, `preview`
921
+ and `all` values and leaves every environment's alone; remove one with
922
+ `naro env remove KEY qa` (`Remove KEY (qa) from this project?`). A key
923
+ that only environments hold fails `ENV_NOT_FOUND` `No KEY variable found.`
924
+ and nothing is removed.
925
+ - `naro env pull --env qa` writes an environment's values. A surface's own
926
+ value now wins over the `all` one whatever order the server lists them in
927
+ (before, the last row won), and preview's values never reach an
928
+ environment, as in the deploy. An environment the project does not have
929
+ fails `ENVIRONMENT_NOT_FOUND` `Environment not found.` before anything is
930
+ written. `--env` takes `production`, `preview` or a slug; anything else,
931
+ `""` included, fails with
932
+ `--env must be production, preview or an environment name.` (it was
933
+ `--env must be production or preview.`, and `--env ""` pulled preview).
934
+ The count in `✅ Pulled N variable(s)` and `--json` is the keys written,
935
+ so a key held by `all` and the surface counts once.
936
+ - `naro env import <file> [target]` uploads every variable in a dotenv file
937
+ to one target, `all` by default. It lists the keys on stdout (stderr with
938
+ `--json`), every value masked but a `NEXT_PUBLIC_` one: the others,
939
+ `VITE_`, `REACT_APP_` and `PUBLIC_` included, are uploaded as secrets. It
940
+ asks `Upload 3 variables to qa?` (`1 variable`; `--yes` in CI),
941
+ and prints `✅ Imported 3 variables (qa)` (`--json`:
942
+ `{ projectId, file, target, count }`). Before any request it fails with
943
+ `Cannot read <file>.`, `No variables found in <file>.`,
944
+ `Invalid keys in <file>: A-B, 1X.` or
945
+ `Values over 5 KB in <file>: BIG.` (5,120 UTF-8 bytes, the limit the
946
+ server keeps). It uploads 100 variables per request, so a refusal of a
947
+ later request leaves the earlier ones saved. A line `export KEY=value`
948
+ reads as `KEY`. Values with `\"` or `\\` inside double quotes are read as
949
+ written, not unescaped, so a file `naro env pull` wrote with such a value
950
+ does not import back as it was (known-issues #224).
951
+ - `naro env add` with a value typed at the prompt no longer loses it to a
952
+ refusal. It reads the project first, so a `--project` of another team or
953
+ of a deleted project fails `404 NOT_FOUND "Project not found."` before the
954
+ value is asked for. For an environment target it looks the environment up
955
+ too: a slug the project does not have fails `ENVIRONMENT_NOT_FOUND`
956
+ `Environment not found.` before the value is asked for, and while
957
+ environments are switched off `404 NOT_FOUND "Not found."` does. When the
958
+ role cannot write `all` (the default, or typed out), it asks
959
+ `You do not have permission to change production environment variables on this project. Save KEY for preview only?`
960
+ and on yes saves the same value for preview (`✅ Added KEY (preview, secret)`).
961
+ A named `production`, `preview` or environment target is not offered
962
+ another. A piped value works as before.
963
+ - `naro usage` names a project that has moved to another team
964
+ `Moved to another team <id>`. Before, it read `Deleted project <id>`.
965
+ - `naro db reset` reads the migration files the way the control plane now
966
+ runs them: `ALTER TABLE a RENAME TO b` moves `a`'s policies to `b`
967
+ (known-issues #87), so a policy a renamed table took along is no longer
968
+ listed as gone after the reset. A file that creates one of them again on
969
+ `b`, as the old advice said, would now stop the re-apply, and is named
970
+ before the schema is dropped:
971
+ `⚠ <file> would be refused: statement <n> of <m> failed and the migration was rolled back: policy "<name>" for table "b" already exists`.
972
+ - `naro db table rename` moves the table's Data API policies to the new name
973
+ and rewrites the policies of other tables that read it, in the same
974
+ migration, as `naro db push` does (known-issues #87): the command prints
975
+ `⚠ Moved 1 Data API policy with posts to articles: own.` and
976
+ `⚠ Rewrote 1 policy that read posts to read articles: docs.team.`. A rename
977
+ a policy cannot follow is refused before anything runs. Before, the
978
+ policies stayed under the old name and the table was closed. Renaming the
979
+ table back brings them back.
980
+ - `naro db table create`, `drop` and `rename` no longer print policies
981
+ "removed before the change ran" when the change fails: a change that fails
982
+ changes no policy now.
983
+ - On a backend from before named policies, creating, dropping or renaming a
984
+ table answers `409 BACKEND_OUTDATED` until `naro backend enable` runs —
985
+ through `naro db table`, `naro db push` and `naro db query` alike.
986
+
811
987
  ### 0.18.0
812
988
 
813
989
  - `naro usage` shows a team's usage for a UTC month from the terminal:
@@ -866,8 +1042,9 @@ An `--update-check` you give replaces the default: without
866
1042
  `buildCode`, the code the dashboard shows. It is a deployment error code,
867
1043
  such as `NEXT_VERSION_UNSUPPORTED`, `INSTALL_FAILED`, `BUILD_FAILED`,
868
1044
  `ARTIFACT_INVALID` (static output a deploy cannot take, like a symbolic
869
- link), `FRAMEWORK_DETECTION_FAILED`, or `NO_DEPLOYMENT_STRATEGY` when every
870
- deployment strategy of a Next.js app failed. Before, the stage's code was
1045
+ link), `FRAMEWORK_DETECTION_FAILED`, or `NO_DEPLOYMENT_STRATEGY` when a
1046
+ Next.js app's own build did not fail but no deployment strategy could ship
1047
+ it (its own `next build` failing is `BUILD_FAILED`). Before, the stage's code was
871
1048
  only in the message. A failed upload still fails with its own error and no
872
1049
  `buildCode`; the dashboard shows its deployment code, or `DEPLOY_FAILED`.
873
1050
  - `naro storage ls naro://<bucket>[/<prefix>] --search <text>` lists only the
@@ -1186,12 +1363,13 @@ Next.js), `INSTALL_FAILED` (the dependency install), `ARTIFACT_INVALID` (static
1186
1363
  output a deploy cannot take, like a symbolic link), `FRAMEWORK_DETECTION_FAILED`
1187
1364
  (no framework found, or an Angular app without an output path) and
1188
1365
  `BUILD_FAILED` (the app's own build, or a failure that carried no code). A
1189
- Next.js app is built by trying deployment strategies in turn, so when
1190
- every one fails — the app's own build error included — `buildCode` is
1191
- `NO_DEPLOYMENT_STRATEGY` and the message says what each strategy failed at.
1366
+ Next.js app is built by trying deployment strategies in turn: when the app's
1367
+ own `next build` fails, `buildCode` is `BUILD_FAILED`; when its own build did
1368
+ not fail but no strategy can ship it, `NO_DEPLOYMENT_STRATEGY`. Either way the message says
1369
+ what each strategy failed at.
1192
1370
 
1193
1371
  `--yes` (or `-y`) suppresses every prompt — destructive actions
1194
- (production rollback/promote, env/domain removal, database reset, backend key
1372
+ (production rollback/promote, env/domain/environment removal, `naro env import`, turning off an environment's protection, database reset, backend key
1195
1373
  rotation, policy removal and drop, opening the preview with
1196
1374
  `naro protection disable`, replacing or removing the bypass secret) run
1197
1375
  unconfirmed, so use it deliberately in
@@ -1215,9 +1393,11 @@ credentials live in `~/.naro/credentials.json` (0600).
1215
1393
 
1216
1394
  - Values are entered via hidden prompt or stdin — never as an argument:
1217
1395
  `echo "$DATABASE_URL" | naro env add DATABASE_URL production --yes`
1218
- - Targets: `production`, `preview`, `all` (default).
1396
+ - Targets: `production`, `preview`, `all` (default), or a named
1397
+ environment's slug: `naro env add DATABASE_URL qa`.
1219
1398
  - `naro env pull` writes `.env.local` (preview + all vars by default,
1220
- `--env production` for production values).
1399
+ `--env production` for production values, `--env <name>` for an
1400
+ environment's).
1221
1401
 
1222
1402
  ## Configuration
1223
1403