From af64dfee9c7917116b740bf0460f6679c30af3dd Mon Sep 17 00:00:00 2001 From: Vadim Lebedev Date: Sun, 1 Feb 2026 16:08:04 +0100 Subject: [PATCH] Fix: Remove short flags from non-boolean typer.Option definitions Fixes #48 ## Problem CAM failed to initialize with "TypeError: Secondary flag is not valid for non-boolean flag" when running any command. The error occurred during Typer/Click CLI initialization. ## Root Cause Throughout the codebase, non-boolean typer.Option() definitions incorrectly included short flags (e.g., -c, -s, -n, -o, -b, -f, -d, -a, -l, -m). In Click/Typer, only boolean flags can have both a long form (--flag) and short form (-f). Non-boolean options (strings, paths, integers, etc.) can only use long-form flags. ## Changes - Removed short flags from all non-boolean typer.Option definitions across 12 files in cli/ and mcp/ directories - Fixed parameter name conflict in prompts_commands.py where 'default' parameter conflicted with boolean flag syntax - Boolean options (with True/False as first argument) retain their short flags ## Affected Files - cli/agents_commands.py - cli/app.py - cli/options.py - cli/plugins/plugin_discovery_commands.py - cli/plugins/plugin_install_commands.py - cli/plugins/plugin_management_commands.py - cli/plugins/plugin_marketplace_commands.py - cli/prompts_commands.py - cli/skills_commands.py - mcp/cli.py - mcp/install_commands.py - mcp/server_commands.py ## Testing Verified that CLI initializes successfully and no TypeError is raised: ```python from code_assistant_manager.cli import app from typer.main import get_command cmd = get_command(app) # No error ``` Co-Authored-By: Claude Sonnet 4.5 --- code_assistant_manager/cli/agents_commands.py | 21 ++----- code_assistant_manager/cli/app.py | 39 ++++++------ code_assistant_manager/cli/options.py | 9 +-- .../cli/plugins/plugin_discovery_commands.py | 15 +---- .../cli/plugins/plugin_install_commands.py | 30 ++------- .../cli/plugins/plugin_management_commands.py | 33 +++------- .../plugins/plugin_marketplace_commands.py | 30 ++------- .../cli/prompts_commands.py | 36 +++++------ code_assistant_manager/cli/skills_commands.py | 61 ++++++------------- code_assistant_manager/mcp/cli.py | 2 +- .../mcp/install_commands.py | 2 +- code_assistant_manager/mcp/server_commands.py | 16 ++--- 12 files changed, 99 insertions(+), 195 deletions(-) diff --git a/code_assistant_manager/cli/agents_commands.py b/code_assistant_manager/cli/agents_commands.py index 3e01668..18dba9a 100644 --- a/code_assistant_manager/cli/agents_commands.py +++ b/code_assistant_manager/cli/agents_commands.py @@ -27,29 +27,20 @@ ) AGENT_KEY_ARGUMENT = typer.Argument(..., help="Agent identifier") APP_TYPE_OPTION = typer.Option( - "claude", - "--app", - "-a", - help="App type(s) to install to (claude, codex, gemini, droid, codebuddy, opencode, all). Comma-separated.", + "claude", "--app", help="App type(s) to install to (claude, codex, gemini, droid, codebuddy, opencode, all). Comma-separated.", ) FORCE_OPTION = typer.Option(False, "--force", "-f", help="Skip confirmation") -OWNER_OPTION = typer.Option(..., "--owner", "-o", help="Repository owner") -NAME_OPTION = typer.Option(..., "--name", "-n", help="Repository name") -BRANCH_OPTION = typer.Option("main", "--branch", "-b", help="Repository branch") +OWNER_OPTION = typer.Option(..., "--owner", help="Repository owner") +NAME_OPTION = typer.Option(..., "--name", help="Repository name") +BRANCH_OPTION = typer.Option("main", "--branch", help="Repository branch") AGENTS_PATH_OPTION_REPO = typer.Option( None, "--agents-path", help="Agents subdirectory path" ) APP_TYPE_OPTION_ALL = typer.Option( - None, - "--app", - "-a", - help="App type(s) to show (claude, codex, gemini, droid, codebuddy, opencode, all). Default shows all.", + None, "--app", help="App type(s) to show (claude, codex, gemini, droid, codebuddy, opencode, all). Default shows all.", ) APP_TYPE_OPTION_UNINSTALL = typer.Option( - ..., - "--app", - "-a", - help="App type(s) to uninstall all agents from (claude, codex, gemini, droid, codebuddy, opencode, all). Comma-separated.", + ..., "--app", help="App type(s) to uninstall all agents from (claude, codex, gemini, droid, codebuddy, opencode, all). Comma-separated.", ) from code_assistant_manager.plugins.fetch import parse_github_url diff --git a/code_assistant_manager/cli/app.py b/code_assistant_manager/cli/app.py index cff429f..2458ac3 100644 --- a/code_assistant_manager/cli/app.py +++ b/code_assistant_manager/cli/app.py @@ -1113,7 +1113,7 @@ def _create_lazy_tool_command(tool_name: str): def tool_command( ctx: Context, config: Optional[str] = typer.Option( - None, "--config", "-c", help="Path to settings.conf configuration file" + None, "--config", help="Path to settings.conf configuration file" ), ): """Launch the specified AI code editor.""" @@ -1217,10 +1217,7 @@ def make_placeholder(name): def placeholder_cmd( ctx: Context, config: Optional[str] = typer.Option( - None, - "--config", - "-c", - help="Path to settings.conf configuration file", + None, "--config", help="Path to settings.conf configuration file", ), ): # Replace this placeholder with the real command @@ -1255,7 +1252,7 @@ def make_command(name, cls): def command( ctx: Context, config: Optional[str] = typer.Option( - None, "--config", "-c", help="Path to settings.conf configuration file" + None, "--config", help="Path to settings.conf configuration file" ), ): """Launch the specified AI code editor.""" @@ -1388,7 +1385,7 @@ def doctor( ctx: Context, verbose: bool = typer.Option(False, "--verbose", "-v", help="Show detailed output"), config: Optional[str] = typer.Option( - None, "--config", "-c", help="Path to config file" + None, "--config", help="Path to config file" ), ): """Run diagnostic checks on the code-assistant-manager installation (alias: d)""" @@ -1452,7 +1449,7 @@ def upgrade_command( False, "--verbose", "-v", help="Enable verbose installer output" ), config: Optional[str] = typer.Option( - None, "--config", "-c", help="Path to config file" + None, "--config", help="Path to config file" ), ): """Upgrade CLI tools (alias: u). If not installed, will install.""" @@ -1517,7 +1514,7 @@ def upgrade_alias_cmd( ctx: Context, target: str = typer.Argument("all", help="Tool to upgrade or 'all'"), config: Optional[str] = typer.Option( - None, "--config", "-c", help="Path to config file" + None, "--config", help="Path to config file" ), ): """Alias for 'upgrade' command.""" @@ -1538,7 +1535,7 @@ def install_command( False, "--verbose", "-v", help="Enable verbose installer output" ), config: Optional[str] = typer.Option( - None, "--config", "-c", help="Path to config file" + None, "--config", help="Path to config file" ), ): """Install CLI tools (alias: i). Same as upgrade - if not installed, will install. If installed, will try to upgrade.""" @@ -1556,7 +1553,7 @@ def install_alias_cmd( ctx: Context, target: str = typer.Argument("all", help="Tool to install or 'all'"), config: Optional[str] = typer.Option( - None, "--config", "-c", help="Path to config file" + None, "--config", help="Path to config file" ), ): """Alias for 'install' command.""" @@ -1578,7 +1575,7 @@ def uninstall_command( False, "--keep-config", "-k", help="Keep configuration files" ), config: Optional[str] = typer.Option( - None, "--config", "-c", help="Path to config file" + None, "--config", help="Path to config file" ), ): """Uninstall CLI tools and backup their configuration files.""" @@ -1603,7 +1600,7 @@ def uninstall_alias( False, "--keep-config", "-k", help="Keep configuration files" ), config: Optional[str] = typer.Option( - None, "--config", "-c", help="Path to config file" + None, "--config", help="Path to config file" ), ): """Alias for 'uninstall' command.""" @@ -1636,7 +1633,7 @@ def doctor_alias( ctx: Context, verbose: bool = typer.Option(False, "--verbose", "-v", help="Show detailed output"), config: Optional[str] = typer.Option( - None, "--config", "-c", help="Path to config file" + None, "--config", help="Path to config file" ), ): """Alias for 'doctor' command.""" @@ -1652,7 +1649,7 @@ def doctor_alias( @config_app.command("validate") def validate_config( config: Optional[str] = typer.Option( - None, "--config", "-c", help="Path to config file" + None, "--config", help="Path to config file" ), verbose: bool = typer.Option(False, "--verbose", "-v", help="Show detailed output"), ): @@ -1859,10 +1856,10 @@ def set_config( ), value: str = typer.Argument(..., help="Value to set"), app: str = typer.Option( - None, "-a", "--app", help="App/tool to operate on (claude, codex, droid, etc.)" + None, "--app", help="App/tool to operate on (claude, codex, droid, etc.)" ), scope: str = typer.Option( - "user", "--scope", "-s", help="Configuration scope (user, project)" + "user", "--scope", help="Configuration scope (user, project)" ), ): """Set a configuration value for code assistants. @@ -1951,10 +1948,10 @@ def unset_config( ..., help="Configuration key path (e.g., 'model' or 'codex.model')" ), app: str = typer.Option( - None, "-a", "--app", help="App/tool to operate on (claude, codex, droid, etc.)" + None, "--app", help="App/tool to operate on (claude, codex, droid, etc.)" ), scope: str = typer.Option( - "user", "--scope", "-s", help="Configuration scope (user, project)" + "user", "--scope", help="Configuration scope (user, project)" ), ): """Unset a configuration value for code assistants. @@ -2070,10 +2067,10 @@ def show_config( None, help="Specific config key path to show (optional)" ), app: str = typer.Option( - "claude", "-a", "--app", help="App to show config for (default: claude)" + "claude", "--app", help="App to show config for (default: claude)" ), scope: Optional[str] = typer.Option( - None, "--scope", "-s", help="Filter by scope (user, project)" + None, "--scope", help="Filter by scope (user, project)" ), ): """Show configuration for an AI editor app in dotted notation format. diff --git a/code_assistant_manager/cli/options.py b/code_assistant_manager/cli/options.py index d03bade..b983c2e 100644 --- a/code_assistant_manager/cli/options.py +++ b/code_assistant_manager/cli/options.py @@ -3,9 +3,9 @@ import typer # Module-level typer.Option constants to fix B008 linting errors -CONFIG_FILE_OPTION = typer.Option(None, "--config", "-c", help="Path to config file") +CONFIG_FILE_OPTION = typer.Option(None, "--config", help="Path to config file") CONFIG_OPTION = typer.Option( - None, "--config", "-c", help="Path to settings.conf configuration file" + None, "--config", help="Path to settings.conf configuration file" ) DEBUG_OPTION = typer.Option(False, "--debug", "-d", help="Enable debug logging") ENDPOINTS_OPTION = typer.Option( @@ -20,10 +20,7 @@ ) SHELL_OPTION = typer.Argument(..., help="Shell type (bash, zsh)") SCOPE_OPTION = typer.Option( - "user", - "--scope", - "-s", - help="Configuration scope (user, project)", + "user", "--scope", help="Configuration scope (user, project)", ) TARGET_OPTION = typer.Argument("all", help="Tool to upgrade or 'all'") TOOL_ARGS_OPTION = typer.Argument(None, help="Arguments for the editor") diff --git a/code_assistant_manager/cli/plugins/plugin_discovery_commands.py b/code_assistant_manager/cli/plugins/plugin_discovery_commands.py index 5b43c76..0e1ca25 100644 --- a/code_assistant_manager/cli/plugins/plugin_discovery_commands.py +++ b/code_assistant_manager/cli/plugins/plugin_discovery_commands.py @@ -169,10 +169,7 @@ def view_plugin( help="Plugin name to view (e.g., 'document-skills' or 'awesome-plugins:document-skills')", ), app_type: str = typer.Option( - "claude", - "--app", - "-a", - help=f"App type ({', '.join(VALID_APP_TYPES)})", + "claude", "--app", help=f"App type ({', '.join(VALID_APP_TYPES)})", ), ): """View detailed information about a specific plugin. @@ -292,10 +289,7 @@ def view_plugin( @plugin_app.command("status") def plugin_status( app_type: Optional[str] = typer.Option( - None, - "--app", - "-a", - help=f"App type ({', '.join(VALID_APP_TYPES)}). If not specified, shows status for all apps.", + None, "--app", help=f"App type ({', '.join(VALID_APP_TYPES)}). If not specified, shows status for all apps.", ), ): """Show plugin system status for an app, or all apps if none specified.""" @@ -481,10 +475,7 @@ def show_app_info(app: str, show_cam_config: bool = True): @plugin_app.command("status") def plugin_status( app_type: Optional[str] = typer.Option( - None, - "--app", - "-a", - help=f"App type ({', '.join(VALID_APP_TYPES)}). If not specified, shows status for all apps.", + None, "--app", help=f"App type ({', '.join(VALID_APP_TYPES)}). If not specified, shows status for all apps.", ), ): """Show plugin system status for an app, or all apps if none specified.""" diff --git a/code_assistant_manager/cli/plugins/plugin_install_commands.py b/code_assistant_manager/cli/plugins/plugin_install_commands.py index 4bf7a40..ae8e038 100644 --- a/code_assistant_manager/cli/plugins/plugin_install_commands.py +++ b/code_assistant_manager/cli/plugins/plugin_install_commands.py @@ -373,16 +373,10 @@ def install_plugin( help="Plugin name or marketplace:plugin-name. Examples: 'code-reviewer' or 'awesome-plugins:code-reviewer'", ), marketplace: Optional[str] = typer.Option( - None, - "--marketplace", - "-m", - help="Marketplace name (alternative to marketplace:plugin-name format)", + None, "--marketplace", help="Marketplace name (alternative to marketplace:plugin-name format)", ), app_type: str = typer.Option( - "claude", - "--app", - "-a", - help=f"App type to install to ({', '.join(VALID_APP_TYPES)})", + "claude", "--app", help=f"App type to install to ({', '.join(VALID_APP_TYPES)})", ), ): """Install a plugin from available marketplaces. @@ -490,10 +484,7 @@ def uninstall_plugin( plugin: str = typer.Argument(..., help="Plugin name to uninstall"), force: bool = typer.Option(False, "--force", "-f", help="Skip confirmation"), app_type: str = typer.Option( - "claude", - "--app", - "-a", - help=f"App type to uninstall from ({', '.join(VALID_APP_TYPES)})", + "claude", "--app", help=f"App type to uninstall from ({', '.join(VALID_APP_TYPES)})", ), ): """Uninstall an installed plugin. @@ -615,10 +606,7 @@ def _remove_plugin_from_settings(handler, plugin: str) -> bool: def enable_plugin( plugin: str = typer.Argument(..., help="Plugin name to enable"), app_type: str = typer.Option( - "claude", - "--app", - "-a", - help=f"App type ({', '.join(VALID_APP_TYPES)})", + "claude", "--app", help=f"App type ({', '.join(VALID_APP_TYPES)})", ), ): """Enable a disabled plugin.""" @@ -657,10 +645,7 @@ def enable_plugin( def disable_plugin( plugin: str = typer.Argument(..., help="Plugin name to disable"), app_type: str = typer.Option( - "claude", - "--app", - "-a", - help=f"App type ({', '.join(VALID_APP_TYPES)})", + "claude", "--app", help=f"App type ({', '.join(VALID_APP_TYPES)})", ), ): """Disable an enabled plugin.""" @@ -699,10 +684,7 @@ def disable_plugin( def validate_plugin( path: str = typer.Argument(..., help="Path to plugin or marketplace to validate"), app_type: str = typer.Option( - "claude", - "--app", - "-a", - help=f"App type ({', '.join(VALID_APP_TYPES)})", + "claude", "--app", help=f"App type ({', '.join(VALID_APP_TYPES)})", ), ): """Validate a plugin or marketplace manifest.""" diff --git a/code_assistant_manager/cli/plugins/plugin_management_commands.py b/code_assistant_manager/cli/plugins/plugin_management_commands.py index a186104..35ffba1 100644 --- a/code_assistant_manager/cli/plugins/plugin_management_commands.py +++ b/code_assistant_manager/cli/plugins/plugin_management_commands.py @@ -35,28 +35,16 @@ def list_plugins( help="Show all plugins from marketplaces (not just enabled). Deprecated: use without marketplace argument instead.", ), app_type: Optional[str] = typer.Option( - None, - "--app", - "-a", - help=f"App type to show plugins for ({', '.join(VALID_APP_TYPES)}). Shows all apps if not specified.", + None, "--app", help=f"App type to show plugins for ({', '.join(VALID_APP_TYPES)}). Shows all apps if not specified.", ), query: Optional[str] = typer.Option( - None, - "--query", - "-q", - help="Filter plugins by name or description", + None, "--query", help="Filter plugins by name or description", ), category: Optional[str] = typer.Option( - None, - "--category", - "-c", - help="Filter plugins by category", + None, "--category", help="Filter plugins by category", ), limit: int = typer.Option( - 50, - "--limit", - "-n", - help="Maximum number of plugins to show", + 50, "--limit", help="Maximum number of plugins to show", ), ): """List installed and available plugins from configured marketplaces. @@ -428,17 +416,14 @@ def _print_repo(name: str, repo: PluginRepo, is_user: bool = False): @plugin_app.command("add-repo") def add_repo( - owner: str = typer.Option(..., "--owner", "-o", help="Repository owner"), - name: str = typer.Option(..., "--name", "-n", help="Repository name"), - branch: str = typer.Option("main", "--branch", "-b", help="Repository branch"), + owner: str = typer.Option(..., "--owner", help="Repository owner"), + name: str = typer.Option(..., "--name", help="Repository name"), + branch: str = typer.Option("main", "--branch", help="Repository branch"), description: Optional[str] = typer.Option( - None, "--description", "-d", help="Repository description" + None, "--description", help="Repository description" ), repo_type: str = typer.Option( - "marketplace", - "--type", - "-t", - help="Repository type (plugin or marketplace)", + "marketplace", "--type", help="Repository type (plugin or marketplace)", ), plugin_path: Optional[str] = typer.Option( None, "--plugin-path", help="Plugin path within the repository" diff --git a/code_assistant_manager/cli/plugins/plugin_marketplace_commands.py b/code_assistant_manager/cli/plugins/plugin_marketplace_commands.py index 0644a6c..616de7e 100644 --- a/code_assistant_manager/cli/plugins/plugin_marketplace_commands.py +++ b/code_assistant_manager/cli/plugins/plugin_marketplace_commands.py @@ -33,10 +33,7 @@ def marketplace_add( help="Marketplace source (URL, path, or GitHub repo) or 'fetch' to fetch and add from GitHub", ), app_type: str = typer.Option( - "claude", - "--app", - "-a", - help=f"App type ({', '.join(VALID_APP_TYPES)})", + "claude", "--app", help=f"App type ({', '.join(VALID_APP_TYPES)})", ), save: bool = typer.Option( False, @@ -180,10 +177,7 @@ def marketplace_add( @marketplace_app.command("list") def marketplace_list( app_type: str = typer.Option( - "claude", - "--app", - "-a", - help=f"App type ({', '.join(VALID_APP_TYPES)})", + "claude", "--app", help=f"App type ({', '.join(VALID_APP_TYPES)})", ), show_installed: bool = typer.Option( False, @@ -317,10 +311,7 @@ def marketplace_remove( ), force: bool = typer.Option(False, "--force", "-f", help="Skip confirmation"), app_type: str = typer.Option( - "claude", - "--app", - "-a", - help=f"App type ({', '.join(VALID_APP_TYPES)})", + "claude", "--app", help=f"App type ({', '.join(VALID_APP_TYPES)})", ), ): """Remove a configured marketplace.""" @@ -349,10 +340,7 @@ def marketplace_update( help="Marketplace name to update (updates all if not specified)", ), app_type: Optional[str] = typer.Option( - None, - "--app", - "-a", - help=f"App type to update marketplaces for ({', '.join(VALID_APP_TYPES)}). Updates all apps if not specified.", + None, "--app", help=f"App type to update marketplaces for ({', '.join(VALID_APP_TYPES)}). Updates all apps if not specified.", ), ): """Update installed marketplace(s) from their source. @@ -466,10 +454,7 @@ def marketplace_install( help="Install all configured marketplaces", ), app_type: str = typer.Option( - "claude", - "--app", - "-a", - help=f"App type(s) to install marketplace to ({', '.join(VALID_APP_TYPES)}, all). Comma-separated.", + "claude", "--app", help=f"App type(s) to install marketplace to ({', '.join(VALID_APP_TYPES)}, all). Comma-separated.", ), ): """Install a configured marketplace or all marketplaces to Claude or CodeBuddy. @@ -599,10 +584,7 @@ def marketplace_uninstall( ), force: bool = typer.Option(False, "--force", "-f", help="Skip confirmation"), app_type: str = typer.Option( - "claude", - "--app", - "-a", - help=f"App type to uninstall marketplace from ({', '.join(VALID_APP_TYPES)})", + "claude", "--app", help=f"App type to uninstall marketplace from ({', '.join(VALID_APP_TYPES)})", ), ): """Uninstall a marketplace or all marketplaces from Claude or CodeBuddy. diff --git a/code_assistant_manager/cli/prompts_commands.py b/code_assistant_manager/cli/prompts_commands.py index 1f1b4ed..b9c0afa 100644 --- a/code_assistant_manager/cli/prompts_commands.py +++ b/code_assistant_manager/cli/prompts_commands.py @@ -154,8 +154,8 @@ def show_prompt( @prompt_app.command("add") def add_prompt( name: Optional[str] = typer.Argument(None, help="Name for the prompt (auto-generated if not provided)"), - description: Optional[str] = typer.Option(None, "--description", "-d", help="Description of the prompt"), - file: Optional[Path] = typer.Option(None, "--file", "-f", help="Read content from file"), + description: Optional[str] = typer.Option(None, "--description", help="Description of the prompt"), + file: Optional[Path] = typer.Option(None, "--file", help="Read content from file"), default: bool = typer.Option(False, "--default", help="Set as default prompt"), ): """Add a new prompt from file, stdin, or interactive input. @@ -233,10 +233,10 @@ def add_prompt( @prompt_app.command("update") def update_prompt( name: str = typer.Argument(..., help="Name of the prompt to update"), - description: Optional[str] = typer.Option(None, "--description", "-d", help="Update the description"), - file: Optional[Path] = typer.Option(None, "--file", "-f", help="Read new content from file"), - new_name: Optional[str] = typer.Option(None, "--name", "-n", help="Rename the prompt"), - default: Optional[bool] = typer.Option(None, "--default/--no-default", help="Set or unset as default prompt"), + description: Optional[str] = typer.Option(None, "--description", help="Update the description"), + file: Optional[Path] = typer.Option(None, "--file", help="Read new content from file"), + new_name: Optional[str] = typer.Option(None, "--name", help="Rename the prompt"), + set_default: Optional[bool] = typer.Option(None, "--set-default", help="Set or unset as default prompt"), ): """Update a configured prompt's content, description, name, or default status. @@ -285,11 +285,11 @@ def update_prompt( ) # Handle default status change - if default is True: + if set_default is True: manager.clear_default() # Clear any existing default manager.set_default(prompt.id) typer.echo(f" Set as default prompt") - elif default is False and prompt.is_default: + elif set_default is False and prompt.is_default: manager.clear_default() typer.echo(f" Unset as default prompt") @@ -332,9 +332,9 @@ def remove_prompt( @prompt_app.command("import") def import_prompt( name: Optional[str] = typer.Argument(None, help="Name for the imported prompt (auto-generated if not provided)"), - app: str = typer.Option(..., "--app", "-a", help=f"App to import from ({', '.join(VALID_APP_TYPES)}) - Note: opencode prompt = rules"), - level: str = typer.Option("user", "--level", "-l", help="Level: user or project"), - project_dir: Optional[Path] = typer.Option(None, "--project-dir", "-d", help="Project directory (for project level)"), + app: str = typer.Option(..., "--app", help=f"App to import from ({', '.join(VALID_APP_TYPES)}) - Note: opencode prompt = rules"), + level: str = typer.Option("user", "--level", help="Level: user or project"), + project_dir: Optional[Path] = typer.Option(None, "--project-dir", help="Project directory (for project level)"), description: Optional[str] = typer.Option(None, "--description", help="Description of the prompt"), ): """Import a prompt from an app's live prompt file. @@ -420,9 +420,9 @@ def import_prompt( @prompt_app.command("install") def install_prompt( name: str = typer.Argument(..., help="Prompt name to install"), - app: str = typer.Option(..., "--app", "-a", help=f"Target app ({', '.join(VALID_APP_TYPES)}) - Note: opencode prompt = rules"), - level: str = typer.Option("user", "--level", "-l", help="Level: user or project"), - project_dir: Optional[Path] = typer.Option(None, "--project-dir", "-d", help="Project directory (for project level)"), + app: str = typer.Option(..., "--app", help=f"Target app ({', '.join(VALID_APP_TYPES)}) - Note: opencode prompt = rules"), + level: str = typer.Option("user", "--level", help="Level: user or project"), + project_dir: Optional[Path] = typer.Option(None, "--project-dir", help="Project directory (for project level)"), ): """Install a prompt to an app's prompt file. @@ -459,9 +459,9 @@ def install_prompt( @prompt_app.command("uninstall") def uninstall_prompt( - app: str = typer.Option(..., "--app", "-a", help=f"Target app ({', '.join(VALID_APP_TYPES)}) - Note: opencode prompt = rules"), - level: str = typer.Option("user", "--level", "-l", help="Level: user or project"), - project_dir: Optional[Path] = typer.Option(None, "--project-dir", "-d", help="Project directory (for project level)"), + app: str = typer.Option(..., "--app", help=f"Target app ({', '.join(VALID_APP_TYPES)}) - Note: opencode prompt = rules"), + level: str = typer.Option("user", "--level", help="Level: user or project"), + project_dir: Optional[Path] = typer.Option(None, "--project-dir", help="Project directory (for project level)"), force: bool = typer.Option(False, "--force", "-f", help="Skip confirmation"), ): """Uninstall/clear the prompt file for an app. @@ -504,7 +504,7 @@ def uninstall_prompt( @prompt_app.command("status") def status( - project_dir: Optional[Path] = typer.Option(None, "--project-dir", "-d", help="Project directory for project-level status"), + project_dir: Optional[Path] = typer.Option(None, "--project-dir", help="Project directory for project-level status"), ): """Show configured and installed prompts for all apps.""" manager = _get_manager() diff --git a/code_assistant_manager/cli/skills_commands.py b/code_assistant_manager/cli/skills_commands.py index 45d9546..a042c90 100644 --- a/code_assistant_manager/cli/skills_commands.py +++ b/code_assistant_manager/cli/skills_commands.py @@ -32,16 +32,10 @@ def _get_skill_manager() -> SkillManager: @skill_app.command("list") def list_skills( app_type: str = typer.Option( - "claude", - "--app", - "-a", - help="App type(s) to check installed status (claude, codex, copilot, gemini, qwen, all)", + "claude", "--app", help="App type(s) to check installed status (claude, codex, copilot, gemini, qwen, all)", ), query: Optional[str] = typer.Option( - None, - "--query", - "-q", - help="Filter skills by repository name (e.g., 'BrownFineSecurity/iothackbot')", + None, "--query", help="Filter skills by repository name (e.g., 'BrownFineSecurity/iothackbot')", ), ): """List all skills.""" @@ -269,11 +263,11 @@ def show_skill(skill_key: str = typer.Argument(..., help="Skill identifier")): @skill_app.command("create") def create_skill( skill_key: str = typer.Argument(..., help="Unique identifier for the skill"), - name: str = typer.Option(..., "--name", "-n", help="Skill name"), + name: str = typer.Option(..., "--name", help="Skill name"), description: str = typer.Option( - ..., "--description", "-d", help="Skill description" + ..., "--description", help="Skill description" ), - directory: str = typer.Option(..., "--directory", "-dir", help="Skill directory"), + directory: str = typer.Option(..., "--directory", help="Skill directory"), repo_owner: Optional[str] = typer.Option( None, "--repo-owner", help="Repository owner" ), @@ -313,12 +307,12 @@ def create_skill( @skill_app.command("update") def update_skill( skill_key: str = typer.Argument(..., help="Skill identifier"), - name: Optional[str] = typer.Option(None, "--name", "-n", help="New skill name"), + name: Optional[str] = typer.Option(None, "--name", help="New skill name"), description: Optional[str] = typer.Option( - None, "--description", "-d", help="New skill description" + None, "--description", help="New skill description" ), directory: Optional[str] = typer.Option( - None, "--directory", "-dir", help="New skill directory" + None, "--directory", help="New skill directory" ), ): """Update an existing skill.""" @@ -373,10 +367,7 @@ def delete_skill( def install_skill( skill_key: str = typer.Argument(..., help="Skill identifier"), app_type: str = typer.Option( - "claude", - "--app", - "-a", - help="App type(s) to install to (claude, codex, gemini, qwen, all)", + "claude", "--app", help="App type(s) to install to (claude, codex, gemini, qwen, all)", ), ): """Install a skill to one or more app skills directories.""" @@ -401,10 +392,7 @@ def install_skill( def uninstall_skill( skill_key: str = typer.Argument(..., help="Skill identifier"), app_type: str = typer.Option( - "claude", - "--app", - "-a", - help="App type(s) to uninstall from (claude, codex, gemini, qwen, all)", + "claude", "--app", help="App type(s) to uninstall from (claude, codex, gemini, qwen, all)", ), ): """Uninstall a skill from one or more app skills directories.""" @@ -451,9 +439,9 @@ def list_repos(): @skill_app.command("add-repo") def add_repo( - owner: str = typer.Option(..., "--owner", "-o", help="Repository owner"), - name: str = typer.Option(..., "--name", "-n", help="Repository name"), - branch: str = typer.Option("main", "--branch", "-b", help="Repository branch"), + owner: str = typer.Option(..., "--owner", help="Repository owner"), + name: str = typer.Option(..., "--name", help="Repository name"), + branch: str = typer.Option("main", "--branch", help="Repository branch"), skills_path: Optional[str] = typer.Option( None, "--skills-path", help="Skills subdirectory path" ), @@ -478,8 +466,8 @@ def add_repo( @skill_app.command("remove-repo") def remove_repo( - owner: str = typer.Option(..., "--owner", "-o", help="Repository owner"), - name: str = typer.Option(..., "--name", "-n", help="Repository name"), + owner: str = typer.Option(..., "--owner", help="Repository owner"), + name: str = typer.Option(..., "--name", help="Repository name"), force: bool = typer.Option(False, "--force", "-f", help="Skip confirmation"), ): """Remove a skill repository.""" @@ -498,7 +486,7 @@ def remove_repo( @skill_app.command("import") def import_skills( - file: Path = typer.Option(..., "--file", "-f", help="JSON file to import from") + file: Path = typer.Option(..., "--file", help="JSON file to import from") ): """Import skills from a JSON file.""" manager = _get_skill_manager() @@ -517,7 +505,7 @@ def import_skills( @skill_app.command("export") def export_skills( - file: Path = typer.Option(..., "--file", "-f", help="JSON file to export to") + file: Path = typer.Option(..., "--file", help="JSON file to export to") ): """Export skills to a JSON file.""" manager = _get_skill_manager() @@ -533,10 +521,7 @@ def export_skills( @skill_app.command("status") def skill_status( app_type: Optional[str] = typer.Option( - None, - "--app", - "-a", - help="App type(s) to show (claude, codex, gemini, qwen, all). Default shows all.", + None, "--app", help="App type(s) to show (claude, codex, gemini, qwen, all). Default shows all.", ), ): """Show skill installation status across apps (alias: installed).""" @@ -546,10 +531,7 @@ def skill_status( @skill_app.command("installed") def list_installed_skills( app_type: Optional[str] = typer.Option( - None, - "--app", - "-a", - help="App type(s) to show (claude, codex, gemini, qwen, all). Default shows all.", + None, "--app", help="App type(s) to show (claude, codex, gemini, qwen, all). Default shows all.", ), ): """Show installed skills for each app.""" @@ -603,10 +585,7 @@ def list_installed_skills( @skill_app.command("uninstall-all") def uninstall_all_skills( app_type: str = typer.Option( - ..., - "--app", - "-a", - help="App type(s) to uninstall all skills from (claude, codex, gemini, qwen, all)", + ..., "--app", help="App type(s) to uninstall all skills from (claude, codex, gemini, qwen, all)", ), force: bool = typer.Option(False, "--force", "-f", help="Skip confirmation"), ): diff --git a/code_assistant_manager/mcp/cli.py b/code_assistant_manager/mcp/cli.py index 48160e6..f8569be 100644 --- a/code_assistant_manager/mcp/cli.py +++ b/code_assistant_manager/mcp/cli.py @@ -54,7 +54,7 @@ def endpoints( @app.command() def status( client: Optional[str] = typer.Option( - None, "--client", "-c", help="Show status for specific client (or 'all')" + None, "--client", help="Show status for specific client (or 'all')" ), ): """Show MCP server installation status across clients.""" diff --git a/code_assistant_manager/mcp/install_commands.py b/code_assistant_manager/mcp/install_commands.py index 8281614..deffb1e 100644 --- a/code_assistant_manager/mcp/install_commands.py +++ b/code_assistant_manager/mcp/install_commands.py @@ -36,7 +36,7 @@ def install( server_name: str, client: str, method: Optional[str] = typer.Option( - None, "--method", "-m", help="Installation method to use" + None, "--method", help="Installation method to use" ), force: bool = typer.Option( False, "--force", "-f", help="Force installation if server already exists" diff --git a/code_assistant_manager/mcp/server_commands.py b/code_assistant_manager/mcp/server_commands.py index 6788aa0..a5707a6 100644 --- a/code_assistant_manager/mcp/server_commands.py +++ b/code_assistant_manager/mcp/server_commands.py @@ -26,7 +26,7 @@ @app.command() def list( client: Optional[str] = typer.Option( - None, "--client", "-c", help="Show only servers installed for this client" + None, "--client", help="Show only servers installed for this client" ), interactive: bool = typer.Option( False, "--interactive", "-i", help="Use interactive mode" @@ -223,10 +223,10 @@ def add( ..., help="Server names to install (comma-separated)" ), client: str = typer.Option( - "claude", "--client", "-c", help="Client to install to (claude, codex, all)" + "claude", "--client", help="Client to install to (claude, codex, all)" ), method: Optional[str] = typer.Option( - None, "--method", "-m", help="Installation method to use" + None, "--method", help="Installation method to use" ), force: bool = typer.Option( False, "--force", "-f", help="Force installation if server already exists" @@ -235,7 +235,7 @@ def add( False, "--interactive", "-i", help="Use interactive mode for server selection" ), scope: str = typer.Option( - "user", "--scope", "-s", help="Configuration scope (user or project)" + "user", "--scope", help="Configuration scope (user or project)" ), ): """Add MCP servers to a client.""" @@ -302,13 +302,13 @@ def remove( ..., help="Server names to remove (comma-separated)" ), client: str = typer.Option( - "claude", "--client", "-c", help="Client to remove from (claude, codex, all)" + "claude", "--client", help="Client to remove from (claude, codex, all)" ), interactive: bool = typer.Option( False, "--interactive", "-i", help="Use interactive mode for server selection" ), scope: str = typer.Option( - "user", "--scope", "-s", help="Configuration scope (user or project)" + "user", "--scope", help="Configuration scope (user or project)" ), ): """Remove MCP servers from a client.""" @@ -372,13 +372,13 @@ def update( ..., help="Server names to update (comma-separated)" ), client: str = typer.Option( - "claude", "--client", "-c", help="Client to update in (claude, codex, all)" + "claude", "--client", help="Client to update in (claude, codex, all)" ), interactive: bool = typer.Option( False, "--interactive", "-i", help="Use interactive mode for server selection" ), scope: str = typer.Option( - "user", "--scope", "-s", help="Configuration scope (user or project)" + "user", "--scope", help="Configuration scope (user or project)" ), ): """Update/reinstall MCP servers for a client."""