Skip to content

Commit b76aaab

Browse files
authored
Merge pull request #23 from zhujian0805/main
feat(cli): support multiple app targets for marketplace installation
2 parents 290b181 + 2aacc97 commit b76aaab

1 file changed

Lines changed: 49 additions & 59 deletions

File tree

code_assistant_manager/cli/plugins/plugin_marketplace_commands.py

Lines changed: 49 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -469,13 +469,13 @@ def marketplace_install(
469469
"claude",
470470
"--app",
471471
"-a",
472-
help=f"App type to install marketplace to ({', '.join(VALID_APP_TYPES)})",
472+
help=f"App type(s) to install marketplace to ({', '.join(VALID_APP_TYPES)}, all). Comma-separated.",
473473
),
474474
):
475475
"""Install a configured marketplace or all marketplaces to Claude or CodeBuddy.
476476
477477
This installs a marketplace that has been previously configured in CAM
478-
to the target AI assistant app. The marketplace must already be configured
478+
to the target AI assistant app(s). The marketplace must already be configured
479479
using 'cam plugin marketplace add' before it can be installed.
480480
481481
After installation, you can browse plugins with 'cam plugin browse <marketplace>'
@@ -485,13 +485,12 @@ def marketplace_install(
485485
cam plugin marketplace install awesome-claude-code-plugins
486486
cam plugin marketplace install my-marketplace --app codebuddy
487487
cam plugin marketplace install --all
488-
cam plugin marketplace install --all --app codebuddy
488+
cam plugin marketplace install --all --app claude,codebuddy
489489
"""
490-
from code_assistant_manager.cli.option_utils import resolve_single_app
490+
from code_assistant_manager.cli.option_utils import resolve_app_targets
491491
from code_assistant_manager.plugins import PluginManager
492492

493-
app = resolve_single_app(app_type, VALID_APP_TYPES, default="claude")
494-
handler = get_handler(app)
493+
target_apps = resolve_app_targets(app_type, VALID_APP_TYPES, default="claude")
495494
manager = PluginManager()
496495

497496
# Get all configured marketplaces
@@ -510,9 +509,6 @@ def marketplace_install(
510509
# Determine which marketplaces to install
511510
if all_marketplaces:
512511
marketplaces_to_install = configured_marketplaces
513-
typer.echo(
514-
f"{Colors.CYAN}Installing all configured marketplaces to {app}...{Colors.RESET}"
515-
)
516512
elif marketplace:
517513
# Install single marketplace
518514
if marketplace not in configured_marketplaces:
@@ -536,64 +532,58 @@ def marketplace_install(
536532
typer.echo(f" • {name}")
537533
raise typer.Exit(1)
538534

539-
# Install the marketplaces
540-
installed_count = 0
541-
failed_count = 0
542-
already_installed_count = 0
535+
# Install the marketplaces to each target app
536+
for app in target_apps:
537+
typer.echo(f"\n{Colors.BOLD}Installing to {app}...{Colors.RESET}")
538+
handler = get_handler(app)
543539

544-
for name, repo in marketplaces_to_install.items():
545-
if repo.type != "marketplace":
546-
typer.echo(
547-
f"{Colors.YELLOW}⚠ Skipping '{name}' (not a marketplace, type: {repo.type}){Colors.RESET}"
548-
)
549-
continue
540+
installed_count = 0
541+
failed_count = 0
542+
already_installed_count = 0
550543

551-
if not repo.repo_owner or not repo.repo_name:
552-
typer.echo(
553-
f"{Colors.YELLOW}⚠ Skipping '{name}' (no GitHub source configured){Colors.RESET}"
554-
)
555-
continue
544+
for name, repo in marketplaces_to_install.items():
545+
if repo.type != "marketplace":
546+
continue
556547

557-
repo_url = f"https://github.com/{repo.repo_owner}/{repo.repo_name}"
548+
if not repo.repo_owner or not repo.repo_name:
549+
typer.echo(
550+
f"{Colors.YELLOW}⚠ Skipping '{name}' (no GitHub source configured){Colors.RESET}"
551+
)
552+
continue
558553

559-
typer.echo(f"{Colors.CYAN}Installing marketplace: {name}...{Colors.RESET}")
560-
success, msg = handler.marketplace_add(repo_url)
554+
repo_url = f"https://github.com/{repo.repo_owner}/{repo.repo_name}"
561555

562-
if success:
563-
typer.echo(f"{Colors.GREEN}✓ Marketplace installed: {name}{Colors.RESET}")
564-
installed_count += 1
565-
elif "already installed" in msg.lower():
556+
typer.echo(f"{Colors.CYAN}Installing marketplace: {name}...{Colors.RESET}")
557+
success, msg = handler.marketplace_add(repo_url)
558+
559+
if success:
560+
typer.echo(f"{Colors.GREEN}✓ Marketplace installed: {name}{Colors.RESET}")
561+
installed_count += 1
562+
elif "already installed" in msg.lower():
563+
typer.echo(
564+
f"{Colors.YELLOW}Marketplace '{name}' is already installed.{Colors.RESET}"
565+
)
566+
already_installed_count += 1
567+
else:
568+
typer.echo(f"{Colors.RED}✗ Failed to install '{name}': {msg}{Colors.RESET}")
569+
failed_count += 1
570+
571+
# Summary for current app
572+
total_attempted = len(marketplaces_to_install)
573+
typer.echo(f" {Colors.BOLD}Summary for {app}:{Colors.RESET}")
574+
typer.echo(f" Installed: {installed_count}")
575+
typer.echo(f" Already installed: {already_installed_count}")
576+
typer.echo(f" Failed: {failed_count}")
577+
578+
if len(target_apps) == 1:
579+
if installed_count > 0 or already_installed_count > 0:
566580
typer.echo(
567-
f"{Colors.YELLOW}Marketplace '{name}' is already installed.{Colors.RESET}"
581+
f"\n{Colors.CYAN}Browse plugins with:{Colors.RESET} cam plugin marketplace browse <marketplace>"
582+
)
583+
typer.echo(
584+
f"{Colors.CYAN}Install plugins with:{Colors.RESET} cam plugin install <plugin-name>@<marketplace>"
568585
)
569-
already_installed_count += 1
570-
else:
571-
typer.echo(f"{Colors.RED}✗ Failed to install '{name}': {msg}{Colors.RESET}")
572-
failed_count += 1
573-
574-
# Summary
575-
total_attempted = len(marketplaces_to_install)
576-
typer.echo(f"\n{Colors.BOLD}Installation Summary:{Colors.RESET}")
577-
typer.echo(f" Installed: {installed_count}")
578-
typer.echo(f" Already installed: {already_installed_count}")
579-
typer.echo(f" Failed: {failed_count}")
580-
typer.echo(
581-
f" Skipped: {total_attempted - installed_count - failed_count - already_installed_count}"
582-
)
583-
584-
if installed_count > 0 or already_installed_count > 0:
585-
typer.echo(
586-
f"\n{Colors.CYAN}Browse plugins with:{Colors.RESET} cam plugin browse <marketplace>"
587-
)
588-
typer.echo(
589-
f"{Colors.CYAN}Install plugins with:{Colors.RESET} cam plugin install <plugin-name>@<marketplace>"
590-
)
591586

592-
if failed_count > 0:
593-
typer.echo(
594-
f"\n{Colors.YELLOW}{failed_count} marketplace(s) failed to install.{Colors.RESET}"
595-
)
596-
raise typer.Exit(1)
597587

598588

599589
@marketplace_app.command("uninstall")

0 commit comments

Comments
 (0)