fix(cli): support unattended mode in dataset lifecycle commands#1497
Conversation
📦 Bundle Stats —
|
| Metric | Value | vs main (3ff6c1f) |
|---|---|---|
| Internal (raw) | 2.2 KB | - |
| Internal (gzip) | 838 B | - |
| Bundled (raw) | 11.20 MB | - |
| Bundled (gzip) | 2.11 MB | - |
| Import time | 874ms | +7ms, +0.8% |
bin:sanity
| Metric | Value | vs main (3ff6c1f) |
|---|---|---|
| Internal (raw) | 782 B | - |
| Internal (gzip) | 423 B | - |
| Bundled (raw) | 9.90 MB | - |
| Bundled (gzip) | 1.78 MB | - |
| Import time | 2.27s | +11ms, +0.5% |
🗺️ View treemap · Artifacts
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
📦 Bundle Stats — @sanity/cli-core
Compared against main (3ff6c1f8)
| Metric | Value | vs main (3ff6c1f) |
|---|---|---|
| Internal (raw) | 113.4 KB | - |
| Internal (gzip) | 29.0 KB | - |
| Bundled (raw) | 21.76 MB | - |
| Bundled (gzip) | 3.46 MB | - |
| Import time | 771ms | -8ms, -1.1% |
🗺️ View treemap · Artifacts
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
📦 Bundle Stats — @sanity/cli-build
Compared against main (3ff6c1f8)
@sanity/cli-build/_internal/build
| Metric | Value | vs main (3ff6c1f) |
|---|---|---|
| Internal (raw) | 113.8 KB | - |
| Internal (gzip) | 28.7 KB | - |
| Bundled (raw) | 18.10 MB | - |
| Bundled (gzip) | 3.64 MB | - |
| Import time | 1.35s | -11ms, -0.8% |
@sanity/cli-build/_internal/env
| Metric | Value | vs main (3ff6c1f) |
|---|---|---|
| Internal (raw) | 1.8 KB | - |
| Internal (gzip) | 644 B | - |
| Bundled (raw) | 1.31 MB | - |
| Bundled (gzip) | 333.8 KB | - |
| Import time | 123ms | +2ms, +1.7% |
@sanity/cli-build/_internal/extract
| Metric | Value | vs main (3ff6c1f) |
|---|---|---|
| Internal (raw) | 8.6 KB | - |
| Internal (gzip) | 2.7 KB | - |
| Bundled (raw) | 155.0 KB | - |
| Bundled (gzip) | 39.5 KB | - |
| Import time | 244ms | +1ms, +0.5% |
🗺️ ./_internal/env · ./_internal/extract · @sanity/cli-build:./_internal/build treemap too large to embed · Artifacts
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
📦 Bundle Stats — create-sanity
Compared against main (3ff6c1f8)
| Metric | Value | vs main (3ff6c1f) |
|---|---|---|
| Internal (raw) | 908 B | - |
| Internal (gzip) | 483 B | - |
| Bundled (raw) | 931 B | - |
| Bundled (gzip) | 491 B | - |
| Import time | ❌ ChildProcess denied: node | - |
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
Coverage Delta
Comparing 9 changed files against main @ Overall Coverage
|
a2af7d3 to
36b238c
Compare
7bc11e6 to
46a157c
Compare
36b238c to
80deb7f
Compare
| // If the file already exists, ask for confirmation if it should be overwritten. | ||
| if (!this.flags.overwrite && exists) { | ||
| if (this.isUnattended()) { | ||
| this.error(`File "${out}" already exists. Pass --overwrite to replace it.`, {exit: 2}) |
There was a problem hiding this comment.
should we include messaging about this being a destructive action? it's implicit, but it would possibly help the agent pause and surface the action to a human or supervising agent before pressing ahead
There was a problem hiding this comment.
IMO no, the error message already communicates that it's replacing the file. it's a local only change too which makes me less scared of misuse
shapirodaniel
left a comment
There was a problem hiding this comment.
a few non-blocking questions/suggestions, otherwise looks great
80deb7f to
f46b2c4
Compare
664fbf9 to
3cdb32e
Compare
f46b2c4 to
ee15a3b
Compare
3cdb32e to
8e4076f
Compare
171ff2d to
bf094ea
Compare
Signed-off-by: Jonah Snider <jonah@jonahsnider.com>
bf094ea to
b4cdfd5
Compare
Description
Adds unattended-mode support for dataset lifecycle commands.
What to review
Review the flags, prompt handling, and automated coverage.
Testing
Note
Medium Risk
Touches destructive flows (delete, copy, export/import) and backup download overwrite behavior; unattended mode makes misuse easier in automation but adds explicit guards and
--forcefor delete.Overview
Adds unattended (non-interactive) behavior across dataset and backup CLI commands so CI/scripts can run without prompts.
When
isUnattended()is true, commands fail fast withUSAGE_ERROR(and clearer messages) instead of callingselect/input/confirm—e.g. required<dataset>,--backup-id,--dataset, source/target for copy, dataset name for create, and--forcefor delete. Export and backup download pick deterministic default output paths undercwdwhen--outis omitted; existing output files require--overwriterather than a confirm prompt. Interactive cancel on backup overwrite now usesUSER_ABORT.Validation and usage mistakes increasingly exit with
exitCodes.USAGE_ERRORinstead of genericexit: 1. Delete refreshes the type-to-confirm prompt copy; user cancel during confirm no longer forces exit code 1.Tests are extended with
isInteractive: false/isUnattendedmocks for the new paths.Reviewed by Cursor Bugbot for commit b4cdfd5. Bugbot is set up for automated code reviews on this repo. Configure here.