Skip to content

Commit 1f9580f

Browse files
nhortonclaude
andauthored
Add support for multiple auto-detected platforms in install (#43)
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 Co-authored-by: Claude <noreply@anthropic.com>
1 parent eb95477 commit 1f9580f

3 files changed

Lines changed: 76 additions & 24 deletions

File tree

src/deepwork/cli/install.py

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,10 @@ def _install_deepwork(platform_name: str | None, project_path: Path) -> None:
216216
)
217217
console.print(" [green]✓[/green] Git repository found")
218218

219-
# Step 2: Detect or validate platform
219+
# Step 2: Detect or validate platform(s)
220220
detector = PlatformDetector(project_path)
221+
platforms_to_add: list[str] = []
222+
detected_adapters: list[AgentAdapter] = []
221223

222224
if platform_name:
223225
# User specified platform - check if it's available
@@ -234,10 +236,11 @@ def _install_deepwork(platform_name: str | None, project_path: Path) -> None:
234236
)
235237

236238
console.print(f" [green]✓[/green] {adapter.display_name} detected")
237-
platform_to_add = adapter.name
239+
platforms_to_add = [adapter.name]
240+
detected_adapters = [adapter]
238241
else:
239-
# Auto-detect platform
240-
console.print("[yellow]→[/yellow] Auto-detecting AI platform...")
242+
# Auto-detect all available platforms
243+
console.print("[yellow]→[/yellow] Auto-detecting AI platforms...")
241244
available_adapters = detector.detect_all_platforms()
242245

243246
if not available_adapters:
@@ -251,17 +254,11 @@ def _install_deepwork(platform_name: str | None, project_path: Path) -> None:
251254
"Please set up one of these platforms first, or use --platform to specify."
252255
)
253256

254-
if len(available_adapters) > 1:
255-
# Multiple platforms - ask user to specify
256-
platform_names = ", ".join(a.display_name for a in available_adapters)
257-
raise InstallError(
258-
f"Multiple AI platforms detected: {platform_names}\n"
259-
"Please specify which platform to use with --platform option."
260-
)
261-
262-
adapter = available_adapters[0]
263-
console.print(f" [green]✓[/green] {adapter.display_name} detected")
264-
platform_to_add = adapter.name
257+
# Add all detected platforms
258+
for adapter in available_adapters:
259+
console.print(f" [green]✓[/green] {adapter.display_name} detected")
260+
platforms_to_add.append(adapter.name)
261+
detected_adapters = available_adapters
265262

266263
# Step 3: Create .deepwork/ directory structure
267264
console.print("[yellow]→[/yellow] Creating DeepWork directory structure...")
@@ -304,12 +301,16 @@ def _install_deepwork(platform_name: str | None, project_path: Path) -> None:
304301
if "platforms" not in config_data:
305302
config_data["platforms"] = []
306303

307-
# Add platform if not already present
308-
if platform_to_add not in config_data["platforms"]:
309-
config_data["platforms"].append(platform_to_add)
310-
console.print(f" [green]✓[/green] Added {adapter.display_name} to platforms")
311-
else:
312-
console.print(f" [dim]•[/dim] {adapter.display_name} already configured")
304+
# Add each platform if not already present
305+
added_platforms: list[str] = []
306+
for i, platform in enumerate(platforms_to_add):
307+
adapter = detected_adapters[i]
308+
if platform not in config_data["platforms"]:
309+
config_data["platforms"].append(platform)
310+
added_platforms.append(adapter.display_name)
311+
console.print(f" [green]✓[/green] Added {adapter.display_name} to platforms")
312+
else:
313+
console.print(f" [dim]•[/dim] {adapter.display_name} already configured")
313314

314315
save_yaml(config_file, config_data)
315316
console.print(f" [green]✓[/green] Updated {config_file.relative_to(project_path)}")
@@ -328,8 +329,9 @@ def _install_deepwork(platform_name: str | None, project_path: Path) -> None:
328329

329330
# Success message
330331
console.print()
332+
platform_names = ", ".join(a.display_name for a in detected_adapters)
331333
console.print(
332-
f"[bold green]✓ DeepWork installed successfully for {adapter.display_name}![/bold green]"
334+
f"[bold green]✓ DeepWork installed successfully for {platform_names}![/bold green]"
333335
)
334336
console.print()
335337
console.print("[bold]Next steps:[/bold]")

tests/conftest.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,26 @@ def mock_claude_project(mock_git_repo: Path) -> Path:
3535
return mock_git_repo
3636

3737

38+
@pytest.fixture
39+
def mock_gemini_project(mock_git_repo: Path) -> Path:
40+
"""Create a mock project with Gemini CLI setup."""
41+
gemini_dir = mock_git_repo / ".gemini"
42+
gemini_dir.mkdir(exist_ok=True)
43+
return mock_git_repo
44+
45+
46+
@pytest.fixture
47+
def mock_multi_platform_project(mock_git_repo: Path) -> Path:
48+
"""Create a mock project with multiple AI platforms setup."""
49+
claude_dir = mock_git_repo / ".claude"
50+
claude_dir.mkdir(exist_ok=True)
51+
(claude_dir / "settings.json").write_text('{"version": "1.0"}')
52+
53+
gemini_dir = mock_git_repo / ".gemini"
54+
gemini_dir.mkdir(exist_ok=True)
55+
return mock_git_repo
56+
57+
3858
@pytest.fixture
3959
def fixtures_dir() -> Path:
4060
"""Return the path to the fixtures directory."""

tests/integration/test_install_flow.py

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,38 @@ def test_install_fails_without_platform(self, mock_git_repo: Path) -> None:
7979
assert result.exit_code != 0
8080
assert "No AI platform detected" in result.output
8181

82-
# NOTE: Multiple platform detection test removed since we currently only support Claude.
83-
# When more adapters are added, this test should be reinstated.
82+
def test_install_with_multiple_platforms_auto_detect(
83+
self, mock_multi_platform_project: Path
84+
) -> None:
85+
"""Test installing with auto-detection when multiple platforms are present."""
86+
runner = CliRunner()
87+
88+
result = runner.invoke(
89+
cli,
90+
["install", "--path", str(mock_multi_platform_project)],
91+
catch_exceptions=False,
92+
)
93+
94+
assert result.exit_code == 0
95+
assert "Auto-detecting AI platforms" in result.output
96+
assert "Claude Code detected" in result.output
97+
assert "Gemini CLI detected" in result.output
98+
assert "DeepWork installed successfully for Claude Code, Gemini CLI" in result.output
99+
100+
# Verify config.yml has both platforms
101+
config_file = mock_multi_platform_project / ".deepwork" / "config.yml"
102+
config = load_yaml(config_file)
103+
assert config is not None
104+
assert "claude" in config["platforms"]
105+
assert "gemini" in config["platforms"]
106+
107+
# Verify commands were created for both platforms
108+
claude_dir = mock_multi_platform_project / ".claude" / "commands"
109+
assert (claude_dir / "deepwork_jobs.define.md").exists()
110+
111+
# Gemini uses job_name/step_id.toml structure
112+
gemini_dir = mock_multi_platform_project / ".gemini" / "commands"
113+
assert (gemini_dir / "deepwork_jobs" / "define.toml").exists()
84114

85115
def test_install_with_specified_platform_when_missing(self, mock_git_repo: Path) -> None:
86116
"""Test that install fails when specified platform is not present."""

0 commit comments

Comments
 (0)