Skip to content

fix(cli): support unattended mode in dataset lifecycle commands#1497

Merged
jonahsnider merged 8 commits into
mainfrom
aigro-5168/unattended-dataset-lifecycle
Jul 17, 2026
Merged

fix(cli): support unattended mode in dataset lifecycle commands#1497
jonahsnider merged 8 commits into
mainfrom
aigro-5168/unattended-dataset-lifecycle

Conversation

@jonahsnider

@jonahsnider jonahsnider commented Jul 13, 2026

Copy link
Copy Markdown
Member

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 --force for 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 with USAGE_ERROR (and clearer messages) instead of calling select/input/confirm—e.g. required <dataset>, --backup-id, --dataset, source/target for copy, dataset name for create, and --force for delete. Export and backup download pick deterministic default output paths under cwd when --out is omitted; existing output files require --overwrite rather than a confirm prompt. Interactive cancel on backup overwrite now uses USER_ABORT.

Validation and usage mistakes increasingly exit with exitCodes.USAGE_ERROR instead of generic exit: 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 / isUnattended mocks for the new paths.

Reviewed by Cursor Bugbot for commit b4cdfd5. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Stats — @sanity/cli

Compared against main (3ff6c1f8)

@sanity/cli

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.

@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Coverage Delta

File Statements
packages/@sanity/cli/src/commands/backups/disable.ts 91.9% (+ 0.5%)
packages/@sanity/cli/src/commands/backups/download.ts 94.8% (+ 0.6%)
packages/@sanity/cli/src/commands/backups/enable.ts 100.0% (±0%)
packages/@sanity/cli/src/commands/backups/list.ts 96.8% (+ 0.1%)
packages/@sanity/cli/src/commands/datasets/copy.ts 91.4% (+ 0.6%)
packages/@sanity/cli/src/commands/datasets/create.ts 100.0% (±0%)
packages/@sanity/cli/src/commands/datasets/delete.ts 100.0% (+ 5.7%)
packages/@sanity/cli/src/commands/datasets/export.ts 91.8% (- 1.7%)
packages/@sanity/cli/src/commands/datasets/import.ts 87.7% (±0%)

Comparing 9 changed files against main @ 3ff6c1f8670d6155e56afd42a6560f37c9ef4ae5

Overall Coverage

Metric Coverage
Statements 78.0% (+ 0.1%)
Branches 69.5% (+ 0.1%)
Functions 73.7% (+ 0.0%)
Lines 78.5% (+ 0.1%)

@jonahsnider
jonahsnider marked this pull request as ready for review July 15, 2026 21:45
@jonahsnider
jonahsnider requested a review from a team as a code owner July 15, 2026 21:45
@jonahsnider
jonahsnider force-pushed the aigro-5168/unattended-dataset-lifecycle branch from a2af7d3 to 36b238c Compare July 16, 2026 01:58
@jonahsnider
jonahsnider changed the base branch from main to aigro-5168/unattended-admin July 16, 2026 01:58
@jonahsnider
jonahsnider force-pushed the aigro-5168/unattended-admin branch from 7bc11e6 to 46a157c Compare July 16, 2026 02:05
@jonahsnider
jonahsnider force-pushed the aigro-5168/unattended-dataset-lifecycle branch from 36b238c to 80deb7f Compare July 16, 2026 02:05
Comment thread packages/@sanity/cli/src/commands/backups/disable.ts Outdated
// 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})

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread packages/@sanity/cli/src/commands/backups/download.ts Outdated
Comment thread packages/@sanity/cli/src/commands/datasets/delete.ts
Comment thread packages/@sanity/cli/src/commands/datasets/import.ts Outdated
shapirodaniel
shapirodaniel previously approved these changes Jul 16, 2026

@shapirodaniel shapirodaniel left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a few non-blocking questions/suggestions, otherwise looks great

@jonahsnider
jonahsnider force-pushed the aigro-5168/unattended-dataset-lifecycle branch from 80deb7f to f46b2c4 Compare July 17, 2026 00:50
@jonahsnider
jonahsnider force-pushed the aigro-5168/unattended-admin branch 2 times, most recently from 664fbf9 to 3cdb32e Compare July 17, 2026 15:34
@jonahsnider
jonahsnider force-pushed the aigro-5168/unattended-dataset-lifecycle branch from f46b2c4 to ee15a3b Compare July 17, 2026 15:34
@jonahsnider
jonahsnider force-pushed the aigro-5168/unattended-admin branch from 3cdb32e to 8e4076f Compare July 17, 2026 15:54
@jonahsnider
jonahsnider force-pushed the aigro-5168/unattended-dataset-lifecycle branch 2 times, most recently from 171ff2d to bf094ea Compare July 17, 2026 16:02
Base automatically changed from aigro-5168/unattended-admin to main July 17, 2026 17:14
@jonahsnider
jonahsnider dismissed shapirodaniel’s stale review July 17, 2026 17:14

The base branch was changed.

@jonahsnider
jonahsnider force-pushed the aigro-5168/unattended-dataset-lifecycle branch from bf094ea to b4cdfd5 Compare July 17, 2026 17:51
@jonahsnider
jonahsnider enabled auto-merge (squash) July 17, 2026 17:53

@shapirodaniel shapirodaniel left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚢

@jonahsnider
jonahsnider merged commit 1e4332b into main Jul 17, 2026
53 checks passed
@jonahsnider
jonahsnider deleted the aigro-5168/unattended-dataset-lifecycle branch July 17, 2026 20:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants