From 0a9e788d4ac72e81d628315f21a9efa42ce9510e Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 15 Jan 2026 20:43:37 +0000 Subject: [PATCH] Add support for multiple auto-detected platforms in install When no --platform is specified and multiple platforms are detected, install now adds all of them to config.yml instead of erroring. This simplifies setup for projects using multiple AI platforms. Changes: - Modified install to detect and add all available platforms when no specific platform is specified - Updated success message to list all installed platforms - Added test fixtures for gemini and multi-platform projects - Added test for multi-platform auto-detection behavior --- src/deepwork/cli/install.py | 46 ++++++++++++++------------ tests/conftest.py | 20 +++++++++++ tests/integration/test_install_flow.py | 34 +++++++++++++++++-- uv.lock | 2 +- 4 files changed, 77 insertions(+), 25 deletions(-) diff --git a/src/deepwork/cli/install.py b/src/deepwork/cli/install.py index cc6733c0..0c8b9979 100644 --- a/src/deepwork/cli/install.py +++ b/src/deepwork/cli/install.py @@ -174,8 +174,10 @@ def _install_deepwork(platform_name: str | None, project_path: Path) -> None: ) console.print(" [green]✓[/green] Git repository found") - # Step 2: Detect or validate platform + # Step 2: Detect or validate platform(s) detector = PlatformDetector(project_path) + platforms_to_add: list[str] = [] + detected_adapters: list[AgentAdapter] = [] if platform_name: # User specified platform - check if it's available @@ -192,10 +194,11 @@ def _install_deepwork(platform_name: str | None, project_path: Path) -> None: ) console.print(f" [green]✓[/green] {adapter.display_name} detected") - platform_to_add = adapter.name + platforms_to_add = [adapter.name] + detected_adapters = [adapter] else: - # Auto-detect platform - console.print("[yellow]→[/yellow] Auto-detecting AI platform...") + # Auto-detect all available platforms + console.print("[yellow]→[/yellow] Auto-detecting AI platforms...") available_adapters = detector.detect_all_platforms() if not available_adapters: @@ -209,17 +212,11 @@ def _install_deepwork(platform_name: str | None, project_path: Path) -> None: "Please set up one of these platforms first, or use --platform to specify." ) - if len(available_adapters) > 1: - # Multiple platforms - ask user to specify - platform_names = ", ".join(a.display_name for a in available_adapters) - raise InstallError( - f"Multiple AI platforms detected: {platform_names}\n" - "Please specify which platform to use with --platform option." - ) - - adapter = available_adapters[0] - console.print(f" [green]✓[/green] {adapter.display_name} detected") - platform_to_add = adapter.name + # Add all detected platforms + for adapter in available_adapters: + console.print(f" [green]✓[/green] {adapter.display_name} detected") + platforms_to_add.append(adapter.name) + detected_adapters = available_adapters # Step 3: Create .deepwork/ directory structure console.print("[yellow]→[/yellow] Creating DeepWork directory structure...") @@ -256,12 +253,16 @@ def _install_deepwork(platform_name: str | None, project_path: Path) -> None: if "platforms" not in config_data: config_data["platforms"] = [] - # Add platform if not already present - if platform_to_add not in config_data["platforms"]: - config_data["platforms"].append(platform_to_add) - console.print(f" [green]✓[/green] Added {adapter.display_name} to platforms") - else: - console.print(f" [dim]•[/dim] {adapter.display_name} already configured") + # Add each platform if not already present + added_platforms: list[str] = [] + for i, platform in enumerate(platforms_to_add): + adapter = detected_adapters[i] + if platform not in config_data["platforms"]: + config_data["platforms"].append(platform) + added_platforms.append(adapter.display_name) + console.print(f" [green]✓[/green] Added {adapter.display_name} to platforms") + else: + console.print(f" [dim]•[/dim] {adapter.display_name} already configured") save_yaml(config_file, config_data) console.print(f" [green]✓[/green] Updated {config_file.relative_to(project_path)}") @@ -280,8 +281,9 @@ def _install_deepwork(platform_name: str | None, project_path: Path) -> None: # Success message console.print() + platform_names = ", ".join(a.display_name for a in detected_adapters) console.print( - f"[bold green]✓ DeepWork installed successfully for {adapter.display_name}![/bold green]" + f"[bold green]✓ DeepWork installed successfully for {platform_names}![/bold green]" ) console.print() console.print("[bold]Next steps:[/bold]") diff --git a/tests/conftest.py b/tests/conftest.py index ffb6554a..0f540293 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -35,6 +35,26 @@ def mock_claude_project(mock_git_repo: Path) -> Path: return mock_git_repo +@pytest.fixture +def mock_gemini_project(mock_git_repo: Path) -> Path: + """Create a mock project with Gemini CLI setup.""" + gemini_dir = mock_git_repo / ".gemini" + gemini_dir.mkdir(exist_ok=True) + return mock_git_repo + + +@pytest.fixture +def mock_multi_platform_project(mock_git_repo: Path) -> Path: + """Create a mock project with multiple AI platforms setup.""" + claude_dir = mock_git_repo / ".claude" + claude_dir.mkdir(exist_ok=True) + (claude_dir / "settings.json").write_text('{"version": "1.0"}') + + gemini_dir = mock_git_repo / ".gemini" + gemini_dir.mkdir(exist_ok=True) + return mock_git_repo + + @pytest.fixture def fixtures_dir() -> Path: """Return the path to the fixtures directory.""" diff --git a/tests/integration/test_install_flow.py b/tests/integration/test_install_flow.py index 09c97ffc..21565052 100644 --- a/tests/integration/test_install_flow.py +++ b/tests/integration/test_install_flow.py @@ -79,8 +79,38 @@ def test_install_fails_without_platform(self, mock_git_repo: Path) -> None: assert result.exit_code != 0 assert "No AI platform detected" in result.output - # NOTE: Multiple platform detection test removed since we currently only support Claude. - # When more adapters are added, this test should be reinstated. + def test_install_with_multiple_platforms_auto_detect( + self, mock_multi_platform_project: Path + ) -> None: + """Test installing with auto-detection when multiple platforms are present.""" + runner = CliRunner() + + result = runner.invoke( + cli, + ["install", "--path", str(mock_multi_platform_project)], + catch_exceptions=False, + ) + + assert result.exit_code == 0 + assert "Auto-detecting AI platforms" in result.output + assert "Claude Code detected" in result.output + assert "Gemini CLI detected" in result.output + assert "DeepWork installed successfully for Claude Code, Gemini CLI" in result.output + + # Verify config.yml has both platforms + config_file = mock_multi_platform_project / ".deepwork" / "config.yml" + config = load_yaml(config_file) + assert config is not None + assert "claude" in config["platforms"] + assert "gemini" in config["platforms"] + + # Verify commands were created for both platforms + claude_dir = mock_multi_platform_project / ".claude" / "commands" + assert (claude_dir / "deepwork_jobs.define.md").exists() + + # Gemini uses job_name/step_id.toml structure + gemini_dir = mock_multi_platform_project / ".gemini" / "commands" + assert (gemini_dir / "deepwork_jobs" / "define.toml").exists() def test_install_with_specified_platform_when_missing(self, mock_git_repo: Path) -> None: """Test that install fails when specified platform is not present.""" diff --git a/uv.lock b/uv.lock index d780f0db..ccd8b049 100644 --- a/uv.lock +++ b/uv.lock @@ -126,7 +126,7 @@ toml = [ [[package]] name = "deepwork" -version = "0.1.0" +version = "0.1.1" source = { editable = "." } dependencies = [ { name = "click" },