Skip to content

fix(cli): add non-interactive TTY detection, dockerhub dedup, and clearer errors#126

Merged
mmurrs merged 3 commits into
Layr-Labs:masterfrom
mmurrs:fix/cli-agent-friendly
Apr 16, 2026
Merged

fix(cli): add non-interactive TTY detection, dockerhub dedup, and clearer errors#126
mmurrs merged 3 commits into
Layr-Labs:masterfrom
mmurrs:fix/cli-agent-friendly

Conversation

@mmurrs
Copy link
Copy Markdown
Contributor

@mmurrs mmurrs commented Apr 16, 2026

Summary

Addresses RND-548: make ecloud CLI automation/AI-agent friendly.

  • TTY detection (P0): Add ensureInteractive() guard to all prompt functions — in non-TTY environments (CI, agents), throws clear errors naming the missing flag instead of an opaque ExitPromptError
  • Dockerhub dedup (P1): Add Map-based dedup for dockerhub entries in getAvailableRegistries(), matching existing GCR pattern — Docker Desktop creates 3 identical auth entries for the same account
  • App name lookup error (P1): Error message now explains cache staleness and suggests using app ID directly or running ecloud compute app list
  • Health verification hint (P1): Post-deploy/upgrade output notes that "Running" means container started, not necessarily serving traffic

Out of scope (validated as not-bugs or needing backend work)

  • Upgrade reliability/rollback — requires backend blue-green deployment
  • "Broken hostname filter" — NOT A BUG (extractHostname() strips path correctly)
  • --image-ref bypass — WORKS CORRECTLY (prompt is already bypassed)
  • --name + --skip-profile conflict — NOT A BUG (flags are independent)
  • --name on upgrade — BY DESIGN (upgrade takes existing app-id)

Files changed (3)

  • packages/cli/src/utils/prompts.tsensureInteractive() helper, dockerhub dedup, error message
  • packages/cli/src/commands/compute/app/deploy.ts — post-deploy health note
  • packages/cli/src/commands/compute/app/upgrade.ts — post-upgrade health note

Test plan

  • pnpm typecheck — no new type errors (57 pre-existing)
  • pnpm lint (CLI package) — clean
  • pnpm format — clean
  • Piped stdin test: echo "" | node packages/cli/bin/run.js compute app deploy --environment sepolia → clear non-interactive error
  • Flag-specific errors: --dockerfile without --image-ref → error names --image-ref; --image-ref without --name → error names --name
  • Name lookup: ecloud compute app info nonexistent-name → error suggests ecloud compute app list
  • Manual: verify dockerhub dedup with Docker Desktop multi-auth config

🤖 Generated with Claude Code

mmurrs and others added 3 commits April 16, 2026 11:39
…arer errors

Addresses RND-548: make ecloud CLI automation/AI-agent friendly.

TTY detection (P0):
- Add ensureInteractive() guard to all prompt functions in prompts.ts
- In non-TTY environments (CI, agents), throws clear errors naming the
  missing flag instead of opaque @inquirer/prompts ExitPromptError
- Guard confirmWithDefault() separately — refuses to auto-confirm in
  non-interactive mode for safety

Dockerhub registry dedup (P1):
- Add dockerhubUsers Map in getAvailableRegistries(), matching existing
  GCR dedup pattern — Docker Desktop creates 3 auth entries for the
  same account, now only one appears in the registry selection prompt

Improved app name lookup error (P1):
- Error message now explains the local cache may be stale and suggests
  using the app ID directly or running 'ecloud compute app list'

Post-deploy/upgrade health note (P1):
- Add informational note after deploy/upgrade success clarifying that
  "Running" means container started, not necessarily serving traffic
- Deploy output includes a curl command to verify connectivity

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Allows renaming an app's profile during upgrade via --name flag.
The profile update happens after a successful upgrade, so if the
upgrade fails the name stays unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
setProfile does a full replace, not a merge. Without fetching the
existing profile first, passing only --name would wipe website,
description, and xURL fields. Now fetches current profile via
getInfos and preserves all existing fields.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.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.

3 participants