diff --git a/lib/cli/src/crewai_cli/deploy/main.py b/lib/cli/src/crewai_cli/deploy/main.py index 4de738fa4..292805716 100644 --- a/lib/cli/src/crewai_cli/deploy/main.py +++ b/lib/cli/src/crewai_cli/deploy/main.py @@ -1,3 +1,4 @@ +from pathlib import Path from typing import Any from rich.console import Console @@ -23,6 +24,41 @@ class DeployCommand(BaseCommand, PlusAPIMixin): BaseCommand.__init__(self) PlusAPIMixin.__init__(self) self.project_name = get_project_name(require=True) + self._validate_project_structure() + + def _validate_project_structure(self) -> None: + """Validate that the local project has the files required for deployment.""" + errors: list[str] = [] + + if not Path("pyproject.toml").exists(): + errors.append("Cannot find pyproject.toml in the current directory.") + + has_lockfile = Path("uv.lock").exists() or Path("poetry.lock").exists() + if not has_lockfile: + errors.append( + "No uv.lock or poetry.lock found. " + "Run 'uv lock' or 'poetry lock' to generate one." + ) + + src_dir = Path("src") / (self.project_name or "") + crew_py = src_dir / "crew.py" + config_dir = src_dir / "config" + if not crew_py.exists() and not config_dir.exists(): + errors.append( + f"Cannot find src/{self.project_name}/crew.py or " + f"src/{self.project_name}/config. " + "Ensure you are running this command from the project root." + ) + + if errors: + console.print( + "\n[bold red]Pre-flight check failed:[/bold red] " + "Your project is missing required files for deployment.\n" + ) + for error in errors: + console.print(f" • {error}", style="red") + console.print() + raise SystemExit(1) def _standard_no_param_error_message(self) -> None: """