diff --git a/docs/README.skills.md b/docs/README.skills.md index 381cbc66..7dcffbad 100644 --- a/docs/README.skills.md +++ b/docs/README.skills.md @@ -24,16 +24,24 @@ Skills differ from other primitives by supporting bundled assets (scripts, code | ---- | ----------- | -------------- | | [appinsights-instrumentation](../skills/appinsights-instrumentation/SKILL.md) | Instrument a webapp to send useful telemetry data to Azure App Insights | `LICENSE.txt`
`examples/appinsights.bicep`
`references/ASPNETCORE.md`
`references/AUTO.md`
`references/NODEJS.md`
`references/PYTHON.md`
`scripts/appinsights.ps1` | | [azure-deployment-preflight](../skills/azure-deployment-preflight/SKILL.md) | Performs comprehensive preflight validation of Bicep deployments to Azure, including template syntax validation, what-if analysis, and permission checks. Use this skill before any deployment to Azure to preview changes, identify potential issues, and ensure the deployment will succeed. Activate when users mention deploying to Azure, validating Bicep files, checking deployment permissions, previewing infrastructure changes, running what-if, or preparing for azd provision. | `references/ERROR-HANDLING.md`
`references/REPORT-TEMPLATE.md`
`references/VALIDATION-COMMANDS.md` | +| [azure-devops-cli](../skills/azure-devops-cli/SKILL.md) | Manage Azure DevOps resources via CLI including projects, repos, pipelines, builds, pull requests, work items, artifacts, and service endpoints. Use when working with Azure DevOps, az commands, devops automation, CI/CD, or when user mentions Azure DevOps CLI. | None | | [azure-resource-visualizer](../skills/azure-resource-visualizer/SKILL.md) | Analyze Azure resource groups and generate detailed Mermaid architecture diagrams showing the relationships between individual resources. Use this skill when the user asks for a diagram of their Azure resources or help in understanding how the resources relate to each other. | `LICENSE.txt`
`assets/template-architecture.md` | | [azure-role-selector](../skills/azure-role-selector/SKILL.md) | When user is asking for guidance for which role to assign to an identity given desired permissions, this agent helps them understand the role that will meet the requirements with least privilege access and how to apply that role. | `LICENSE.txt` | | [azure-static-web-apps](../skills/azure-static-web-apps/SKILL.md) | Helps create, configure, and deploy Azure Static Web Apps using the SWA CLI. Use when deploying static sites to Azure, setting up SWA local development, configuring staticwebapp.config.json, adding Azure Functions APIs to SWA, or setting up GitHub Actions CI/CD for Static Web Apps. | None | +| [chrome-devtools](../skills/chrome-devtools/SKILL.md) | Expert-level browser automation, debugging, and performance analysis using Chrome DevTools MCP. Use for interacting with web pages, capturing screenshots, analyzing network traffic, and profiling performance. | None | +| [gh-cli](../skills/gh-cli/SKILL.md) | GitHub CLI (gh) comprehensive reference for repositories, issues, pull requests, Actions, projects, releases, gists, codespaces, organizations, extensions, and all GitHub operations from the command line. | None | +| [git-commit](../skills/git-commit/SKILL.md) | Execute git commit with conventional commit message analysis, intelligent staging, and message generation. Use when user asks to commit changes, create a git commit, or mentions "/commit". Supports: (1) Auto-detecting type and scope from changes, (2) Generating conventional commit messages from diff, (3) Interactive commit with optional type/scope/description overrides, (4) Intelligent file staging for logical grouping | None | | [github-issues](../skills/github-issues/SKILL.md) | Create, update, and manage GitHub issues using MCP tools. Use this skill when users want to create bug reports, feature requests, or task issues, update existing issues, add labels/assignees/milestones, or manage issue workflows. Triggers on requests like "create an issue", "file a bug", "request a feature", "update issue X", or any GitHub issue management task. | `references/templates.md` | | [image-manipulation-image-magick](../skills/image-manipulation-image-magick/SKILL.md) | Process and manipulate images using ImageMagick. Supports resizing, format conversion, batch processing, and retrieving image metadata. Use when working with images, creating thumbnails, resizing wallpapers, or performing batch image operations. | None | | [legacy-circuit-mockups](../skills/legacy-circuit-mockups/SKILL.md) | Generate breadboard circuit mockups and visual diagrams using HTML5 Canvas drawing techniques. Use when asked to create circuit layouts, visualize electronic component placements, draw breadboard diagrams, mockup 6502 builds, generate retro computer schematics, or design vintage electronics projects. Supports 555 timers, W65C02S microprocessors, 28C256 EEPROMs, W65C22 VIA chips, 7400-series logic gates, LEDs, resistors, capacitors, switches, buttons, crystals, and wires. | `references/28256-eeprom.md`
`references/555.md`
`references/6502.md`
`references/6522.md`
`references/6C62256.md`
`references/7400-series.md`
`references/assembly-compiler.md`
`references/assembly-language.md`
`references/basic-electronic-components.md`
`references/breadboard.md`
`references/common-breadboard-components.md`
`references/connecting-electronic-components.md`
`references/emulator-28256-eeprom.md`
`references/emulator-6502.md`
`references/emulator-6522.md`
`references/emulator-6C62256.md`
`references/emulator-lcd.md`
`references/lcd.md`
`references/minipro.md`
`references/t48eeprom-programmer.md` | | [make-skill-template](../skills/make-skill-template/SKILL.md) | Create new Agent Skills for GitHub Copilot from prompts or by duplicating this template. Use when asked to "create a skill", "make a new skill", "scaffold a skill", or when building specialized AI capabilities with bundled resources. Generates SKILL.md files with proper frontmatter, directory structure, and optional scripts/references/assets folders. | None | +| [mcp-cli](../skills/mcp-cli/SKILL.md) | Interface for MCP (Model Context Protocol) servers via CLI. Use when you need to interact with external tools, APIs, or data sources through MCP servers, list available MCP servers/tools, or call MCP tools from command line. | None | | [microsoft-code-reference](../skills/microsoft-code-reference/SKILL.md) | Look up Microsoft API references, find working code samples, and verify SDK code is correct. Use when working with Azure SDKs, .NET libraries, or Microsoft APIs—to find the right method, check parameters, get working examples, or troubleshoot errors. Catches hallucinated methods, wrong signatures, and deprecated patterns by querying official docs. | None | | [microsoft-docs](../skills/microsoft-docs/SKILL.md) | Query official Microsoft documentation to understand concepts, find tutorials, and learn how services work. Use for Azure, .NET, Microsoft 365, Windows, Power Platform, and all Microsoft technologies. Get accurate, current information from learn.microsoft.com and other official Microsoft websites—architecture overviews, quickstarts, configuration guides, limits, and best practices. | None | | [nuget-manager](../skills/nuget-manager/SKILL.md) | Manage NuGet packages in .NET projects/solutions. Use this skill when adding, removing, or updating NuGet package versions. It enforces using `dotnet` CLI for package management and provides strict procedures for direct file edits only when updating versions. | None | +| [plantuml-ascii](../skills/plantuml-ascii/SKILL.md) | Generate ASCII art diagrams using PlantUML text mode. Use when user asks to create ASCII diagrams, text-based diagrams, terminal-friendly diagrams, or mentions plantuml ascii, text diagram, ascii art diagram. Supports: Converting PlantUML diagrams to ASCII art, Creating sequence diagrams, class diagrams, flowcharts in ASCII format, Generating Unicode-enhanced ASCII art with -utxt flag | None | +| [prd](../skills/prd/SKILL.md) | Generate high-quality Product Requirements Documents (PRDs) for AI agents and software systems. Includes executive summaries, user stories, technical specifications, AI-specific requirements (models, data, prompts), and risk analysis. | None | +| [refactor](../skills/refactor/SKILL.md) | Surgical code refactoring to improve maintainability without changing behavior. Covers extracting functions, renaming variables, breaking down god functions, improving type safety, eliminating code smells, and applying design patterns. Less drastic than repo-rebuilder; use for gradual improvements. | None | | [snowflake-semanticview](../skills/snowflake-semanticview/SKILL.md) | Create, alter, and validate Snowflake semantic views using Snowflake CLI (snow). Use when asked to build or troubleshoot semantic views/semantic layer definitions with CREATE/ALTER SEMANTIC VIEW, to validate semantic-view DDL against Snowflake via CLI, or to guide Snowflake CLI installation and connection setup. | None | | [vscode-ext-commands](../skills/vscode-ext-commands/SKILL.md) | Guidelines for contributing commands in VS Code extensions. Indicates naming convention, visibility, localization and other relevant attributes, following VS Code extension development guidelines, libraries and good practices | None | | [vscode-ext-localization](../skills/vscode-ext-localization/SKILL.md) | Guidelines for proper localization of VS Code extensions, following VS Code extension development guidelines, libraries and good practices | None | diff --git a/skills/azure-devops-cli/SKILL.md b/skills/azure-devops-cli/SKILL.md new file mode 100644 index 00000000..dd2ceb78 --- /dev/null +++ b/skills/azure-devops-cli/SKILL.md @@ -0,0 +1,2467 @@ +--- +name: azure-devops-cli +description: Manage Azure DevOps resources via CLI including projects, repos, pipelines, builds, pull requests, work items, artifacts, and service endpoints. Use when working with Azure DevOps, az commands, devops automation, CI/CD, or when user mentions Azure DevOps CLI. +--- + +# Azure DevOps CLI + +This Skill helps manage Azure DevOps resources using the Azure CLI with Azure DevOps extension. + +**CLI Version:** 2.81.0 (current as of 2025) + +## Prerequisites + +Install Azure CLI and Azure DevOps extension: + +```bash +# Install Azure CLI +brew install azure-cli # macOS +curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash # Linux +pip install azure-cli # via pip + +# Verify installation +az --version + +# Install Azure DevOps extension +az extension add --name azure-devops +az extension show --name azure-devops +``` + +## CLI Structure + +``` +az devops # Main DevOps commands +├── admin # Administration (banner) +├── extension # Extension management +├── project # Team projects +├── security # Security operations +│ ├── group # Security groups +│ └── permission # Security permissions +├── service-endpoint # Service connections +├── team # Teams +├── user # Users +├── wiki # Wikis +├── configure # Set defaults +├── invoke # Invoke REST API +├── login # Authenticate +└── logout # Clear credentials + +az pipelines # Azure Pipelines +├── agent # Agents +├── build # Builds +├── folder # Pipeline folders +├── pool # Agent pools +├── queue # Agent queues +├── release # Releases +├── runs # Pipeline runs +├── variable # Pipeline variables +└── variable-group # Variable groups + +az boards # Azure Boards +├── area # Area paths +├── iteration # Iterations +└── work-item # Work items + +az repos # Azure Repos +├── import # Git imports +├── policy # Branch policies +├── pr # Pull requests +└── ref # Git references + +az artifacts # Azure Artifacts +└── universal # Universal Packages + ├── download # Download packages + └── publish # Publish packages +``` + +## Authentication + +### Login to Azure DevOps + +```bash +# Interactive login (prompts for PAT) +az devops login --organization https://dev.azure.com/{org} + +# Login with PAT token +az devops login --organization https://dev.azure.com/{org} --token YOUR_PAT_TOKEN + +# Logout +az devops logout --organization https://dev.azure.com/{org} +``` + +### Configure Defaults + +```bash +# Set default organization and project +az devops configure --defaults organization=https://dev.azure.com/{org} project={project} + +# List current configuration +az devops configure --list + +# Enable Git aliases +az devops configure --use-git-aliases true +``` + +## Extension Management + +### List Extensions + +```bash +# List available extensions +az extension list-available --output table + +# List installed extensions +az extension list --output table +``` + +### Manage Azure DevOps Extension + +```bash +# Install Azure DevOps extension +az extension add --name azure-devops + +# Update Azure DevOps extension +az extension update --name azure-devops + +# Remove extension +az extension remove --name azure-devops + +# Install from local path +az extension add --source ~/extensions/azure-devops.whl +``` + +## Projects + +### List Projects + +```bash +az devops project list --organization https://dev.azure.com/{org} +az devops project list --top 10 --output table +``` + +### Create Project + +```bash +az devops project create \ + --name myNewProject \ + --organization https://dev.azure.com/{org} \ + --description "My new DevOps project" \ + --source-control git \ + --visibility private +``` + +### Show Project Details + +```bash +az devops project show --project {project-name} --org https://dev.azure.com/{org} +``` + +### Delete Project + +```bash +az devops project delete --id {project-id} --org https://dev.azure.com/{org} --yes +``` + +## Repositories + +### List Repositories + +```bash +az repos list --org https://dev.azure.com/{org} --project {project} +az repos list --output table +``` + +### Show Repository Details + +```bash +az repos show --repository {repo-name} --project {project} +``` + +### Create Repository + +```bash +az repos create --name {repo-name} --project {project} +``` + +### Delete Repository + +```bash +az repos delete --id {repo-id} --project {project} --yes +``` + +### Update Repository + +```bash +az repos update --id {repo-id} --name {new-name} --project {project} +``` + +## Repository Import + +### Import Git Repository + +```bash +# Import from public Git repository +az repos import create \ + --git-source-url https://github.com/user/repo \ + --repository {repo-name} + +# Import with authentication +az repos import create \ + --git-source-url https://github.com/user/private-repo \ + --repository {repo-name} \ + --user {username} \ + --password {password-or-pat} +``` + +## Pull Requests + +### Create Pull Request + +```bash +# Basic PR creation +az repos pr create \ + --repository {repo} \ + --source-branch {source-branch} \ + --target-branch {target-branch} \ + --title "PR Title" \ + --description "PR description" \ + --open + +# PR with work items +az repos pr create \ + --repository {repo} \ + --source-branch {source-branch} \ + --work-items 63 64 + +# Draft PR with reviewers +az repos pr create \ + --repository {repo} \ + --source-branch feature/new-feature \ + --target-branch main \ + --title "Feature: New functionality" \ + --draft true \ + --reviewers user1@example.com user2@example.com \ + --required-reviewers lead@example.com \ + --labels "enhancement" "backlog" +``` + +### List Pull Requests + +```bash +# All PRs +az repos pr list --repository {repo} + +# Filter by status +az repos pr list --repository {repo} --status active + +# Filter by creator +az repos pr list --repository {repo} --creator {email} + +# Output as table +az repos pr list --repository {repo} --output table +``` + +### Show PR Details + +```bash +az repos pr show --id {pr-id} +az repos pr show --id {pr-id} --open # Open in browser +``` + +### Update PR (Complete/Abandon/Draft) + +```bash +# Complete PR +az repos pr update --id {pr-id} --status completed + +# Abandon PR +az repos pr update --id {pr-id} --status abandoned + +# Set to draft +az repos pr update --id {pr-id} --draft true + +# Publish draft PR +az repos pr update --id {pr-id} --draft false + +# Auto-complete when policies pass +az repos pr update --id {pr-id} --auto-complete true + +# Set title and description +az repos pr update --id {pr-id} --title "New title" --description "New description" +``` + +### Checkout PR Locally + +```bash +# Checkout PR branch +az repos pr checkout --id {pr-id} + +# Checkout with specific remote +az repos pr checkout --id {pr-id} --remote-name upstream +``` + +### Vote on PR + +```bash +az repos pr set-vote --id {pr-id} --vote approve +az repos pr set-vote --id {pr-id} --vote approve-with-suggestions +az repos pr set-vote --id {pr-id} --vote reject +az repos pr set-vote --id {pr-id} --vote wait-for-author +az repos pr set-vote --id {pr-id} --vote reset +``` + +### PR Reviewers + +```bash +# Add reviewers +az repos pr reviewer add --id {pr-id} --reviewers user1@example.com user2@example.com + +# List reviewers +az repos pr reviewer list --id {pr-id} + +# Remove reviewers +az repos pr reviewer remove --id {pr-id} --reviewers user1@example.com +``` + +### PR Work Items + +```bash +# Add work items to PR +az repos pr work-item add --id {pr-id} --work-items {id1} {id2} + +# List PR work items +az repos pr work-item list --id {pr-id} + +# Remove work items from PR +az repos pr work-item remove --id {pr-id} --work-items {id1} +``` + +### PR Policies + +```bash +# List policies for a PR +az repos pr policy list --id {pr-id} + +# Queue policy evaluation for a PR +az repos pr policy queue --id {pr-id} --evaluation-id {evaluation-id} +``` + +## Pipelines + +### List Pipelines + +```bash +az pipelines list --output table +az pipelines list --query "[?name=='myPipeline']" +az pipelines list --folder-path 'folder/subfolder' +``` + +### Create Pipeline + +```bash +# From local repository context (auto-detects settings) +az pipelines create --name 'ContosoBuild' --description 'Pipeline for contoso project' + +# With specific branch and YAML path +az pipelines create \ + --name {pipeline-name} \ + --repository {repo} \ + --branch main \ + --yaml-path azure-pipelines.yml \ + --description "My CI/CD pipeline" + +# For GitHub repository +az pipelines create \ + --name 'GitHubPipeline' \ + --repository https://github.com/Org/Repo \ + --branch main \ + --repository-type github + +# Skip first run +az pipelines create --name 'MyPipeline' --skip-run true +``` + +### Show Pipeline + +```bash +az pipelines show --id {pipeline-id} +az pipelines show --name {pipeline-name} +``` + +### Update Pipeline + +```bash +az pipelines update --id {pipeline-id} --name "New name" --description "Updated description" +``` + +### Delete Pipeline + +```bash +az pipelines delete --id {pipeline-id} --yes +``` + +### Run Pipeline + +```bash +# Run by name +az pipelines run --name {pipeline-name} --branch main + +# Run by ID +az pipelines run --id {pipeline-id} --branch refs/heads/main + +# With parameters +az pipelines run --name {pipeline-name} --parameters version=1.0.0 environment=prod + +# With variables +az pipelines run --name {pipeline-name} --variables buildId=123 configuration=release + +# Open results in browser +az pipelines run --name {pipeline-name} --open +``` + +## Pipeline Runs + +### List Runs + +```bash +az pipelines runs list --pipeline {pipeline-id} +az pipelines runs list --name {pipeline-name} --top 10 +az pipelines runs list --branch main --status completed +``` + +### Show Run Details + +```bash +az pipelines runs show --run-id {run-id} +az pipelines runs show --run-id {run-id} --open +``` + +### Pipeline Artifacts + +```bash +# List artifacts for a run +az pipelines runs artifact list --run-id {run-id} + +# Download artifact +az pipelines runs artifact download \ + --artifact-name '{artifact-name}' \ + --path {local-path} \ + --run-id {run-id} + +# Upload artifact +az pipelines runs artifact upload \ + --artifact-name '{artifact-name}' \ + --path {local-path} \ + --run-id {run-id} +``` + +### Pipeline Run Tags + +```bash +# Add tag to run +az pipelines runs tag add --run-id {run-id} --tags production v1.0 + +# List run tags +az pipelines runs tag list --run-id {run-id} --output table +``` + +## Builds + +### List Builds + +```bash +az pipelines build list +az pipelines build list --definition {build-definition-id} +az pipelines build list --status completed --result succeeded +``` + +### Queue Build + +```bash +az pipelines build queue --definition {build-definition-id} --branch main +az pipelines build queue --definition {build-definition-id} --parameters version=1.0.0 +``` + +### Show Build Details + +```bash +az pipelines build show --id {build-id} +``` + +### Cancel Build + +```bash +az pipelines build cancel --id {build-id} +``` + +### Build Tags + +```bash +# Add tag to build +az pipelines build tag add --build-id {build-id} --tags prod release + +# Delete tag from build +az pipelines build tag delete --build-id {build-id} --tag prod +``` + +## Build Definitions + +### List Build Definitions + +```bash +az pipelines build definition list +az pipelines build definition list --name {definition-name} +``` + +### Show Build Definition + +```bash +az pipelines build definition show --id {definition-id} +``` + +## Releases + +### List Releases + +```bash +az pipelines release list +az pipelines release list --definition {release-definition-id} +``` + +### Create Release + +```bash +az pipelines release create --definition {release-definition-id} +az pipelines release create --definition {release-definition-id} --description "Release v1.0" +``` + +### Show Release + +```bash +az pipelines release show --id {release-id} +``` + +## Release Definitions + +### List Release Definitions + +```bash +az pipelines release definition list +``` + +### Show Release Definition + +```bash +az pipelines release definition show --id {definition-id} +``` + +## Pipeline Variables + +### List Variables + +```bash +az pipelines variable list --pipeline-id {pipeline-id} +``` + +### Create Variable + +```bash +# Non-secret variable +az pipelines variable create \ + --name {var-name} \ + --value {var-value} \ + --pipeline-id {pipeline-id} + +# Secret variable +az pipelines variable create \ + --name {var-name} \ + --secret true \ + --pipeline-id {pipeline-id} + +# Secret with prompt +az pipelines variable create \ + --name {var-name} \ + --secret true \ + --prompt true \ + --pipeline-id {pipeline-id} +``` + +### Update Variable + +```bash +az pipelines variable update \ + --name {var-name} \ + --value {new-value} \ + --pipeline-id {pipeline-id} + +# Update secret variable +az pipelines variable update \ + --name {var-name} \ + --secret true \ + --value "{new-secret-value}" \ + --pipeline-id {pipeline-id} +``` + +### Delete Variable + +```bash +az pipelines variable delete --name {var-name} --pipeline-id {pipeline-id} --yes +``` + +## Variable Groups + +### List Variable Groups + +```bash +az pipelines variable-group list +az pipelines variable-group list --output table +``` + +### Show Variable Group + +```bash +az pipelines variable-group show --id {group-id} +``` + +### Create Variable Group + +```bash +az pipelines variable-group create \ + --name {group-name} \ + --variables key1=value1 key2=value2 \ + --authorize true +``` + +### Update Variable Group + +```bash +az pipelines variable-group update \ + --id {group-id} \ + --name {new-name} \ + --description "Updated description" +``` + +### Delete Variable Group + +```bash +az pipelines variable-group delete --id {group-id} --yes +``` + +### Variable Group Variables + +#### List Variables + +```bash +az pipelines variable-group variable list --group-id {group-id} +``` + +#### Create Variable + +```bash +# Non-secret variable +az pipelines variable-group variable create \ + --group-id {group-id} \ + --name {var-name} \ + --value {var-value} + +# Secret variable (will prompt for value if not provided) +az pipelines variable-group variable create \ + --group-id {group-id} \ + --name {var-name} \ + --secret true + +# Secret with environment variable +export AZURE_DEVOPS_EXT_PIPELINE_VAR_MySecret=secretvalue +az pipelines variable-group variable create \ + --group-id {group-id} \ + --name MySecret \ + --secret true +``` + +#### Update Variable + +```bash +az pipelines variable-group variable update \ + --group-id {group-id} \ + --name {var-name} \ + --value {new-value} \ + --secret false +``` + +#### Delete Variable + +```bash +az pipelines variable-group variable delete \ + --group-id {group-id} \ + --name {var-name} +``` + +## Pipeline Folders + +### List Folders + +```bash +az pipelines folder list +``` + +### Create Folder + +```bash +az pipelines folder create --path 'folder/subfolder' --description "My folder" +``` + +### Delete Folder + +```bash +az pipelines folder delete --path 'folder/subfolder' +``` + +### Update Folder + +```bash +az pipelines folder update --path 'old-folder' --new-path 'new-folder' +``` + +## Agent Pools + +### List Agent Pools + +```bash +az pipelines pool list +az pipelines pool list --pool-type automation +az pipelines pool list --pool-type deployment +``` + +### Show Agent Pool + +```bash +az pipelines pool show --pool-id {pool-id} +``` + +## Agent Queues + +### List Agent Queues + +```bash +az pipelines queue list +az pipelines queue list --pool-name {pool-name} +``` + +### Show Agent Queue + +```bash +az pipelines queue show --id {queue-id} +``` + +## Work Items (Boards) + +### Query Work Items + +```bash +# WIQL query +az boards query \ + --wiql "SELECT [System.Id], [System.Title], [System.State] FROM WorkItems WHERE [System.AssignedTo] = @Me AND [System.State] = 'Active'" + +# Query with output format +az boards query --wiql "SELECT * FROM WorkItems" --output table +``` + +### Show Work Item + +```bash +az boards work-item show --id {work-item-id} +az boards work-item show --id {work-item-id} --open +``` + +### Create Work Item + +```bash +# Basic work item +az boards work-item create \ + --title "Fix login bug" \ + --type Bug \ + --assigned-to user@example.com \ + --description "Users cannot login with SSO" + +# With area and iteration +az boards work-item create \ + --title "New feature" \ + --type "User Story" \ + --area "Project\\Area1" \ + --iteration "Project\\Sprint 1" + +# With custom fields +az boards work-item create \ + --title "Task" \ + --type Task \ + --fields "Priority=1" "Severity=2" + +# With discussion comment +az boards work-item create \ + --title "Issue" \ + --type Bug \ + --discussion "Initial investigation completed" + +# Open in browser after creation +az boards work-item create --title "Bug" --type Bug --open +``` + +### Update Work Item + +```bash +# Update state, title, and assignee +az boards work-item update \ + --id {work-item-id} \ + --state "Active" \ + --title "Updated title" \ + --assigned-to user@example.com + +# Move to different area +az boards work-item update \ + --id {work-item-id} \ + --area "{ProjectName}\\{Team}\\{Area}" + +# Change iteration +az boards work-item update \ + --id {work-item-id} \ + --iteration "{ProjectName}\\Sprint 5" + +# Add comment/discussion +az boards work-item update \ + --id {work-item-id} \ + --discussion "Work in progress" + +# Update with custom fields +az boards work-item update \ + --id {work-item-id} \ + --fields "Priority=1" "StoryPoints=5" +``` + +### Delete Work Item + +```bash +# Soft delete (can be restored) +az boards work-item delete --id {work-item-id} --yes + +# Permanent delete +az boards work-item delete --id {work-item-id} --destroy --yes +``` + +### Work Item Relations + +```bash +# List relations +az boards work-item relation list --id {work-item-id} + +# List supported relation types +az boards work-item relation list-type + +# Add relation +az boards work-item relation add --id {work-item-id} --relation-type parent --target-id {parent-id} + +# Remove relation +az boards work-item relation remove --id {work-item-id} --relation-id {relation-id} +``` + +## Area Paths + +### List Areas for Project + +```bash +az boards area project list --project {project} +az boards area project show --path "Project\\Area1" --project {project} +``` + +### Create Area + +```bash +az boards area project create --path "Project\\NewArea" --project {project} +``` + +### Update Area + +```bash +az boards area project update \ + --path "Project\\OldArea" \ + --new-path "Project\\UpdatedArea" \ + --project {project} +``` + +### Delete Area + +```bash +az boards area project delete --path "Project\\AreaToDelete" --project {project} --yes +``` + +### Area Team Management + +```bash +# List areas for team +az boards area team list --team {team-name} --project {project} + +# Add area to team +az boards area team add \ + --team {team-name} \ + --path "Project\\NewArea" \ + --project {project} + +# Remove area from team +az boards area team remove \ + --team {team-name} \ + --path "Project\\AreaToRemove" \ + --project {project} + +# Update team area +az boards area team update \ + --team {team-name} \ + --path "Project\\Area" \ + --project {project} \ + --include-sub-areas true +``` + +## Iterations + +### List Iterations for Project + +```bash +az boards iteration project list --project {project} +az boards iteration project show --path "Project\\Sprint 1" --project {project} +``` + +### Create Iteration + +```bash +az boards iteration project create --path "Project\\Sprint 1" --project {project} +``` + +### Update Iteration + +```bash +az boards iteration project update \ + --path "Project\\OldSprint" \ + --new-path "Project\\NewSprint" \ + --project {project} +``` + +### Delete Iteration + +```bash +az boards iteration project delete --path "Project\\OldSprint" --project {project} --yes +``` + +### List Iterations for Team + +```bash +az boards iteration team list --team {team-name} --project {project} +``` + +### Add Iteration to Team + +```bash +az boards iteration team add \ + --team {team-name} \ + --path "Project\\Sprint 1" \ + --project {project} +``` + +### Remove Iteration from Team + +```bash +az boards iteration team remove \ + --team {team-name} \ + --path "Project\\Sprint 1" \ + --project {project} +``` + +### List Work Items in Iteration + +```bash +az boards iteration team list-work-items \ + --team {team-name} \ + --path "Project\\Sprint 1" \ + --project {project} +``` + +### Set Default Iteration for Team + +```bash +az boards iteration team set-default-iteration \ + --team {team-name} \ + --path "Project\\Sprint 1" \ + --project {project} +``` + +### Show Default Iteration + +```bash +az boards iteration team show-default-iteration \ + --team {team-name} \ + --project {project} +``` + +### Set Backlog Iteration for Team + +```bash +az boards iteration team set-backlog-iteration \ + --team {team-name} \ + --path "Project\\Sprint 1" \ + --project {project} +``` + +### Show Backlog Iteration + +```bash +az boards iteration team show-backlog-iteration \ + --team {team-name} \ + --project {project} +``` + +### Show Current Iteration + +```bash +az boards iteration team show --team {team-name} --project {project} --timeframe current +``` + +## Git References + +### List References (Branches) + +```bash +az repos ref list --repository {repo} +az repos ref list --repository {repo} --query "[?name=='refs/heads/main']" +``` + +### Create Reference (Branch) + +```bash +az repos ref create --name refs/heads/new-branch --object-type commit --object {commit-sha} +``` + +### Delete Reference (Branch) + +```bash +az repos ref delete --name refs/heads/old-branch --repository {repo} --project {project} +``` + +### Lock Branch + +```bash +az repos ref lock --name refs/heads/main --repository {repo} --project {project} +``` + +### Unlock Branch + +```bash +az repos ref unlock --name refs/heads/main --repository {repo} --project {project} +``` + +## Repository Policies + +### List All Policies + +```bash +az repos policy list --repository {repo-id} --branch main +``` + +### Create Policy Using Configuration File + +```bash +az repos policy create --config policy.json +``` + +### Update/Delete Policy + +```bash +# Update +az repos policy update --id {policy-id} --config updated-policy.json + +# Delete +az repos policy delete --id {policy-id} --yes +``` + +### Policy Types + +#### Approver Count Policy + +```bash +az repos policy approver-count create \ + --blocking true \ + --enabled true \ + --branch main \ + --repository-id {repo-id} \ + --minimum-approver-count 2 \ + --creator-vote-counts true +``` + +#### Build Policy + +```bash +az repos policy build create \ + --blocking true \ + --enabled true \ + --branch main \ + --repository-id {repo-id} \ + --build-definition-id {definition-id} \ + --queue-on-source-update-only true \ + --valid-duration 720 +``` + +#### Work Item Linking Policy + +```bash +az repos policy work-item-linking create \ + --blocking true \ + --branch main \ + --enabled true \ + --repository-id {repo-id} +``` + +#### Required Reviewer Policy + +```bash +az repos policy required-reviewer create \ + --blocking true \ + --enabled true \ + --branch main \ + --repository-id {repo-id} \ + --required-reviewers user@example.com +``` + +#### Merge Strategy Policy + +```bash +az repos policy merge-strategy create \ + --blocking true \ + --enabled true \ + --branch main \ + --repository-id {repo-id} \ + --allow-squash true \ + --allow-rebase true \ + --allow-no-fast-forward true +``` + +#### Case Enforcement Policy + +```bash +az repos policy case-enforcement create \ + --blocking true \ + --enabled true \ + --branch main \ + --repository-id {repo-id} +``` + +#### Comment Required Policy + +```bash +az repos policy comment-required create \ + --blocking true \ + --enabled true \ + --branch main \ + --repository-id {repo-id} +``` + +#### File Size Policy + +```bash +az repos policy file-size create \ + --blocking true \ + --enabled true \ + --branch main \ + --repository-id {repo-id} \ + --maximum-file-size 10485760 # 10MB in bytes +``` + +## Service Endpoints + +### List Service Endpoints + +```bash +az devops service-endpoint list --project {project} +az devops service-endpoint list --project {project} --output table +``` + +### Show Service Endpoint + +```bash +az devops service-endpoint show --id {endpoint-id} --project {project} +``` + +### Create Service Endpoint + +```bash +# Using configuration file +az devops service-endpoint create --service-endpoint-configuration endpoint.json --project {project} +``` + +### Delete Service Endpoint + +```bash +az devops service-endpoint delete --id {endpoint-id} --project {project} --yes +``` + +## Teams + +### List Teams + +```bash +az devops team list --project {project} +``` + +### Show Team + +```bash +az devops team show --team {team-name} --project {project} +``` + +### Create Team + +```bash +az devops team create \ + --name {team-name} \ + --description "Team description" \ + --project {project} +``` + +### Update Team + +```bash +az devops team update \ + --team {team-name} \ + --project {project} \ + --name "{new-team-name}" \ + --description "Updated description" +``` + +### Delete Team + +```bash +az devops team delete --team {team-name} --project {project} --yes +``` + +### Show Team Members + +```bash +az devops team list-member --team {team-name} --project {project} +``` + +## Users + +### List Users + +```bash +az devops user list --org https://dev.azure.com/{org} +az devops user list --top 10 --output table +``` + +### Show User + +```bash +az devops user show --user {user-id-or-email} --org https://dev.azure.com/{org} +``` + +### Add User + +```bash +az devops user add \ + --email user@example.com \ + --license-type express \ + --org https://dev.azure.com/{org} +``` + +### Update User + +```bash +az devops user update \ + --user {user-id-or-email} \ + --license-type advanced \ + --org https://dev.azure.com/{org} +``` + +### Remove User + +```bash +az devops user remove --user {user-id-or-email} --org https://dev.azure.com/{org} --yes +``` + +## Security Groups + +### List Groups + +```bash +# List all groups in project +az devops security group list --project {project} + +# List all groups in organization +az devops security group list --scope organization + +# List with filtering +az devops security group list --project {project} --subject-types vstsgroup +``` + +### Show Group Details + +```bash +az devops security group show --group-id {group-id} +``` + +### Create Group + +```bash +az devops security group create \ + --name {group-name} \ + --description "Group description" \ + --project {project} +``` + +### Update Group + +```bash +az devops security group update \ + --group-id {group-id} \ + --name "{new-group-name}" \ + --description "Updated description" +``` + +### Delete Group + +```bash +az devops security group delete --group-id {group-id} --yes +``` + +### Group Memberships + +```bash +# List memberships +az devops security group membership list --id {group-id} + +# Add member +az devops security group membership add \ + --group-id {group-id} \ + --member-id {member-id} + +# Remove member +az devops security group membership remove \ + --group-id {group-id} \ + --member-id {member-id} --yes +``` + +## Security Permissions + +### List Namespaces + +```bash +az devops security permission namespace list +``` + +### Show Namespace Details + +```bash +# Show permissions available in a namespace +az devops security permission namespace show --namespace "GitRepositories" +``` + +### List Permissions + +```bash +# List permissions for user/group and namespace +az devops security permission list \ + --id {user-or-group-id} \ + --namespace "GitRepositories" \ + --project {project} + +# List for specific token (repository) +az devops security permission list \ + --id {user-or-group-id} \ + --namespace "GitRepositories" \ + --project {project} \ + --token "repoV2/{project}/{repository-id}" +``` + +### Show Permissions + +```bash +az devops security permission show \ + --id {user-or-group-id} \ + --namespace "GitRepositories" \ + --project {project} \ + --token "repoV2/{project}/{repository-id}" +``` + +### Update Permissions + +```bash +# Grant permission +az devops security permission update \ + --id {user-or-group-id} \ + --namespace "GitRepositories" \ + --project {project} \ + --token "repoV2/{project}/{repository-id}" \ + --permission-mask "Pull,Contribute" + +# Deny permission +az devops security permission update \ + --id {user-or-group-id} \ + --namespace "GitRepositories" \ + --project {project} \ + --token "repoV2/{project}/{repository-id}" \ + --permission-mask 0 +``` + +### Reset Permissions + +```bash +# Reset specific permission bits +az devops security permission reset \ + --id {user-or-group-id} \ + --namespace "GitRepositories" \ + --project {project} \ + --token "repoV2/{project}/{repository-id}" \ + --permission-mask "Pull,Contribute" + +# Reset all permissions +az devops security permission reset-all \ + --id {user-or-group-id} \ + --namespace "GitRepositories" \ + --project {project} \ + --token "repoV2/{project}/{repository-id}" --yes +``` + +## Wikis + +### List Wikis + +```bash +# List all wikis in project +az devops wiki list --project {project} + +# List all wikis in organization +az devops wiki list +``` + +### Show Wiki + +```bash +az devops wiki show --wiki {wiki-name} --project {project} +az devops wiki show --wiki {wiki-name} --project {project} --open +``` + +### Create Wiki + +```bash +# Create project wiki +az devops wiki create \ + --name {wiki-name} \ + --project {project} \ + --type projectWiki + +# Create code wiki from repository +az devops wiki create \ + --name {wiki-name} \ + --project {project} \ + --type codeWiki \ + --repository {repo-name} \ + --mapped-path /wiki +``` + +### Delete Wiki + +```bash +az devops wiki delete --wiki {wiki-id} --project {project} --yes +``` + +### Wiki Pages + +```bash +# List pages +az devops wiki page list --wiki {wiki-name} --project {project} + +# Show page +az devops wiki page show \ + --wiki {wiki-name} \ + --path "/page-name" \ + --project {project} + +# Create page +az devops wiki page create \ + --wiki {wiki-name} \ + --path "/new-page" \ + --content "# New Page\n\nPage content here..." \ + --project {project} + +# Update page +az devops wiki page update \ + --wiki {wiki-name} \ + --path "/existing-page" \ + --content "# Updated Page\n\nNew content..." \ + --project {project} + +# Delete page +az devops wiki page delete \ + --wiki {wiki-name} \ + --path "/old-page" \ + --project {project} --yes +``` + +## Administration + +### Banner Management + +```bash +# List banners +az devops admin banner list + +# Show banner details +az devops admin banner show --id {banner-id} + +# Add new banner +az devops admin banner add \ + --message "System maintenance scheduled" \ + --level info # info, warning, error + +# Update banner +az devops admin banner update \ + --id {banner-id} \ + --message "Updated message" \ + --level warning \ + --expiration-date "2025-12-31T23:59:59Z" + +# Remove banner +az devops admin banner remove --id {banner-id} +``` + +## DevOps Extensions + +Manage extensions installed in an Azure DevOps organization (different from CLI extensions). + +```bash +# List installed extensions +az devops extension list --org https://dev.azure.com/{org} + +# Search marketplace extensions +az devops extension search --search-query "docker" + +# Show extension details +az devops extension show --ext-id {extension-id} --org https://dev.azure.com/{org} + +# Install extension +az devops extension install \ + --ext-id {extension-id} \ + --org https://dev.azure.com/{org} \ + --publisher {publisher-id} + +# Enable extension +az devops extension enable \ + --ext-id {extension-id} \ + --org https://dev.azure.com/{org} + +# Disable extension +az devops extension disable \ + --ext-id {extension-id} \ + --org https://dev.azure.com/{org} + +# Uninstall extension +az devops extension uninstall \ + --ext-id {extension-id} \ + --org https://dev.azure.com/{org} --yes +``` + +## Universal Packages + +### Publish Package + +```bash +az artifacts universal publish \ + --feed {feed-name} \ + --name {package-name} \ + --version {version} \ + --path {package-path} \ + --project {project} +``` + +### Download Package + +```bash +az artifacts universal download \ + --feed {feed-name} \ + --name {package-name} \ + --version {version} \ + --path {download-path} \ + --project {project} +``` + +## Agents + +### List Agents in Pool + +```bash +az pipelines agent list --pool-id {pool-id} +``` + +### Show Agent Details + +```bash +az pipelines agent show --agent-id {agent-id} --pool-id {pool-id} +``` + +## Git Aliases + +After enabling git aliases: + +```bash +# Enable Git aliases +az devops configure --use-git-aliases true + +# Use Git commands for DevOps operations +git pr create --target-branch main +git pr list +git pr checkout 123 +``` + +## Output Formats + +All commands support multiple output formats: + +```bash +# Table format (human-readable) +az pipelines list --output table + +# JSON format (default, machine-readable) +az pipelines list --output json + +# JSONC (colored JSON) +az pipelines list --output jsonc + +# YAML format +az pipelines list --output yaml + +# YAMLC (colored YAML) +az pipelines list --output yamlc + +# TSV format (tab-separated values) +az pipelines list --output tsv + +# None (no output) +az pipelines list --output none +``` + +## JMESPath Queries + +Filter and transform output: + +```bash +# Filter by name +az pipelines list --query "[?name=='myPipeline']" + +# Get specific fields +az pipelines list --query "[].{Name:name, ID:id}" + +# Chain queries +az pipelines list --query "[?name.contains('CI')].{Name:name, ID:id}" --output table + +# Get first result +az pipelines list --query "[0]" + +# Get top N +az pipelines list --query "[0:5]" +``` + +## Global Arguments + +Available on all commands: + +- `--help` / `-h`: Show help +- `--output` / `-o`: Output format (json, jsonc, none, table, tsv, yaml, yamlc) +- `--query`: JMESPath query string +- `--verbose`: Increase logging verbosity +- `--debug`: Show all debug logs +- `--only-show-errors`: Only show errors, suppress warnings +- `--subscription`: Name or ID of subscription + +## Common Parameters + +| Parameter | Description | +| -------------------------- | ------------------------------------------------------------------- | +| `--org` / `--organization` | Azure DevOps organization URL (e.g., `https://dev.azure.com/{org}`) | +| `--project` / `-p` | Project name or ID | +| `--detect` | Auto-detect organization from git config | +| `--yes` / `-y` | Skip confirmation prompts | +| `--open` | Open in web browser | + +## Common Workflows + +### Create PR from current branch + +```bash +CURRENT_BRANCH=$(git branch --show-current) +az repos pr create \ + --source-branch $CURRENT_BRANCH \ + --target-branch main \ + --title "Feature: $(git log -1 --pretty=%B)" \ + --open +``` + +### Create work item on pipeline failure + +```bash +az boards work-item create \ + --title "Build $BUILD_BUILDNUMBER failed" \ + --type bug \ + --org $SYSTEM_TEAMFOUNDATIONCOLLECTIONURI \ + --project $SYSTEM_TEAMPROJECT +``` + +### Download latest pipeline artifact + +```bash +RUN_ID=$(az pipelines runs list --pipeline {pipeline-id} --top 1 --query "[0].id" -o tsv) +az pipelines runs artifact download \ + --artifact-name 'webapp' \ + --path ./output \ + --run-id $RUN_ID +``` + +### Approve and complete PR + +```bash +# Vote approve +az repos pr set-vote --id {pr-id} --vote approve + +# Complete PR +az repos pr update --id {pr-id} --status completed +``` + +### Create pipeline from local repo + +```bash +# From local git repository (auto-detects repo, branch, etc.) +az pipelines create --name 'CI-Pipeline' --description 'Continuous Integration' +``` + +### Bulk update work items + +```bash +# Query items and update in loop +for id in $(az boards query --wiql "SELECT ID FROM WorkItems WHERE State='New'" -o tsv); do + az boards work-item update --id $id --state "Active" +done +``` + +## Best Practices + +### Authentication and Security + +```bash +# Use PAT from environment variable (most secure) +export AZURE_DEVOPS_EXT_PAT=$MY_PAT +az devops login --organization $ORG_URL + +# Pipe PAT securely (avoids shell history) +echo $MY_PAT | az devops login --organization $ORG_URL + +# Set defaults to avoid repetition +az devops configure --defaults organization=$ORG_URL project=$PROJECT + +# Clear credentials after use +az devops logout --organization $ORG_URL +``` + +### Idempotent Operations + +```bash +# Always use --detect for auto-detection +az devops configure --defaults organization=$ORG_URL project=$PROJECT + +# Check existence before creation +if ! az pipelines show --id $PIPELINE_ID 2>/dev/null; then + az pipelines create --name "$PIPELINE_NAME" --yaml-path azure-pipelines.yml +fi + +# Use --output tsv for shell parsing +PIPELINE_ID=$(az pipelines list --query "[?name=='MyPipeline'].id" --output tsv) + +# Use --output json for programmatic access +BUILD_STATUS=$(az pipelines build show --id $BUILD_ID --query "status" --output json) +``` + +### Script-Safe Output + +```bash +# Suppress warnings and errors +az pipelines list --only-show-errors + +# No output (useful for commands that only need to execute) +az pipelines run --name "$PIPELINE_NAME" --output none + +# TSV format for shell scripts (clean, no formatting) +az repos pr list --output tsv --query "[].{ID:pullRequestId,Title:title}" + +# JSON with specific fields +az pipelines list --output json --query "[].{Name:name, ID:id, URL:url}" +``` + +### Pipeline Orchestration + +```bash +# Run pipeline and wait for completion +RUN_ID=$(az pipelines run --name "$PIPELINE_NAME" --query "id" -o tsv) + +while true; do + STATUS=$(az pipelines runs show --run-id $RUN_ID --query "status" -o tsv) + if [[ "$STATUS" != "inProgress" && "$STATUS" != "notStarted" ]]; then + break + fi + sleep 10 +done + +# Check result +RESULT=$(az pipelines runs show --run-id $RUN_ID --query "result" -o tsv) +if [[ "$RESULT" == "succeeded" ]]; then + echo "Pipeline succeeded" +else + echo "Pipeline failed with result: $RESULT" + exit 1 +fi +``` + +### Variable Group Management + +```bash +# Create variable group idempotently +VG_NAME="production-variables" +VG_ID=$(az pipelines variable-group list --query "[?name=='$VG_NAME'].id" -o tsv) + +if [[ -z "$VG_ID" ]]; then + VG_ID=$(az pipelines variable-group create \ + --name "$VG_NAME" \ + --variables API_URL=$API_URL API_KEY=$API_KEY \ + --authorize true \ + --query "id" -o tsv) + echo "Created variable group with ID: $VG_ID" +else + echo "Variable group already exists with ID: $VG_ID" +fi +``` + +### Service Connection Automation + +```bash +# Create service connection using configuration file +cat > service-connection.json <<'EOF' +{ + "data": { + "subscriptionId": "$SUBSCRIPTION_ID", + "subscriptionName": "My Subscription", + "creationMode": "Manual", + "serviceEndpointId": "$SERVICE_ENDPOINT_ID" + }, + "url": "https://management.azure.com/", + "authorization": { + "parameters": { + "tenantid": "$TENANT_ID", + "serviceprincipalid": "$SP_ID", + "authenticationType": "spnKey", + "serviceprincipalkey": "$SP_KEY" + }, + "scheme": "ServicePrincipal" + }, + "type": "azurerm", + "isShared": false, + "isReady": true +} +EOF + +az devops service-endpoint create \ + --service-endpoint-configuration service-connection.json \ + --project "$PROJECT" +``` + +### Pull Request Automation + +```bash +# Create PR with work items and reviewers +PR_ID=$(az repos pr create \ + --repository "$REPO_NAME" \ + --source-branch "$FEATURE_BRANCH" \ + --target-branch main \ + --title "Feature: $(git log -1 --pretty=%B)" \ + --description "$(git log -1 --pretty=%B)" \ + --work-items $WORK_ITEM_1 $WORK_ITEM_2 \ + --reviewers "$REVIEWER_1" "$REVIEWER_2" \ + --required-reviewers "$LEAD_EMAIL" \ + --labels "enhancement" "backlog" \ + --open \ + --query "pullRequestId" -o tsv) + +# Set auto-complete when policies pass +az repos pr update --id $PR_ID --auto-complete true +``` + +## Error Handling and Retry Patterns + +### Retry Logic for Transient Failures + +```bash +# Retry function for network operations +retry_command() { + local max_attempts=3 + local attempt=1 + local delay=5 + + while [[ $attempt -le $max_attempts ]]; do + if "$@"; then + return 0 + fi + echo "Attempt $attempt failed. Retrying in ${delay}s..." + sleep $delay + ((attempt++)) + delay=$((delay * 2)) + done + + echo "All $max_attempts attempts failed" + return 1 +} + +# Usage +retry_command az pipelines run --name "$PIPELINE_NAME" +``` + +### Check and Handle Errors + +```bash +# Check if pipeline exists before operations +PIPELINE_ID=$(az pipelines list --query "[?name=='$PIPELINE_NAME'].id" -o tsv) + +if [[ -z "$PIPELINE_ID" ]]; then + echo "Pipeline not found. Creating..." + az pipelines create --name "$PIPELINE_NAME" --yaml-path azure-pipelines.yml +else + echo "Pipeline exists with ID: $PIPELINE_ID" +fi +``` + +### Validate Inputs + +```bash +# Validate required parameters +if [[ -z "$PROJECT" || -z "$REPO" ]]; then + echo "Error: PROJECT and REPO must be set" + exit 1 +fi + +# Check if branch exists +if ! az repos ref list --repository "$REPO" --query "[?name=='refs/heads/$BRANCH']" -o tsv | grep -q .; then + echo "Error: Branch $BRANCH does not exist" + exit 1 +fi +``` + +### Handle Permission Errors + +```bash +# Try operation, handle permission errors +if az devops security permission update \ + --id "$USER_ID" \ + --namespace "GitRepositories" \ + --project "$PROJECT" \ + --token "repoV2/$PROJECT/$REPO_ID" \ + --allow-bit 2 \ + --deny-bit 0 2>&1 | grep -q "unauthorized"; then + echo "Error: Insufficient permissions to update repository permissions" + exit 1 +fi +``` + +### Pipeline Failure Notification + +```bash +# Run pipeline and check result +RUN_ID=$(az pipelines run --name "$PIPELINE_NAME" --query "id" -o tsv) + +# Wait for completion +while true; do + STATUS=$(az pipelines runs show --run-id $RUN_ID --query "status" -o tsv) + if [[ "$STATUS" != "inProgress" && "$STATUS" != "notStarted" ]]; then + break + fi + sleep 10 +done + +# Check result and create work item on failure +RESULT=$(az pipelines runs show --run-id $RUN_ID --query "result" -o tsv) +if [[ "$RESULT" != "succeeded" ]]; then + BUILD_NUMBER=$(az pipelines runs show --run-id $RUN_ID --query "buildNumber" -o tsv) + + az boards work-item create \ + --title "Build $BUILD_NUMBER failed" \ + --type Bug \ + --description "Pipeline run $RUN_ID failed with result: $RESULT\n\nURL: $ORG_URL/$PROJECT/_build/results?buildId=$RUN_ID" +fi +``` + +### Graceful Degradation + +```bash +# Try to download artifact, fallback to alternative source +if ! az pipelines runs artifact download \ + --artifact-name 'webapp' \ + --path ./output \ + --run-id $RUN_ID 2>/dev/null; then + echo "Warning: Failed to download from pipeline run. Falling back to backup source..." + + # Alternative download method + curl -L "$BACKUP_URL" -o ./output/backup.zip +fi +``` + +## Advanced JMESPath Queries + +### Filtering and Sorting + +```bash +# Filter by multiple conditions +az pipelines list --query "[?name.contains('CI') && enabled==true]" + +# Filter by status and result +az pipelines runs list --query "[?status=='completed' && result=='succeeded']" + +# Sort by date (descending) +az pipelines runs list --query "sort_by([?status=='completed'], &finishTime | reverse(@))" + +# Get top N items after filtering +az pipelines runs list --query "[?result=='succeeded'] | [0:5]" +``` + +### Nested Queries + +```bash +# Extract nested properties +az pipelines show --id $PIPELINE_ID --query "{Name:name, Repo:repository.{Name:name, Type:type}, Folder:folder}" + +# Query build details +az pipelines build show --id $BUILD_ID --query "{ID:id, Number:buildNumber, Status:status, Result:result, Requested:requestedFor.displayName}" +``` + +### Complex Filtering + +```bash +# Find pipelines with specific YAML path +az pipelines list --query "[?process.type.name=='yaml' && process.yamlFilename=='azure-pipelines.yml']" + +# Find PRs from specific reviewer +az repos pr list --query "[?contains(reviewers[?displayName=='John Doe'].displayName, 'John Doe')]" + +# Find work items with specific iteration and state +az boards work-item show --id $WI_ID --query "{Title:fields['System.Title'], State:fields['System.State'], Iteration:fields['System.IterationPath']}" +``` + +### Aggregation + +```bash +# Count items by status +az pipelines runs list --query "groupBy([?status=='completed'], &[result]) | {Succeeded: [?key=='succeeded'][0].count, Failed: [?key=='failed'][0].count}" + +# Get unique reviewers +az repos pr list --query "unique_by(reviewers[], &displayName)" + +# Sum values +az pipelines runs list --query "[?result=='succeeded'] | [].{Duration:duration} | [0].Duration" +``` + +### Conditional Transformation + +```bash +# Format dates +az pipelines runs list --query "[].{ID:id, Date:createdDate, Formatted:createdDate | format_datetime(@, 'yyyy-MM-dd HH:mm')}" + +# Conditional output +az pipelines list --query "[].{Name:name, Status:(enabled ? 'Enabled' : 'Disabled')}" + +# Extract with defaults +az pipelines show --id $PIPELINE_ID --query "{Name:name, Folder:folder || 'Root', Description:description || 'No description'}" +``` + +### Complex Workflows + +```bash +# Find longest running builds +az pipelines build list --query "sort_by([?result=='succeeded'], &queueTime) | reverse(@) | [0:3].{ID:id, Number:buildNumber, Duration:duration}" + +# Get PR statistics per reviewer +az repos pr list --query "groupBy([], &reviewers[].displayName) | [].{Reviewer:@.key, Count:length(@)}" + +# Find work items with multiple child items +az boards work-item relation list --id $PARENT_ID --query "[?rel=='System.LinkTypes.Hierarchy-Forward'] | [].{ChildID:url | split('/', @) | [-1]}" +``` + +## Scripting Patterns for Idempotent Operations + +### Create or Update Pattern + +```bash +# Ensure pipeline exists, update if different +ensure_pipeline() { + local name=$1 + local yaml_path=$2 + + PIPELINE=$(az pipelines list --query "[?name=='$name']" -o json) + + if [[ -z "$PIPELINE" ]]; then + echo "Creating pipeline: $name" + az pipelines create --name "$name" --yaml-path "$yaml_path" + else + echo "Pipeline exists: $name" + fi +} +``` + +### Ensure Variable Group + +```bash +# Create variable group with idempotent updates +ensure_variable_group() { + local vg_name=$1 + shift + local variables=("$@") + + VG_ID=$(az pipelines variable-group list --query "[?name=='$vg_name'].id" -o tsv) + + if [[ -z "$VG_ID" ]]; then + echo "Creating variable group: $vg_name" + VG_ID=$(az pipelines variable-group create \ + --name "$vg_name" \ + --variables "${variables[@]}" \ + --authorize true \ + --query "id" -o tsv) + else + echo "Variable group exists: $vg_name (ID: $VG_ID)" + fi + + echo "$VG_ID" +} +``` + +### Ensure Service Connection + +```bash +# Check if service connection exists, create if not +ensure_service_connection() { + local name=$1 + local project=$2 + + SC_ID=$(az devops service-endpoint list \ + --project "$project" \ + --query "[?name=='$name'].id" \ + -o tsv) + + if [[ -z "$SC_ID" ]]; then + echo "Service connection not found. Creating..." + # Create logic here + else + echo "Service connection exists: $name" + echo "$SC_ID" + fi +} +``` + +### Idempotent Work Item Creation + +```bash +# Create work item only if doesn't exist with same title +create_work_item_if_new() { + local title=$1 + local type=$2 + + WI_ID=$(az boards query \ + --wiql "SELECT ID FROM WorkItems WHERE [System.WorkItemType]='$type' AND [System.Title]='$title'" \ + --query "[0].id" -o tsv) + + if [[ -z "$WI_ID" ]]; then + echo "Creating work item: $title" + WI_ID=$(az boards work-item create --title "$title" --type "$type" --query "id" -o tsv) + else + echo "Work item exists: $title (ID: $WI_ID)" + fi + + echo "$WI_ID" +} +``` + +### Bulk Idempotent Operations + +```bash +# Ensure multiple pipelines exist +declare -a PIPELINES=( + "ci-pipeline:azure-pipelines.yml" + "deploy-pipeline:deploy.yml" + "test-pipeline:test.yml" +) + +for pipeline in "${PIPELINES[@]}"; do + IFS=':' read -r name yaml <<< "$pipeline" + ensure_pipeline "$name" "$yaml" +done +``` + +### Configuration Synchronization + +```bash +# Sync variable groups from config file +sync_variable_groups() { + local config_file=$1 + + while IFS=',' read -r vg_name variables; do + ensure_variable_group "$vg_name" "$variables" + done < "$config_file" +} + +# config.csv format: +# prod-vars,API_URL=prod.com,API_KEY=secret123 +# dev-vars,API_URL=dev.com,API_KEY=secret456 +``` + +## Real-World Workflows + +### CI/CD Pipeline Setup + +```bash +# Setup complete CI/CD pipeline +setup_cicd_pipeline() { + local project=$1 + local repo=$2 + local branch=$3 + + # Create variable groups + VG_DEV=$(ensure_variable_group "dev-vars" "ENV=dev API_URL=api-dev.com") + VG_PROD=$(ensure_variable_group "prod-vars" "ENV=prod API_URL=api-prod.com") + + # Create CI pipeline + az pipelines create \ + --name "$repo-CI" \ + --repository "$repo" \ + --branch "$branch" \ + --yaml-path .azure/pipelines/ci.yml \ + --skip-run true + + # Create CD pipeline + az pipelines create \ + --name "$repo-CD" \ + --repository "$repo" \ + --branch "$branch" \ + --yaml-path .azure/pipelines/cd.yml \ + --skip-run true + + echo "CI/CD pipeline setup complete" +} +``` + +### Automated PR Creation + +```bash +# Create PR from feature branch with automation +create_automated_pr() { + local branch=$1 + local title=$2 + + # Get branch info + LAST_COMMIT=$(git log -1 --pretty=%B "$branch") + COMMIT_SHA=$(git rev-parse "$branch") + + # Find related work items + WORK_ITEMS=$(az boards query \ + --wiql "SELECT ID FROM WorkItems WHERE [System.ChangedBy] = @Me AND [System.State] = 'Active'" \ + --query "[].id" -o tsv) + + # Create PR + PR_ID=$(az repos pr create \ + --source-branch "$branch" \ + --target-branch main \ + --title "$title" \ + --description "$LAST_COMMIT" \ + --work-items $WORK_ITEMS \ + --auto-complete true \ + --query "pullRequestId" -o tsv) + + # Set required reviewers + az repos pr reviewer add \ + --id $PR_ID \ + --reviewers $(git log -1 --pretty=format:'%ae' "$branch") \ + --required true + + echo "Created PR #$PR_ID" +} +``` + +### Pipeline Monitoring and Alerting + +```bash +# Monitor pipeline and alert on failure +monitor_pipeline() { + local pipeline_name=$1 + local slack_webhook=$2 + + while true; do + # Get latest run + RUN_ID=$(az pipelines list --query "[?name=='$pipeline_name'] | [0].id" -o tsv) + RUNS=$(az pipelines runs list --pipeline $RUN_ID --top 1) + + LATEST_RUN_ID=$(echo "$RUNS" | jq -r '.[0].id') + RESULT=$(echo "$RUNS" | jq -r '.[0].result') + + # Check if failed and not already processed + if [[ "$RESULT" == "failed" ]]; then + # Send Slack alert + curl -X POST "$slack_webhook" \ + -H 'Content-Type: application/json' \ + -d "{\"text\": \"Pipeline $pipeline_name failed! Run ID: $LATEST_RUN_ID\"}" + fi + + sleep 300 # Check every 5 minutes + done +} +``` + +### Bulk Work Item Management + +```bash +# Bulk update work items based on query +bulk_update_work_items() { + local wiql=$1 + local updates=("$@") + + # Query work items + WI_IDS=$(az boards query --wiql "$wiql" --query "[].id" -o tsv) + + # Update each work item + for wi_id in $WI_IDS; do + az boards work-item update --id $wi_id "${updates[@]}" + echo "Updated work item: $wi_id" + done +} + +# Usage: bulk_update_work_items "SELECT ID FROM WorkItems WHERE State='New'" --state "Active" --assigned-to "user@example.com" +``` + +### Branch Policy Automation + +```bash +# Apply branch policies to all repositories +apply_branch_policies() { + local branch=$1 + local project=$2 + + # Get all repositories + REPOS=$(az repos list --project "$project" --query "[].id" -o tsv) + + for repo_id in $REPOS; do + echo "Applying policies to repo: $repo_id" + + # Require minimum approvers + az repos policy approver-count create \ + --blocking true \ + --enabled true \ + --branch "$branch" \ + --repository-id "$repo_id" \ + --minimum-approver-count 2 \ + --creator-vote-counts true + + # Require work item linking + az repos policy work-item-linking create \ + --blocking true \ + --branch "$branch" \ + --enabled true \ + --repository-id "$repo_id" + + # Require build validation + BUILD_ID=$(az pipelines list --query "[?name=='CI'].id" -o tsv | head -1) + az repos policy build create \ + --blocking true \ + --enabled true \ + --branch "$branch" \ + --repository-id "$repo_id" \ + --build-definition-id "$BUILD_ID" \ + --queue-on-source-update-only true + done +} +``` + +### Multi-Environment Deployment + +```bash +# Deploy across multiple environments +deploy_to_environments() { + local run_id=$1 + shift + local environments=("$@") + + # Download artifacts + ARTIFACT_NAME=$(az pipelines runs artifact list --run-id $run_id --query "[0].name" -o tsv) + az pipelines runs artifact download \ + --artifact-name "$ARTIFACT_NAME" \ + --path ./artifacts \ + --run-id $run_id + + # Deploy to each environment + for env in "${environments[@]}"; do + echo "Deploying to: $env" + + # Get environment-specific variables + VG_ID=$(az pipelines variable-group list --query "[?name=='$env-vars'].id" -o tsv) + + # Run deployment pipeline + DEPLOY_RUN_ID=$(az pipelines run \ + --name "Deploy-$env" \ + --variables ARTIFACT_PATH=./artifacts ENV="$env" \ + --query "id" -o tsv) + + # Wait for deployment + while true; do + STATUS=$(az pipelines runs show --run-id $DEPLOY_RUN_ID --query "status" -o tsv) + if [[ "$STATUS" != "inProgress" ]]; then + break + fi + sleep 10 + done + done +} +``` + +## Enhanced Global Arguments + +| Parameter | Description | +| -------------------- | ---------------------------------------------------------- | +| `--help` / `-h` | Show command help | +| `--output` / `-o` | Output format (json, jsonc, none, table, tsv, yaml, yamlc) | +| `--query` | JMESPath query string for filtering output | +| `--verbose` | Increase logging verbosity | +| `--debug` | Show all debug logs | +| `--only-show-errors` | Only show errors, suppress warnings | +| `--subscription` | Name or ID of subscription | +| `--yes` / `-y` | Skip confirmation prompts | + +## Enhanced Common Parameters + +| Parameter | Description | +| -------------------------- | ------------------------------------------------------------------- | +| `--org` / `--organization` | Azure DevOps organization URL (e.g., `https://dev.azure.com/{org}`) | +| `--project` / `-p` | Project name or ID | +| `--detect` | Auto-detect organization from git config | +| `--yes` / `-y` | Skip confirmation prompts | +| `--open` | Open resource in web browser | +| `--subscription` | Azure subscription (for Azure resources) | + +## Getting Help + +```bash +# General help +az devops --help + +# Help for specific command group +az pipelines --help +az repos pr --help + +# Help for specific command +az repos pr create --help + +# Search for examples +az find "az repos pr create" +``` diff --git a/skills/chrome-devtools/SKILL.md b/skills/chrome-devtools/SKILL.md new file mode 100644 index 00000000..3e7a53f4 --- /dev/null +++ b/skills/chrome-devtools/SKILL.md @@ -0,0 +1,97 @@ +--- +name: chrome-devtools +description: 'Expert-level browser automation, debugging, and performance analysis using Chrome DevTools MCP. Use for interacting with web pages, capturing screenshots, analyzing network traffic, and profiling performance.' +license: MIT +--- + +# Chrome DevTools Agent + +## Overview + +A specialized skill for controlling and inspecting a live Chrome browser. This skill leverages the `chrome-devtools` MCP server to perform a wide range of browser-related tasks, from simple navigation to complex performance profiling. + +## When to Use + +Use this skill when: + +- **Browser Automation**: Navigating pages, clicking elements, filling forms, and handling dialogs. +- **Visual Inspection**: Taking screenshots or text snapshots of web pages. +- **Debugging**: Inspecting console messages, evaluating JavaScript in the page context, and analyzing network requests. +- **Performance Analysis**: Recording and analyzing performance traces to identify bottlenecks and Core Web Vital issues. +- **Emulation**: Resizing the viewport or emulating network/CPU conditions. + +## Tool Categories + +### 1. Navigation & Page Management + +- `new_page`: Open a new tab/page. +- `navigate_page`: Go to a specific URL, reload, or navigate history. +- `select_page`: Switch context between open pages. +- `list_pages`: See all open pages and their IDs. +- `close_page`: Close a specific page. +- `wait_for`: Wait for specific text to appear on the page. + +### 2. Input & Interaction + +- `click`: Click on an element (use `uid` from snapshot). +- `fill` / `fill_form`: Type text into inputs or fill multiple fields at once. +- `hover`: Move the mouse over an element. +- `press_key`: Send keyboard shortcuts or special keys (e.g., "Enter", "Control+C"). +- `drag`: Drag and drop elements. +- `handle_dialog`: Accept or dismiss browser alerts/prompts. +- `upload_file`: Upload a file through a file input. + +### 3. Debugging & Inspection + +- `take_snapshot`: Get a text-based accessibility tree (best for identifying elements). +- `take_screenshot`: Capture a visual representation of the page or a specific element. +- `list_console_messages` / `get_console_message`: Inspect the page's console output. +- `evaluate_script`: Run custom JavaScript in the page context. +- `list_network_requests` / `get_network_request`: Analyze network traffic and request details. + +### 4. Emulation & Performance + +- `resize_page`: Change the viewport dimensions. +- `emulate`: Throttling CPU/Network or emulating geolocation. +- `performance_start_trace`: Start recording a performance profile. +- `performance_stop_trace`: Stop recording and save the trace. +- `performance_analyze_insight`: Get detailed analysis from recorded performance data. + +## Workflow Patterns + +### Pattern A: Identifying Elements (Snapshot-First) + +Always prefer `take_snapshot` over `take_screenshot` for finding elements. The snapshot provides `uid` values which are required by interaction tools. + +```markdown +1. `take_snapshot` to get the current page structure. +2. Find the `uid` of the target element. +3. Use `click(uid=...)` or `fill(uid=..., value=...)`. +``` + +### Pattern B: Troubleshooting Errors + +When a page is failing, check both console logs and network requests. + +```markdown +1. `list_console_messages` to check for JavaScript errors. +2. `list_network_requests` to identify failed (4xx/5xx) resources. +3. `evaluate_script` to check the value of specific DOM elements or global variables. +``` + +### Pattern C: Performance Profiling + +Identify why a page is slow. + +```markdown +1. `performance_start_trace(reload=true, autoStop=true)` +2. Wait for the page to load/trace to finish. +3. `performance_analyze_insight` to find LCP issues or layout shifts. +``` + +## Best Practices + +- **Context Awareness**: Always run `list_pages` and `select_page` if you are unsure which tab is currently active. +- **Snapshots**: Take a new snapshot after any major navigation or DOM change, as `uid` values may change. +- **Timeouts**: Use reasonable timeouts for `wait_for` to avoid hanging on slow-loading elements. +- **Screenshots**: Use `take_screenshot` sparingly for visual verification, but rely on `take_snapshot` for logic. diff --git a/skills/gh-cli/SKILL.md b/skills/gh-cli/SKILL.md new file mode 100644 index 00000000..bc7d1b07 --- /dev/null +++ b/skills/gh-cli/SKILL.md @@ -0,0 +1,2189 @@ +--- +name: gh-cli +description: GitHub CLI (gh) comprehensive reference for repositories, issues, pull requests, Actions, projects, releases, gists, codespaces, organizations, extensions, and all GitHub operations from the command line. +--- + +# GitHub CLI (gh) + +Comprehensive reference for GitHub CLI (gh) - work seamlessly with GitHub from the command line. + +**Version:** 2.85.0 (current as of January 2026) + +## Prerequisites + +### Installation + +```bash +# macOS +brew install gh + +# Linux +curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null +sudo apt update +sudo apt install gh + +# Windows +winget install --id GitHub.cli + +# Verify installation +gh --version +``` + +### Authentication + +```bash +# Interactive login (default: github.com) +gh auth login + +# Login with specific hostname +gh auth login --hostname enterprise.internal + +# Login with token +gh auth login --with-token < mytoken.txt + +# Check authentication status +gh auth status + +# Switch accounts +gh auth switch --hostname github.com --user username + +# Logout +gh auth logout --hostname github.com --user username +``` + +### Setup Git Integration + +```bash +# Configure git to use gh as credential helper +gh auth setup-git + +# View active token +gh auth token + +# Refresh authentication scopes +gh auth refresh --scopes write:org,read:public_key +``` + +## CLI Structure + +``` +gh # Root command +├── auth # Authentication +│ ├── login +│ ├── logout +│ ├── refresh +│ ├── setup-git +│ ├── status +│ ├── switch +│ └── token +├── browse # Open in browser +├── codespace # GitHub Codespaces +│ ├── code +│ ├── cp +│ ├── create +│ ├── delete +│ ├── edit +│ ├── jupyter +│ ├── list +│ ├── logs +│ ├── ports +│ ├── rebuild +│ ├── ssh +│ ├── stop +│ └── view +├── gist # Gists +│ ├── clone +│ ├── create +│ ├── delete +│ ├── edit +│ ├── list +│ ├── rename +│ └── view +├── issue # Issues +│ ├── create +│ ├── list +│ ├── status +│ ├── close +│ ├── comment +│ ├── delete +│ ├── develop +│ ├── edit +│ ├── lock +│ ├── pin +│ ├── reopen +│ ├── transfer +│ ├── unlock +│ └── view +├── org # Organizations +│ └── list +├── pr # Pull Requests +│ ├── create +│ ├── list +│ ├── status +│ ├── checkout +│ ├── checks +│ ├── close +│ ├── comment +│ ├── diff +│ ├── edit +│ ├── lock +│ ├── merge +│ ├── ready +│ ├── reopen +│ ├── revert +│ ├── review +│ ├── unlock +│ ├── update-branch +│ └── view +├── project # Projects +│ ├── close +│ ├── copy +│ ├── create +│ ├── delete +│ ├── edit +│ ├── field-create +│ ├── field-delete +│ ├── field-list +│ ├── item-add +│ ├── item-archive +│ ├── item-create +│ ├── item-delete +│ ├── item-edit +│ ├── item-list +│ ├── link +│ ├── list +│ ├── mark-template +│ ├── unlink +│ └── view +├── release # Releases +│ ├── create +│ ├── list +│ ├── delete +│ ├── delete-asset +│ ├── download +│ ├── edit +│ ├── upload +│ ├── verify +│ ├── verify-asset +│ └── view +├── repo # Repositories +│ ├── create +│ ├── list +│ ├── archive +│ ├── autolink +│ ├── clone +│ ├── delete +│ ├── deploy-key +│ ├── edit +│ ├── fork +│ ├── gitignore +│ ├── license +│ ├── rename +│ ├── set-default +│ ├── sync +│ ├── unarchive +│ └── view +├── cache # Actions caches +│ ├── delete +│ └── list +├── run # Workflow runs +│ ├── cancel +│ ├── delete +│ ├── download +│ ├── list +│ ├── rerun +│ ├── view +│ └── watch +├── workflow # Workflows +│ ├── disable +│ ├── enable +│ ├── list +│ ├── run +│ └── view +├── agent-task # Agent tasks +├── alias # Command aliases +│ ├── delete +│ ├── import +│ ├── list +│ └── set +├── api # API requests +├── attestation # Artifact attestations +│ ├── download +│ ├── trusted-root +│ └── verify +├── completion # Shell completion +├── config # Configuration +│ ├── clear-cache +│ ├── get +│ ├── list +│ └── set +├── extension # Extensions +│ ├── browse +│ ├── create +│ ├── exec +│ ├── install +│ ├── list +│ ├── remove +│ ├── search +│ └── upgrade +├── gpg-key # GPG keys +│ ├── add +│ ├── delete +│ └── list +├── label # Labels +│ ├── clone +│ ├── create +│ ├── delete +│ ├── edit +│ └── list +├── preview # Preview features +├── ruleset # Rulesets +│ ├── check +│ ├── list +│ └── view +├── search # Search +│ ├── code +│ ├── commits +│ ├── issues +│ ├── prs +│ └── repos +├── secret # Secrets +│ ├── delete +│ ├── list +│ └── set +├── ssh-key # SSH keys +│ ├── add +│ ├── delete +│ └── list +├── status # Status overview +└── variable # Variables + ├── delete + ├── get + ├── list + └── set +``` + +## Configuration + +### Global Configuration + +```bash +# List all configuration +gh config list + +# Get specific configuration value +gh config list git_protocol +gh config get editor + +# Set configuration value +gh config set editor vim +gh config set git_protocol ssh +gh config set prompt disabled +gh config set pager "less -R" + +# Clear configuration cache +gh config clear-cache +``` + +### Environment Variables + +```bash +# GitHub token (for automation) +export GH_TOKEN=ghp_xxxxxxxxxxxx + +# GitHub hostname +export GH_HOST=github.com + +# Disable prompts +export GH_PROMPT_DISABLED=true + +# Custom editor +export GH_EDITOR=vim + +# Custom pager +export GH_PAGER=less + +# HTTP timeout +export GH_TIMEOUT=30 + +# Custom repository (override default) +export GH_REPO=owner/repo + +# Custom git protocol +export GH_ENTERPRISE_HOSTNAME=hostname +``` + +## Authentication (gh auth) + +### Login + +```bash +# Interactive login +gh auth login + +# Web-based authentication +gh auth login --web + +# With clipboard for OAuth code +gh auth login --web --clipboard + +# With specific git protocol +gh auth login --git-protocol ssh + +# With custom hostname (GitHub Enterprise) +gh auth login --hostname enterprise.internal + +# Login with token from stdin +gh auth login --with-token < token.txt + +# Insecure storage (plain text) +gh auth login --insecure-storage +``` + +### Status + +```bash +# Show all authentication status +gh auth status + +# Show active account only +gh auth status --active + +# Show specific hostname +gh auth status --hostname github.com + +# Show token in output +gh auth status --show-token + +# JSON output +gh auth status --json hosts + +# Filter with jq +gh auth status --json hosts --jq '.hosts | add' +``` + +### Switch Accounts + +```bash +# Interactive switch +gh auth switch + +# Switch to specific user/host +gh auth switch --hostname github.com --user monalisa +``` + +### Token + +```bash +# Print authentication token +gh auth token + +# Token for specific host/user +gh auth token --hostname github.com --user monalisa +``` + +### Refresh + +```bash +# Refresh credentials +gh auth refresh + +# Add scopes +gh auth refresh --scopes write:org,read:public_key + +# Remove scopes +gh auth refresh --remove-scopes delete_repo + +# Reset to default scopes +gh auth refresh --reset-scopes + +# With clipboard +gh auth refresh --clipboard +``` + +### Setup Git + +```bash +# Setup git credential helper +gh auth setup-git + +# Setup for specific host +gh auth setup-git --hostname enterprise.internal + +# Force setup even if host not known +gh auth setup-git --hostname enterprise.internal --force +``` + +## Browse (gh browse) + +```bash +# Open repository in browser +gh browse + +# Open specific path +gh browse script/ +gh browse main.go:312 + +# Open issue or PR +gh browse 123 + +# Open commit +gh browse 77507cd94ccafcf568f8560cfecde965fcfa63 + +# Open with specific branch +gh browse main.go --branch bug-fix + +# Open different repository +gh browse --repo owner/repo + +# Open specific pages +gh browse --actions # Actions tab +gh browse --projects # Projects tab +gh browse --releases # Releases tab +gh browse --settings # Settings page +gh browse --wiki # Wiki page + +# Print URL instead of opening +gh browse --no-browser +``` + +## Repositories (gh repo) + +### Create Repository + +```bash +# Create new repository +gh repo create my-repo + +# Create with description +gh repo create my-repo --description "My awesome project" + +# Create public repository +gh repo create my-repo --public + +# Create private repository +gh repo create my-repo --private + +# Create with homepage +gh repo create my-repo --homepage https://example.com + +# Create with license +gh repo create my-repo --license mit + +# Create with gitignore +gh repo create my-repo --gitignore python + +# Initialize as template repository +gh repo create my-repo --template + +# Create repository in organization +gh repo create org/my-repo + +# Create without cloning locally +gh repo create my-repo --source=. + +# Disable issues +gh repo create my-repo --disable-issues + +# Disable wiki +gh repo create my-repo --disable-wiki +``` + +### Clone Repository + +```bash +# Clone repository +gh repo clone owner/repo + +# Clone to specific directory +gh repo clone owner/repo my-directory + +# Clone with different branch +gh repo clone owner/repo --branch develop +``` + +### List Repositories + +```bash +# List all repositories +gh repo list + +# List repositories for owner +gh repo list owner + +# Limit results +gh repo list --limit 50 + +# Public repositories only +gh repo list --public + +# Source repositories only (not forks) +gh repo list --source + +# JSON output +gh repo list --json name,visibility,owner + +# Table output +gh repo list --limit 100 | tail -n +2 + +# Filter with jq +gh repo list --json name --jq '.[].name' +``` + +### View Repository + +```bash +# View repository details +gh repo view + +# View specific repository +gh repo view owner/repo + +# JSON output +gh repo view --json name,description,defaultBranchRef + +# View in browser +gh repo view --web +``` + +### Edit Repository + +```bash +# Edit description +gh repo edit --description "New description" + +# Set homepage +gh repo edit --homepage https://example.com + +# Change visibility +gh repo edit --visibility private +gh repo edit --visibility public + +# Enable/disable features +gh repo edit --enable-issues +gh repo edit --disable-issues +gh repo edit --enable-wiki +gh repo edit --disable-wiki +gh repo edit --enable-projects +gh repo edit --disable-projects + +# Set default branch +gh repo edit --default-branch main + +# Rename repository +gh repo rename new-name + +# Archive repository +gh repo archive +gh repo unarchive +``` + +### Delete Repository + +```bash +# Delete repository +gh repo delete owner/repo + +# Confirm without prompt +gh repo delete owner/repo --yes +``` + +### Fork Repository + +```bash +# Fork repository +gh repo fork owner/repo + +# Fork to organization +gh repo fork owner/repo --org org-name + +# Clone after forking +gh repo fork owner/repo --clone + +# Remote name for fork +gh repo fork owner/repo --remote-name upstream +``` + +### Sync Fork + +```bash +# Sync fork with upstream +gh repo sync + +# Sync specific branch +gh repo sync --branch feature + +# Force sync +gh repo sync --force +``` + +### Set Default Repository + +```bash +# Set default repository for current directory +gh repo set-default + +# Set default explicitly +gh repo set-default owner/repo + +# Unset default +gh repo set-default --unset +``` + +### Repository Autolinks + +```bash +# List autolinks +gh repo autolink list + +# Add autolink +gh repo autolink add \ + --key-prefix JIRA- \ + --url-template https://jira.example.com/browse/ + +# Delete autolink +gh repo autolink delete 12345 +``` + +### Repository Deploy Keys + +```bash +# List deploy keys +gh repo deploy-key list + +# Add deploy key +gh repo deploy-key add ~/.ssh/id_rsa.pub \ + --title "Production server" \ + --read-only + +# Delete deploy key +gh repo deploy-key delete 12345 +``` + +### Gitignore and License + +```bash +# View gitignore template +gh repo gitignore + +# View license template +gh repo license mit + +# License with full name +gh repo license mit --fullname "John Doe" +``` + +## Issues (gh issue) + +### Create Issue + +```bash +# Create issue interactively +gh issue create + +# Create with title +gh issue create --title "Bug: Login not working" + +# Create with title and body +gh issue create \ + --title "Bug: Login not working" \ + --body "Steps to reproduce..." + +# Create with body from file +gh issue create --body-file issue.md + +# Create with labels +gh issue create --title "Fix bug" --labels bug,high-priority + +# Create with assignees +gh issue create --title "Fix bug" --assignee user1,user2 + +# Create in specific repository +gh issue create --repo owner/repo --title "Issue title" + +# Create issue from web +gh issue create --web +``` + +### List Issues + +```bash +# List all open issues +gh issue list + +# List all issues (including closed) +gh issue list --state all + +# List closed issues +gh issue list --state closed + +# Limit results +gh issue list --limit 50 + +# Filter by assignee +gh issue list --assignee username +gh issue list --assignee @me + +# Filter by labels +gh issue list --labels bug,enhancement + +# Filter by milestone +gh issue list --milestone "v1.0" + +# Search/filter +gh issue list --search "is:open is:issue label:bug" + +# JSON output +gh issue list --json number,title,state,author + +# Table view +gh issue list --json number,title,labels --jq '.[] | [.number, .title, .labels[].name] | @tsv' + +# Show comments count +gh issue list --json number,title,comments --jq '.[] | [.number, .title, .comments]' + +# Sort by +gh issue list --sort created --order desc +``` + +### View Issue + +```bash +# View issue +gh issue view 123 + +# View with comments +gh issue view 123 --comments + +# View in browser +gh issue view 123 --web + +# JSON output +gh issue view 123 --json title,body,state,labels,comments + +# View specific fields +gh issue view 123 --json title --jq '.title' +``` + +### Edit Issue + +```bash +# Edit interactively +gh issue edit 123 + +# Edit title +gh issue edit 123 --title "New title" + +# Edit body +gh issue edit 123 --body "New description" + +# Add labels +gh issue edit 123 --add-label bug,high-priority + +# Remove labels +gh issue edit 123 --remove-label stale + +# Add assignees +gh issue edit 123 --add-assignee user1,user2 + +# Remove assignees +gh issue edit 123 --remove-assignee user1 + +# Set milestone +gh issue edit 123 --milestone "v1.0" +``` + +### Close/Reopen Issue + +```bash +# Close issue +gh issue close 123 + +# Close with comment +gh issue close 123 --comment "Fixed in PR #456" + +# Reopen issue +gh issue reopen 123 +``` + +### Comment on Issue + +```bash +# Add comment +gh issue comment 123 --body "This looks good!" + +# Edit comment +gh issue comment 123 --edit 456789 --body "Updated comment" + +# Delete comment +gh issue comment 123 --delete 456789 +``` + +### Issue Status + +```bash +# Show issue status summary +gh issue status + +# Status for specific repository +gh issue status --repo owner/repo +``` + +### Pin/Unpin Issues + +```bash +# Pin issue (pinned to repo dashboard) +gh issue pin 123 + +# Unpin issue +gh issue unpin 123 +``` + +### Lock/Unlock Issue + +```bash +# Lock conversation +gh issue lock 123 + +# Lock with reason +gh issue lock 123 --reason off-topic + +# Unlock +gh issue unlock 123 +``` + +### Transfer Issue + +```bash +# Transfer to another repository +gh issue transfer 123 --repo owner/new-repo +``` + +### Delete Issue + +```bash +# Delete issue +gh issue delete 123 + +# Confirm without prompt +gh issue delete 123 --yes +``` + +### Develop Issue (Draft PR) + +```bash +# Create draft PR from issue +gh issue develop 123 + +# Create in specific branch +gh issue develop 123 --branch fix/issue-123 + +# Create with base branch +gh issue develop 123 --base main +``` + +## Pull Requests (gh pr) + +### Create Pull Request + +```bash +# Create PR interactively +gh pr create + +# Create with title +gh pr create --title "Feature: Add new functionality" + +# Create with title and body +gh pr create \ + --title "Feature: Add new functionality" \ + --body "This PR adds..." + +# Fill body from template +gh pr create --body-file .github/PULL_REQUEST_TEMPLATE.md + +# Set base branch +gh pr create --base main + +# Set head branch (default: current branch) +gh pr create --head feature-branch + +# Create draft PR +gh pr create --draft + +# Add assignees +gh pr create --assignee user1,user2 + +# Add reviewers +gh pr create --reviewer user1,user2 + +# Add labels +gh pr create --labels enhancement,feature + +# Link to issue +gh pr create --issue 123 + +# Create in specific repository +gh pr create --repo owner/repo + +# Open in browser after creation +gh pr create --web +``` + +### List Pull Requests + +```bash +# List open PRs +gh pr list + +# List all PRs +gh pr list --state all + +# List merged PRs +gh pr list --state merged + +# List closed (not merged) PRs +gh pr list --state closed + +# Filter by head branch +gh pr list --head feature-branch + +# Filter by base branch +gh pr list --base main + +# Filter by author +gh pr list --author username +gh pr list --author @me + +# Filter by assignee +gh pr list --assignee username + +# Filter by labels +gh pr list --labels bug,enhancement + +# Limit results +gh pr list --limit 50 + +# Search +gh pr list --search "is:open is:pr label:review-required" + +# JSON output +gh pr list --json number,title,state,author,headRefName + +# Show check status +gh pr list --json number,title,statusCheckRollup --jq '.[] | [.number, .title, .statusCheckRollup[]?.status]' + +# Sort by +gh pr list --sort created --order desc +``` + +### View Pull Request + +```bash +# View PR +gh pr view 123 + +# View with comments +gh pr view 123 --comments + +# View in browser +gh pr view 123 --web + +# JSON output +gh pr view 123 --json title,body,state,author,commits,files + +# View diff +gh pr view 123 --json files --jq '.files[].path' + +# View with jq query +gh pr view 123 --json title,state --jq '"\(.title): \(.state)"' +``` + +### Checkout Pull Request + +```bash +# Checkout PR branch +gh pr checkout 123 + +# Checkout with specific branch name +gh pr checkout 123 --branch name-123 + +# Force checkout +gh pr checkout 123 --force +``` + +### Diff Pull Request + +```bash +# View PR diff +gh pr diff 123 + +# View diff with color +gh pr diff 123 --color always + +# Output to file +gh pr diff 123 > pr-123.patch + +# View diff of specific files +gh pr diff 123 --name-only +``` + +### Merge Pull Request + +```bash +# Merge PR +gh pr merge 123 + +# Merge with specific method +gh pr merge 123 --merge +gh pr merge 123 --squash +gh pr merge 123 --rebase + +# Delete branch after merge +gh pr merge 123 --delete-branch + +# Merge with comment +gh pr merge 123 --subject "Merge PR #123" --body "Merging feature" + +# Merge draft PR +gh pr merge 123 --admin + +# Force merge (skip checks) +gh pr merge 123 --admin +``` + +### Close Pull Request + +```bash +# Close PR (as draft, not merge) +gh pr close 123 + +# Close with comment +gh pr close 123 --comment "Closing due to..." +``` + +### Reopen Pull Request + +```bash +# Reopen closed PR +gh pr reopen 123 +``` + +### Edit Pull Request + +```bash +# Edit interactively +gh pr edit 123 + +# Edit title +gh pr edit 123 --title "New title" + +# Edit body +gh pr edit 123 --body "New description" + +# Add labels +gh pr edit 123 --add-label bug,enhancement + +# Remove labels +gh pr edit 123 --remove-label stale + +# Add assignees +gh pr edit 123 --add-assignee user1,user2 + +# Remove assignees +gh pr edit 123 --remove-assignee user1 + +# Add reviewers +gh pr edit 123 --add-reviewer user1,user2 + +# Remove reviewers +gh pr edit 123 --remove-reviewer user1 + +# Mark as ready for review +gh pr edit 123 --ready +``` + +### Ready for Review + +```bash +# Mark draft PR as ready +gh pr ready 123 +``` + +### Pull Request Checks + +```bash +# View PR checks +gh pr checks 123 + +# Watch checks in real-time +gh pr checks 123 --watch + +# Watch interval (seconds) +gh pr checks 123 --watch --interval 5 +``` + +### Comment on Pull Request + +```bash +# Add comment +gh pr comment 123 --body "Looks good!" + +# Comment on specific line +gh pr comment 123 --body "Fix this" \ + --repo owner/repo \ + --head-owner owner --head-branch feature + +# Edit comment +gh pr comment 123 --edit 456789 --body "Updated" + +# Delete comment +gh pr comment 123 --delete 456789 +``` + +### Review Pull Request + +```bash +# Review PR (opens editor) +gh pr review 123 + +# Approve PR +gh pr review 123 --approve + +--approve-body "LGTM!" + +# Request changes +gh pr review 123 --request-changes \ + --body "Please fix these issues" + +# Comment on PR +gh pr review 123 --comment --body "Some thoughts..." + +# Dismiss review +gh pr review 123 --dismiss +``` + +### Update Branch + +```bash +# Update PR branch with latest base branch +gh pr update-branch 123 + +# Force update +gh pr update-branch 123 --force + +# Use merge strategy +gh pr update-branch 123 --merge +``` + +### Lock/Unlock Pull Request + +```bash +# Lock PR conversation +gh pr lock 123 + +# Lock with reason +gh pr lock 123 --reason off-topic + +# Unlock +gh pr unlock 123 +``` + +### Revert Pull Request + +```bash +# Revert merged PR +gh pr revert 123 + +# Revert with specific branch name +gh pr revert 123 --branch revert-pr-123 +``` + +### Pull Request Status + +```bash +# Show PR status summary +gh pr status + +# Status for specific repository +gh pr status --repo owner/repo +``` + +## GitHub Actions + +### Workflow Runs (gh run) + +```bash +# List workflow runs +gh run list + +# List for specific workflow +gh run list --workflow "ci.yml" + +# List for specific branch +gh run list --branch main + +# Limit results +gh run list --limit 20 + +# JSON output +gh run list --json databaseId,status,conclusion,headBranch + +# View run details +gh run view 123456789 + +# View run with verbose logs +gh run view 123456789 --log + +# View specific job +gh run view 123456789 --job 987654321 + +# View in browser +gh run view 123456789 --web + +# Watch run in real-time +gh run watch 123456789 + +# Watch with interval +gh run watch 123456789 --interval 5 + +# Rerun failed run +gh run rerun 123456789 + +# Rerun specific job +gh run rerun 123456789 --job 987654321 + +# Cancel run +gh run cancel 123456789 + +# Delete run +gh run delete 123456789 + +# Download run artifacts +gh run download 123456789 + +# Download specific artifact +gh run download 123456789 --name build + +# Download to directory +gh run download 123456789 --dir ./artifacts +``` + +### Workflows (gh workflow) + +```bash +# List workflows +gh workflow list + +# View workflow details +gh workflow view ci.yml + +# View workflow YAML +gh workflow view ci.yml --yaml + +# View in browser +gh workflow view ci.yml --web + +# Enable workflow +gh workflow enable ci.yml + +# Disable workflow +gh workflow disable ci.yml + +# Run workflow manually +gh workflow run ci.yml + +# Run with inputs +gh workflow run ci.yml \ + --raw-field \ + version="1.0.0" \ + environment="production" + +# Run from specific branch +gh workflow run ci.yml --ref develop +``` + +### Action Caches (gh cache) + +```bash +# List caches +gh cache list + +# List for specific branch +gh cache list --branch main + +# List with limit +gh cache list --limit 50 + +# Delete cache +gh cache delete 123456789 + +# Delete all caches +gh cache delete --all +``` + +### Action Secrets (gh secret) + +```bash +# List secrets +gh secret list + +# Set secret (prompts for value) +gh secret set MY_SECRET + +# Set secret from environment +echo "$MY_SECRET" | gh secret set MY_SECRET + +# Set secret for specific environment +gh secret set MY_SECRET --env production + +# Set secret for organization +gh secret set MY_SECRET --org orgname + +# Delete secret +gh secret delete MY_SECRET + +# Delete from environment +gh secret delete MY_SECRET --env production +``` + +### Action Variables (gh variable) + +```bash +# List variables +gh variable list + +# Set variable +gh variable set MY_VAR "some-value" + +# Set variable for environment +gh variable set MY_VAR "value" --env production + +# Set variable for organization +gh variable set MY_VAR "value" --org orgname + +# Get variable value +gh variable get MY_VAR + +# Delete variable +gh variable delete MY_VAR + +# Delete from environment +gh variable delete MY_VAR --env production +``` + +## Projects (gh project) + +```bash +# List projects +gh project list + +# List for owner +gh project list --owner owner + +# Open projects +gh project list --open + +# View project +gh project view 123 + +# View project items +gh project view 123 --format json + +# Create project +gh project create --title "My Project" + +# Create in organization +gh project create --title "Project" --org orgname + +# Create with readme +gh project create --title "Project" --readme "Description here" + +# Edit project +gh project edit 123 --title "New Title" + +# Delete project +gh project delete 123 + +# Close project +gh project close 123 + +# Copy project +gh project copy 123 --owner target-owner --title "Copy" + +# Mark template +gh project mark-template 123 + +# List fields +gh project field-list 123 + +# Create field +gh project field-create 123 --title "Status" --datatype single_select + +# Delete field +gh project field-delete 123 --id 456 + +# List items +gh project item-list 123 + +# Create item +gh project item-create 123 --title "New item" + +# Add item to project +gh project item-add 123 --owner-owner --repo repo --issue 456 + +# Edit item +gh project item-edit 123 --id 456 --title "Updated title" + +# Delete item +gh project item-delete 123 --id 456 + +# Archive item +gh project item-archive 123 --id 456 + +# Link items +gh project link 123 --id 456 --link-id 789 + +# Unlink items +gh project unlink 123 --id 456 --link-id 789 + +# View project in browser +gh project view 123 --web +``` + +## Releases (gh release) + +```bash +# List releases +gh release list + +# View latest release +gh release view + +# View specific release +gh release view v1.0.0 + +# View in browser +gh release view v1.0.0 --web + +# Create release +gh release create v1.0.0 \ + --notes "Release notes here" + +# Create release with notes from file +gh release create v1.0.0 --notes-file notes.md + +# Create release with target +gh release create v1.0.0 --target main + +# Create release as draft +gh release create v1.0.0 --draft + +# Create pre-release +gh release create v1.0.0 --prerelease + +# Create release with title +gh release create v1.0.0 --title "Version 1.0.0" + +# Upload asset to release +gh release upload v1.0.0 ./file.tar.gz + +# Upload multiple assets +gh release upload v1.0.0 ./file1.tar.gz ./file2.tar.gz + +# Upload with label (casing sensitive) +gh release upload v1.0.0 ./file.tar.gz --casing + +# Delete release +gh release delete v1.0.0 + +# Delete with cleanup tag +gh release delete v1.0.0 --yes + +# Delete specific asset +gh release delete-asset v1.0.0 file.tar.gz + +# Download release assets +gh release download v1.0.0 + +# Download specific asset +gh release download v1.0.0 --pattern "*.tar.gz" + +# Download to directory +gh release download v1.0.0 --dir ./downloads + +# Download archive (zip/tar) +gh release download v1.0.0 --archive zip + +# Edit release +gh release edit v1.0.0 --notes "Updated notes" + +# Verify release signature +gh release verify v1.0.0 + +# Verify specific asset +gh release verify-asset v1.0.0 file.tar.gz +``` + +## Gists (gh gist) + +```bash +# List gists +gh gist list + +# List all gists (including private) +gh gist list --public + +# Limit results +gh gist list --limit 20 + +# View gist +gh gist view abc123 + +# View gist files +gh gist view abc123 --files + +# Create gist +gh gist create script.py + +# Create gist with description +gh gist create script.py --desc "My script" + +# Create public gist +gh gist create script.py --public + +# Create multi-file gist +gh gist create file1.py file2.py + +# Create from stdin +echo "print('hello')" | gh gist create + +# Edit gist +gh gist edit abc123 + +# Delete gist +gh gist delete abc123 + +# Rename gist file +gh gist rename abc123 --filename old.py new.py + +# Clone gist +gh gist clone abc123 + +# Clone to directory +gh gist clone abc123 my-directory +``` + +## Codespaces (gh codespace) + +```bash +# List codespaces +gh codespace list + +# Create codespace +gh codespace create + +# Create with specific repository +gh codespace create --repo owner/repo + +# Create with branch +gh codespace create --branch develop + +# Create with specific machine +gh codespace create --machine premiumLinux + +# View codespace details +gh codespace view + +# SSH into codespace +gh codespace ssh + +# SSH with specific command +gh codespace ssh --command "cd /workspaces && ls" + +# Open codespace in browser +gh codespace code + +# Open in VS Code +gh codespace code --codec + +# Open with specific path +gh codespace code --path /workspaces/repo + +# Stop codespace +gh codespace stop + +# Delete codespace +gh codespace delete + +# View logs +gh codespace logs + +--tail 100 + +# View ports +gh codespace ports + +# Forward port +gh codespace cp 8080:8080 + +# Rebuild codespace +gh codespace rebuild + +# Edit codespace +gh codespace edit --machine standardLinux + +# Jupyter support +gh codespace jupyter + +# Copy files to/from codespace +gh codespace cp file.txt :/workspaces/file.txt +gh codespace cp :/workspaces/file.txt ./file.txt +``` + +## Organizations (gh org) + +```bash +# List organizations +gh org list + +# List for user +gh org list --user username + +# JSON output +gh org list --json login,name,description + +# View organization +gh org view orgname + +# View organization members +gh org view orgname --json members --jq '.members[] | .login' +``` + +## Search (gh search) + +```bash +# Search code +gh search code "TODO" + +# Search in specific repository +gh search code "TODO" --repo owner/repo + +# Search commits +gh search commits "fix bug" + +# Search issues +gh search issues "label:bug state:open" + +# Search PRs +gh search prs "is:open is:pr review:required" + +# Search repositories +gh search repos "stars:>1000 language:python" + +# Limit results +gh search repos "topic:api" --limit 50 + +# JSON output +gh search repos "stars:>100" --json name,description,stargazers + +# Order results +gh search repos "language:rust" --order desc --sort stars + +# Search with extensions +gh search code "import" --extension py + +# Web search (open in browser) +gh search prs "is:open" --web +``` + +## Labels (gh label) + +```bash +# List labels +gh label list + +# Create label +gh label create bug --color "d73a4a" --description "Something isn't working" + +# Create with hex color +gh label create enhancement --color "#a2eeef" + +# Edit label +gh label edit bug --name "bug-report" --color "ff0000" + +# Delete label +gh label delete bug + +# Clone labels from repository +gh label clone owner/repo + +# Clone to specific repository +gh label clone owner/repo --repo target/repo +``` + +## SSH Keys (gh ssh-key) + +```bash +# List SSH keys +gh ssh-key list + +# Add SSH key +gh ssh-key add ~/.ssh/id_rsa.pub --title "My laptop" + +# Add key with type +gh ssh-key add ~/.ssh/id_ed25519.pub --type "authentication" + +# Delete SSH key +gh ssh-key delete 12345 + +# Delete by title +gh ssh-key delete --title "My laptop" +``` + +## GPG Keys (gh gpg-key) + +```bash +# List GPG keys +gh gpg-key list + +# Add GPG key +gh gpg-key add ~/.ssh/id_rsa.pub + +# Delete GPG key +gh gpg-key delete 12345 + +# Delete by key ID +gh gpg-key delete ABCD1234 +``` + +## Status (gh status) + +```bash +# Show status overview +gh status + +# Status for specific repositories +gh status --repo owner/repo + +# JSON output +gh status --json +``` + +## Configuration (gh config) + +```bash +# List all config +gh config list + +# Get specific value +gh config get editor + +# Set value +gh config set editor vim + +# Set git protocol +gh config set git_protocol ssh + +# Clear cache +gh config clear-cache + +# Set prompt behavior +gh config set prompt disabled +gh config set prompt enabled +``` + +## Extensions (gh extension) + +```bash +# List installed extensions +gh extension list + +# Search extensions +gh extension search github + +# Install extension +gh extension install owner/extension-repo + +# Install from branch +gh extension install owner/extension-repo --branch develop + +# Upgrade extension +gh extension upgrade extension-name + +# Remove extension +gh extension remove extension-name + +# Create new extension +gh extension create my-extension + +# Browse extensions +gh extension browse + +# Execute extension command +gh extension exec my-extension --arg value +``` + +## Aliases (gh alias) + +```bash +# List aliases +gh alias list + +# Set alias +gh alias set prview 'pr view --web' + +# Set shell alias +gh alias set co 'pr checkout' --shell + +# Delete alias +gh alias delete prview + +# Import aliases +gh alias import ./aliases.sh +``` + +## API Requests (gh api) + +```bash +# Make API request +gh api /user + +# Request with method +gh api --method POST /repos/owner/repo/issues \ + --field title="Issue title" \ + --field body="Issue body" + +# Request with headers +gh api /user \ + --header "Accept: application/vnd.github.v3+json" + +# Request with pagination +gh api /user/repos --paginate + +# Raw output (no formatting) +gh api /user --raw + +# Include headers in output +gh api /user --include + +# Silent mode (no progress output) +gh api /user --silent + +# Input from file +gh api --input request.json + +# jq query on response +gh api /user --jq '.login' + +# Field from response +gh api /repos/owner/repo --jq '.stargazers_count' + +# GitHub Enterprise +gh api /user --hostname enterprise.internal + +# GraphQL query +gh api graphql \ + -f query=' + { + viewer { + login + repositories(first: 5) { + nodes { + name + } + } + } + }' +``` + +## Rulesets (gh ruleset) + +```bash +# List rulesets +gh ruleset list + +# View ruleset +gh ruleset view 123 + +# Check ruleset +gh ruleset check --branch feature + +# Check specific repository +gh ruleset check --repo owner/repo --branch main +``` + +## Attestations (gh attestation) + +```bash +# Download attestation +gh attestation download owner/repo \ + --artifact-id 123456 + +# Verify attestation +gh attestation verify owner/repo + +# Get trusted root +gh attestation trusted-root +``` + +## Completion (gh completion) + +```bash +# Generate shell completion +gh completion -s bash > ~/.gh-complete.bash +gh completion -s zsh > ~/.gh-complete.zsh +gh completion -s fish > ~/.gh-complete.fish +gh completion -s powershell > ~/.gh-complete.ps1 + +# Shell-specific instructions +gh completion --shell=bash +gh completion --shell=zsh +``` + +## Preview (gh preview) + +```bash +# List preview features +gh preview + +# Run preview script +gh preview prompter +``` + +## Agent Tasks (gh agent-task) + +```bash +# List agent tasks +gh agent-task list + +# View agent task +gh agent-task view 123 + +# Create agent task +gh agent-task create --description "My task" +``` + +## Global Flags + +| Flag | Description | +| -------------------------- | -------------------------------------- | +| `--help` / `-h` | Show help for command | +| `--version` | Show gh version | +| `--repo [HOST/]OWNER/REPO` | Select another repository | +| `--hostname HOST` | GitHub hostname | +| `--jq EXPRESSION` | Filter JSON output | +| `--json FIELDS` | Output JSON with specified fields | +| `--template STRING` | Format JSON using Go template | +| `--web` | Open in browser | +| `--paginate` | Make additional API calls | +| `--verbose` | Show verbose output | +| `--debug` | Show debug output | +| `--timeout SECONDS` | Maximum API request duration | +| `--cache CACHE` | Cache control (default, force, bypass) | + +## Output Formatting + +### JSON Output + +```bash +# Basic JSON +gh repo view --json name,description + +# Nested fields +gh repo view --json owner,name --jq '.owner.login + "/" + .name' + +# Array operations +gh pr list --json number,title --jq '.[] | select(.number > 100)' + +# Complex queries +gh issue list --json number,title,labels \ + --jq '.[] | {number, title: .title, tags: [.labels[].name]}' +``` + +### Template Output + +```bash +# Custom template +gh repo view \ + --template '{{.name}}: {{.description}}' + +# Multiline template +gh pr view 123 \ + --template 'Title: {{.title}} +Author: {{.author.login}} +State: {{.state}} +' +``` + +## Common Workflows + +### Create PR from Issue + +```bash +# Create branch from issue +gh issue develop 123 --branch feature/issue-123 + +# Make changes, commit, push +git add . +git commit -m "Fix issue #123" +git push + +# Create PR linking to issue +gh pr create --title "Fix #123" --body "Closes #123" +``` + +### Bulk Operations + +```bash +# Close multiple issues +gh issue list --search "label:stale" \ + --json number \ + --jq '.[].number' | \ + xargs -I {} gh issue close {} --comment "Closing as stale" + +# Add label to multiple PRs +gh pr list --search "review:required" \ + --json number \ + --jq '.[].number' | \ + xargs -I {} gh pr edit {} --add-label needs-review +``` + +### Repository Setup Workflow + +```bash +# Create repository with initial setup +gh repo create my-project --public \ + --description "My awesome project" \ + --clone \ + --gitignore python \ + --license mit + +cd my-project + +# Set up branches +git checkout -b develop +git push -u origin develop + +# Create labels +gh label create bug --color "d73a4a" --description "Bug report" +gh label create enhancement --color "a2eeef" --description "Feature request" +gh label create documentation --color "0075ca" --description "Documentation" +``` + +### CI/CD Workflow + +```bash +# Run workflow and wait +RUN_ID=$(gh workflow run ci.yml --ref main --jq '.databaseId') + +# Watch the run +gh run watch "$RUN_ID" + +# Download artifacts on completion +gh run download "$RUN_ID" --dir ./artifacts +``` + +### Fork Sync Workflow + +```bash +# Fork repository +gh repo fork original/repo --clone + +cd repo + +# Add upstream remote +git remote add upstream https://github.com/original/repo.git + +# Sync fork +gh repo sync + +# Or manual sync +git fetch upstream +git checkout main +git merge upstream/main +git push origin main +``` + +## Environment Setup + +### Shell Integration + +```bash +# Add to ~/.bashrc or ~/.zshrc +eval "$(gh completion -s bash)" # or zsh/fish + +# Create useful aliases +alias gs='gh status' +alias gpr='gh pr view --web' +alias gir='gh issue view --web' +alias gco='gh pr checkout' +``` + +### Git Configuration + +```bash +# Use gh as credential helper +gh auth setup-git + +# Set gh as default for repo operations +git config --global credential.helper 'gh !gh auth setup-git' + +# Or manually +git config --global credential.helper github +``` + +## Best Practices + +1. **Authentication**: Use environment variables for automation + + ```bash + export GH_TOKEN=$(gh auth token) + ``` + +2. **Default Repository**: Set default to avoid repetition + + ```bash + gh repo set-default owner/repo + ``` + +3. **JSON Parsing**: Use jq for complex data extraction + + ```bash + gh pr list --json number,title --jq '.[] | select(.title | contains("fix"))' + ``` + +4. **Pagination**: Use --paginate for large result sets + + ```bash + gh issue list --state all --paginate + ``` + +5. **Caching**: Use cache control for frequently accessed data + ```bash + gh api /user --cache force + ``` + +## Getting Help + +```bash +# General help +gh --help + +# Command help +gh pr --help +gh issue create --help + +# Help topics +gh help formatting +gh help environment +gh help exit-codes +gh help accessibility +``` + +## References + +- Official Manual: https://cli.github.com/manual/ +- GitHub Docs: https://docs.github.com/en/github-cli +- REST API: https://docs.github.com/en/rest +- GraphQL API: https://docs.github.com/en/graphql diff --git a/skills/git-commit/SKILL.md b/skills/git-commit/SKILL.md new file mode 100644 index 00000000..c35f13b8 --- /dev/null +++ b/skills/git-commit/SKILL.md @@ -0,0 +1,124 @@ +--- +name: git-commit +description: 'Execute git commit with conventional commit message analysis, intelligent staging, and message generation. Use when user asks to commit changes, create a git commit, or mentions "/commit". Supports: (1) Auto-detecting type and scope from changes, (2) Generating conventional commit messages from diff, (3) Interactive commit with optional type/scope/description overrides, (4) Intelligent file staging for logical grouping' +license: MIT +allowed-tools: Bash +--- + +# Git Commit with Conventional Commits + +## Overview + +Create standardized, semantic git commits using the Conventional Commits specification. Analyze the actual diff to determine appropriate type, scope, and message. + +## Conventional Commit Format + +``` +[optional scope]: + +[optional body] + +[optional footer(s)] +``` + +## Commit Types + +| Type | Purpose | +| ---------- | ------------------------------ | +| `feat` | New feature | +| `fix` | Bug fix | +| `docs` | Documentation only | +| `style` | Formatting/style (no logic) | +| `refactor` | Code refactor (no feature/fix) | +| `perf` | Performance improvement | +| `test` | Add/update tests | +| `build` | Build system/dependencies | +| `ci` | CI/config changes | +| `chore` | Maintenance/misc | +| `revert` | Revert commit | + +## Breaking Changes + +``` +# Exclamation mark after type/scope +feat!: remove deprecated endpoint + +# BREAKING CHANGE footer +feat: allow config to extend other configs + +BREAKING CHANGE: `extends` key behavior changed +``` + +## Workflow + +### 1. Analyze Diff + +```bash +# If files are staged, use staged diff +git diff --staged + +# If nothing staged, use working tree diff +git diff + +# Also check status +git status --porcelain +``` + +### 2. Stage Files (if needed) + +If nothing is staged or you want to group changes differently: + +```bash +# Stage specific files +git add path/to/file1 path/to/file2 + +# Stage by pattern +git add *.test.* +git add src/components/* + +# Interactive staging +git add -p +``` + +**Never commit secrets** (.env, credentials.json, private keys). + +### 3. Generate Commit Message + +Analyze the diff to determine: + +- **Type**: What kind of change is this? +- **Scope**: What area/module is affected? +- **Description**: One-line summary of what changed (present tense, imperative mood, <72 chars) + +### 4. Execute Commit + +```bash +# Single line +git commit -m "[scope]: " + +# Multi-line with body/footer +git commit -m "$(cat <<'EOF' +[scope]: + + + + +EOF +)" +``` + +## Best Practices + +- One logical change per commit +- Present tense: "add" not "added" +- Imperative mood: "fix bug" not "fixes bug" +- Reference issues: `Closes #123`, `Refs #456` +- Keep description under 72 characters + +## Git Safety Protocol + +- NEVER update git config +- NEVER run destructive commands (--force, hard reset) without explicit request +- NEVER skip hooks (--no-verify) unless user asks +- NEVER force push to main/master +- If commit fails due to hooks, fix and create NEW commit (don't amend) diff --git a/skills/mcp-cli/SKILL.md b/skills/mcp-cli/SKILL.md new file mode 100644 index 00000000..d5b801ee --- /dev/null +++ b/skills/mcp-cli/SKILL.md @@ -0,0 +1,78 @@ +--- +name: mcp-cli +description: Interface for MCP (Model Context Protocol) servers via CLI. Use when you need to interact with external tools, APIs, or data sources through MCP servers, list available MCP servers/tools, or call MCP tools from command line. +--- + +# MCP-CLI + +Access MCP servers through the command line. MCP enables interaction with external systems like GitHub, filesystems, databases, and APIs. + +## Commands + +| Command | Output | +| ---------------------------------- | ------------------------------- | +| `mcp-cli` | List all servers and tool names | +| `mcp-cli ` | Show tools with parameters | +| `mcp-cli /` | Get tool JSON schema | +| `mcp-cli / ''` | Call tool with arguments | +| `mcp-cli grep ""` | Search tools by name | + +**Add `-d` to include descriptions** (e.g., `mcp-cli filesystem -d`) + +## Workflow + +1. **Discover**: `mcp-cli` → see available servers and tools +2. **Explore**: `mcp-cli ` → see tools with parameters +3. **Inspect**: `mcp-cli /` → get full JSON input schema +4. **Execute**: `mcp-cli / ''` → run with arguments + +## Examples + +```bash +# List all servers and tool names +mcp-cli + +# See all tools with parameters +mcp-cli filesystem + +# With descriptions (more verbose) +mcp-cli filesystem -d + +# Get JSON schema for specific tool +mcp-cli filesystem/read_file + +# Call the tool +mcp-cli filesystem/read_file '{"path": "./README.md"}' + +# Search for tools +mcp-cli grep "*file*" + +# JSON output for parsing +mcp-cli filesystem/read_file '{"path": "./README.md"}' --json + +# Complex JSON with quotes (use heredoc or stdin) +mcp-cli server/tool < Alice : hello +Alice -> Bob : Is it ok? +@enduml +``` + +### 2. Generate ASCII Art + +```bash +# Standard ASCII output +plantuml -txt diagram.puml + +# Unicode-enhanced output (better looking) +plantuml -utxt diagram.puml + +# Using JAR directly +java -jar plantuml.jar -txt diagram.puml +java -jar plantuml.jar -utxt diagram.puml +``` + +### 3. View Output + +Output is saved as `diagram.atxt` (ASCII) or `diagram.utxt` (Unicode). + +## Diagram Types Supported + +### Sequence Diagram + +```plantuml +@startuml +actor User +participant "Web App" as App +database "Database" as DB + +User -> App : Login Request +App -> DB : Validate Credentials +DB --> App : User Data +App --> User : Auth Token +@enduml +``` + +### Class Diagram + +```plantuml +@startuml +class User { + +id: int + +name: string + +email: string + +login(): bool +} + +class Order { + +id: int + +total: float + +items: List + +calculateTotal(): float +} + +User "1" -- "*" Order : places +@enduml +``` + +### Activity Diagram + +```plantuml +@startuml +start +:Initialize; +if (Is Valid?) then (yes) + :Process Data; + :Save Result; +else (no) + :Log Error; + stop +endif +:Complete; +stop +@enduml +``` + +### State Diagram + +```plantuml +@startuml +[*] --> Idle +Idle --> Processing : start +Processing --> Success : complete +Processing --> Error : fail +Success --> [*] +Error --> Idle : retry +@enduml +``` + +### Component Diagram + +```plantuml +@startuml +[Client] as client +[API Gateway] as gateway +[Service A] as svcA +[Service B] as svcB +[Database] as db + +client --> gateway +gateway --> svcA +gateway --> svcB +svcA --> db +svcB --> db +@enduml +``` + +### Use Case Diagram + +```plantuml +@startuml +actor "User" as user +actor "Admin" as admin + +rectangle "System" { + user -- (Login) + user -- (View Profile) + user -- (Update Settings) + admin -- (Manage Users) + admin -- (Configure System) +} +@enduml +``` + +### Deployment Diagram + +```plantuml +@startuml +actor "User" as user +node "Load Balancer" as lb +node "Web Server 1" as ws1 +node "Web Server 2" as ws2 +database "Primary DB" as db1 +database "Replica DB" as db2 + +user --> lb +lb --> ws1 +lb --> ws2 +ws1 --> db1 +ws2 --> db1 +db1 --> db2 : replicate +@enduml +``` + +## Command-Line Options + +```bash +# Specify output directory +plantuml -txt -o ./output diagram.puml + +# Process all files in directory +plantuml -txt ./diagrams/ + +# Include dot files (hidden files) +plantuml -txt -includeDot diagrams/ + +# Verbose output +plantuml -txt -v diagram.puml + +# Specify charset +plantuml -txt -charset UTF-8 diagram.puml +``` + +## Ant Task Integration + +```xml + + + + + + + +``` + +## Tips for Better ASCII Diagrams + +1. **Keep it simple**: Complex diagrams don't render well in ASCII +2. **Short labels**: Long text breaks ASCII alignment +3. **Use Unicode (`-utxt`)**: Better visual quality with box-drawing chars +4. **Test before sharing**: Verify in terminal with fixed-width font +5. **Consider alternatives**: For complex diagrams, use Mermaid.js or graphviz + +## Example Output Comparison + +**Standard ASCII (`-txt`)**: + +``` + ,---. ,---. + |Bob| |Alice| + `---' `---' + | hello | + |------------->| + | | + | Is it ok? | + |<-------------| + | | +``` + +**Unicode ASCII (`-utxt`)**: + +``` +┌─────┐ ┌─────┐ +│ Bob │ │Alice│ +└─────┘ └─────┘ + │ hello │ + │─────────────>│ + │ │ + │ Is it ok? │ + │<─────────────│ + │ │ +``` + +## Quick Reference + +```bash +# Create sequence diagram in ASCII +cat > seq.puml << 'EOF' +@startuml +Alice -> Bob: Request +Bob --> Alice: Response +@enduml +EOF + +plantuml -txt seq.puml +cat seq.atxt + +# Create with Unicode +plantuml -utxt seq.puml +cat seq.utxt +``` + +## Troubleshooting + +**Problem**: Garbled Unicode characters + +- **Solution**: Ensure terminal supports UTF-8 and has proper font + +**Problem**: Diagram looks misaligned + +- **Solution**: Use fixed-width font (Courier, Monaco, Consolas) + +**Problem**: Command not found + +- **Solution**: Install PlantUML or use Java JAR directly + +**Problem**: Output file not created + +- **Solution**: Check file permissions, ensure PlantUML has write access diff --git a/skills/prd/SKILL.md b/skills/prd/SKILL.md new file mode 100644 index 00000000..6614a074 --- /dev/null +++ b/skills/prd/SKILL.md @@ -0,0 +1,150 @@ +--- +name: prd +description: 'Generate high-quality Product Requirements Documents (PRDs) for AI agents and software systems. Includes executive summaries, user stories, technical specifications, AI-specific requirements (models, data, prompts), and risk analysis.' +license: MIT +--- + +# Product Requirements Document (PRD) + +## Overview + +Design comprehensive, production-grade Product Requirements Documents (PRDs) that bridge the gap between business vision and technical execution. This skill is optimized for AI agent development and modern software systems, ensuring that both deterministic and non-deterministic requirements are clearly defined. + +## When to Use + +Use this skill when: + +- Starting a new product or feature development cycle +- Translating a vague idea into a concrete technical specification +- Defining requirements for an AI agent (LLM, ML, etc.) +- Stakeholders need a unified "source of truth" for project scope +- User asks to "write a PRD", "document requirements", or "plan a feature" + +--- + +## Operational Workflow + +### Phase 1: Discovery (The Interview) + +Before writing a single line of the PRD, you **MUST** interrogate the user to fill knowledge gaps. Do not assume context. + +**Ask about:** + +- **The Core Problem**: Why are we building this now? +- **Success Metrics**: How do we know it worked? +- **Constraints**: Budget, tech stack, or deadline? +- **Agent Roles**: If this is for an AI system, what are the subagent responsibilities? + +### Phase 2: Analysis & Scoping + +Synthesize the user's input. Identify dependencies and hidden complexities. + +- Map out the **User Flow**. +- Define **Non-Goals** to protect the timeline. +- Identify **Orchestration Needs** (which tools or agents are required?). + +### Phase 3: Technical Drafting + +Generate the document using the **Strict PRD Schema** below. + +--- + +## PRD Quality Standards + +### Requirements Quality + +Use concrete, measurable criteria. Avoid "fast", "easy", or "intuitive". + +```diff +# Vague (BAD) +- The search should be fast and return relevant results. +- The UI must look modern and be easy to use. + +# Concrete (GOOD) ++ The search must return results within 200ms for a 10k record dataset. ++ The search algorithm must achieve >= 85% Precision@10 in benchmark evals. ++ The UI must follow the 'Vercel/Next.js' design system and achieve 100% Lighthouse Accessibility score. +``` + +--- + +## Strict PRD Schema + +You **MUST** follow this exact structure for the output: + +### 1. Executive Summary + +- **Problem Statement**: 1-2 sentences on the pain point. +- **Proposed Solution**: 1-2 sentences on the fix. +- **Success Criteria**: 3-5 measurable KPIs. + +### 2. User Experience & Functionality + +- **User Personas**: Who is this for? +- **User Stories**: `As a [user], I want to [action] so that [benefit].` +- **Acceptance Criteria**: Bulleted list of "Done" definitions for each story. +- **Non-Goals**: What are we NOT building? + +### 3. AI & Agent Orchestration (If Applicable) + +- **Model Selection**: e.g., `Claude 3.5 Sonnet` for reasoning, `Haiku` for speed. +- **Agent Definitions**: Specific roles for subagents (e.g., `librarian` for research). +- **Tool Whitelist**: Explicit list of tools each agent is allowed to use. +- **Evaluation Strategy**: How to measure AI output quality (Evals, Golden Sets). + +### 4. Technical Specifications + +- **Architecture Overview**: Data flow and component interaction. +- **Integration Points**: APIs, DBs, and Auth. +- **Security & Privacy**: Data handling and compliance. + +### 5. Risks & Roadmap + +- **Phased Rollout**: MVP -> v1.1 -> v2.0. +- **Technical Risks**: Latency, cost, or dependency failures. + +--- + +## Implementation Guidelines + +### DO (Always) + +- **Delegate Visuals**: If the PRD involves UI/UX, explicitly instruct the use of the `frontend-ui-ux-engineer` agent. +- **Define Evals**: For AI systems, specify the **Evaluation Protocol** (how to detect hallucinations or failures). +- **Iterate**: Present a draft and ask for feedback on specific sections. + +### DON'T (Avoid) + +- **Skip Discovery**: Never write a PRD without asking at least 2 clarifying questions first. +- **Hallucinate Constraints**: If the user didn't specify a tech stack, ask or label it as `TBD`. + +--- + +## Example: AI-Powered Search Agent + +### 1. Executive Summary + +**Problem**: Users struggle to find specific documentation snippets in massive repositories. +**Solution**: A RAG-based search agent that provides direct answers with source citations. +**Success**: + +- Reduce search time by 50%. +- Citation accuracy >= 95%. + +### 2. User Stories + +- **Story**: As a developer, I want to ask natural language questions so I don't have to guess keywords. +- **AC**: + - Supports multi-turn clarification. + - Returns code blocks with "Copy" button. + +### 3. Agent Orchestration + +- **Primary Agent**: `Oracle` for reasoning and answer synthesis. +- **Subagent**: `Librarian` for searching docs and indexing code. +- **Tool Whitelist**: `codesearch`, `grep`, `webfetch`. + +### 4. Evaluation + +- **Benchmark**: Use a 'Golden Set' of 50 common dev questions. +- **Pass Rate**: 90% must match ground truth citations. diff --git a/skills/refactor/SKILL.md b/skills/refactor/SKILL.md new file mode 100644 index 00000000..a5b3af02 --- /dev/null +++ b/skills/refactor/SKILL.md @@ -0,0 +1,645 @@ +--- +name: refactor +description: 'Surgical code refactoring to improve maintainability without changing behavior. Covers extracting functions, renaming variables, breaking down god functions, improving type safety, eliminating code smells, and applying design patterns. Less drastic than repo-rebuilder; use for gradual improvements.' +license: MIT +--- + +# Refactor + +## Overview + +Improve code structure and readability without changing external behavior. Refactoring is gradual evolution, not revolution. Use this for improving existing code, not rewriting from scratch. + +## When to Use + +Use this skill when: + +- Code is hard to understand or maintain +- Functions/classes are too large +- Code smells need addressing +- Adding features is difficult due to code structure +- User asks "clean up this code", "refactor this", "improve this" + +--- + +## Refactoring Principles + +### The Golden Rules + +1. **Behavior is preserved** - Refactoring doesn't change what the code does, only how +2. **Small steps** - Make tiny changes, test after each +3. **Version control is your friend** - Commit before and after each safe state +4. **Tests are essential** - Without tests, you're not refactoring, you're editing +5. **One thing at a time** - Don't mix refactoring with feature changes + +### When NOT to Refactor + +``` +- Code that works and won't change again (if it ain't broke...) +- Critical production code without tests (add tests first) +- When you're under a tight deadline +- "Just because" - need a clear purpose +``` + +--- + +## Common Code Smells & Fixes + +### 1. Long Method/Function + +```diff +# BAD: 200-line function that does everything +- async function processOrder(orderId) { +- // 50 lines: fetch order +- // 30 lines: validate order +- // 40 lines: calculate pricing +- // 30 lines: update inventory +- // 20 lines: create shipment +- // 30 lines: send notifications +- } + +# GOOD: Broken into focused functions ++ async function processOrder(orderId) { ++ const order = await fetchOrder(orderId); ++ validateOrder(order); ++ const pricing = calculatePricing(order); ++ await updateInventory(order); ++ const shipment = await createShipment(order); ++ await sendNotifications(order, pricing, shipment); ++ return { order, pricing, shipment }; ++ } +``` + +### 2. Duplicated Code + +```diff +# BAD: Same logic in multiple places +- function calculateUserDiscount(user) { +- if (user.membership === 'gold') return user.total * 0.2; +- if (user.membership === 'silver') return user.total * 0.1; +- return 0; +- } +- +- function calculateOrderDiscount(order) { +- if (order.user.membership === 'gold') return order.total * 0.2; +- if (order.user.membership === 'silver') return order.total * 0.1; +- return 0; +- } + +# GOOD: Extract common logic ++ function getMembershipDiscountRate(membership) { ++ const rates = { gold: 0.2, silver: 0.1 }; ++ return rates[membership] || 0; ++ } ++ ++ function calculateUserDiscount(user) { ++ return user.total * getMembershipDiscountRate(user.membership); ++ } ++ ++ function calculateOrderDiscount(order) { ++ return order.total * getMembershipDiscountRate(order.user.membership); ++ } +``` + +### 3. Large Class/Module + +```diff +# BAD: God object that knows too much +- class UserManager { +- createUser() { /* ... */ } +- updateUser() { /* ... */ } +- deleteUser() { /* ... */ } +- sendEmail() { /* ... */ } +- generateReport() { /* ... */ } +- handlePayment() { /* ... */ } +- validateAddress() { /* ... */ } +- // 50 more methods... +- } + +# GOOD: Single responsibility per class ++ class UserService { ++ create(data) { /* ... */ } ++ update(id, data) { /* ... */ } ++ delete(id) { /* ... */ } ++ } ++ ++ class EmailService { ++ send(to, subject, body) { /* ... */ } ++ } ++ ++ class ReportService { ++ generate(type, params) { /* ... */ } ++ } ++ ++ class PaymentService { ++ process(amount, method) { /* ... */ } ++ } +``` + +### 4. Long Parameter List + +```diff +# BAD: Too many parameters +- function createUser(email, password, name, age, address, city, country, phone) { +- /* ... */ +- } + +# GOOD: Group related parameters ++ interface UserData { ++ email: string; ++ password: string; ++ name: string; ++ age?: number; ++ address?: Address; ++ phone?: string; ++ } ++ ++ function createUser(data: UserData) { ++ /* ... */ ++ } + +# EVEN BETTER: Use builder pattern for complex construction ++ const user = UserBuilder ++ .email('test@example.com') ++ .password('secure123') ++ .name('Test User') ++ .address(address) ++ .build(); +``` + +### 5. Feature Envy + +```diff +# BAD: Method that uses another object's data more than its own +- class Order { +- calculateDiscount(user) { +- if (user.membershipLevel === 'gold') { ++ return this.total * 0.2; ++ } ++ if (user.accountAge > 365) { ++ return this.total * 0.1; ++ } ++ return 0; ++ } ++ } + +# GOOD: Move logic to the object that owns the data ++ class User { ++ getDiscountRate(orderTotal) { ++ if (this.membershipLevel === 'gold') return 0.2; ++ if (this.accountAge > 365) return 0.1; ++ return 0; ++ } ++ } ++ ++ class Order { ++ calculateDiscount(user) { ++ return this.total * user.getDiscountRate(this.total); ++ } ++ } +``` + +### 6. Primitive Obsession + +```diff +# BAD: Using primitives for domain concepts +- function sendEmail(to, subject, body) { /* ... */ } +- sendEmail('user@example.com', 'Hello', '...'); + +- function createPhone(country, number) { +- return `${country}-${number}`; +- } + +# GOOD: Use domain types ++ class Email { ++ private constructor(public readonly value: string) { ++ if (!Email.isValid(value)) throw new Error('Invalid email'); ++ } ++ static create(value: string) { return new Email(value); } ++ static isValid(email: string) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); } ++ } ++ ++ class PhoneNumber { ++ constructor( ++ public readonly country: string, ++ public readonly number: string ++ ) { ++ if (!PhoneNumber.isValid(country, number)) throw new Error('Invalid phone'); ++ } ++ toString() { return `${this.country}-${this.number}`; } ++ static isValid(country: string, number: string) { /* ... */ } ++ } ++ ++ // Usage ++ const email = Email.create('user@example.com'); ++ const phone = new PhoneNumber('1', '555-1234'); +``` + +### 7. Magic Numbers/Strings + +```diff +# BAD: Unexplained values +- if (user.status === 2) { /* ... */ } +- const discount = total * 0.15; +- setTimeout(callback, 86400000); + +# GOOD: Named constants ++ const UserStatus = { ++ ACTIVE: 1, ++ INACTIVE: 2, ++ SUSPENDED: 3 ++ } as const; ++ ++ const DISCOUNT_RATES = { ++ STANDARD: 0.1, ++ PREMIUM: 0.15, ++ VIP: 0.2 ++ } as const; ++ ++ const ONE_DAY_MS = 24 * 60 * 60 * 1000; ++ ++ if (user.status === UserStatus.INACTIVE) { /* ... */ } ++ const discount = total * DISCOUNT_RATES.PREMIUM; ++ setTimeout(callback, ONE_DAY_MS); +``` + +### 8. Nested Conditionals + +```diff +# BAD: Arrow code +- function process(order) { +- if (order) { +- if (order.user) { +- if (order.user.isActive) { +- if (order.total > 0) { +- return processOrder(order); ++ } else { ++ return { error: 'Invalid total' }; ++ } ++ } else { ++ return { error: 'User inactive' }; ++ } ++ } else { ++ return { error: 'No user' }; ++ } ++ } else { ++ return { error: 'No order' }; ++ } ++ } + +# GOOD: Guard clauses / early returns ++ function process(order) { ++ if (!order) return { error: 'No order' }; ++ if (!order.user) return { error: 'No user' }; ++ if (!order.user.isActive) return { error: 'User inactive' }; ++ if (order.total <= 0) return { error: 'Invalid total' }; ++ return processOrder(order); ++ } + +# EVEN BETER: Using Result type ++ function process(order): Result { ++ return Result.combine([ ++ validateOrderExists(order), ++ validateUserExists(order), ++ validateUserActive(order.user), ++ validateOrderTotal(order) ++ ]).flatMap(() => processOrder(order)); ++ } +``` + +### 9. Dead Code + +```diff +# BAD: Unused code lingers +- function oldImplementation() { /* ... */ } +- const DEPRECATED_VALUE = 5; +- import { unusedThing } from './somewhere'; +- // Commented out code +- // function oldCode() { /* ... */ } + +# GOOD: Remove it ++ // Delete unused functions, imports, and commented code ++ // If you need it again, git history has it +``` + +### 10. Inappropriate Intimacy + +```diff +# BAD: One class reaches deep into another +- class OrderProcessor { +- process(order) { +- order.user.profile.address.street; // Too intimate +- order.repository.connection.config; // Breaking encapsulation ++ } ++ } + +# GOOD: Ask, don't tell ++ class OrderProcessor { ++ process(order) { ++ order.getShippingAddress(); // Order knows how to get it ++ order.save(); // Order knows how to save itself ++ } ++ } +``` + +--- + +## Extract Method Refactoring + +### Before and After + +```diff +# Before: One long function +- function printReport(users) { +- console.log('USER REPORT'); +- console.log('============'); +- console.log(''); +- console.log(`Total users: ${users.length}`); +- console.log(''); +- console.log('ACTIVE USERS'); +- console.log('------------'); +- const active = users.filter(u => u.isActive); +- active.forEach(u => { +- console.log(`- ${u.name} (${u.email})`); +- }); +- console.log(''); +- console.log(`Active: ${active.length}`); +- console.log(''); +- console.log('INACTIVE USERS'); +- console.log('--------------'); +- const inactive = users.filter(u => !u.isActive); +- inactive.forEach(u => { +- console.log(`- ${u.name} (${u.email})`); +- }); +- console.log(''); +- console.log(`Inactive: ${inactive.length}`); +- } + +# After: Extracted methods ++ function printReport(users) { ++ printHeader('USER REPORT'); ++ console.log(`Total users: ${users.length}\n`); ++ printUserSection('ACTIVE USERS', users.filter(u => u.isActive)); ++ printUserSection('INACTIVE USERS', users.filter(u => !u.isActive)); ++ } ++ ++ function printHeader(title) { ++ const line = '='.repeat(title.length); ++ console.log(title); ++ console.log(line); ++ console.log(''); ++ } ++ ++ function printUserSection(title, users) { ++ console.log(title); ++ console.log('-'.repeat(title.length)); ++ users.forEach(u => console.log(`- ${u.name} (${u.email})`)); ++ console.log(''); ++ console.log(`${title.split(' ')[0]}: ${users.length}`); ++ console.log(''); ++ } +``` + +--- + +## Introducing Type Safety + +### From Untyped to Typed + +```diff +# Before: No types +- function calculateDiscount(user, total, membership, date) { +- if (membership === 'gold' && date.getDay() === 5) { +- return total * 0.25; +- } +- if (membership === 'gold') return total * 0.2; +- return total * 0.1; +- } + +# After: Full type safety ++ type Membership = 'bronze' | 'silver' | 'gold'; ++ ++ interface User { ++ id: string; ++ name: string; ++ membership: Membership; ++ } ++ ++ interface DiscountResult { ++ original: number; ++ discount: number; ++ final: number; ++ rate: number; ++ } ++ ++ function calculateDiscount( ++ user: User, ++ total: number, ++ date: Date = new Date() ++ ): DiscountResult { ++ if (total < 0) throw new Error('Total cannot be negative'); ++ ++ let rate = 0.1; // Default bronze ++ ++ if (user.membership === 'gold' && date.getDay() === 5) { ++ rate = 0.25; // Friday bonus for gold ++ } else if (user.membership === 'gold') { ++ rate = 0.2; ++ } else if (user.membership === 'silver') { ++ rate = 0.15; ++ } ++ ++ const discount = total * rate; ++ ++ return { ++ original: total, ++ discount, ++ final: total - discount, ++ rate ++ }; ++ } +``` + +--- + +## Design Patterns for Refactoring + +### Strategy Pattern + +```diff +# Before: Conditional logic +- function calculateShipping(order, method) { +- if (method === 'standard') { +- return order.total > 50 ? 0 : 5.99; +- } else if (method === 'express') { +- return order.total > 100 ? 9.99 : 14.99; ++ } else if (method === 'overnight') { ++ return 29.99; ++ } ++ } + +# After: Strategy pattern ++ interface ShippingStrategy { ++ calculate(order: Order): number; ++ } ++ ++ class StandardShipping implements ShippingStrategy { ++ calculate(order: Order) { ++ return order.total > 50 ? 0 : 5.99; ++ } ++ } ++ ++ class ExpressShipping implements ShippingStrategy { ++ calculate(order: Order) { ++ return order.total > 100 ? 9.99 : 14.99; ++ } ++ } ++ ++ class OvernightShipping implements ShippingStrategy { ++ calculate(order: Order) { ++ return 29.99; ++ } ++ } ++ ++ function calculateShipping(order: Order, strategy: ShippingStrategy) { ++ return strategy.calculate(order); ++ } +``` + +### Chain of Responsibility + +```diff +# Before: Nested validation +- function validate(user) { +- const errors = []; +- if (!user.email) errors.push('Email required'); ++ else if (!isValidEmail(user.email)) errors.push('Invalid email'); ++ if (!user.name) errors.push('Name required'); ++ if (user.age < 18) errors.push('Must be 18+'); ++ if (user.country === 'blocked') errors.push('Country not supported'); ++ return errors; ++ } + +# After: Chain of responsibility ++ abstract class Validator { ++ abstract validate(user: User): string | null; ++ setNext(validator: Validator): Validator { ++ this.next = validator; ++ return validator; ++ } ++ validate(user: User): string | null { ++ const error = this.doValidate(user); ++ if (error) return error; ++ return this.next?.validate(user) ?? null; ++ } ++ } ++ ++ class EmailRequiredValidator extends Validator { ++ doValidate(user: User) { ++ return !user.email ? 'Email required' : null; ++ } ++ } ++ ++ class EmailFormatValidator extends Validator { ++ doValidate(user: User) { ++ return user.email && !isValidEmail(user.email) ? 'Invalid email' : null; ++ } ++ } ++ ++ // Build the chain ++ const validator = new EmailRequiredValidator() ++ .setNext(new EmailFormatValidator()) ++ .setNext(new NameRequiredValidator()) ++ .setNext(new AgeValidator()) ++ .setNext(new CountryValidator()); +``` + +--- + +## Refactoring Steps + +### Safe Refactoring Process + +``` +1. PREPARE + - Ensure tests exist (write them if missing) + - Commit current state + - Create feature branch + +2. IDENTIFY + - Find the code smell to address + - Understand what the code does + - Plan the refactoring + +3. REFACTOR (small steps) + - Make one small change + - Run tests + - Commit if tests pass + - Repeat + +4. VERIFY + - All tests pass + - Manual testing if needed + - Performance unchanged or improved + +5. CLEAN UP + - Update comments + - Update documentation + - Final commit +``` + +--- + +## Refactoring Checklist + +### Code Quality + +- [ ] Functions are small (< 50 lines) +- [ ] Functions do one thing +- [ ] No duplicated code +- [ ] Descriptive names (variables, functions, classes) +- [ ] No magic numbers/strings +- [ ] Dead code removed + +### Structure + +- [ ] Related code is together +- [ ] Clear module boundaries +- [ ] Dependencies flow in one direction +- [ ] No circular dependencies + +### Type Safety + +- [ ] Types defined for all public APIs +- [ ] No `any` types without justification +- [ ] Nullable types explicitly marked + +### Testing + +- [ ] Refactored code is tested +- [ ] Tests cover edge cases +- [ ] All tests pass + +--- + +## Common Refactoring Operations + +| Operation | Description | +| --------------------------------------------- | ------------------------------------- | +| Extract Method | Turn code fragment into method | +| Extract Class | Move behavior to new class | +| Extract Interface | Create interface from implementation | +| Inline Method | Move method body back to caller | +| Inline Class | Move class behavior to caller | +| Pull Up Method | Move method to superclass | +| Push Down Method | Move method to subclass | +| Rename Method/Variable | Improve clarity | +| Introduce Parameter Object | Group related parameters | +| Replace Conditional with Polymorphism | Use polymorphism instead of switch/if | +| Replace Magic Number with Constant | Named constants | +| Decompose Conditional | Break complex conditions | +| Consolidate Conditional | Combine duplicate conditions | +| Replace Nested Conditional with Guard Clauses | Early returns | +| Introduce Null Object | Eliminate null checks | +| Replace Type Code with Class/Enum | Strong typing | +| Replace Inheritance with Delegation | Composition over inheritance |