{"id":29901139,"url":"https://github.com/jordangarrison/hubctl","last_synced_at":"2026-04-18T11:03:32.844Z","repository":{"id":306178684,"uuid":"1024139232","full_name":"jordangarrison/hubctl","owner":"jordangarrison","description":"Enterprise enabled github cli tool","archived":false,"fork":false,"pushed_at":"2025-07-24T02:54:02.000Z","size":58,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-24T05:53:30.552Z","etag":null,"topics":["cli","github","github-enterprise","github-enterprise-cloud","ruby","thor"],"latest_commit_sha":null,"homepage":"https://github.com/jordangarrison/hubctl","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jordangarrison.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-22T08:40:30.000Z","updated_at":"2025-07-24T03:02:50.000Z","dependencies_parsed_at":"2025-07-24T05:53:49.111Z","dependency_job_id":"1650d6c5-5533-44d5-b514-91458440e1af","html_url":"https://github.com/jordangarrison/hubctl","commit_stats":null,"previous_names":["jordangarrison/hubctl"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/jordangarrison/hubctl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jordangarrison%2Fhubctl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jordangarrison%2Fhubctl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jordangarrison%2Fhubctl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jordangarrison%2Fhubctl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jordangarrison","download_url":"https://codeload.github.com/jordangarrison/hubctl/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jordangarrison%2Fhubctl/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268241513,"owners_count":24218376,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-01T02:00:08.611Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","github","github-enterprise","github-enterprise-cloud","ruby","thor"],"created_at":"2025-08-01T14:16:47.429Z","updated_at":"2026-04-18T11:03:32.795Z","avatar_url":"https://github.com/jordangarrison.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hubctl\n\nA **comprehensive, production-ready CLI tool** for GitHub administration with real GitHub API integration, multiple output formats, interactive prompts, and beautiful error handling.\n\n## ✨ Features\n\n- 🚀 **Full GitHub API Integration** - Real GitHub API calls using Octokit\n- 🎨 **Multiple Output Formats** - Table, JSON, and list formats with colored output\n- 🛡️ **Comprehensive Error Handling** - Meaningful error messages with suggested solutions\n- 🎯 **Interactive Prompts** - Confirmation dialogs and user input with TTY-Prompt\n- ⚡ **Loading Indicators** - Spinning animations for API calls\n- 🔐 **Flexible Authentication** - Environment variables or configuration file\n- 📊 **Beautiful Tables** - Formatted output with TTY-Table\n- 🌈 **Colorized Output** - Pastel-powered colored terminal output\n- 🔄 **Batch Operations** - Bulk management operations\n- 📝 **Detailed Help** - Comprehensive help system with examples\n\n## Installation\n\n### Via Devbox\n\nIf you have [Devbox](https://www.jetify.com/devbox/docs/installing_devbox/) installed:\n\n```bash\ndevbox add github:jordangarrison/hubctl\ndevbox shell\nhubctl --help\n```\n\n### Via Nix Flake\n\nIf you have Nix installed with flakes enabled:\n\n```bash\n# Install directly from GitHub\nnix profile install github:jordangarrison/hubctl\n\n# Or run without installing\nnix run github:jordangarrison/hubctl -- --help\n\n# For development\ngit clone \u003crepository-url\u003e\ncd hubctl\nnix develop  # Enter development shell with all dependencies\n```\n\n#### Using as a Flake Input\n\nAdd hubctl to your `flake.nix` inputs:\n\n```nix\n{\n  inputs = {\n    nixpkgs.url = \"github:NixOS/nixpkgs/nixos-unstable\";\n    hubctl.url = \"github:jordangarrison/hubctl\";\n  };\n\n  outputs = { self, nixpkgs, hubctl }:\n    let\n      system = \"x86_64-linux\";\n      pkgs = nixpkgs.legacyPackages.${system};\n    in {\n      # For development shells\n      devShells.${system}.default = pkgs.mkShell {\n        buildInputs = [\n          hubctl.packages.${system}.default\n        ];\n      };\n      \n      # For NixOS system configuration\n      nixosConfigurations.yourhost = nixpkgs.lib.nixosSystem {\n        inherit system;\n        modules = [\n          {\n            environment.systemPackages = [\n              hubctl.packages.${system}.default\n            ];\n          }\n        ];\n      };\n      \n      # For Home Manager\n      homeConfigurations.youruser = home-manager.lib.homeManagerConfiguration {\n        inherit pkgs;\n        modules = [\n          {\n            home.packages = [\n              hubctl.packages.${system}.default\n            ];\n          }\n        ];\n      };\n    };\n}\n```\n\n### Local Development\n\n```bash\n# Clone the repository\ngit clone \u003crepository-url\u003e\ncd hubctl\n\n# Install dependencies\nbundle install\n\n# Make the binary executable\nchmod +x bin/hubctl\n\n# Run from local directory\n./bin/hubctl --help\n```\n\n### Build and Install as Gem\n\n```bash\n# Build the gem\ngem build hubctl.gemspec\n\n# Install locally\ngem install hubctl-0.2.1.gem\n\n# Use globally\nhubctl --help\n```\n\n## Quick Start\n\n1. **Set up authentication:**\n\n   ```bash\n   # Option 1: Environment variable (recommended)\n   export GITHUB_TOKEN=your_personal_access_token\n\n   # Option 2: Configuration file\n   hubctl config init\n   hubctl config set github_token your_personal_access_token\n   ```\n\n2. **Verify authentication:**\n\n   ```bash\n   hubctl auth\n   hubctl users whoami\n   ```\n\n3. **Set default organization (optional):**\n\n   ```bash\n   hubctl config set default_org your-org-name\n   ```\n\n## Authentication \u0026 Configuration\n\n### GitHub Token Setup\n\nCreate a Personal Access Token at \u003chttps://github.com/settings/tokens\u003e with appropriate scopes:\n\n- `repo` - Repository access\n- `admin:org` - Organization administration\n- `read:org` - Read organization data\n- `user` - User information\n\n### Configuration Commands\n\n```bash\n# Initialize configuration file\nhubctl config init\n\n# Show current configuration\nhubctl config show\n\n# Get/set specific values\nhubctl config get github_token\nhubctl config set default_org myorg\n\n# Edit config file in your editor\nhubctl config edit\n\n# Show config file path\nhubctl config path\n```\n\n## Usage Examples\n\n### Global Options\n\nAll commands support these global options:\n\n```bash\n--format=FORMAT    # Output format: table, json, list (default: table)\n--no-color         # Disable colored output\n--yes              # Skip confirmation prompts\n```\n\n**Output Format Behavior:**\n\n- **Table format**: Both data and log messages go to stdout (standard CLI behavior)\n- **JSON/List formats**: Data goes to stdout, log messages go to stderr (keeps output clean for piping/redirection)\n\n### User Management\n\n```bash\n# List users in organization (with beautiful table output)\nhubctl users list --org=myorg\nhubctl users list --org=myorg --role=admin --format=json\n\n# Show detailed user information\nhubctl users show octocat\nhubctl users whoami\n\n# Invite users to organization\nhubctl users invite user@example.com --org=myorg --role=direct_member\nhubctl users invite user@example.com --org=myorg --team-ids=123,456\n\n# Remove users (with confirmation prompt)\nhubctl users remove username --org=myorg\nhubctl users remove username --org=myorg --yes  # Skip confirmation\n```\n\n### Team Management\n\n```bash\n# List teams with member/repo counts\nhubctl teams list --org=myorg\n\n# Create teams with different permissions\nhubctl teams create \"Frontend Team\" --org=myorg \\\n  --description=\"Frontend developers\" \\\n  --privacy=closed --permission=push\n\n# Manage team membership\nhubctl teams members frontend-team --org=myorg\nhubctl teams add-member frontend-team johndoe --org=myorg --role=maintainer\nhubctl teams remove-member frontend-team johndoe --org=myorg\n\n# Show team details\nhubctl teams show frontend-team --org=myorg\n```\n\n### Repository Management\n\n```bash\n# List repositories with sorting and filtering\nhubctl repos list                                    # Personal repos\nhubctl repos list --org=myorg                        # Organization repos\nhubctl repos list --type=private --sort=created      # Filter and sort\nhubctl repos list --format=json                      # JSON output\n\n# Create repositories with templates\nhubctl repos create myrepo \\\n  --description=\"My awesome project\" \\\n  --private \\\n  --gitignore=Node \\\n  --license=MIT\n\n# Show detailed repository information\nhubctl repos show myorg/myrepo\n\n# Clone repositories\nhubctl repos clone myorg/myrepo --path=./local-name\nhubctl repos clone myorg/myrepo --depth=1  # Shallow clone\n\n# Manage repository topics\nhubctl repos topics myorg/myrepo                     # List topics\nhubctl repos topics myorg/myrepo --set=ruby,cli,api  # Set topics\nhubctl repos topics myorg/myrepo --add=new-topic     # Add topics\nhubctl repos topics myorg/myrepo --remove=old-topic  # Remove topics\n\n# Archive repositories (with confirmation)\nhubctl repos archive myorg/old-repo\n```\n\n### Organization Management\n\n```bash\n# List your organizations\nhubctl orgs list\n\n# Show detailed organization information\nhubctl orgs show myorg\n\n# List organization members with role filtering\nhubctl orgs members myorg --role=admin\nhubctl orgs members myorg --filter=2fa_disabled\n\n# List organization repositories and teams\nhubctl orgs repos myorg --type=private --sort=updated\nhubctl orgs teams myorg\n\n# Show authentication info and memberships\nhubctl orgs info\n```\n\n### Enterprise Management\n\n**Complete GitHub Enterprise Cloud management with billing insights, member administration, and security features.**\n\n#### Enterprise Overview\n\n```bash\n# Show detailed enterprise information\nhubctl enterprise show myenterprise\n\n# View enterprise statistics and metrics\nhubctl enterprise stats myenterprise\n```\n\n#### Enterprise Billing \u0026 Usage Analytics\n\n**Comprehensive billing breakdown with multiple output formats:**\n\n```bash\n# Detailed billing report (table format)\nhubctl enterprise billing myenterprise\n\n# JSON output for programmatic analysis\nhubctl enterprise billing myenterprise --format json\n\n# Tab-separated for shell processing\nhubctl enterprise billing myenterprise --format list\n```\n\n**Billing data includes:**\n- **GitHub Actions**: Total minutes, cost breakdown by runner type (Linux, Windows, macOS), usage percentages\n- **GitHub Packages**: Storage (GB-hours), data transfer (GB), associated costs\n- **GitHub Copilot**: User-months, subscription costs\n- **Total enterprise costs**: Aggregated across all services\n\n**Example JSON output for automation:**\n```json\n{\n  \"enterprise\": \"myenterprise\",\n  \"total_cost\": 8106.89,\n  \"actions\": {\n    \"total_minutes\": 682129,\n    \"total_cost\": 3285.33,\n    \"runner_breakdown\": {\n      \"Actions Linux\": {\"minutes\": 671583, \"cost\": 2844.82, \"percentage\": 98.5},\n      \"Actions Windows\": {\"minutes\": 3516, \"cost\": 10.42, \"percentage\": 0.5},\n      \"Actions macOS 3-core\": {\"minutes\": 2352, \"cost\": 32.48, \"percentage\": 0.3}\n    }\n  },\n  \"packages\": {\"total_storage_gb_hours\": 162.33, \"total_cost\": 0.0},\n  \"copilot\": {\"total_user_months\": 253.77, \"total_cost\": 4821.56}\n}\n```\n\n#### Enterprise Member \u0026 Owner Management\n\n**Complete user administration with role-based access:**\n\n```bash\n# List all enterprise members with role filtering\nhubctl enterprise members myenterprise\nhubctl enterprise members myenterprise --role=admin\nhubctl enterprise members myenterprise --role=member\nhubctl enterprise members myenterprise --two_factor_disabled\n\n# List enterprise owners\nhubctl enterprise owners myenterprise\n\n# Manage enterprise ownership\nhubctl enterprise add-owner myenterprise username\nhubctl enterprise remove-owner myenterprise username\n```\n\n**Member data includes:**\n- Login, email, role (Owner/Member/Outside collaborator)\n- Two-factor authentication status\n- SAML identity configuration\n- Organization membership details\n\n#### Enterprise Organization Management\n\n```bash\n# List organizations in enterprise\nhubctl enterprise organizations myenterprise\n\n# Create new organization in enterprise\nhubctl enterprise create-org myenterprise neworg \\\n  --display-name=\"New Organization\" \\\n  --description=\"Organization description\" \\\n  --billing-email=billing@company.com\n```\n\n#### Enterprise Security \u0026 Compliance\n\n**SAML SSO Authorization Management:**\n\n```bash\n# List SAML SSO authorizations\nhubctl enterprise saml-sso list myenterprise\n\n# Show specific user's SAML authorization\nhubctl enterprise saml-sso show myenterprise username\n\n# Remove SAML SSO authorization (with confirmation)\nhubctl enterprise saml-sso remove myenterprise username\n```\n\n**Security Analysis Settings:**\n\n```bash\n# View current security settings\nhubctl enterprise security myenterprise\n\n# Enable security features for new repositories\nhubctl enterprise security myenterprise \\\n  --dependency-graph-enabled-for-new-repositories \\\n  --secret-scanning-enabled-for-new-repositories \\\n  --secret-scanning-push-protection-enabled-for-new-repositories\n```\n\n**Audit Log Access:**\n\n```bash\n# View enterprise audit log\nhubctl enterprise audit-log myenterprise\n\n# Filter audit log by phrase and time range\nhubctl enterprise audit-log myenterprise \\\n  --phrase=\"repository.create\" \\\n  --after=\"2024-01-01T00:00:00Z\" \\\n  --before=\"2024-12-31T23:59:59Z\"\n```\n\n#### Enterprise Automation Examples\n\n**Billing Analysis Script:**\n```bash\n#!/bin/bash\n# Monthly billing report\nENTERPRISE=\"myenterprise\"\nREPORT_DATE=$(date +\"%Y-%m\")\n\necho \"Enterprise Billing Report - $REPORT_DATE\"\necho \"========================================\"\n\n# Get billing data in JSON for processing\nBILLING_DATA=$(hubctl enterprise billing $ENTERPRISE --format json)\n\n# Extract key metrics\nTOTAL_COST=$(echo \"$BILLING_DATA\" | jq -r '.total_cost')\nACTIONS_MINUTES=$(echo \"$BILLING_DATA\" | jq -r '.actions.total_minutes')\nCOPILOT_USERS=$(echo \"$BILLING_DATA\" | jq -r '.copilot.total_user_months')\n\necho \"Total Cost: \\$${TOTAL_COST}\"\necho \"Actions Minutes: ${ACTIONS_MINUTES}\"\necho \"Copilot User-Months: ${COPILOT_USERS}\"\n\n# Runner type breakdown\necho -e \"\\nRunner Usage:\"\necho \"$BILLING_DATA\" | jq -r '.actions.runner_breakdown | to_entries[] | \"\\(.key): \\(.value.minutes) minutes (\\(.value.percentage)%)\"'\n```\n\n**Member Audit Script:**\n```bash\n#!/bin/bash\n# Security audit: Find users with 2FA disabled\nENTERPRISE=\"myenterprise\"\n\necho \"Security Audit: Users without 2FA\"\necho \"================================\"\n\n# Get members without 2FA in list format for processing\nhubctl enterprise members $ENTERPRISE --two_factor_disabled --format list | \\\nwhile IFS=$'\\t' read -r login role email two_factor_disabled saml_identity; do\n    echo \"⚠️  $login ($role) - Email: $email\"\ndone\n\necho -e \"\\nRecommendation: Enable 2FA requirement in organization settings\"\n```\n\n### Output Format Examples\n\nhubctl supports three output formats optimized for different use cases:\n\n#### Table Format (Default)\n\nBeautiful formatted tables for human consumption:\n\n```bash\n# Default table output with colors and formatting\nhubctl users list --org=myorg\nhubctl orgs list\nhubctl repos list --org=myorg\n```\n\n#### JSON Format + jq\n\nPerfect for scripting and programmatic access. Log messages go to stderr, keeping stdout clean:\n\n```bash\n# Extract specific fields\nhubctl users list --org=myorg --format=json | jq '.[] | .login'\nhubctl orgs list --format=json | jq '.[].login'\n\n# Filter and transform data\nhubctl users list --format=json | jq '.[] | select(.type == \"User\") | .login'\nhubctl repos list --format=json | jq '.[] | select(.private == true) | {name, stars}'\n\n# Complex queries and aggregation\nhubctl users list --format=json | jq 'group_by(.type) | map({type: .[0].type, count: length})'\nhubctl repos list --format=json | jq 'map(.stars) | add'  # Total stars\n\n# Save data for processing\nhubctl users list --format=json \u003e users.json\nhubctl orgs list --format=json | jq '.[0]' \u003e org_info.json\n```\n\n#### List Format + GNU Tools\n\nTab-separated values optimized for awk, cut, sort, grep, and other Unix tools:\n\n```bash\n# Extract fields with cut\nhubctl users list --format=list | cut -f1              # Just usernames\nhubctl orgs list --format=list | cut -f1,3             # Names and descriptions\nhubctl repos list --format=list | cut -f1,7,8          # Name, stars, forks\n\n# Process with awk\nhubctl users list --format=list | awk -F'\\t' '{print $1}'                    # Usernames\nhubctl users list --format=list | awk -F'\\t' '{print NF, $1}'                # Field count + username\nhubctl orgs list --format=list | awk -F'\\t' '$3 != \"-\" {print $1 \": \" $3}'   # Orgs with descriptions\n\n# Sorting and filtering\nhubctl repos list --format=list | sort -t$'\\t' -k7 -nr          # Sort by stars (descending)\nhubctl users list --format=list | grep -E '^(admin|bot)'        # Users starting with admin/bot\nhubctl orgs list --format=list | sort -t$'\\t' -k3               # Sort by description\n\n# Counting and statistics\nhubctl users list --format=list | awk -F'\\t' '{print $3}' | sort | uniq -c    # Count by user type\nhubctl repos list --format=list | awk -F'\\t' '{sum+=$7} END {print sum}'      # Total stars\nhubctl users list --format=list | wc -l                                       # Total users\n\n# Advanced processing\nhubctl users list --format=list | awk -F'\\t' 'length($1) \u003e 10 {print $1}'    # Long usernames\nhubctl repos list --format=list | awk -F'\\t' '$2==\"false\" \u0026\u0026 $7\u003e100'         # Public repos with 100+ stars\n```\n\n#### Combining Formats in Scripts\n\n```bash\n#!/bin/bash\n# Example: Create a report of org statistics\n\necho \"Organization Report\"\necho \"==================\"\n\n# Get org info in JSON for structured data\nORG_INFO=$(hubctl orgs show myorg --format=json)\nORG_NAME=$(echo \"$ORG_INFO\" | jq -r '.name // .login')\necho \"Organization: $ORG_NAME\"\n\n# Use list format for easy counting\nUSER_COUNT=$(hubctl users list --org=myorg --format=list 2\u003e/dev/null | wc -l)\nREPO_COUNT=$(hubctl repos list --org=myorg --format=list 2\u003e/dev/null | wc -l)\nTEAM_COUNT=$(hubctl teams list --org=myorg --format=list 2\u003e/dev/null | wc -l)\n\necho \"Users: $USER_COUNT\"\necho \"Repositories: $REPO_COUNT\"\necho \"Teams: $TEAM_COUNT\"\n\n# Use JSON for complex analysis\necho -e \"\\nTop repositories by stars:\"\nhubctl repos list --org=myorg --format=json 2\u003e/dev/null | \\\n  jq -r 'sort_by(.stars) | reverse | .[0:5] | .[] | \"\\(.name): \\(.stars) stars\"'\n```\n\n#### Format Selection Guide\n\n- **Table**: Human-readable output, terminal viewing, reports\n- **JSON**: Scripts, APIs, complex data processing, integration with other tools\n- **List**: Shell scripting, GNU tools (awk/cut/sort), simple data extraction\n\nAll formats support the same commands and options - just add `--format=FORMAT` to any command.\n\n## Advanced Features\n\n### Error Handling \u0026 Recovery\n\nhubctl provides detailed error messages with suggested solutions:\n\n```bash\n$ hubctl users list --org=nonexistent\n✗ Resource not found. Please check the name and your permissions.\n\n$ hubctl users list  # No org specified\n✗ Organization is required but not specified\nℹ Specify with --org=ORG or set default: hubctl config set default_org ORG\n```\n\n### Interactive Features\n\n- **Confirmation prompts** for destructive operations\n- **Spinner animations** during API calls\n- **Colorized output** with success/error indicators\n- **Progress feedback** for long-running operations\n\n### Batch Operations\n\nSkip confirmations for scripting:\n\n```bash\n# Remove multiple users in a script\nfor user in user1 user2 user3; do\n  hubctl users remove $user --org=myorg --yes\ndone\n```\n\n## Development\n\n### Project Structure\n\n```\nhubctl/\n├── bin/hubctl                    # Executable entry point\n├── lib/\n│   ├── hubctl.rb                # Main module, loads all components\n│   └── hubctl/\n│       ├── version.rb           # Version constant\n│       ├── cli.rb               # Main CLI class with global options\n│       ├── base_command.rb      # Base class for all subcommands\n│       ├── github_client.rb     # GitHub API client wrapper\n│       ├── formatter.rb         # Output formatting utilities\n│       ├── config.rb            # Configuration management\n│       ├── config_cli.rb        # Config subcommands\n│       ├── users.rb             # User management commands\n│       ├── teams.rb             # Team management commands\n│       ├── repos.rb             # Repository management commands\n│       ├── orgs.rb              # Organization management commands\n│       └── enterprise.rb        # Enterprise management commands\n├── spec/                         # Test suite\n├── docs/                         # Documentation\n├── hubctl.gemspec               # Gem specification\n├── Gemfile                      # Dependencies\n├── Rakefile                     # Build tasks\n├── TESTING.md                   # Testing documentation\n└── README.md                    # This file\n```\n\n### Dependencies\n\n- **thor** ~\u003e 1.4 - CLI framework\n- **octokit** ~\u003e 8.0 - GitHub API client\n- **tty-prompt** ~\u003e 0.23 - Interactive prompts\n- **tty-table** ~\u003e 0.12 - Table formatting\n- **tty-spinner** ~\u003e 0.9 - Loading spinners\n- **pastel** ~\u003e 0.8 - Colored output\n- **json** ~\u003e 2.6 - JSON formatting\n\n### Adding New Commands\n\n1. **Add to existing subcommand:**\n\n   ```ruby\n   # In lib/hubctl/users.rb\n   desc 'block USER', 'Block a user'\n   method_option :org, type: :string, desc: 'Organization name'\n   def block(username)\n     ensure_authenticated!\n     org = require_org!\n\n     begin\n       with_spinner(\"Blocking user\") do\n         github_client.block_user(org, username)\n       end\n       formatter.success(\"Successfully blocked #{username}\")\n     rescue =\u003e e\n       handle_error(e)\n     end\n   end\n   ```\n\n2. **Create new subcommand:**\n   - Create `lib/hubctl/new_feature.rb` inheriting from `BaseCommand`\n   - Add `require_relative` in `lib/hubctl.rb`\n   - Add subcommand in `lib/hubctl/cli.rb`\n\n### Error Handling Pattern\n\n```ruby\ndef my_command\n  ensure_authenticated!  # Check GitHub auth\n  org = require_org!     # Check organization requirement\n\n  begin\n    result = with_spinner(\"Processing\") do\n      github_client.some_api_call(params)\n    end\n\n    formatter.success(\"Operation completed\")\n    formatter.output(result)\n  rescue =\u003e e\n    handle_error(e)  # Consistent error handling\n  end\nend\n```\n\n## Testing\n\n```bash\n# Test core functionality\n./bin/hubctl --help\n./bin/hubctl version\n./bin/hubctl auth\n\n# Test with different formats\n./bin/hubctl config show\n./bin/hubctl config show --format=json\n./bin/hubctl config show --no-color\n\n# Test error handling (without token)\n./bin/hubctl users list --org=test\n```\n\n## Rate Limiting\n\nhubctl automatically handles GitHub's rate limiting:\n\n- Shows rate limit status in `hubctl auth`\n- Provides meaningful error messages when limits exceeded\n- Uses auto-pagination for large result sets\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Make your changes following the established patterns\n4. Add tests if applicable\n5. Commit your changes (`git commit -m 'Add amazing feature'`)\n6. Push to the branch (`git push origin feature/amazing-feature`)\n7. Open a Pull Request\n\n## License\n\nMIT License - see LICENSE file for details.\n\n## Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for detailed version history and release notes.\n\n## Examples in Action\n\n```bash\n# Beautiful table output with colors\n$ hubctl users list --org=octocat\n┌─────────────┬────────┬──────┬────────────┬─────────────────────────────────┐\n│ login       │ id     │ type │ site_admin │ url                             │\n├─────────────┼────────┼──────┼────────────┼─────────────────────────────────┤\n│ octocat     │ 1      │ User │ ✗          │ https://github.com/octocat      │\n│ defunkt     │ 2      │ User │ ✗          │ https://github.com/defunkt      │\n└─────────────┴────────┴──────┴────────────┴─────────────────────────────────┘\n✓ Found 2 users in octocat\n\n# JSON output for scripting\n$ hubctl repos list --format=json | jq '.[0].name'\n\"Hello-World\"\n\n# Interactive confirmation\n$ hubctl users remove baduser --org=myorg\n? Are you sure you want to remove baduser from myorg? No\nℹ Operation cancelled\n```\n\n**hubctl** - Making GitHub administration beautiful, reliable, and efficient! 🚀\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjordangarrison%2Fhubctl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjordangarrison%2Fhubctl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjordangarrison%2Fhubctl/lists"}