Skip to content

feat(cli): default --wait in non-interactive mode, slim init --help#11

Open
caffeinum wants to merge 3 commits into
fix/organisations-listfrom
feat/auto-wait-slim-help
Open

feat(cli): default --wait in non-interactive mode, slim init --help#11
caffeinum wants to merge 3 commits into
fix/organisations-listfrom
feat/auto-wait-slim-help

Conversation

@caffeinum
Copy link
Copy Markdown

Description

Based on analysis of eval trace sanity-22a3b1e3, two small AX improvements that cut wall-clock time and token cost without new commands.

Stacked on fix/organisations-list — depends on the --wait flag added there.

Changes

1. --wait defaults to true in non-interactive mode

The flag exists (added in #10) but agents have to discover it from --help and then opt in. The trace shows the agent wrote sleep 15 && sanity auth status instead of using --wait, costing ~22 seconds of idle time.

  • Flags.boolean({allowNo: true}) (no static default)
  • Command resolves: effectiveWait = typeof flags.wait === 'boolean' ? flags.wait : !isInteractive() && !withToken
  • TTY users: same as before
  • Non-TTY users (CI, agents): get blocking behavior automatically
  • --no-wait explicitly opts out
  • --with-token doesn't trigger wait (token from stdin)

2. Slim sanity init --help

The 80-line flag dump in the trace cost tokens and didn't even surface --organization until the agent hit an error.

  • Description now includes a "Common usage (unattended)" block with 3 typical incantations
  • Hidden flags: coupon, project-plan, mcp, import-dataset, overwrite-files
  • Visible flag count drops from ~24 to ~19

What to review

  • packages/@sanity/cli/src/commands/login.tseffectiveWait resolution
  • packages/@sanity/cli/src/commands/init.ts — description block + hidden flags
  • packages/@sanity/cli/src/commands/__tests__/login.test.ts — two non-interactive tests now pass --no-wait to keep their original assertions valid

Testing

  • 154 tests pass on the affected packages
  • Build clean
  • No new tests added (the new default path is exercised through the existing --wait mocking infra; could add an explicit positive test later)

🤖 Generated with Claude Code

Based on eval trace sanity-22a3b1e3 analysis:

- Make `--wait` default to true when stdout is not a TTY (CI, agents),
  unless --with-token is used. Pass --no-wait to opt out. Agents no
  longer have to discover the flag and guess `sleep 15` cycles.

- Slim `sanity init --help` by hiding niche flags (coupon, project-plan,
  mcp, import-dataset, overwrite-files) and adding a "Common usage"
  block to the command description. Surfaces the typical workflow
  before the full flag list.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@claude
Copy link
Copy Markdown

claude Bot commented May 29, 2026

Claude encountered an error —— View job


I'll analyze this and get back to you.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 29, 2026

📦 Bundle Stats — @sanity/cli

Compared against fix/organisations-list (2d656d71)

@sanity/cli

Metric Value vs fix/organisations-list (2d656d7)
Internal (raw) 2.1 KB -
Internal (gzip) 799 B -
Bundled (raw) 10.97 MB -
Bundled (gzip) 2.06 MB -
Import time 832ms +0ms, +0.0%

bin:sanity

Metric Value vs fix/organisations-list (2d656d7)
Internal (raw) 1023 B -
Internal (gzip) 486 B -
Bundled (raw) 9.84 MB -
Bundled (gzip) 1.77 MB -
Import time 935ms -4ms, -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 fix/organisations-list (2d656d71)

Metric Value vs fix/organisations-list (2d656d7)
Internal (raw) 96.5 KB -
Internal (gzip) 22.7 KB -
Bundled (raw) 21.61 MB -
Bundled (gzip) 3.42 MB -
Import time 796ms +1ms, +0.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 — create-sanity

Compared against fix/organisations-list (2d656d71)

Metric Value vs fix/organisations-list (2d656d7)
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.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a241b0466b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +89 to +90
const effectiveWait =
typeof flags.wait === 'boolean' ? flags.wait : !isInteractive() && !withToken
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Refresh the token cache before default waiting

When non-interactive sanity login is run without --wait/--no-wait and the config already contains an invalid or expired authToken, this new default enters the wait loop after login() has already called getCliToken(), seeding the parent process token cache with the stale token. The background child writes the new token in a separate process, so it cannot clear the parent's cache; subsequent validateSession() calls keep checking the old token and the command times out after 5 minutes even though OAuth completed. Clear the CLI token cache or read the config fresh before/during the wait loop.

Useful? React with 👍 / 👎.

@caffeinum caffeinum added the trigger: preview Publishes a preview build via pkg.pr.new + runs 2027 eval label May 30, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 30, 2026

Preview this PR with pkg.pr.new

Run the Sanity CLI

npx https://pkg.pr.new/team2027/sanity-cli/@sanity/cli@da272cd <command>

...Or upgrade project dependencies

📦 @sanity/cli
pnpm install https://pkg.pr.new/@sanity/cli@da272cd
📦 @sanity/cli-build
pnpm install https://pkg.pr.new/@sanity/cli-build@da272cd
📦 @sanity/cli-core
pnpm install https://pkg.pr.new/@sanity/cli-core@da272cd
📦 @sanity/cli-test
pnpm install https://pkg.pr.new/@sanity/cli-test@da272cd
📦 @sanity/eslint-config-cli
pnpm install https://pkg.pr.new/@sanity/eslint-config-cli@da272cd

View Commit (da272cd)

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 30, 2026

2027 // Getting Started: Staging CLI — C 63.3/100

+ █████████████░░░░░░░   ▲ +5 pts vs baseline
Time Cost Errors Interruptions
6m 36s ▲ +32s $2.37 ▲ +$0.04 2 ▼ -1 0

Tested: example.com → daytona.io
Vars: cliInstall: npm i -g https://pkg.pr.new/team2027/sanity-cli/@sanity/cli@da272cd

Commit da272cd · View report → · Dashboard

The background login child writes the new token to disk in a separate
process, so it cannot invalidate the parent process's in-memory token
cache. If the parent had an existing (stale/expired) token at startup,
`getCliToken()` returns the cached stale value indefinitely and the wait
loop times out after 5 minutes even though OAuth completed.

Call clearCliTokenCache() before each validateSession() iteration in
both the login --wait loop and the initAction auto-login polling, so
the next call re-reads from disk.

Reported by CodeRabbit on PR #11.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f3a5c2ed80

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// so agents and CI get a deterministic exit code without having to discover
// the flag. Pass `--no-wait` to opt out.
const effectiveWait =
typeof flags.wait === 'boolean' ? flags.wait : !isInteractive() && !withToken
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Don't treat the implicit false as an explicit wait choice

In non-interactive sanity login without --wait/--no-wait, oclif boolean flags still parse as false when omitted (the Flags.boolean implementation documents that booleans default to false unless defaulted true), so typeof flags.wait === 'boolean' is always true and effectiveWait becomes false instead of falling through to !isInteractive() && !withToken. This means the new advertised default never applies for agents/CI unless they still discover and pass --wait, preserving the old immediate-return behavior and making --no-wait indistinguishable from omission.

Useful? React with 👍 / 👎.

… --help

Two small AX wins from eval trace sanity-95d47728:

- `sanity tokens add` now prints a copy-pasteable `SANITY_API_TOKEN=...`
  env line after the token. Agents commonly created a token then wrote
  a seed script with raw `@sanity/client` — the env name nudge skips
  one round of "what should I name this var?".

- `sanity init --help` now includes `cd my-studio && sanity typegen
  generate` as an example. In the eval trace the agent hand-wrote a
  TypeScript interface mirroring the schema; typegen would have
  generated it (and kept it in sync).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

Coverage Delta

File Statements
packages/@sanity/cli-core/src/SanityCommand.ts 84.9% (- 1.1%)
packages/@sanity/cli/scripts/check-topic-aliases.ts 0.0% (±0%)
packages/@sanity/cli/src/actions/auth/backgroundLogin.ts 15.9% (new)
packages/@sanity/cli/src/actions/auth/backgroundLoginChild.ts 0.0% (new)
packages/@sanity/cli/src/actions/auth/login/getProvider.ts 100.0% (±0%)
packages/@sanity/cli/src/actions/auth/login/login.ts 80.0% (- 20.0%)
packages/@sanity/cli/src/actions/auth/login/storeAuthToken.ts 100.0% (new)
packages/@sanity/cli/src/actions/debug/gatherDebugInfo.ts 94.9% (- 1.6%)
packages/@sanity/cli/src/actions/deploy/deployStudioSchemasAndManifests.ts 100.0% (±0%)
packages/@sanity/cli/src/actions/init/initAction.ts 85.5% (- 11.6%)
packages/@sanity/cli/src/actions/init/project/createProjectFromName.ts 100.0% (±0%)
packages/@sanity/cli/src/commands/auth/cancel.ts 100.0% (new)
packages/@sanity/cli/src/commands/auth/status.ts 89.5% (new)
packages/@sanity/cli/src/commands/init.ts 100.0% (±0%)
packages/@sanity/cli/src/commands/login.ts 100.0% (±0%)
packages/@sanity/cli/src/commands/organizations/create.ts 96.3% (new)
packages/@sanity/cli/src/commands/organizations/list.ts 97.0% (new)
packages/@sanity/cli/src/commands/projects/list.ts 97.4% (- 2.6%)
packages/@sanity/cli/src/commands/schemas/deploy.ts 95.0% (±0%)
packages/@sanity/cli/src/commands/tokens/add.ts 100.0% (±0%)
packages/@sanity/cli/src/topicAliases.ts 100.0% (±0%)
packages/@sanity/cli/src/util/formatHint.ts 100.0% (new)
packages/@sanity/cli/src/util/sharedFlags.ts 100.0% (±0%)

Comparing 23 changed files against main @ c645f9ba5b692a1c3bea691dd9b56aaf2032d662

Overall Coverage

Metric Coverage
Statements 83.4% (- 0.9%)
Branches 73.8% (- 0.5%)
Functions 83.4% (- 0.8%)
Lines 83.9% (- 0.9%)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

trigger: preview Publishes a preview build via pkg.pr.new + runs 2027 eval

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant