Skip to content

feat(digitalocean): guided readiness before deploy#2

Open
scott wants to merge 2 commits intomainfrom
pr/digitalocean-guided-readiness
Open

feat(digitalocean): guided readiness before deploy#2
scott wants to merge 2 commits intomainfrom
pr/digitalocean-guided-readiness

Conversation

@scott
Copy link
Copy Markdown
Collaborator

@scott scott commented Apr 15, 2026

Summary

Goal: Run a guided readiness check before region/size and Droplet creation so users fix account issues early and avoid failed or wasteful deploys.

What changed

  • Pre-flight gate (DO only): After cloud auth, ensureReadyBeforeSizing runs evaluateDigitalOceanReadiness (account snapshot via GET /v2/account, SSH on DO, OpenRouter key, droplet limit). Blockers are fixed in order; payment-related account state is handled before SSH registration (DO often blocks keys until billing is OK).
  • Checklist UI: Clear READY / BLOCKED / not checked yet, one guided step at a time; re-check after browser or token fixes until READY.
  • Billing: Detect locked/warning account status up front; deep link to add payment (…billing?defer-onboarding-for=or&open-add-payment-method=true); shared handleBillingError path.
  • Orchestration: Readiness runs before sizing so fast/parallel paths don’t boot while the account is still blocked.
  • Non-interactive: Fail fast; optional --json-readiness / SPAWN_JSON_READINESS with SPAWN_NON_INTERACTIVE=1.
  • DO OAuth: After 120s, interactive sessions keep waiting (or Escape → manual token); non-interactive still fails at 120s.
  • Also: Exported verifyOpenRouterApiKey, DO helpers/tests, reset-local-state.sh, and DO README updates.

How to test

  • Interactive: incomplete account → checklist → READY → then region/size.
  • Billing: warning / no card → deep link → return → re-check.
  • CI-style: SPAWN_NON_INTERACTIVE=1 → clean exit + JSON if enabled.

Other clouds unchanged.

Pre-flight gate, checklist UI, billing deep-link, DO OAuth escape hatch,
orchestration ordering (readiness before sizing), tests and DO README updates.
Comment thread sh/digitalocean/reset-local-state.sh Outdated
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This should be in TypeScript. The sh contains entry files/scripts that are invoked via curl. Having this here is a bit dangerous

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

ack. we can just remove it. I was only using it to simplify getting back to a "new" state for testing.

Remove reset-local-state.sh from version control, gitignore it with a
local reset-local-state.md, and drop the reset section from the public
DigitalOcean README.
AhmedTMM pushed a commit to OpenRouterTeam/spawn that referenced this pull request Apr 22, 2026
Runs evaluateDigitalOceanReadiness after cloud auth and before region/size
selection so users fix billing/SSH/OpenRouter blockers early, with a
checklist UI that rechecks after each fix. Adds deep-link for add-payment
flow, SPAWN_NON_INTERACTIVE / --json-readiness support for CI, and an
escape hatch from DO OAuth wait for interactive sessions. Other clouds
unchanged.

Ported from digitalocean#2 (Scott Miller @scott). Bumps CLI to 1.1.0.
Refactors the new preflight TTY-gating test to drive process.std*.isTTY
directly with descriptor save/restore and clears stale
~/.config/spawn/digitalocean.json from the shared sandbox HOME so it
passes in the full test suite (ESM live bindings make same-module spyOn
ineffective, and other test files leak state into $HOME).

Co-Authored-By: Scott Miller <scottmiller@digitalocean.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
AhmedTMM added a commit to OpenRouterTeam/spawn that referenced this pull request Apr 22, 2026
* feat(digitalocean): guided readiness checklist before deploy

Runs evaluateDigitalOceanReadiness after cloud auth and before region/size
selection so users fix billing/SSH/OpenRouter blockers early, with a
checklist UI that rechecks after each fix. Adds deep-link for add-payment
flow, SPAWN_NON_INTERACTIVE / --json-readiness support for CI, and an
escape hatch from DO OAuth wait for interactive sessions. Other clouds
unchanged.

Ported from digitalocean#2 (Scott Miller @scott). Bumps CLI to 1.1.0.
Refactors the new preflight TTY-gating test to drive process.std*.isTTY
directly with descriptor save/restore and clears stale
~/.config/spawn/digitalocean.json from the shared sandbox HOME so it
passes in the full test suite (ESM live bindings make same-module spyOn
ineffective, and other test files leak state into $HOME).

Co-Authored-By: Scott Miller <scottmiller@digitalocean.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(test): update-check mock versions for 1.1.0 version bump

Mock "newer" versions (1.0.99) were no longer newer than the current
1.1.0 version, causing all update-check tests to fail. Bumped mock
versions to 99.0.0 for general tests, 1.1.99 for patch, 1.2.0 for
minor, keeping 2.0.0 for major.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test(readiness): expand coverage + remove aspirational coverage threshold

- Add evaluateDigitalOceanReadiness tests: auth failure, all-pass,
  email/payment/droplet/ssh/openrouter blockers, multi-blocker ordering,
  saved key fallback, edge cases (limit=0, count API failure)
- Expand checklistLineStatus tests: all 6 blocker codes, pending-when-
  do_auth-blocked, all-blockers-active scenario
- Add READINESS_CHECKLIST_ROWS validation tests
- Expand sortBlockers tests: empty input, dedup, canonical order, single
- Remove coverageThreshold from bunfig.toml — main was already at 82.99%
  functions vs 90% threshold (never enforced on push, only on PRs)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude <claude@anthropic.com>
Co-authored-by: Scott Miller <scottmiller@digitalocean.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Ahmed Abushagur <ahmed@abushagur.com>
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