Skip to content

Conversation

biilmann
Copy link
Member

Summary

This PR significantly improves the Agent Experience (AX) of the netlify deploy command, enabling AI agents and automated tools to successfully deploy new projects without getting stuck in interactive menus.

Problem

Previously, agents using netlify deploy would get stuck when:

  • Deploying to a new directory (requires interactive site creation)
  • Multiple teams available (requires interactive team selection)
  • Missing required directory paths (requires interactive input)

Solution

New Flags

  • --create [name]: Create a new site and deploy in one command
    • Optional site name: --create my-site or just --create for random name
    • Proper command parsing handles both variants correctly
  • --team <slug>: Explicit team selection when creating sites
    • Required when user has multiple teams
    • Auto-uses single team when user only has one team

Intelligent Help Text

  • Context-aware: Shows copy-pasteable commands with current flags included
  • Shown everywhere: Before every interactive prompt that could block automation
  • Smart team handling: Only shows --team flag when multiple teams available

Validation & Error Handling

  • Clear error messages with actionable examples
  • Proper TypeScript types (create?: string | boolean)
  • Smart fallbacks and validation

Agent Success Example

This session with Claude Code demonstrates the improved flow:

User: deploy this to netlify, use ~/netlify/cli/bin/run.js as the cli command

⏺ Claude Code: I'll deploy this project to Netlify using the specified CLI command. Let me first check what's in the current directory and then deploy it.

⏺ List(~/programming/html/demo/w1)
⎿ Listed 4 paths (ctrl+r to expand)

Now I'll deploy the project to Netlify using the specified CLI command:

⏺ Bash(~/netlify/cli/bin/run.js deploy --prod --dir .)
⎿ This folder isn't linked to a project yet

💡 To create and deploy in one go, use: netlify deploy --create <SITE_NAME> --team <TEAM_SLUG> --dir . --prod
… +7 lines (ctrl+r to expand)

I need to create a new project since this directory isn't linked to one yet. Let me create and deploy in one command:

⏺ Bash(~/netlify/cli/bin/run.js deploy --create html-demo-w1 --team matt-bpvtv98 --dir . --prod)
⎿ Creating new site: html-demo-w1

Project Created
… +64 lines (ctrl+r to expand)

Successfully deployed! Your site is now live at:

Production URL: https://html-demo-w1.netlify.app
Admin URL: https://app.netlify.com/projects/html-demo-w1

The deployment includes your index.html and styles.css files and is now accessible on the web.

Key Behaviors

Before (Blocking)

$ netlify deploy --prod --dir . This folder isn't linked to a project yet ? What would you like to do? (Use arrow keys) ❯ Link this directory to an existing project   + Create & configure a new project # Agent gets stuck here

After (Non-blocking)

$ netlify deploy --prod --dir . This folder isn't linked to a project yet  💡 To create and deploy in one go, use: netlify deploy --create <SITE_NAME> --team <TEAM_SLUG> --dir . --prod  You must pick a --team: team1, team2, team3  ? What would you like to do? (Use arrow keys) ❯ Link this directory to an existing project   + Create & configure a new project
# Agent can now use the provided command $ netlify deploy --create my-site --team my-team --dir . --prod Creating new site: my-site ✅ Deploy successful!

Backward Compatibility

  • ✅ All existing interactive flows unchanged
  • ✅ All existing flags work identically
  • ✅ No breaking changes to API or behavior
  • ✅ Enhanced experience for both humans and agents

Test Coverage

  • ✅ Command parsing with optional site names
  • ✅ Team validation (single vs multiple teams)
  • ✅ Help text generation in all scenarios
  • ✅ Error handling with actionable messages
  • ✅ TypeScript type safety

This change enables seamless automated deployments while maintaining the excellent interactive experience for human users.

…interactive support This change dramatically improves the "agent experience" (AX) for AI agents and automated tools using the deploy command: **Key Improvements:** - Added `--create [name]` flag to create and deploy sites in one command - Added `--team <slug>` flag for explicit team selection when creating sites - Intelligent team handling: auto-use single team, require explicit selection for multiple teams - Comprehensive help text with copy-pasteable commands shown at every interactive prompt - Proper command parsing with optional site names (`--create` vs `--create sitename`) **Agent Flow Example:** Before: Agents got stuck in interactive menus when deploying new projects After: Agents can successfully deploy with: `netlify deploy --create my-site --team my-team --dir . --prod` **Interactive Improvements:** - Show copy-pasteable commands before every prompt - Context-aware help text (includes current flags like --prod, --dir, etc.) - Better team selection messaging when multiple teams available - Cleaner help text when only one team available **Validation & Error Handling:** - Proper TypeScript types for new flags (`create?: string | boolean`) - Validation that --team only works with --create - Clear error messages with actionable examples - Smart fallbacks for single vs multiple team scenarios This maintains full backward compatibility while enabling seamless automated deployments. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
@biilmann biilmann requested a review from a team as a code owner August 15, 2025 19:59
Copy link

github-actions bot commented Aug 15, 2025

📊 Benchmark results

Comparing with bd4e641

  • Dependency count: 1,074 (no change)
  • Package size: 297 MB (no change)
  • Number of ts-expect-error directives: 382 (no change)
biilmann and others added 5 commits August 16, 2025 09:09
Removed duplicate command generation logic in prepareProductionDeploy by reusing the shared generateDeployCommand helper function. This improves maintainability and ensures consistent command generation across all scenarios. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
…nstructions - Removed emojis from all help text messages for cleaner CLI output - Fixed locked deployment instructions to use --prod-if-unlocked flag instead of manual unlock - Added proper warning about only using --prod-if-unlocked when absolutely sure - Updated generateDeployCommand to support prodIfUnlocked flag 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
…options Refactored generateDeployCommand to derive available flags from the actual Commander.js command definition instead of maintaining a hardcoded flagMap. This approach: - Eliminates manual flag mapping maintenance - Automatically includes new flags as they're added to the command - Uses command.options to introspect actual option definitions - Handles all option types (string, number, boolean) correctly - Maintains special handling for quoted message values The function now dynamically builds commands from the live command definition, making it more maintainable and less prone to drift. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Removed unnecessary filtering of hidden and deprecated options from generateDeployCommand. If users included these flags in their original command, they should be preserved in the copyable command for consistency. This ensures the generated command exactly matches what the user originally attempted to run. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
The teams command is not needed since the deploy command now properly handles team selection with clear error messages that list available teams when multiple teams are present. This simplifies the codebase while maintaining all necessary functionality for both interactive and non-interactive team selection. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Contributor

@sarahetter sarahetter left a comment

Choose a reason for hiding this comment

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

Also saw in testing that if I run netlify deploy --create <SITE_NAME> --team <TEAM_SLUG> in a directory that already has a linked site in state.json it doesn't create a new site, it deploys to the linked site (and doesn't create a new one). I think having these options set should override the saved state config

biilmann and others added 7 commits August 18, 2025 15:05
Change the --create flag to --create-site in the deploy command to make the flag name more explicit and descriptive. This improves clarity about what the flag does when creating new sites during deployment. Changes: - Rename --create flag to --create-site in command definition - Update all option references from options.create to options.createSite - Update help text and examples to use new flag name - Update TypeScript types to reflect the change - Maintain existing functionality and validation logic 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Change error handling from explicit .catch() with process.exit(1) back to simple top-level await. This removes the explicit fatal error logging and process exit, allowing errors to bubble up naturally. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
…ted commands Fix the generateDeployCommand function to properly handle Commander.js negatable boolean options. Previously, both --build and --no-build flags were being added to generated command suggestions, causing confusing output like "netlify deploy --create-site <NAME> --build --no-build". Changes: - Add special handling for the 'build' option to only show --no-build when build is false - Skip processing the --no-build option separately since it's handled with build logic - Add flag deduplication to prevent any duplicate flags in generated commands - Maintain clean command suggestions without redundant or conflicting flags This ensures users get clean, actionable command suggestions without conflicting flags that would cause command errors. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
… flag handling Replace complex special-case logic with clean, generic handling for any --no-* flags. Only include negated flags when explicitly used by the user (value === false). Remove verbose comments and deduplication logic in favor of preventing issues at the source. Changes: - Generic handling for all --no-* flags instead of hardcoding --no-build - Remove special build flag logic and deduplication - Clean up verbose comments for better code readability - Maintain functionality: include --no-build only when user specifies it 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Replace complex nested if/else chains with clean, single-purpose functions. The site creation logic was deeply nested with multiple levels of branching that was hard to follow and maintain. Changes: - Extract ensureSiteExists() as main entry point with clear branching - Add createSiteWithFlags() for --create-site flag handling - Add validateTeamForSiteCreation() for team validation logic - Add promptForSiteAction() for interactive site selection - Use early returns to eliminate nesting levels - Remove verbose comments in favor of self-documenting code Results in cleaner, more testable code with the same functionality. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
…ions Fix ESLint errors introduced in the site creation logic refactor: - Use optional chaining for option.long?.startsWith() - Replace any types with proper TypeScript types ($TSFixMe, SiteInfo) - Ensure all code follows project linting standards 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Contributor

@sarahetter sarahetter left a comment

Choose a reason for hiding this comment

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

Just the one comment re: presentation with a char otherwise LGTM. I believe you'll have to update some snapshots / tests in deploy might not be quite right at the moment

biilmann and others added 6 commits August 19, 2025 12:35
Apply prettier formatting to files that were not properly formatted. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Update the help command snapshot to reflect the new deploy command description that was changed from 'Create a new deploy from the contents of a folder' to 'Deploy your project to Netlify'. This fixes the failing CI/CD integration tests. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Apply prettier formatting to resolve code style warnings. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Update auto-generated documentation to reflect: - New deploy command description: 'Deploy your project to Netlify' - Added --create-site flag documentation - Added --team flag documentation - Updated examples with new flag usage - Improved command description and help text Generated via: npm run docs 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
@biilmann biilmann requested a review from a team as a code owner August 19, 2025 23:47
@biilmann biilmann merged commit 784b6e4 into main Aug 20, 2025
47 checks passed
@biilmann biilmann deleted the ax-improvements-to-deploy branch August 20, 2025 03:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants