remove_packages
Remove Arch Linux packages individually or in batch. Supports dependency removal and forced removal ignoring dependencies. Requires sudo.
Instructions
[LIFECYCLE] Unified tool for removing packages (single or multiple). Accepts either a single package name or a list of packages. Supports removal with dependencies and forced removal. Only works on Arch Linux. Requires sudo access. Examples: packages='firefox', remove_dependencies=true → removes Firefox with its dependencies; packages=['pkg1', 'pkg2', 'pkg3'] → batch removal of multiple packages; packages='lib', force=true → force removal ignoring dependencies (dangerous!).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| packages | Yes | Package name (string) or list of package names (array) to remove | |
| remove_dependencies | No | Remove packages and their dependencies (pacman -Rs). Default: false | |
| force | No | Force removal ignoring dependencies (pacman -Rdd). Use with caution! Default: false |
Implementation Reference
- src/arch_ops_server/pacman.py:476-537 (handler)Main handler function for the 'remove_packages' tool. Dispatches to remove_package() for single package or remove_packages_batch() for multiple packages.
async def remove_packages( packages: Union[str, List[str]], remove_dependencies: bool = False, force: bool = False ) -> Dict[str, Any]: """ Unified tool for removing packages (single or multiple). This consolidates two operations: - Single package removal (replaces remove_package) - Batch package removal (replaces remove_packages_batch) Args: packages: Package name (string) or list of package names to remove remove_dependencies: If True, remove unneeded dependencies (pacman -Rs) force: If True, force removal ignoring dependencies (pacman -Rdd). Only works for single package. Returns: Dict with removal status and information """ if not IS_ARCH: return create_error_response( "NotSupported", "Package removal is only available on Arch Linux" ) if not check_command_exists("pacman"): return create_error_response( "CommandNotFound", "pacman command not found" ) # Normalize input to list if isinstance(packages, str): package_list = [packages] is_single = True else: package_list = packages is_single = False if not package_list: return create_error_response( "ValidationError", "No packages specified for removal" ) # Validate force flag usage if force and not is_single: return create_error_response( "ValidationError", "force flag can only be used with single package removal" ) logger.info(f"Removing {len(package_list)} package(s): {package_list} (deps={remove_dependencies}, force={force})") # Route to appropriate implementation based on input type and flags if is_single: # Single package removal return await remove_package(package_list[0], remove_dependencies, force) else: # Batch package removal (force not supported) return await remove_packages_batch(package_list, remove_dependencies) - Tool registration with input schema definition. Declares 'packages', 'remove_dependencies', and 'force' parameters.
Tool( name="remove_packages", description="[LIFECYCLE] Unified tool for removing packages (single or multiple). Accepts either a single package name or a list of packages. Supports removal with dependencies and forced removal. Only works on Arch Linux. Requires sudo access. Examples: packages='firefox', remove_dependencies=true → removes Firefox with its dependencies; packages=['pkg1', 'pkg2', 'pkg3'] → batch removal of multiple packages; packages='lib', force=true → force removal ignoring dependencies (dangerous!).", inputSchema={ "type": "object", "properties": { "packages": { "oneOf": [ {"type": "string"}, {"type": "array", "items": {"type": "string"}} ], "description": "Package name (string) or list of package names (array) to remove" }, "remove_dependencies": { "type": "boolean", "description": "Remove packages and their dependencies (pacman -Rs). Default: false", "default": False }, "force": { "type": "boolean", "description": "Force removal ignoring dependencies (pacman -Rdd). Use with caution! Default: false", "default": False } }, "required": ["packages"] }, annotations=ToolAnnotations(destructiveHint=True) ), - src/arch_ops_server/server.py:1144-1152 (registration)Tool dispatch in call_tool() that routes the 'remove_packages' name to the handler function.
elif name == "remove_packages": if not IS_ARCH: return [TextContent(type="text", text=create_platform_error_message("remove_packages"))] packages = arguments["packages"] remove_dependencies = arguments.get("remove_dependencies", False) force = arguments.get("force", False) result = await remove_packages(packages, remove_dependencies, force) return [TextContent(type="text", text=json.dumps(result, indent=2))] - Tool metadata definition specifying category, platform, permissions, workflow, and related tools.
"remove_packages": ToolMetadata( name="remove_packages", category="lifecycle", platform="arch", permission="write", workflow="removal", related_tools=["manage_orphans", "verify_package_integrity"], prerequisite_tools=[] ), - Helper function for single package removal (pacman -R, -Rs, or -Rdd). Called by remove_packages() for single package operations.
async def remove_package( package_name: str, remove_dependencies: bool = False, force: bool = False ) -> Dict[str, Any]: """ Remove a single package from the system. Args: package_name: Name of package to remove remove_dependencies: If True, remove unneeded dependencies (pacman -Rs) force: If True, force removal ignoring dependencies (pacman -Rdd) Returns: Dict with removal status and information """ if not IS_ARCH: return create_error_response( "NotSupported", "Package removal is only available on Arch Linux" ) if not check_command_exists("pacman"): return create_error_response( "CommandNotFound", "pacman command not found" ) logger.info(f"Removing package: {package_name} (deps={remove_dependencies}, force={force})") # Build command based on options cmd = ["sudo", "pacman"] if force: cmd.extend(["-Rdd"]) # Force remove, skip dependency checks elif remove_dependencies: cmd.extend(["-Rs"]) # Remove with unused dependencies else: cmd.extend(["-R"]) # Basic removal cmd.extend(["--noconfirm", package_name]) try: exit_code, stdout, stderr = await run_command( cmd, timeout=60, # Longer timeout for removal check=False, skip_sudo_check=True # We're using sudo in the command ) if exit_code != 0: logger.error(f"Package removal failed: {stderr}") return create_error_response( "RemovalError", f"Failed to remove {package_name}: {stderr}", f"Exit code: {exit_code}" ) logger.info(f"Successfully removed {package_name}") return { "success": True, "package": package_name, "removed_dependencies": remove_dependencies, "output": stdout } except Exception as e: logger.error(f"Package removal failed with exception: {e}") return create_error_response( "RemovalError", f"Failed to remove {package_name}: {str(e)}" )