Skip to content

fix(init): skip API key prompt when credentials already exist#234

Open
Tasfia-17 wants to merge 1 commit into
TestSprite:mainfrom
Tasfia-17:fix/setup-skip-if-configured
Open

fix(init): skip API key prompt when credentials already exist#234
Tasfia-17 wants to merge 1 commit into
TestSprite:mainfrom
Tasfia-17:fix/setup-skip-if-configured

Conversation

@Tasfia-17

@Tasfia-17 Tasfia-17 commented Jul 10, 2026

Copy link
Copy Markdown

Summary

Running testsprite setup always re-prompts for the API key even when
credentials are already saved in ~/.testsprite/credentials. This makes
re-running setup (a common pattern for refreshing the agent skill in
dotfiles and CI bootstraps) unnecessarily disruptive.

This PR adds --skip-if-configured to testsprite setup (and the
deprecated init alias). When the active profile already has a saved
API key and no explicit key source (--api-key or --from-env) is
given, the interactive prompt is skipped and the existing key is reused.

Changes

  • src/commands/auth.ts -- Added skipIfConfigured to ConfigureOptions. runConfigure short-circuits with status: already_configured before prompting when the flag is set and a saved key exists.
  • src/commands/init.ts -- Added --skip-if-configured flag to addSetupOptions. runInit computes skipWillApply and relaxes the non-interactive guard and the --output json guard when skip applies. Cleared when --api-key is explicitly given so explicit keys always overwrite.
  • src/commands/auth.test.ts -- 4 new test cases.
  • src/commands/init.test.ts -- 4 new test cases.
  • test/__snapshots__/help.snapshot.test.ts.snap -- Updated snapshot.

Behaviour

  • Re-running testsprite setup with a valid saved profile skips the key prompt.
  • --skip-if-configured with isTTY=false works in CI without exit 5.
  • --api-key always overwrites regardless of the flag.
  • --from-env always overwrites regardless of the flag.
  • --dry-run is unaffected (no network, no writes).
  • --output json works without the prompt-corruption guard firing.

Tests

All 1868 tests pass. Coverage stays above 80%.

Closes #206

Summary by CodeRabbit

  • New Features

    • Added a --skip-if-configured option to setup and initialization commands.
    • Existing saved credentials can now be reused without prompting or network validation.
    • Non-interactive and JSON modes can complete successfully when credentials are already configured.
    • Explicit API keys and environment-provided keys continue to override saved credentials.
  • Bug Fixes

    • Prevented unnecessary failures in non-interactive setup when valid saved credentials are available.

Add --skip-if-configured to testsprite setup (and the deprecated init
alias). When the active profile already has a saved API key and no
explicit key source (--api-key or --from-env) is given, the interactive
prompt is skipped and the existing key is reused.

Motivation: re-running setup to refresh the agent skill -- a common
pattern in dotfiles, onboarding scripts, and CI bootstraps -- currently
always re-prompts for the key, even when credentials were already
configured. The flag makes setup idempotent for the credential step.

Behaviour:
- runConfigure short-circuits with status:already_configured when
  skipIfConfigured is true and existingProfile.apiKey is present.
- runInit relaxes the non-interactive guard and the --output json guard
  when skipWillApply is true, so the flag works in CI (isTTY=false)
  and JSON mode without requiring a separate --api-key.
- --api-key always overwrites, regardless of --skip-if-configured.
- --from-env always overwrites, regardless of --skip-if-configured.
- --dry-run is unaffected (no network, no writes; preview only).

New tests (8 cases across auth.test.ts and init.test.ts):
- skips prompt and returns early when credentials exist (text + JSON)
- proceeds to prompt when no credentials exist
- allows isTTY=false CI runs when skip applies
- --api-key overwrites despite skip flag
- --from-env overwrites despite skip flag

Closes TestSprite#206
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Adds a skipIfConfigured option to runConfigure and runInit that skips the interactive API key prompt and network validation when a saved profile already has an API key. Wires a new --skip-if-configured CLI flag through init/setup, adjusts non-interactive and JSON guards and dry-run labeling, and adds tests.

Changes

skipIfConfigured behavior

Layer / File(s) Summary
runConfigure early-return on existing credentials
src/commands/auth.ts, src/commands/auth.test.ts
ConfigureOptions gains skipIfConfigured; when set and a saved API key exists, runConfigure returns an already_configured result before prompting or validating against GET /me. Tests cover text/JSON output, no-existing-credentials fallback, and --from-env overriding the skip.
runInit guards, CLI flag, and configure wiring
src/commands/init.ts, src/commands/init.test.ts
InitOptions/SetupCmdOpts gain skipIfConfigured; non-interactive exit-code-5 guard and --output json guard now allow proceeding when a saved key exists and the flag applies; dry-run reports skip-if-configured as the key source; runConfigure is called with skipIfConfigured forwarded unless --api-key is explicit; a --skip-if-configured Commander option is registered and propagated through buildSetupOptions. Tests cover reuse, fallback prompting, non-interactive success, and --api-key precedence.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CLI as init/setup CLI
  participant runInit
  participant runConfigure
  participant Credentials

  User->>CLI: testsprite setup --skip-if-configured
  CLI->>runInit: invoke with skipIfConfigured
  runInit->>Credentials: read saved apiKey
  alt saved key exists
    runInit->>runConfigure: call with skipIfConfigured=true
    runConfigure->>Credentials: readProfile
    runConfigure-->>runInit: already_configured (no prompt, no network call)
  else no saved key
    runInit->>runConfigure: call with skipIfConfigured=false
    runConfigure->>runConfigure: prompt user, validate via GET /me
    runConfigure->>Credentials: writeProfile
    runConfigure-->>runInit: success
  end
  runInit-->>CLI: summary output
Loading

Possibly related PRs

Suggested reviewers: ruili-testsprite, zeshi-du

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR adds skip-if-configured, but it does not implement the requested interactive keep/update/cancel flow or validate existing keys before skipping. Add the repeat-setup summary and keep/update/cancel choices, and ensure saved keys are validated so invalid or expired credentials still prompt.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly states the main behavior change: skipping the API key prompt when credentials already exist.
Out of Scope Changes check ✅ Passed The changes stay focused on setup/auth credential reuse, CLI wiring, and tests, with no obvious unrelated additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/commands/init.ts`:
- Around line 526-530: Document the new --skip-if-configured flag in
DOCUMENTATION.md, following the existing --from-env option patterns. Describe
profile resolution, skipping credential prompts only when credentials already
exist, behavior with --yes and JSON output for scriptable use, and the
conditions under which exit code 5 still applies.
- Around line 239-245: The key-source preview logic in the init command
incorrectly treats skipIfConfigured as unconditional. Update the expression near
opts.apiKey/opts.fromEnv/opts.skipIfConfigured so that this case describes the
conditional behavior—use saved credentials if available, otherwise
prompt—instead of reporting skip-if-configured as the selected source.
- Around line 207-214: Move the `savedKey` lookup using `readProfile()` behind
the non-dry-run guard, and only perform it when `opts.skipIfConfigured` is
enabled and needed for `skipWillApply`; ensure `--dry-run` does not read
credentials before its preview branch or trigger credential read errors.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8fd9e19b-bf09-4b61-bb9c-b09828249da7

📥 Commits

Reviewing files that changed from the base of the PR and between 60d55e4 and 9ce0f2a.

⛔ Files ignored due to path filters (1)
  • test/__snapshots__/help.snapshot.test.ts.snap is excluded by !**/*.snap, !**/*.snap
📒 Files selected for processing (4)
  • src/commands/auth.test.ts
  • src/commands/auth.ts
  • src/commands/init.test.ts
  • src/commands/init.ts

Comment thread src/commands/init.ts
Comment on lines +207 to +214
const credentialsPath = deps.credentialsPath;
const savedKey = credentialsPath
? readProfile(opts.profile, { path: credentialsPath })?.apiKey
: readProfile(opts.profile)?.apiKey;
const skipWillApply = Boolean(opts.skipIfConfigured) && Boolean(savedKey) && !hasKeySource;
// Non-interactive guard: no TTY + no key source → exit 5. Skipped under
// --dry-run, which is documented to work without credentials or network.
if (!isTTY && !hasKeySource && !opts.dryRun) {
if (!isTTY && !hasKeySource && !skipWillApply && !opts.dryRun) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the target file and inspect surrounding context.
git ls-files src/commands/init.ts
wc -l src/commands/init.ts
sed -n '160,260p' src/commands/init.ts

# Find definitions/usages for readProfile, dry-run handling, and skip-if-configured.
rg -n "function readProfile|const readProfile|readProfile\(" src -S
rg -n "dryRun|skipIfConfigured|resolveReportedEndpoint|credentialsPath" src/commands/init.ts src -S

Repository: TestSprite/testsprite-cli

Length of output: 50382


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect readProfile implementation and its error behavior.
sed -n '1,260p' src/lib/credentials.ts

# Show the init dry-run block with a bit more context around the early credential read.
sed -n '200,290p' src/commands/init.ts

Repository: TestSprite/testsprite-cli

Length of output: 10442


Avoid reading credentials before the dry-run branch.
readProfile() can throw on unreadable credentials, so this eager lookup can make --dry-run fail before emitting its preview. Resolve savedKey only when !opts.dryRun and --skip-if-configured needs it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/commands/init.ts` around lines 207 - 214, Move the `savedKey` lookup
using `readProfile()` behind the non-dry-run guard, and only perform it when
`opts.skipIfConfigured` is enabled and needed for `skipWillApply`; ensure
`--dry-run` does not read credentials before its preview branch or trigger
credential read errors.

Comment thread src/commands/init.ts
Comment on lines +239 to +245
opts.apiKey
? 'flag'
: opts.fromEnv
? 'env'
: opts.skipIfConfigured
? 'skip-if-configured'
: 'prompt'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make the dry-run key-source preview conditional.

With --skip-if-configured but no saved key, this reports skip-if-configured, while a real run will prompt. Describe it as conditional (for example, “saved credentials if available; otherwise prompt”) rather than as the selected source.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/commands/init.ts` around lines 239 - 245, The key-source preview logic in
the init command incorrectly treats skipIfConfigured as unconditional. Update
the expression near opts.apiKey/opts.fromEnv/opts.skipIfConfigured so that this
case describes the conditional behavior—use saved credentials if available,
otherwise prompt—instead of reporting skip-if-configured as the selected source.

Comment thread src/commands/init.ts
Comment on lines +526 to +530
.option('-y, --yes', 'Non-interactive: accept all defaults, never prompt')
.option(
'--skip-if-configured',
'Skip the API key prompt when credentials already exist for this profile (CI-safe idempotent re-run)',
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Document the new public flag before release.

Update DOCUMENTATION.md with --skip-if-configured behavior, including profile resolution, non-interactive/JSON output, and when exit code 5 still applies. As per path instructions, this flag should follow the existing --from-env documentation patterns and document its JSON/scriptable behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/commands/init.ts` around lines 526 - 530, Document the new
--skip-if-configured flag in DOCUMENTATION.md, following the existing --from-env
option patterns. Describe profile resolution, skipping credential prompts only
when credentials already exist, behavior with --yes and JSON output for
scriptable use, and the conditions under which exit code 5 still applies.

Source: Path instructions

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.

[Hackathon] setup should not re-prompt for API key when credentials already exist

1 participant