Managing GitHub Projects (v2) Skill You are a GitHub Projects v2 expert specializing in project board creation, management, and automation. You understand the modern GraphQL-based Projects API and can help users organize their work effectively using boards, views, and custom fields. When to Use This Skill Auto-invoke this skill when the conversation involves: - Creating or managing GitHub project boards - Setting up sprint planning or kanban workflows - Organizing issues and PRs using project boards - Configuring project fields, views, or automation - GraphQL operations for GitHub Projects v2…

\\t'\n}\n\n# List project items\nlist_project_items() {\n local owner=\"$1\"\n local project_number=\"$2\"\n\n local result\n result=$(get_project \"$owner\" \"$project_number\")\n\n echo \"$result\" | jq -r '\n .data.organization.projectV2.items.nodes[] |\n \"\\(.id)\\t\\(.content.number // \"N/A\")\\t\\(.content.title // \"No title\")\\t\\(.content.state // \"unknown\")\"\n ' | column -t -s

Managing GitHub Projects (v2) Skill You are a GitHub Projects v2 expert specializing in project board creation, management, and automation. You understand the modern GraphQL-based Projects API and can help users organize their work effectively using boards, views, and custom fields. When to Use This Skill Auto-invoke this skill when the conversation involves: - Creating or managing GitHub project boards - Setting up sprint planning or kanban workflows - Organizing issues and PRs using project boards - Configuring project fields, views, or automation - GraphQL operations for GitHub Projects v2…

\\t'\n}\n\n# Get field options (for single select fields)\nget_field_options() {\n local owner=\"$1\"\n local project_number=\"$2\"\n local field_name=\"$3\"\n\n local result\n result=$(get_project \"$owner\" \"$project_number\")\n\n echo \"$result\" | jq -r --arg field \"$field_name\" '\n .data.organization.projectV2.fields.nodes[] |\n select(.name == $field) |\n .options[]? |\n \"\\(.id)\\t\\(.name)\"\n ' | column -t -s

Managing GitHub Projects (v2) Skill You are a GitHub Projects v2 expert specializing in project board creation, management, and automation. You understand the modern GraphQL-based Projects API and can help users organize their work effectively using boards, views, and custom fields. When to Use This Skill Auto-invoke this skill when the conversation involves: - Creating or managing GitHub project boards - Setting up sprint planning or kanban workflows - Organizing issues and PRs using project boards - Configuring project fields, views, or automation - GraphQL operations for GitHub Projects v2…

\\t'\n}\n\n# Usage/help\nshow_usage() {\n cat \u003c\u003cEOF\nUsage: $0 \u003ccommand> [arguments]\n\nCommands:\n get_project \u003cowner> \u003cproject_number>\n Get full project details including fields and items\n\n get_project_id \u003cowner> \u003cproject_number>\n Get project node ID\n\n get_content_id \u003cowner> \u003crepo> \u003cissue|pr> \u003cnumber>\n Get issue or PR node ID\n\n add_item \u003cproject_id> \u003ccontent_id>\n Add an issue or PR to a project\n\n update_field_select \u003cproject_id> \u003citem_id> \u003cfield_id> \u003coption_id>\n Update a single select field\n\n update_field_text \u003cproject_id> \u003citem_id> \u003cfield_id> \u003ctext_value>\n Update a text field\n\n update_field_number \u003cproject_id> \u003citem_id> \u003cfield_id> \u003cnumber_value>\n Update a number field\n\n bulk_update \u003cproject_id> \u003cfield_id> \u003coption_id> \u003citem_id1> [item_id2...]\n Bulk update field for multiple items\n\n list_fields \u003cowner> \u003cproject_number>\n List all fields in a project\n\n list_items \u003cowner> \u003cproject_number>\n List all items in a project\n\n get_options \u003cowner> \u003cproject_number> \u003cfield_name>\n Get options for a single select field\n\nExamples:\n # Get project ID\n $0 get_project_id myorg 1\n\n # Add issue to project\n CONTENT_ID=\\$($0 get_content_id myorg myrepo issue 42)\n PROJECT_ID=\\$($0 get_project_id myorg 1)\n $0 add_item \"\\$PROJECT_ID\" \"\\$CONTENT_ID\"\n\n # Update status field\n $0 update_field_select \"\\$PROJECT_ID\" \"\\$ITEM_ID\" \"\\$FIELD_ID\" \"\\$OPTION_ID\"\n\n # List fields to find IDs\n $0 list_fields myorg 1\n\n # Get status field options\n $0 get_options myorg 1 \"Status\"\n\nNote: Requires 'gh' CLI with authentication and 'jq' for JSON processing.\nEOF\n}\n\n# Main entry point\nmain() {\n # Check for jq\n if ! command -v jq &>/dev/null; then\n error \"jq is required but not installed. Install with: apt-get install jq (Ubuntu) or brew install jq (macOS)\"\n fi\n\n # Check for gh CLI\n if ! command -v gh &>/dev/null; then\n error \"GitHub CLI (gh) is required but not installed. See: https://cli.github.com/\"\n fi\n\n case \"${1:-help}\" in\n get_project)\n [[ $# -lt 3 ]] && error \"Usage: $0 get_project \u003cowner> \u003cproject_number>\"\n get_project \"$2\" \"$3\"\n ;;\n get_project_id)\n [[ $# -lt 3 ]] && error \"Usage: $0 get_project_id \u003cowner> \u003cproject_number>\"\n get_project_node_id \"$2\" \"$3\"\n ;;\n get_content_id)\n [[ $# -lt 5 ]] && error \"Usage: $0 get_content_id \u003cowner> \u003crepo> \u003cissue|pr> \u003cnumber>\"\n get_content_node_id \"$2\" \"$3\" \"$4\" \"$5\"\n ;;\n add_item)\n [[ $# -lt 3 ]] && error \"Usage: $0 add_item \u003cproject_id> \u003ccontent_id>\"\n add_project_item \"$2\" \"$3\"\n ;;\n update_field_select)\n [[ $# -lt 5 ]] && error \"Usage: $0 update_field_select \u003cproject_id> \u003citem_id> \u003cfield_id> \u003coption_id>\"\n update_item_field_single_select \"$2\" \"$3\" \"$4\" \"$5\"\n ;;\n update_field_text)\n [[ $# -lt 5 ]] && error \"Usage: $0 update_field_text \u003cproject_id> \u003citem_id> \u003cfield_id> \u003ctext_value>\"\n update_item_field_text \"$2\" \"$3\" \"$4\" \"$5\"\n ;;\n update_field_number)\n [[ $# -lt 5 ]] && error \"Usage: $0 update_field_number \u003cproject_id> \u003citem_id> \u003cfield_id> \u003cnumber_value>\"\n update_item_field_number \"$2\" \"$3\" \"$4\" \"$5\"\n ;;\n bulk_update)\n [[ $# -lt 5 ]] && error \"Usage: $0 bulk_update \u003cproject_id> \u003cfield_id> \u003coption_id> \u003citem_id1> [item_id2...]\"\n bulk_update_items \"$2\" \"$3\" \"$4\" \"${@:5}\"\n ;;\n list_fields)\n [[ $# -lt 3 ]] && error \"Usage: $0 list_fields \u003cowner> \u003cproject_number>\"\n list_project_fields \"$2\" \"$3\"\n ;;\n list_items)\n [[ $# -lt 3 ]] && error \"Usage: $0 list_items \u003cowner> \u003cproject_number>\"\n list_project_items \"$2\" \"$3\"\n ;;\n get_options)\n [[ $# -lt 4 ]] && error \"Usage: $0 get_options \u003cowner> \u003cproject_number> \u003cfield_name>\"\n get_field_options \"$2\" \"$3\" \"$4\"\n ;;\n help|--help|-h)\n show_usage\n ;;\n *)\n error \"Unknown command: $1\\n\\nRun '$0 help' for usage information.\"\n ;;\n esac\n}\n\n# Run main if executed directly\nif [[ \"${BASH_SOURCE[0]}\" == \"${0}\" ]]; then\n main \"$@\"\nfi\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":13941,"content_sha256":"b408cb8a41de2be075053206dd09c1fe9eeed38ae05f8f1fa471ecdd4253101b"},{"filename":"scripts/project-helpers.sh","content":"#!/usr/bin/env bash\n# GitHub Projects v2 Helper Functions\n# Provides wrapper functions for common project operations\n\nset -euo pipefail\n\n# Colors for output\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nNC='\\033[0m' # No Color\n\n# Error handling\nerror() {\n echo -e \"${RED}Error: $1${NC}\" >&2\n exit 1\n}\n\nsuccess() {\n echo -e \"${GREEN}✓ $1${NC}\"\n}\n\nwarn() {\n echo -e \"${YELLOW}⚠ $1${NC}\"\n}\n\n# Execute command with retry logic\nexecute_with_retry() {\n local max_attempts=\"${MAX_RETRIES:-3}\"\n local attempt=1\n local delay=2\n local command=\"$@\"\n\n while [ $attempt -le $max_attempts ]; do\n if eval \"$command\"; then\n return 0\n fi\n\n if [ $attempt -lt $max_attempts ]; then\n warn \"Attempt $attempt/$max_attempts failed, retrying in ${delay}s...\"\n sleep $delay\n ((attempt++))\n delay=$((delay * 2)) # Exponential backoff\n else\n error \"Command failed after $max_attempts attempts\"\n return 1\n fi\n done\n}\n\n# Validate prerequisites with helpful messages\nvalidate_prerequisites() {\n local errors=()\n\n # Check gh CLI\n if ! command -v gh >/dev/null 2>&1; then\n errors+=(\"GitHub CLI (gh) not installed. Install from: https://github.com/cli/cli#installation\")\n elif ! gh auth status >/dev/null 2>&1; then\n errors+=(\"GitHub CLI not authenticated. Run: gh auth login\")\n fi\n\n # Check jq if available\n if ! command -v jq >/dev/null 2>&1; then\n warn \"jq not installed. Some features may not work. Install from: https://stedolan.github.io/jq/download/\"\n fi\n\n # Report errors\n if [ ${#errors[@]} -gt 0 ]; then\n error \"Prerequisites check failed:\"\n for err in \"${errors[@]}\"; do\n echo \" - $err\" >&2\n done\n return 1\n fi\n\n return 0\n}\n\n# Check prerequisites and ensure gh CLI is installed\nensure_gh_cli() {\n local script_dir=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && cd ../../.. && pwd)\"\n local ensure_gh_script=\"$script_dir/scripts/ensure-gh-cli.sh\"\n local ensure_deps_script=\"$script_dir/scripts/ensure-dependencies.sh\"\n\n # First, ensure dependencies (jq, python3, etc.)\n if [ -f \"$ensure_deps_script\" ]; then\n if ! bash \"$ensure_deps_script\" true false >/dev/null 2>&1; then\n warn \"Some dependencies may be missing (jq, python3)\"\n fi\n fi\n\n # Then, ensure gh CLI\n if [ -f \"$ensure_gh_script\" ]; then\n # Try to ensure gh is installed and authenticated\n if bash \"$ensure_gh_script\" true false; then\n return 0\n else\n error \"GitHub CLI setup failed\"\n return 1\n fi\n else\n # Fallback to simple check\n if ! command -v gh >/dev/null 2>&1; then\n error \"GitHub CLI (gh) is not installed\"\n echo \"Install it from: https://github.com/cli/cli#installation\" >&2\n return 1\n fi\n\n if ! gh auth status >/dev/null 2>&1; then\n error \"Not authenticated with GitHub. Run: gh auth login\"\n return 1\n fi\n fi\n}\n\n# Get organization from current repository\nget_org() {\n gh repo view --json owner -q '.owner.login' 2>/dev/null || echo \"\"\n}\n\n# Create project with template\ncreate_project() {\n local title=\"$1\"\n local template=\"${2:-}\"\n local owner=\"${3:-$(get_org)}\"\n\n ensure_gh_cli || return 1\n\n if [[ -z \"$owner\" ]]; then\n error \"Could not determine organization. Specify with --owner\"\n fi\n\n echo \"Creating project '$title' for $owner...\"\n\n local project_id\n project_id=$(gh project create \\\n --owner \"$owner\" \\\n --title \"$title\" \\\n --format json | jq -r '.id')\n\n if [[ -z \"$project_id\" ]]; then\n error \"Failed to create project\"\n fi\n\n success \"Project created: $project_id\"\n\n # Apply template if specified\n if [[ -n \"$template\" ]]; then\n apply_template \"$project_id\" \"$template\" \"$owner\"\n fi\n\n echo \"$project_id\"\n}\n\n# Apply board template\napply_template() {\n local project_id=\"$1\"\n local template=\"$2\"\n local owner=\"$3\"\n\n case \"$template\" in\n sprint)\n echo \"Applying sprint template...\"\n create_sprint_fields \"$project_id\" \"$owner\"\n ;;\n kanban)\n echo \"Applying kanban template...\"\n create_kanban_fields \"$project_id\" \"$owner\"\n ;;\n roadmap)\n echo \"Applying roadmap template...\"\n create_roadmap_fields \"$project_id\" \"$owner\"\n ;;\n *)\n warn \"Unknown template: $template\"\n ;;\n esac\n}\n\n# Create sprint board fields\ncreate_sprint_fields() {\n local project_id=\"$1\"\n local owner=\"$2\"\n\n echo \"Creating custom fields...\"\n\n # Status field (SingleSelect)\n create_single_select_field \"$project_id\" \"$owner\" \"Status\" \\\n \"Backlog,Sprint,In Progress,Review,Done\"\n\n # Priority field\n create_single_select_field \"$project_id\" \"$owner\" \"Priority\" \\\n \"High,Medium,Low\"\n\n # Story Points field\n create_single_select_field \"$project_id\" \"$owner\" \"Story Points\" \\\n \"1,2,3,5,8,13\"\n\n success \"Sprint fields created\"\n}\n\n# Create kanban board fields\ncreate_kanban_fields() {\n local project_id=\"$1\"\n local owner=\"$2\"\n\n # Status field\n create_single_select_field \"$project_id\" \"$owner\" \"Status\" \\\n \"Todo,In Progress,Review,Done\"\n\n # Priority field\n create_single_select_field \"$project_id\" \"$owner\" \"Priority\" \\\n \"High,Medium,Low\"\n\n # Size field\n create_single_select_field \"$project_id\" \"$owner\" \"Size\" \\\n \"XS,S,M,L,XL\"\n\n success \"Kanban fields created\"\n}\n\n# Create roadmap board fields\ncreate_roadmap_fields() {\n local project_id=\"$1\"\n local owner=\"$2\"\n\n # Status field\n create_single_select_field \"$project_id\" \"$owner\" \"Status\" \\\n \"Planning,In Progress,Completed,On Hold\"\n\n # Quarter field\n create_single_select_field \"$project_id\" \"$owner\" \"Quarter\" \\\n \"Q1 2024,Q2 2024,Q3 2024,Q4 2024\"\n\n success \"Roadmap fields created\"\n}\n\n# Helper to create SingleSelect field via GraphQL\ncreate_single_select_field() {\n local project_id=\"$1\"\n local owner=\"$2\"\n local field_name=\"$3\"\n local options=\"$4\"\n\n echo \"Creating field: $field_name\"\n\n # Convert comma-separated options to JSON array for GraphQL\n local options_json\n options_json=$(echo \"$options\" | jq -R 'split(\",\") | map({name: ., color: \"GRAY\"})')\n\n local mutation\n mutation=$(cat \u003c\u003c'EOF'\nmutation($projectId: ID!, $fieldName: String!, $options: [ProjectV2SingleSelectFieldOptionInput!]!) {\n createProjectV2Field(input: {\n projectId: $projectId\n dataType: SINGLE_SELECT\n name: $fieldName\n singleSelectOptions: $options\n }) {\n projectV2Field {\n ... on ProjectV2SingleSelectField {\n id\n name\n }\n }\n }\n}\nEOF\n)\n\n local result\n result=$(gh api graphql -f query=\"$mutation\" \\\n -f projectId=\"$project_id\" \\\n -f fieldName=\"$field_name\" \\\n --input - \u003c\u003c\u003c \"{\\\"options\\\": $options_json}\" 2>&1)\n\n if echo \"$result\" | jq -e '.data.createProjectV2Field.projectV2Field.id' >/dev/null 2>&1; then\n success \"Created field: $field_name\"\n return 0\n else\n warn \"Failed to create field $field_name: $(echo \"$result\" | jq -r '.errors[0].message // \"unknown error\"')\"\n return 1\n fi\n}\n\n# Bulk add items to project\nbulk_add_items() {\n local project_number=\"$1\"\n local filter=\"$2\"\n local owner=\"${3:-$(get_org)}\"\n\n ensure_gh_cli || return 1\n\n echo \"Searching for items: $filter\"\n\n # Search for issues matching filter\n local issues\n issues=$(gh issue list --search \"$filter\" --json number,url --limit 1000)\n\n local count=0\n echo \"$issues\" | jq -r '.[] | .url' | while read -r url; do\n if gh project item-add \"$project_number\" --owner \"$owner\" --url \"$url\" >/dev/null 2>&1; then\n ((count++)) || true\n echo -n \".\"\n fi\n done\n echo \"\"\n\n success \"Added items to project\"\n}\n\n# Update item status\nupdate_item_status() {\n local project_id=\"$1\"\n local item_id=\"$2\"\n local status=\"$3\"\n local owner=\"${4:-$(get_org)}\"\n\n echo \"Updating item $item_id to status: $status\"\n\n # Get graphql-queries.sh location\n local script_dir=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n local graphql_script=\"$script_dir/graphql-queries.sh\"\n\n if [[ ! -f \"$graphql_script\" ]]; then\n error \"graphql-queries.sh not found at $graphql_script\"\n fi\n\n # First, get the Status field ID and option ID\n local project_number\n project_number=$(gh project list --owner \"$owner\" --format json | \\\n jq -r --arg id \"$project_id\" '.projects[] | select(.id == $id) | .number')\n\n if [[ -z \"$project_number\" ]]; then\n error \"Could not find project number for ID: $project_id\"\n fi\n\n # Get field options\n local field_info\n field_info=$(bash \"$graphql_script\" get_options \"$owner\" \"$project_number\" \"Status\" 2>/dev/null)\n\n local option_id\n option_id=$(echo \"$field_info\" | grep -i \"$status\" | awk '{print $1}')\n\n if [[ -z \"$option_id\" ]]; then\n error \"Could not find option ID for status: $status\"\n fi\n\n # Get Status field ID\n local field_id\n field_id=$(bash \"$graphql_script\" list_fields \"$owner\" \"$project_number\" 2>/dev/null | \\\n grep -i \"Status\" | awk '{print $1}')\n\n if [[ -z \"$field_id\" ]]; then\n error \"Could not find Status field ID\"\n fi\n\n # Update the field\n if bash \"$graphql_script\" update_field_select \"$project_id\" \"$item_id\" \"$field_id\" \"$option_id\"; then\n success \"Updated item status to: $status\"\n else\n error \"Failed to update item status\"\n fi\n}\n\n# Archive completed items\narchive_done_items() {\n local project_number=\"$1\"\n local owner=\"${2:-$(get_org)}\"\n local days_old=\"${3:-14}\"\n\n echo \"Archiving items older than $days_old days in Done status...\"\n\n ensure_gh_cli || return 1\n\n # Get graphql-queries.sh location\n local script_dir=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n local graphql_script=\"$script_dir/graphql-queries.sh\"\n\n # Get project ID\n local project_id\n project_id=$(bash \"$graphql_script\" get_project_id \"$owner\" \"$project_number\" 2>/dev/null)\n\n if [[ -z \"$project_id\" || \"$project_id\" == \"null\" ]]; then\n error \"Could not get project ID for project #$project_number\"\n fi\n\n # Query for done items with their updated dates\n local query\n query=$(cat \u003c\u003c'EOF'\nquery($projectId: ID!) {\n node(id: $projectId) {\n ... on ProjectV2 {\n items(first: 100) {\n nodes {\n id\n updatedAt\n fieldValues(first: 10) {\n nodes {\n ... on ProjectV2ItemFieldSingleSelectValue {\n name\n field { ... on ProjectV2SingleSelectField { name } }\n }\n }\n }\n }\n }\n }\n }\n}\nEOF\n)\n\n local result\n result=$(gh api graphql -f query=\"$query\" -f projectId=\"$project_id\" 2>/dev/null)\n\n # Filter for Done items older than N days\n local cutoff_date\n cutoff_date=$(date -d \"-$days_old days\" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || \\\n date -v-${days_old}d +%Y-%m-%dT%H:%M:%SZ)\n\n local items_to_archive\n items_to_archive=$(echo \"$result\" | jq -r --arg cutoff \"$cutoff_date\" '\n .data.node.items.nodes[] |\n select(\n .updatedAt \u003c $cutoff and\n (.fieldValues.nodes[] | select(.field.name == \"Status\" and .name == \"Done\"))\n ) | .id\n ')\n\n if [[ -z \"$items_to_archive\" ]]; then\n echo \"No items to archive\"\n return 0\n fi\n\n local archive_count=0\n while IFS= read -r item_id; do\n [[ -z \"$item_id\" ]] && continue\n\n local archive_mutation\n archive_mutation=$(cat \u003c\u003c'EOF'\nmutation($projectId: ID!, $itemId: ID!) {\n archiveProjectV2Item(input: {\n projectId: $projectId\n itemId: $itemId\n }) {\n item { id }\n }\n}\nEOF\n)\n\n if gh api graphql -f query=\"$archive_mutation\" \\\n -f projectId=\"$project_id\" \\\n -f itemId=\"$item_id\" >/dev/null 2>&1; then\n ((archive_count++))\n echo -n \".\"\n fi\n done \u003c\u003c\u003c \"$items_to_archive\"\n\n echo \"\"\n success \"Archived $archive_count items\"\n}\n\n# Generate project report\ngenerate_report() {\n local project_number=\"$1\"\n local owner=\"${2:-$(get_org)}\"\n\n echo \"Generating report for project #$project_number...\"\n\n ensure_gh_cli || return 1\n\n # Get graphql-queries.sh location\n local script_dir=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n local graphql_script=\"$script_dir/graphql-queries.sh\"\n\n # Get full project data via GraphQL\n local result\n result=$(bash \"$graphql_script\" get_project \"$owner\" \"$project_number\" 2>/dev/null)\n\n if [[ -z \"$result\" ]]; then\n error \"Could not fetch project data\"\n fi\n\n local title\n title=$(echo \"$result\" | jq -r '.data.organization.projectV2.title // \"Unknown\"')\n\n echo \"\"\n echo \"=========================================\"\n echo \"Project Report: $title\"\n echo \"=========================================\"\n echo \"\"\n\n # Calculate statistics\n local total_items\n total_items=$(echo \"$result\" | jq '.data.organization.projectV2.items.nodes | length')\n\n echo \"Total items: $total_items\"\n echo \"\"\n\n # Count by status\n echo \"By Status:\"\n echo \"$result\" | jq -r '\n .data.organization.projectV2.items.nodes |\n map(\n .fieldValues.nodes[] |\n select(.field.name == \"Status\") |\n .name // \"No Status\"\n ) |\n group_by(.) |\n map({status: .[0], count: length}) |\n sort_by(-.count) |\n .[] |\n \" \\(.status): \\(.count)\"\n '\n\n echo \"\"\n\n # Calculate completion rate\n local done_count\n done_count=$(echo \"$result\" | jq '[\n .data.organization.projectV2.items.nodes[] |\n select(.fieldValues.nodes[] | select(.field.name == \"Status\" and .name == \"Done\"))\n ] | length')\n\n if [[ \"$total_items\" -gt 0 ]]; then\n local completion_pct\n completion_pct=$(echo \"scale=1; $done_count * 100 / $total_items\" | bc)\n echo \"Completion: $done_count/$total_items ($completion_pct%)\"\n else\n echo \"Completion: 0/0 (0%)\"\n fi\n\n # Show open vs closed issues\n echo \"\"\n echo \"Item States:\"\n echo \"$result\" | jq -r '\n .data.organization.projectV2.items.nodes |\n group_by(.content.state // \"unknown\") |\n map({state: .[0].content.state // \"unknown\", count: length}) |\n .[] |\n \" \\(.state): \\(.count)\"\n '\n\n echo \"\"\n}\n\n# List user's projects\nlist_projects() {\n local owner=\"${1:-$(get_org)}\"\n\n ensure_gh_cli || return 1\n\n if [[ -z \"$owner\" ]]; then\n error \"Could not determine organization\"\n fi\n\n echo \"Projects for $owner:\"\n echo \"\"\n\n gh project list --owner \"$owner\" --format json | jq -r '.projects[] | \" #\\(.number): \\(.title)\"'\n}\n\n# Main command router\nmain() {\n local command=\"${1:-help}\"\n shift || true\n\n case \"$command\" in\n create_project)\n create_project \"$@\"\n ;;\n bulk_add_items)\n bulk_add_items \"$@\"\n ;;\n update_status)\n update_item_status \"$@\"\n ;;\n archive_done_items)\n archive_done_items \"$@\"\n ;;\n generate_report)\n generate_report \"$@\"\n ;;\n list_projects)\n list_projects \"$@\"\n ;;\n help|*)\n cat \u003c\u003cEOF\nGitHub Projects Helper Script\n\nUsage: $0 \u003ccommand> [options]\n\nCommands:\n create_project \u003ctitle> [template] [owner]\n Create a new project with optional template\n Templates: sprint, kanban, roadmap\n\n bulk_add_items \u003cproject_number> \u003cfilter> [owner]\n Add items matching filter to project\n Example: bulk_add_items 1 \"is:issue is:open label:feature\"\n\n update_status \u003cproject_id> \u003citem_id> \u003cstatus> [owner]\n Update item status (requires GraphQL)\n\n archive_done_items \u003cproject_number> [owner] [days_old]\n Archive completed items older than N days\n\n generate_report \u003cproject_number> [owner]\n Generate project progress report\n\n list_projects [owner]\n List all projects for owner\n\nExamples:\n $0 create_project \"Sprint 5\" sprint\n $0 bulk_add_items 1 \"is:issue label:feature\"\n $0 generate_report 1\n $0 list_projects myorg\n\nEOF\n ;;\n esac\n}\n\n# Run main if executed directly\nif [[ \"${BASH_SOURCE[0]}\" == \"${0}\" ]]; then\n main \"$@\"\nfi\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":16600,"content_sha256":"3f52386b3450dac6fc2d6e26cf7f7781a70c62a9b3f3e20cb8941c0feea56315"},{"filename":"scripts/validate-board-config.py","content":"#!/usr/bin/env python3\n\"\"\"\nValidate Board Configuration\nValidates GitHub Projects v2 board configuration including fields, items, and views.\n\"\"\"\n\nimport argparse\nimport json\nimport subprocess\nimport sys\nfrom typing import Any\n\n# Colors for output\nRED = '\\033[0;31m'\nGREEN = '\\033[0;32m'\nYELLOW = '\\033[1;33m'\nBLUE = '\\033[0;34m'\nNC = '\\033[0m'\n\n\ndef run_gh(args: list[str]) -> str:\n \"\"\"Execute gh command and return output.\"\"\"\n try:\n result = subprocess.run(\n ['gh'] + args,\n capture_output=True,\n text=True,\n check=True,\n encoding='utf-8'\n )\n return result.stdout.strip()\n except subprocess.CalledProcessError as e:\n print(f\"{RED}Error running gh command: {e.stderr}{NC}\", file=sys.stderr)\n return \"\"\n except FileNotFoundError:\n print(f\"{RED}Error: GitHub CLI (gh) not found. Install from: https://github.com/cli/cli{NC}\", file=sys.stderr)\n sys.exit(1)\n\n\ndef get_project_data(owner: str, project_number: int) -> dict[str, Any]:\n \"\"\"Fetch project data via GraphQL.\"\"\"\n query = '''\n query($owner: String!, $number: Int!) {\n organization(login: $owner) {\n projectV2(number: $number) {\n id\n title\n fields(first: 50) {\n nodes {\n ... on ProjectV2Field {\n id\n name\n dataType\n }\n ... on ProjectV2SingleSelectField {\n id\n name\n dataType\n options {\n id\n name\n }\n }\n ... on ProjectV2IterationField {\n id\n name\n dataType\n }\n }\n }\n items(first: 100) {\n nodes {\n id\n type\n content {\n ... on Issue {\n number\n title\n state\n }\n ... on PullRequest {\n number\n title\n state\n }\n }\n fieldValues(first: 20) {\n nodes {\n ... on ProjectV2ItemFieldSingleSelectValue {\n name\n field { ... on ProjectV2SingleSelectField { name } }\n }\n ... on ProjectV2ItemFieldTextValue {\n text\n field { ... on ProjectV2Field { name } }\n }\n ... on ProjectV2ItemFieldNumberValue {\n number\n field { ... on ProjectV2Field { name } }\n }\n ... on ProjectV2ItemFieldDateValue {\n date\n field { ... on ProjectV2Field { name } }\n }\n }\n }\n }\n }\n views(first: 20) {\n nodes {\n id\n name\n layout\n }\n }\n }\n }\n user(login: $owner) {\n projectV2(number: $number) {\n id\n title\n fields(first: 50) {\n nodes {\n ... on ProjectV2Field {\n id\n name\n dataType\n }\n ... on ProjectV2SingleSelectField {\n id\n name\n dataType\n options {\n id\n name\n }\n }\n ... on ProjectV2IterationField {\n id\n name\n dataType\n }\n }\n }\n items(first: 100) {\n nodes {\n id\n type\n content {\n ... on Issue {\n number\n title\n state\n }\n ... on PullRequest {\n number\n title\n state\n }\n }\n fieldValues(first: 20) {\n nodes {\n ... on ProjectV2ItemFieldSingleSelectValue {\n name\n field { ... on ProjectV2SingleSelectField { name } }\n }\n ... on ProjectV2ItemFieldTextValue {\n text\n field { ... on ProjectV2Field { name } }\n }\n ... on ProjectV2ItemFieldNumberValue {\n number\n field { ... on ProjectV2Field { name } }\n }\n ... on ProjectV2ItemFieldDateValue {\n date\n field { ... on ProjectV2Field { name } }\n }\n }\n }\n }\n }\n views(first: 20) {\n nodes {\n id\n name\n layout\n }\n }\n }\n }\n }\n '''\n\n result = run_gh([\n 'api', 'graphql',\n '-f', f'query={query}',\n '-f', f'owner={owner}',\n '-F', f'number={project_number}'\n ])\n\n if not result:\n return {}\n\n try:\n data = json.loads(result)\n # Try organization first, then user\n project = (data.get('data', {}).get('organization', {}).get('projectV2') or\n data.get('data', {}).get('user', {}).get('projectV2'))\n return project or {}\n except json.JSONDecodeError as e:\n print(f\"{RED}Error parsing GraphQL response: {e}{NC}\", file=sys.stderr)\n return {}\n\n\ndef validate_fields(project: dict[str, Any]) -> list[dict[str, str]]:\n \"\"\"Validate project field configuration.\"\"\"\n issues = []\n fields = project.get('fields', {}).get('nodes', [])\n\n if not fields:\n issues.append({\n 'severity': 'error',\n 'message': 'No fields found in project',\n 'suggestion': 'Add fields like Status, Priority, etc.'\n })\n return issues\n\n field_names = [f.get('name', '') for f in fields]\n\n # Check for required fields\n recommended_fields = ['Status', 'Priority']\n for field in recommended_fields:\n if field not in field_names:\n issues.append({\n 'severity': 'warning',\n 'message': f'Recommended field \"{field}\" not found',\n 'suggestion': f'Consider adding a {field} field for better organization'\n })\n\n # Check single select fields have options\n for field in fields:\n if field.get('dataType') == 'SINGLE_SELECT':\n options = field.get('options', [])\n if not options:\n issues.append({\n 'severity': 'error',\n 'message': f'SingleSelect field \"{field.get(\"name\")}\" has no options',\n 'suggestion': 'Add options to the field'\n })\n elif len(options) \u003c 2:\n issues.append({\n 'severity': 'warning',\n 'message': f'SingleSelect field \"{field.get(\"name\")}\" has only {len(options)} option(s)',\n 'suggestion': 'Consider adding more options for flexibility'\n })\n\n # Check for duplicate field names (shouldn't happen but good to check)\n seen = set()\n for name in field_names:\n if name in seen:\n issues.append({\n 'severity': 'error',\n 'message': f'Duplicate field name: \"{name}\"',\n 'suggestion': 'Remove or rename duplicate field'\n })\n seen.add(name)\n\n return issues\n\n\ndef validate_items(project: dict[str, Any], check_orphans: bool = False) -> list[dict[str, str]]:\n \"\"\"Validate project items.\"\"\"\n issues = []\n items = project.get('items', {}).get('nodes', [])\n fields = project.get('fields', {}).get('nodes', [])\n\n if not items:\n issues.append({\n 'severity': 'info',\n 'message': 'No items in project',\n 'suggestion': 'Add issues or PRs to the project board'\n })\n return issues\n\n # Get Status field options if exists\n status_field = next((f for f in fields if f.get('name') == 'Status'), None)\n status_options = [opt.get('name') for opt in status_field.get('options', [])] if status_field else []\n\n # Check each item\n orphan_count = 0\n items_without_status = []\n\n for item in items:\n item_id = item.get('id', 'unknown')\n content = item.get('content', {})\n item_title = content.get('title', 'Unknown')\n item_number = content.get('number', '?')\n\n if not content:\n orphan_count += 1\n if check_orphans:\n issues.append({\n 'severity': 'warning',\n 'message': f'Item {item_id} has no linked content (orphaned)',\n 'suggestion': 'Remove orphaned items or link to an issue/PR'\n })\n continue\n\n # Check if item has Status field value\n field_values = item.get('fieldValues', {}).get('nodes', [])\n has_status = any(\n fv.get('field', {}).get('name') == 'Status'\n for fv in field_values\n if fv.get('field')\n )\n\n if not has_status and status_field:\n items_without_status.append(f\"#{item_number}: {item_title}\")\n\n if orphan_count > 0 and not check_orphans:\n issues.append({\n 'severity': 'warning',\n 'message': f'{orphan_count} orphaned item(s) found (no linked content)',\n 'suggestion': 'Run with --check-orphans for details'\n })\n\n if items_without_status:\n if len(items_without_status) \u003c= 5:\n for item in items_without_status:\n issues.append({\n 'severity': 'warning',\n 'message': f'Item without Status: {item}',\n 'suggestion': 'Set Status field for better tracking'\n })\n else:\n issues.append({\n 'severity': 'warning',\n 'message': f'{len(items_without_status)} items without Status field',\n 'suggestion': 'Set Status field for better tracking'\n })\n\n return issues\n\n\ndef validate_views(project: dict[str, Any]) -> list[dict[str, str]]:\n \"\"\"Validate project views configuration.\"\"\"\n issues = []\n views = project.get('views', {}).get('nodes', [])\n\n if not views:\n issues.append({\n 'severity': 'warning',\n 'message': 'No views configured',\n 'suggestion': 'Add views like Board, Table, or Roadmap'\n })\n return issues\n\n view_layouts = [v.get('layout') for v in views]\n\n # Check for recommended views\n if 'BOARD_LAYOUT' not in view_layouts:\n issues.append({\n 'severity': 'info',\n 'message': 'No Board view configured',\n 'suggestion': 'Consider adding a Board view for Kanban-style workflow'\n })\n\n if 'TABLE_LAYOUT' not in view_layouts:\n issues.append({\n 'severity': 'info',\n 'message': 'No Table view configured',\n 'suggestion': 'Consider adding a Table view for detailed item list'\n })\n\n # Check for duplicate view names\n view_names = [v.get('name', '') for v in views]\n seen = set()\n for name in view_names:\n if name in seen:\n issues.append({\n 'severity': 'warning',\n 'message': f'Duplicate view name: \"{name}\"',\n 'suggestion': 'Rename one of the views for clarity'\n })\n seen.add(name)\n\n return issues\n\n\ndef print_validation_results(project_title: str, all_issues: list[dict[str, str]]) -> int:\n \"\"\"Print validation results and return exit code.\"\"\"\n errors = [i for i in all_issues if i['severity'] == 'error']\n warnings = [i for i in all_issues if i['severity'] == 'warning']\n infos = [i for i in all_issues if i['severity'] == 'info']\n\n print(f\"\\n{BLUE}Validation Results for: {project_title}{NC}\")\n print(\"=\" * 50)\n\n if not all_issues:\n print(f\"\\n{GREEN}All checks passed!{NC}\")\n return 0\n\n # Print errors\n if errors:\n print(f\"\\n{RED}Errors ({len(errors)}):{NC}\")\n for issue in errors:\n print(f\" {RED}[ERROR]{NC} {issue['message']}\")\n print(f\" {issue['suggestion']}\")\n\n # Print warnings\n if warnings:\n print(f\"\\n{YELLOW}Warnings ({len(warnings)}):{NC}\")\n for issue in warnings:\n print(f\" {YELLOW}[WARN]{NC} {issue['message']}\")\n print(f\" {issue['suggestion']}\")\n\n # Print info\n if infos:\n print(f\"\\n{BLUE}Info ({len(infos)}):{NC}\")\n for issue in infos:\n print(f\" {BLUE}[INFO]{NC} {issue['message']}\")\n print(f\" {issue['suggestion']}\")\n\n # Summary\n print(f\"\\n{BLUE}Summary:{NC}\")\n print(f\" Errors: {len(errors)}\")\n print(f\" Warnings: {len(warnings)}\")\n print(f\" Info: {len(infos)}\")\n\n # Return exit code\n if errors:\n return 1\n return 0\n\n\ndef main():\n parser = argparse.ArgumentParser(\n description='Validate GitHub Projects v2 board configuration',\n formatter_class=argparse.RawDescriptionHelpFormatter,\n epilog='''\nExamples:\n %(prog)s myorg 1\n Basic validation of project #1 for organization 'myorg'\n\n %(prog)s myorg 1 --check-orphans\n Include detailed orphan item checking\n\n %(prog)s myorg 1 --check-fields --check-orphans\n Full validation with all checks\n '''\n )\n\n parser.add_argument('owner', help='GitHub organization or username')\n parser.add_argument('project_number', type=int, help='Project number')\n parser.add_argument('--check-orphans', action='store_true',\n help='List individual orphaned items')\n parser.add_argument('--check-fields', action='store_true',\n help='Perform detailed field validation')\n parser.add_argument('--json', action='store_true',\n help='Output results as JSON')\n\n args = parser.parse_args()\n\n # Fetch project data\n print(f\"Fetching project #{args.project_number} for {args.owner}...\")\n project = get_project_data(args.owner, args.project_number)\n\n if not project:\n print(f\"{RED}Error: Could not fetch project data{NC}\", file=sys.stderr)\n print(\"Check that:\", file=sys.stderr)\n print(f\" - Project #{args.project_number} exists for {args.owner}\", file=sys.stderr)\n print(\" - You have access to the project\", file=sys.stderr)\n print(\" - gh CLI is authenticated: gh auth status\", file=sys.stderr)\n sys.exit(1)\n\n project_title = project.get('title', 'Unknown Project')\n print(f\"Validating: {project_title}\")\n\n # Run validations\n all_issues = []\n\n # Field validation\n field_issues = validate_fields(project)\n all_issues.extend(field_issues)\n\n # Item validation\n item_issues = validate_items(project, check_orphans=args.check_orphans)\n all_issues.extend(item_issues)\n\n # View validation\n view_issues = validate_views(project)\n all_issues.extend(view_issues)\n\n # Output results\n if args.json:\n result = {\n 'project': project_title,\n 'owner': args.owner,\n 'project_number': args.project_number,\n 'issues': all_issues,\n 'summary': {\n 'errors': len([i for i in all_issues if i['severity'] == 'error']),\n 'warnings': len([i for i in all_issues if i['severity'] == 'warning']),\n 'info': len([i for i in all_issues if i['severity'] == 'info'])\n }\n }\n print(json.dumps(result, indent=2))\n sys.exit(0 if result['summary']['errors'] == 0 else 1)\n else:\n exit_code = print_validation_results(project_title, all_issues)\n sys.exit(exit_code)\n\n\nif __name__ == '__main__':\n main()\n","content_type":"text/x-python; charset=utf-8","language":"python","size":16076,"content_sha256":"c43b7c595795729d3c9f43d6c060c05be5df623da2e746854a1c99df1a7f7714"},{"filename":"skill-report.json","content":"{\n \"schema_version\": \"2.0\",\n \"meta\": {\n \"generated_at\": \"2026-01-16T20:50:03.629Z\",\n \"slug\": \"c0ntr0lledcha0s-managing-projects\",\n \"source_url\": \"https://github.com/C0ntr0lledCha0s/claude-code-plugin-automations/tree/main/github-workflows/skills/managing-projects\",\n \"source_ref\": \"main\",\n \"model\": \"claude\",\n \"analysis_version\": \"3.0.0\",\n \"source_type\": \"community\",\n \"content_hash\": \"cc719d3c8d7423f3edc0646afb3685edaf754fc1339e7020859cdf35df1e1f01\",\n \"tree_hash\": \"1850f20f64b39aacb59bfccbebbed06b7031f49a16d5e876aa4b33240898b790\"\n },\n \"skill\": {\n \"name\": \"managing-projects\",\n \"description\": \"GitHub Projects v2 expertise for creating and managing project boards, fields, views, and items. Auto-invokes when project boards, sprints, kanban workflows, or issue organization is mentioned. Uses GraphQL for advanced project operations.\",\n \"summary\": \"GitHub Projects v2 expertise for creating and managing project boards, fields, views, and items. Aut...\",\n \"icon\": \"📋\",\n \"version\": \"1.1.0\",\n \"author\": \"C0ntr0lledCha0s\",\n \"license\": \"MIT\",\n \"category\": \"productivity\",\n \"tags\": [\n \"github\",\n \"project-management\",\n \"kanban\",\n \"graphql\",\n \"boards\"\n ],\n \"supported_tools\": [\n \"claude\",\n \"claude-code\"\n ],\n \"risk_factors\": [\n \"external_commands\",\n \"network\",\n \"filesystem\"\n ]\n },\n \"security_audit\": {\n \"risk_level\": \"low\",\n \"is_blocked\": false,\n \"safe_to_publish\": true,\n \"summary\": \"This is a legitimate GitHub Projects v2 management skill with standard development tooling. All 486 static findings are false positives: shell command patterns are documentation examples in markdown files, not executable code. Scripts execute only documented gh CLI commands for GitHub API operations. No data exfiltration, credential theft, or suspicious network behavior detected.\",\n \"risk_factor_evidence\": [\n {\n \"factor\": \"external_commands\",\n \"evidence\": [\n {\n \"file\": \"SKILL.md\",\n \"line_start\": 36,\n \"line_end\": 60\n },\n {\n \"file\": \"references/graphql-workarounds.md\",\n \"line_start\": 1,\n \"line_end\": 100\n },\n {\n \"file\": \"scripts/project-helpers.sh\",\n \"line_start\": 1,\n \"line_end\": 50\n }\n ]\n },\n {\n \"factor\": \"network\",\n \"evidence\": [\n {\n \"file\": \"SKILL.md\",\n \"line_start\": 47,\n \"line_end\": 49\n },\n {\n \"file\": \"references/graphql-workarounds.md\",\n \"line_start\": 486,\n \"line_end\": 488\n }\n ]\n },\n {\n \"factor\": \"filesystem\",\n \"evidence\": [\n {\n \"file\": \"scripts/project-helpers.sh\",\n \"line_start\": 56,\n \"line_end\": 63\n }\n ]\n }\n ],\n \"critical_findings\": [],\n \"high_findings\": [],\n \"medium_findings\": [],\n \"low_findings\": [],\n \"dangerous_patterns\": [],\n \"files_scanned\": 11,\n \"total_lines\": 4015,\n \"audit_model\": \"claude\",\n \"audited_at\": \"2026-01-16T20:50:03.629Z\"\n },\n \"content\": {\n \"user_title\": \"Manage GitHub Projects v2 boards and workflows\",\n \"value_statement\": \"Managing project boards manually takes time and creates inconsistent tracking. This skill provides GraphQL-powered automation for creating boards, configuring fields, and organizing issues across sprints, kanban, and roadmap workflows.\",\n \"seo_keywords\": [\n \"GitHub Projects v2\",\n \"project board management\",\n \"kanban board\",\n \"sprint planning\",\n \"GitHub automation\",\n \"GraphQL projects\",\n \"Claude Code\",\n \"issue tracking\",\n \"roadmap planning\",\n \"issue organization\"\n ],\n \"actual_capabilities\": [\n \"Create project boards with sprint, kanban, roadmap, and bug triage templates\",\n \"Configure custom fields including Status, Priority, Sprint, and Story Points\",\n \"Add and update issues and PRs across project items via GraphQL\",\n \"Generate project reports with status counts and completion rates\",\n \"Archive completed items and sync repository state with boards\",\n \"Execute bulk operations for multiple items and field updates\"\n ],\n \"limitations\": [\n \"Supports GitHub Projects v2 only, not Classic Projects\",\n \"Requires GitHub CLI (gh) installation and authentication\",\n \"Rate limits apply to GraphQL API operations\",\n \"Cannot create projects without appropriate organization/user permissions\"\n ],\n \"use_cases\": [\n {\n \"target_user\": \"Development Teams\",\n \"title\": \"Sprint Planning Boards\",\n \"description\": \"Create sprint boards with backlog, iterations, and burndown tracking for agile teams.\"\n },\n {\n \"target_user\": \"Product Managers\",\n \"title\": \"Roadmap Planning\",\n \"description\": \"Build timeline-based roadmaps with target dates, quarters, and feature tracking.\"\n },\n {\n \"target_user\": \"QA Engineers\",\n \"title\": \"Bug Triage Workflows\",\n \"description\": \"Set up triage boards with severity, priority, and version tracking for bug management.\"\n }\n ],\n \"prompt_templates\": [\n {\n \"title\": \"Create Sprint Board\",\n \"scenario\": \"New sprint planning setup\",\n \"prompt\": \"Create a new sprint planning board with 2-week iterations, status columns, and story points field for our organization.\"\n },\n {\n \"title\": \"Add Issues to Board\",\n \"scenario\": \"Bulk import issues\",\n \"prompt\": \"Add all open issues with the feature label to our sprint board and set initial priority.\"\n },\n {\n \"title\": \"Generate Report\",\n \"scenario\": \"Sprint progress check\",\n \"prompt\": \"Show me the sprint progress report with status breakdown, completion rate, and any blockers.\"\n },\n {\n \"title\": \"Archive Completed\",\n \"scenario\": \"Board maintenance\",\n \"prompt\": \"Archive all items in Done status that have been closed for more than 14 days.\"\n }\n ],\n \"output_examples\": [\n {\n \"input\": \"Create a kanban board for our team with priority tracking\",\n \"output\": [\n \"Created Kanban Workflow Board for your organization\",\n \"Added Status field with Todo, In Progress, Review, Done options\",\n \"Added Priority field with High, Medium, Low options\",\n \"Added Size field with XS, S, M, L, XL options\",\n \"Configured Board view grouped by Status\",\n \"Board URL: https://github.com/orgs/org/projects/X\"\n ]\n },\n {\n \"input\": \"Show me the sprint progress\",\n \"output\": [\n \"Sprint 5 Progress Report:\",\n \"Total Items: 24\",\n \"Done: 12 (50%)\",\n \"In Progress: 6 (25%)\",\n \"Todo: 4 (17%)\",\n \"Review: 2 (8%)\",\n \"Completion: 45/80 story points (56%)\",\n \"Blockers: Issue #56 waiting on API approval\"\n ]\n }\n ],\n \"best_practices\": [\n \"Use consistent field naming across projects to enable cross-project reporting\",\n \"Configure automation rules to auto-add issues and archive completed items\",\n \"Regularly generate reports to track team velocity and identify bottlenecks\"\n ],\n \"anti_patterns\": [\n \"Manually adding items one by one instead of using bulk operations\",\n \"Creating many similar boards instead of using filters and views on one board\",\n \"Leaving orphaned items in boards without linking to issues or PRs\"\n ],\n \"faq\": [\n {\n \"question\": \"Does this work with GitHub Classic Projects?\",\n \"answer\": \"No, this skill supports only GitHub Projects v2 which uses GraphQL API.\"\n },\n {\n \"question\": \"What are the rate limits for project operations?\",\n \"answer\": \"GraphQL operations share your GitHub account rate limit. Complex queries count as multiple operations.\"\n },\n {\n \"question\": \"Can I use this with personal accounts not organizations?\",\n \"answer\": \"Yes, the skill supports both organization and user-level projects via the owner parameter.\"\n },\n {\n \"question\": \"Is my project data sent to third parties?\",\n \"answer\": \"No, all API calls go directly to GitHub's official API using your authenticated gh CLI session.\"\n },\n {\n \"question\": \"Why do I need the gh CLI installed?\",\n \"answer\": \"The skill uses gh CLI for authentication and API access. It handles GraphQL operations securely.\"\n },\n {\n \"question\": \"How is this different from GitHub project commands?\",\n \"answer\": \"This skill provides automation, templates, and bulk operations beyond basic gh project commands.\"\n }\n ]\n },\n \"file_structure\": [\n {\n \"name\": \"references\",\n \"type\": \"dir\",\n \"path\": \"references\",\n \"children\": [\n {\n \"name\": \"board-best-practices.md\",\n \"type\": \"file\",\n \"path\": \"references/board-best-practices.md\",\n \"lines\": 97\n },\n {\n \"name\": \"board-examples.md\",\n \"type\": \"file\",\n \"path\": \"references/board-examples.md\",\n \"lines\": 269\n },\n {\n \"name\": \"gh-project-api.md\",\n \"type\": \"file\",\n \"path\": \"references/gh-project-api.md\",\n \"lines\": 234\n },\n {\n \"name\": \"graphql-schema.md\",\n \"type\": \"file\",\n \"path\": \"references/graphql-schema.md\",\n \"lines\": 159\n },\n {\n \"name\": \"graphql-workarounds.md\",\n \"type\": \"file\",\n \"path\": \"references/graphql-workarounds.md\",\n \"lines\": 508\n }\n ]\n },\n {\n \"name\": \"scripts\",\n \"type\": \"dir\",\n \"path\": \"scripts\",\n \"children\": [\n {\n \"name\": \"graphql-queries.sh\",\n \"type\": \"file\",\n \"path\": \"scripts/graphql-queries.sh\",\n \"lines\": 574\n },\n {\n \"name\": \"project-helpers.sh\",\n \"type\": \"file\",\n \"path\": \"scripts/project-helpers.sh\",\n \"lines\": 631\n },\n {\n \"name\": \"validate-board-config.py\",\n \"type\": \"file\",\n \"path\": \"scripts/validate-board-config.py\",\n \"lines\": 517\n }\n ]\n },\n {\n \"name\": \"templates\",\n \"type\": \"dir\",\n \"path\": \"templates\",\n \"children\": [\n {\n \"name\": \"board-templates.json\",\n \"type\": \"file\",\n \"path\": \"templates/board-templates.json\",\n \"lines\": 167\n }\n ]\n },\n {\n \"name\": \"SKILL.md\",\n \"type\": \"file\",\n \"path\": \"SKILL.md\",\n \"lines\": 616\n }\n ]\n}\n","content_type":"application/json; charset=utf-8","language":"json","size":10820,"content_sha256":"3ebd66f69e4282d1f612838e85d2c3dc997076cc62b61e262456b139ef2feb82"},{"filename":"templates/board-templates.json","content":"{\n \"sprint\": {\n \"name\": \"Sprint Planning Board\",\n \"description\": \"Scrum-style sprint board with backlog, sprint, and progress tracking\",\n \"columns\": [\"Backlog\", \"Sprint\", \"In Progress\", \"Review\", \"Done\"],\n \"fields\": {\n \"Status\": {\n \"type\": \"SingleSelect\",\n \"options\": [\"Backlog\", \"Sprint\", \"In Progress\", \"Review\", \"Done\"]\n },\n \"Priority\": {\n \"type\": \"SingleSelect\",\n \"options\": [\"High\", \"Medium\", \"Low\"]\n },\n \"Story Points\": {\n \"type\": \"SingleSelect\",\n \"options\": [\"1\", \"2\", \"3\", \"5\", \"8\", \"13\", \"21\"]\n },\n \"Sprint\": {\n \"type\": \"Iteration\",\n \"duration\": 14,\n \"startDay\": 1\n }\n },\n \"views\": [\n {\n \"name\": \"Sprint Board\",\n \"type\": \"board\",\n \"groupBy\": \"Status\"\n },\n {\n \"name\": \"Backlog\",\n \"type\": \"table\",\n \"filter\": \"Status:Backlog\",\n \"sortBy\": \"Priority\"\n }\n ],\n \"automation\": {\n \"autoAdd\": \"label:sprint\",\n \"autoArchive\": \"Status:Done AND closed:>30days\"\n }\n },\n \"kanban\": {\n \"name\": \"Kanban Workflow Board\",\n \"description\": \"Simple kanban board for continuous flow\",\n \"columns\": [\"Todo\", \"In Progress\", \"Review\", \"Done\"],\n \"fields\": {\n \"Status\": {\n \"type\": \"SingleSelect\",\n \"options\": [\"Todo\", \"In Progress\", \"Review\", \"Done\"]\n },\n \"Priority\": {\n \"type\": \"SingleSelect\",\n \"options\": [\"High\", \"Medium\", \"Low\"]\n },\n \"Size\": {\n \"type\": \"SingleSelect\",\n \"options\": [\"XS\", \"S\", \"M\", \"L\", \"XL\"]\n },\n \"Assignee\": {\n \"type\": \"Assignee\"\n }\n },\n \"views\": [\n {\n \"name\": \"Board\",\n \"type\": \"board\",\n \"groupBy\": \"Status\"\n },\n {\n \"name\": \"By Assignee\",\n \"type\": \"table\",\n \"groupBy\": \"Assignee\"\n }\n ],\n \"automation\": {\n \"autoAdd\": \"is:issue OR is:pr\",\n \"autoArchive\": \"Status:Done AND closed:>14days\"\n }\n },\n \"roadmap\": {\n \"name\": \"Product Roadmap\",\n \"description\": \"Timeline-based roadmap for planning features\",\n \"columns\": [\"Planned\", \"In Progress\", \"Completed\"],\n \"fields\": {\n \"Status\": {\n \"type\": \"SingleSelect\",\n \"options\": [\"Planned\", \"In Progress\", \"Completed\"]\n },\n \"Quarter\": {\n \"type\": \"SingleSelect\",\n \"options\": [\"Q1\", \"Q2\", \"Q3\", \"Q4\"]\n },\n \"Priority\": {\n \"type\": \"SingleSelect\",\n \"options\": [\"Critical\", \"High\", \"Medium\", \"Low\"]\n },\n \"Target Date\": {\n \"type\": \"Date\"\n },\n \"Owner\": {\n \"type\": \"Assignee\"\n }\n },\n \"views\": [\n {\n \"name\": \"Roadmap\",\n \"type\": \"roadmap\",\n \"groupBy\": \"Quarter\",\n \"sortBy\": \"Target Date\"\n },\n {\n \"name\": \"By Priority\",\n \"type\": \"table\",\n \"groupBy\": \"Priority\",\n \"sortBy\": \"Target Date\"\n }\n ],\n \"automation\": {\n \"autoAdd\": \"label:roadmap\",\n \"autoArchive\": \"Status:Completed AND closed:>90days\"\n }\n },\n \"bug-triage\": {\n \"name\": \"Bug Triage Board\",\n \"description\": \"Bug tracking and triage workflow\",\n \"columns\": [\"New\", \"Confirmed\", \"In Progress\", \"Fixed\", \"Verified\"],\n \"fields\": {\n \"Status\": {\n \"type\": \"SingleSelect\",\n \"options\": [\"New\", \"Confirmed\", \"In Progress\", \"Fixed\", \"Verified\"]\n },\n \"Severity\": {\n \"type\": \"SingleSelect\",\n \"options\": [\"Critical\", \"High\", \"Medium\", \"Low\"]\n },\n \"Priority\": {\n \"type\": \"SingleSelect\",\n \"options\": [\"P0\", \"P1\", \"P2\", \"P3\"]\n },\n \"Affected Version\": {\n \"type\": \"Text\"\n },\n \"Assignee\": {\n \"type\": \"Assignee\"\n }\n },\n \"views\": [\n {\n \"name\": \"Triage Board\",\n \"type\": \"board\",\n \"groupBy\": \"Status\"\n },\n {\n \"name\": \"By Severity\",\n \"type\": \"table\",\n \"groupBy\": \"Severity\",\n \"sortBy\": \"Priority\"\n }\n ],\n \"automation\": {\n \"autoAdd\": \"label:bug\",\n \"autoArchive\": \"Status:Verified AND closed:>30days\"\n }\n }\n}\n","content_type":"application/json; charset=utf-8","language":"json","size":4099,"content_sha256":"55e229cbe38065f579026def2096c03ea59355731ab4e627b327c875b2ece7ac"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Managing GitHub Projects (v2) Skill","type":"text"}]},{"type":"paragraph","content":[{"text":"You are a GitHub Projects v2 expert specializing in project board creation, management, and automation. You understand the modern GraphQL-based Projects API and can help users organize their work effectively using boards, views, and custom fields.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When to Use This Skill","type":"text"}]},{"type":"paragraph","content":[{"text":"Auto-invoke this skill when the conversation involves:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Creating or managing GitHub project boards","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Setting up sprint planning or kanban workflows","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Organizing issues and PRs using project boards","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Configuring project fields, views, or automation","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"GraphQL operations for GitHub Projects v2","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Keywords: \"project board\", \"sprint\", \"kanban\", \"roadmap\", \"project view\"","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Your Capabilities","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Board Creation","type":"text","marks":[{"type":"strong"}]},{"text":": Create project boards with templates (Kanban, Sprint, Roadmap)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Field Management","type":"text","marks":[{"type":"strong"}]},{"text":": Configure custom fields (Status, Priority, Sprint, etc.)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"View Configuration","type":"text","marks":[{"type":"strong"}]},{"text":": Set up Table, Board, and Roadmap views","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Item Management","type":"text","marks":[{"type":"strong"}]},{"text":": Add/move issues and PRs across project items","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"GraphQL Operations","type":"text","marks":[{"type":"strong"}]},{"text":": Execute complex project queries and mutations","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Automation","type":"text","marks":[{"type":"strong"}]},{"text":": Configure auto-add, auto-archive, and field update rules","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Your Expertise","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"1. ","type":"text"},{"text":"Prerequisites and Setup","type":"text","marks":[{"type":"strong"}]}]},{"type":"paragraph","content":[{"text":"The plugin automatically ensures GitHub CLI is installed:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Auto-detection","type":"text","marks":[{"type":"strong"}]},{"text":": Checks if ","type":"text"},{"text":"gh","type":"text","marks":[{"type":"code_inline"}]},{"text":" is installed","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Auto-installation","type":"text","marks":[{"type":"strong"}]},{"text":": Installs ","type":"text"},{"text":"gh","type":"text","marks":[{"type":"code_inline"}]},{"text":" if missing (requires sudo on Linux)","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Linux: Debian/Ubuntu (apt), RHEL/Fedora (dnf/yum), Arch (pacman)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"macOS: via Homebrew","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Windows: via winget","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Auth check","type":"text","marks":[{"type":"strong"}]},{"text":": Verifies authentication status","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Helpful errors","type":"text","marks":[{"type":"strong"}]},{"text":": Clear messages if setup fails","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Manual installation","type":"text","marks":[{"type":"strong"}]},{"text":" (if auto-install fails):","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Debian/Ubuntu/WSL\ncurl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg\nsudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg\necho \"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\nsudo apt update && sudo apt install gh\n\n# macOS\nbrew install gh\n\n# Windows\nwinget install --id GitHub.cli\n\n# Authenticate\ngh auth login","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"2. ","type":"text"},{"text":"GitHub Projects v2 Architecture","type":"text","marks":[{"type":"strong"}]}]},{"type":"paragraph","content":[{"text":"Understanding the new Projects system:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Projects are organization/user-level","type":"text","marks":[{"type":"strong"}]},{"text":" (not repository-level)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"GraphQL-based API","type":"text","marks":[{"type":"strong"}]},{"text":" (no REST API for Projects v2)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Flexible custom fields","type":"text","marks":[{"type":"strong"}]},{"text":" (SingleSelect, Text, Number, Date, Iteration)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Multiple views","type":"text","marks":[{"type":"strong"}]},{"text":" (Table, Board, Roadmap, custom)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Powerful automation","type":"text","marks":[{"type":"strong"}]},{"text":" (auto-add, auto-archive, field updates)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"3. ","type":"text"},{"text":"Project Board Operations","type":"text","marks":[{"type":"strong"}]}]},{"type":"paragraph","content":[{"text":"Create Projects","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Create new project\ngh project create --owner ORG --title \"Sprint Planning\"\n\n# Create with description\ngh project create --owner ORG --title \"Q1 Roadmap\" --body \"Q1 2024 feature roadmap\"\n\n# Get project details\ngh project list --owner ORG\ngh project view NUMBER --owner ORG","type":"text"}]},{"type":"paragraph","content":[{"text":"Project Fields","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Status (SingleSelect): Todo, In Progress, Review, Done","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Priority (SingleSelect): High, Medium, Low","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Size (SingleSelect): XS, S, M, L, XL","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Sprint (Iteration): 2-week sprints","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Due Date (Date): Target completion","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Assignee (built-in)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"4. ","type":"text"},{"text":"GraphQL Operations","type":"text","marks":[{"type":"strong"}]}]},{"type":"paragraph","content":[{"text":"Why GraphQL for Projects","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Projects v2 API is GraphQL-only","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"More efficient for complex queries","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Single request for multiple operations","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Real-time field updates","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Common GraphQL patterns","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"paragraph","content":[{"text":"Get project with fields:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"graphql"},"content":[{"text":"query($org: String!, $number: Int!) {\n organization(login: $org) {\n projectV2(number: $number) {\n id\n title\n fields(first: 20) {\n nodes {\n ... on ProjectV2SingleSelectField {\n id\n name\n options {\n id\n name\n }\n }\n }\n }\n }\n }\n}","type":"text"}]},{"type":"paragraph","content":[{"text":"Add item to project:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"graphql"},"content":[{"text":"mutation($projectId: ID!, $contentId: ID!) {\n addProjectV2ItemById(input: {\n projectId: $projectId\n contentId: $contentId\n }) {\n item {\n id\n }\n }\n}","type":"text"}]},{"type":"paragraph","content":[{"text":"Update item field:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"graphql"},"content":[{"text":"mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $value: ProjectV2FieldValue!) {\n updateProjectV2ItemFieldValue(input: {\n projectId: $projectId\n itemId: $itemId\n fieldId: $fieldId\n value: $value\n }) {\n projectV2Item {\n id\n }\n }\n}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"5. ","type":"text"},{"text":"Board Templates","type":"text","marks":[{"type":"strong"}]}]},{"type":"paragraph","content":[{"text":"Sprint Board","type":"text","marks":[{"type":"strong"}]},{"text":" (Scrum):","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Columns: Backlog, Sprint, In Progress, Review, Done","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Fields: Sprint (iteration), Story Points, Priority","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Automation: Auto-add issues with sprint label","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Kanban Board","type":"text","marks":[{"type":"strong"}]},{"text":" (Continuous flow):","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Columns: Todo, In Progress, Review, Done","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Fields: Priority, Size, Assignee","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Automation: Auto-add all issues/PRs","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Roadmap Board","type":"text","marks":[{"type":"strong"}]},{"text":" (Planning):","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"View: Roadmap (timeline)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Fields: Quarter, Status, Owner, Target Date","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Grouping: By quarter","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Bug Triage Board","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Columns: New, Confirmed, In Progress, Fixed, Verified","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Fields: Severity, Priority, Affected Version","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Automation: Auto-add issues with bug label","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"6. ","type":"text"},{"text":"Item Management","type":"text","marks":[{"type":"strong"}]}]},{"type":"paragraph","content":[{"text":"Add items to boards","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Add issue to project\ngh project item-add NUMBER --owner ORG --url https://github.com/org/repo/issues/42\n\n# Add PR to project\ngh project item-add NUMBER --owner ORG --url https://github.com/org/repo/pull/123\n\n# Bulk add (use script)\n{baseDir}/scripts/project-helpers.sh bulk_add_issues PROJECT_NUMBER \"label:feature\"","type":"text"}]},{"type":"paragraph","content":[{"text":"Update item fields","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use GraphQL mutations (see templates)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Helper script: ","type":"text"},{"text":"{baseDir}/scripts/graphql-queries.sh","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Example: Set status, priority, sprint","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Archive completed items","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Archive single item\ngh project item-archive NUMBER --owner ORG --id ITEM_ID\n\n# Bulk archive (use automation or script)\n{baseDir}/scripts/project-helpers.sh archive_done_items PROJECT_NUMBER","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"7. ","type":"text"},{"text":"Views and Automation","type":"text","marks":[{"type":"strong"}]}]},{"type":"paragraph","content":[{"text":"Create custom views","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Board view: Kanban-style columns","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Table view: Spreadsheet-like","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Roadmap view: Timeline visualization","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Custom filters: By assignee, label, milestone","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Setup automation","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Auto-add items: When issues/PRs created","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Auto-archive: When items closed","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Auto-set fields: Based on labels or other triggers","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Your Capabilities","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"1. Create Project Boards","type":"text"}]},{"type":"paragraph","content":[{"text":"Help users create boards with appropriate templates:","type":"text"}]},{"type":"paragraph","content":[{"text":"For sprint planning","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"I'll create a sprint board with:\n- Columns: Backlog, This Sprint, In Progress, Review, Done\n- Fields: Sprint (2-week iterations), Story Points, Priority\n- Automation: Auto-add issues with sprint label\n\nCreating project...","type":"text"}]},{"type":"paragraph","content":[{"text":"For kanban workflow","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"Setting up kanban board:\n- Columns: Todo, In Progress, Review, Done\n- Fields: Priority (High/Medium/Low), Size (S/M/L)\n- Automation: Auto-add all issues and PRs\n\nReady to track your workflow!","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"2. Add Items to Boards","type":"text"}]},{"type":"paragraph","content":[{"text":"Add issues, PRs, or draft issues to projects:","type":"text"}]},{"type":"paragraph","content":[{"text":"Single item","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Use GitHub CLI\ngh project item-add $PROJECT_NUMBER --owner $ORG --url $ISSUE_URL","type":"text"}]},{"type":"paragraph","content":[{"text":"Bulk add","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Use helper script\n{baseDir}/scripts/project-helpers.sh bulk_add_items $PROJECT_NUMBER \\\n --issues \"is:issue is:open label:feature\" \\\n --prs \"is:pr is:open\"","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"3. Update Item Status and Fields","type":"text"}]},{"type":"paragraph","content":[{"text":"Move items between columns and update custom fields:","type":"text"}]},{"type":"paragraph","content":[{"text":"Update status","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"I'll move issue #42 to \"In Progress\":\n1. Get project and item IDs\n2. Get Status field ID\n3. Get \"In Progress\" option ID\n4. Execute GraphQL mutation\n\n[Executes update via {baseDir}/scripts/graphql-queries.sh]\n\n✅ Issue #42 moved to \"In Progress\"","type":"text"}]},{"type":"paragraph","content":[{"text":"Bulk update","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"Updating all \"Review\" items to \"Done\" for closed PRs:\n- Found 5 items in \"Review\" with merged PRs\n- Updating status field...\n- ✅ 5 items moved to \"Done\"","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"4. Generate Board Reports","type":"text"}]},{"type":"paragraph","content":[{"text":"Create status reports and analytics:","type":"text"}]},{"type":"paragraph","content":[{"text":"Sprint burndown","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"Sprint 5 Progress Report:\n\n**Total Items**: 24\n- ✅ Done: 12 (50%)\n- 🔄 In Progress: 6 (25%)\n- 📋 Todo: 4 (17%)\n- ⏳ Review: 2 (8%)\n\n**Story Points**:\n- Completed: 45/80 (56%)\n- Remaining: 35 points\n- Avg velocity: 6 points/day\n- Days left: 4\n- On track: ⚠️ Slightly behind\n\n**Blockers**: 2 items blocked\n- Issue #56: Waiting on API approval\n- Issue #78: Dependencies not ready","type":"text"}]},{"type":"paragraph","content":[{"text":"Team capacity","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"Team Distribution:\n\n@alice: 8 items (4 in progress, 4 todo)\n@bob: 6 items (2 in progress, 4 todo)\n@carol: 10 items (5 in progress, 5 todo) ⚠️ Overloaded\n\n**Recommendation**: Rebalance load, move 2 items from @carol to @bob","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"5. Board Automation Setup","type":"text"}]},{"type":"paragraph","content":[{"text":"Configure automation rules:","type":"text"}]},{"type":"paragraph","content":[{"text":"Auto-add rules","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"Setting up automation:\n- ✅ Auto-add issues with \"sprint\" label → Sprint column\n- ✅ Auto-add PRs → Review column\n- ✅ Auto-archive completed items after 30 days\n- ✅ Auto-set Priority based on issue labels\n\nAutomation active!","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"6. Board Maintenance","type":"text"}]},{"type":"paragraph","content":[{"text":"Keep boards clean and organized:","type":"text"}]},{"type":"paragraph","content":[{"text":"Archive completed","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"Archiving completed items:\n- Closed > 14 days ago\n- Status: Done\n- Found: 23 items\n\nArchiving... ✅ Done\nBoard cleaned up!","type":"text"}]},{"type":"paragraph","content":[{"text":"Sync with repository","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"Syncing board with repository state:\n- New issues since last sync: 5 → Added to board\n- Closed items not archived: 3 → Archived\n- Orphaned items (deleted issues): 1 → Removed\n\n✅ Board is now up-to-date","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Workflow Patterns","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Pattern 1: Create Sprint Board","type":"text"}]},{"type":"paragraph","content":[{"text":"User trigger","type":"text","marks":[{"type":"strong"}]},{"text":": \"Create a sprint planning board\"","type":"text"}]},{"type":"paragraph","content":[{"text":"Your workflow","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Ask for board name and sprint duration","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Create project with gh CLI","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Add custom fields (Sprint, Story Points, Priority)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Setup columns (Backlog, Sprint, In Progress, Review, Done)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Configure automation rules","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Provide board URL and next steps","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Pattern 2: Sync Issues to Board","type":"text"}]},{"type":"paragraph","content":[{"text":"User trigger","type":"text","marks":[{"type":"strong"}]},{"text":": \"Add all feature issues to the board\"","type":"text"}]},{"type":"paragraph","content":[{"text":"Your workflow","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Get project ID","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Search for issues matching criteria","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Bulk add items to project","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Set initial field values (Priority, Size)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Report summary with item count","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Pattern 3: Sprint Progress Check","type":"text"}]},{"type":"paragraph","content":[{"text":"User trigger","type":"text","marks":[{"type":"strong"}]},{"text":": \"Show sprint progress\"","type":"text"}]},{"type":"paragraph","content":[{"text":"Your workflow","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Query project items with GraphQL","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Calculate statistics (done, in progress, todo)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Analyze velocity and burndown","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identify blockers","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Generate report with recommendations","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Pattern 4: Board Cleanup","type":"text"}]},{"type":"paragraph","content":[{"text":"User trigger","type":"text","marks":[{"type":"strong"}]},{"text":": \"Clean up the project board\"","type":"text"}]},{"type":"paragraph","content":[{"text":"Your workflow","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Find completed items (Done status, closed)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Archive items older than threshold","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Remove orphaned items","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Sync with repository state","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Report cleanup results","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Helper Scripts","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Use {baseDir} for Script Invocation","type":"text"}]},{"type":"paragraph","content":[{"text":"Project operations","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Create project with template\n{baseDir}/scripts/project-helpers.sh create_project \"Sprint 5\" \"sprint\"\n\n# Bulk add items\n{baseDir}/scripts/project-helpers.sh bulk_add_items PROJECT_ID --filter \"label:feature\"\n\n# Update item status\n{baseDir}/scripts/project-helpers.sh update_status PROJECT_ID ITEM_ID \"In Progress\"\n\n# Generate report\n{baseDir}/scripts/project-helpers.sh generate_report PROJECT_ID","type":"text"}]},{"type":"paragraph","content":[{"text":"GraphQL operations","type":"text","marks":[{"type":"strong"}]},{"text":" (using helper script):","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Get project details\n{baseDir}/scripts/graphql-queries.sh get_project OWNER PROJECT_NUMBER\n\n# Add issue/PR to project\n{baseDir}/scripts/graphql-queries.sh add_item PROJECT_ID CONTENT_ID\n\n# Update single select field (Status, Priority, etc.)\n{baseDir}/scripts/graphql-queries.sh update_field_select PROJECT_ID ITEM_ID FIELD_ID OPTION_ID\n\n# Update text field\n{baseDir}/scripts/graphql-queries.sh update_field_text PROJECT_ID ITEM_ID FIELD_ID \"Text value\"\n\n# Update number field (Story Points, etc.)\n{baseDir}/scripts/graphql-queries.sh update_field_number PROJECT_ID ITEM_ID FIELD_ID 5\n\n# Bulk update multiple items\n{baseDir}/scripts/graphql-queries.sh bulk_update PROJECT_ID FIELD_ID OPTION_ID ITEM_ID1 ITEM_ID2...\n\n# List all fields to find IDs\n{baseDir}/scripts/graphql-queries.sh list_fields OWNER PROJECT_NUMBER\n\n# Get field options (for single select fields)\n{baseDir}/scripts/graphql-queries.sh get_options OWNER PROJECT_NUMBER \"Status\"\n\n# Show help and examples\n{baseDir}/scripts/graphql-queries.sh help","type":"text"}]},{"type":"paragraph","content":[{"text":"Direct gh api commands","type":"text","marks":[{"type":"strong"}]},{"text":" (see ","type":"text"},{"text":"{baseDir}/references/graphql-workarounds.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" for complete guide):","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# When you need full control or the helper script isn't available\n\n# Get project ID\ngh api graphql -f query='query($o: String!, $n: Int!) {\n organization(login: $o) {projectV2(number: $n) {id}}\n}' -f o=OWNER -F n=PROJECT_NUM --jq '.data.organization.projectV2.id'\n\n# Add item to project\ngh api graphql -f query='mutation($p: ID!, $c: ID!) {\n addProjectV2ItemById(input: {projectId: $p, contentId: $c}) {item {id}}\n}' -f p=PROJECT_ID -f c=CONTENT_ID\n\n# Update status field\ngh api graphql -f query='mutation($p: ID!, $i: ID!, $f: ID!, $o: String!) {\n updateProjectV2ItemFieldValue(input: {\n projectId: $p, itemId: $i, fieldId: $f,\n value: {singleSelectOptionId: $o}\n }) {projectV2Item {id}}\n}' -f p=PROJECT_ID -f i=ITEM_ID -f f=FIELD_ID -f o=OPTION_ID","type":"text"}]},{"type":"paragraph","content":[{"text":"Validation","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Validate board configuration\npython {baseDir}/scripts/validate-board-config.py PROJECT_ID\n\n# Check for issues\npython {baseDir}/scripts/validate-board-config.py PROJECT_ID --check-orphans --check-fields","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Templates","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Board Configuration Templates","type":"text"}]},{"type":"paragraph","content":[{"text":"Sprint board template","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"json"},"content":[{"text":"{baseDir}/templates/board-templates.json: sprint-template","type":"text"}]},{"type":"paragraph","content":[{"text":"Kanban board template","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"json"},"content":[{"text":"{baseDir}/templates/board-templates.json: kanban-template","type":"text"}]},{"type":"paragraph","content":[{"text":"Roadmap template","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"json"},"content":[{"text":"{baseDir}/templates/board-templates.json: roadmap-template","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"References","type":"text"}]},{"type":"paragraph","content":[{"text":"GitHub Projects v2 Documentation","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"GraphQL Workarounds Guide","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"{baseDir}/references/graphql-workarounds.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" ⭐","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Complete gh api command reference","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Direct alternatives to helper scripts","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Bulk operation examples","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Troubleshooting common issues","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Copy-paste ready commands","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Official guide: ","type":"text"},{"text":"{baseDir}/references/gh-project-api.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"GraphQL schema: ","type":"text"},{"text":"{baseDir}/references/graphql-schema.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Best practices: ","type":"text"},{"text":"{baseDir}/references/board-best-practices.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Examples: ","type":"text"},{"text":"{baseDir}/references/board-examples.md","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"paragraph","content":[{"text":"Important","type":"text","marks":[{"type":"strong"}]},{"text":": The ","type":"text"},{"text":"graphql-workarounds.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" reference provides direct ","type":"text"},{"text":"gh api","type":"text","marks":[{"type":"code_inline"}]},{"text":" commands for all GraphQL operations. Use this when:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"You want to understand what the helper scripts do under the hood","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"You need to customize or debug GraphQL operations","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"The helper script doesn't support your specific use case","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"You're learning the GitHub Projects v2 API","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Common Use Cases","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Use Case 1: Sprint Planning","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"User: \"Set up sprint planning for our team\"\n\nYou:\n1. Create \"Sprint Planning\" project\n2. Add Sprint field (2-week iterations)\n3. Add Story Points field (Fibonacci: 1,2,3,5,8,13)\n4. Setup columns: Backlog, Current Sprint, In Progress, Review, Done\n5. Configure auto-add for issues with \"sprint\" label\n6. Generate initial report\n\nBoard ready! Add issues and start planning.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Use Case 2: Issue Organization","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"User: \"Organize all our open issues on a board\"\n\nYou:\n1. Create \"Issue Backlog\" project\n2. Add Priority and Size fields\n3. Bulk add all open issues\n4. Auto-label based on issue labels\n5. Group by priority in table view\n\n47 issues added to board!","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Use Case 3: Release Tracking","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"User: \"Track issues for v2.0 release\"\n\nYou:\n1. Create \"Release v2.0\" project\n2. Add milestone filter\n3. Add all issues in v2.0 milestone\n4. Setup roadmap view with target dates\n5. Configure status tracking\n\nTracking 34 issues for v2.0 release.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Integration Points","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"With Other Skills","type":"text"}]},{"type":"paragraph","content":[{"text":"triaging-issues","type":"text","marks":[{"type":"strong"}]},{"text":": Add triaged issues to boards ","type":"text"},{"text":"organizing-with-labels","type":"text","marks":[{"type":"strong"}]},{"text":": Use labels to auto-categorize board items ","type":"text"},{"text":"reviewing-pull-requests","type":"text","marks":[{"type":"strong"}]},{"text":": Add PRs to boards for review tracking ","type":"text"},{"text":"managing-commits","type":"text","marks":[{"type":"strong"}]},{"text":": Link commits to board items","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"With Self-Improvement","type":"text"}]},{"type":"paragraph","content":[{"text":"Generate quality reports for board health:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Item organization quality","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Field consistency","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Automation effectiveness","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Important Notes","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Projects v2 only","type":"text","marks":[{"type":"strong"}]},{"text":": Old Projects (Classic) not supported","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"GraphQL required","type":"text","marks":[{"type":"strong"}]},{"text":": Complex operations need GraphQL","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Organization/User scope","type":"text","marks":[{"type":"strong"}]},{"text":": Projects not tied to single repo","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Permissions","type":"text","marks":[{"type":"strong"}]},{"text":": Need project write access","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Rate limits","type":"text","marks":[{"type":"strong"}]},{"text":": GraphQL has separate rate limits","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Caching","type":"text","marks":[{"type":"strong"}]},{"text":": Project data cached for performance","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Error Handling","type":"text"}]},{"type":"paragraph","content":[{"text":"Common errors","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Not authenticated → Run ","type":"text"},{"text":"gh auth login","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No project access → Check permissions","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"GraphQL errors → Check query syntax","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Rate limited → Wait and retry","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When you encounter project board operations, use this expertise to help users organize their work effectively with GitHub Projects v2!","type":"text"}]}]},"metadata":{"date":"2026-06-05","name":"managing-projects","author":"@skillopedia","source":{"stars":336,"repo_name":"marketplace","origin_url":"https://github.com/aiskillstore/marketplace/blob/HEAD/skills/c0ntr0lledcha0s/managing-projects/SKILL.md","repo_owner":"aiskillstore","body_sha256":"b786fb387f29307bcce8ce887707ed63831685609071c7bad5ec85e6c26e3646","cluster_key":"558ddd2b309c28c4d93b61a670b89228ce9648557ff079b8b19e874922f687d7","clean_bundle":{"format":"clean-skill-bundle-v1","source":"aiskillstore/marketplace/skills/c0ntr0lledcha0s/managing-projects/SKILL.md","attachments":[{"id":"11e753bd-b786-5dd0-9dac-824318a60d9b","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/11e753bd-b786-5dd0-9dac-824318a60d9b/attachment.md","path":"references/board-best-practices.md","size":1885,"sha256":"ec6b4d628d1f2f57081cf658d01c586084ab83af0368ac13e5bf0c5b21fb4322","contentType":"text/markdown; charset=utf-8"},{"id":"318256fd-07c3-5f3a-8a93-f6b2bb6cd89c","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/318256fd-07c3-5f3a-8a93-f6b2bb6cd89c/attachment.md","path":"references/board-examples.md","size":5285,"sha256":"253e27322598d7bcc275ffb5aa959373890b566c3bea34c7cb6d3860b5204547","contentType":"text/markdown; charset=utf-8"},{"id":"012862d6-bddc-50da-9c40-51a3b730a2ac","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/012862d6-bddc-50da-9c40-51a3b730a2ac/attachment.md","path":"references/gh-project-api.md","size":4966,"sha256":"3a7b5addca264b302a3644bfe764703432a9c6b9d9599dfdf9b7255d95a4b314","contentType":"text/markdown; charset=utf-8"},{"id":"9215abc6-25cf-51c7-b62d-63a361cd8e61","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/9215abc6-25cf-51c7-b62d-63a361cd8e61/attachment.md","path":"references/graphql-schema.md","size":2736,"sha256":"639bee91ee254e3d290c64cce6db174d330c43eaa2fc7b6f3fc2e29e97b4b5cc","contentType":"text/markdown; charset=utf-8"},{"id":"d5eb4471-6fdb-5c01-bd6d-d1ddf7a60ee1","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/d5eb4471-6fdb-5c01-bd6d-d1ddf7a60ee1/attachment.md","path":"references/graphql-workarounds.md","size":13247,"sha256":"ade9aa19f6851683e2486d91be6ac25095b041961b4497c3c3a6b8956c54d946","contentType":"text/markdown; charset=utf-8"},{"id":"7b55f21e-0101-5dbb-8008-ac68467047b4","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/7b55f21e-0101-5dbb-8008-ac68467047b4/attachment.sh","path":"scripts/graphql-queries.sh","size":13941,"sha256":"b408cb8a41de2be075053206dd09c1fe9eeed38ae05f8f1fa471ecdd4253101b","contentType":"application/x-sh; charset=utf-8"},{"id":"09644fa8-e8b3-5b93-8f14-996333be0e92","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/09644fa8-e8b3-5b93-8f14-996333be0e92/attachment.sh","path":"scripts/project-helpers.sh","size":16600,"sha256":"3f52386b3450dac6fc2d6e26cf7f7781a70c62a9b3f3e20cb8941c0feea56315","contentType":"application/x-sh; charset=utf-8"},{"id":"27fef0e7-d8e2-5832-9364-6125d0a47748","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/27fef0e7-d8e2-5832-9364-6125d0a47748/attachment.py","path":"scripts/validate-board-config.py","size":16076,"sha256":"c43b7c595795729d3c9f43d6c060c05be5df623da2e746854a1c99df1a7f7714","contentType":"text/x-python; charset=utf-8"},{"id":"39bed979-9b8e-5cc5-8b39-d1a25e4e5b78","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/39bed979-9b8e-5cc5-8b39-d1a25e4e5b78/attachment.json","path":"skill-report.json","size":10820,"sha256":"3ebd66f69e4282d1f612838e85d2c3dc997076cc62b61e262456b139ef2feb82","contentType":"application/json; charset=utf-8"},{"id":"8d5a25ca-28ec-5216-9983-167707434b55","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/8d5a25ca-28ec-5216-9983-167707434b55/attachment.json","path":"templates/board-templates.json","size":4099,"sha256":"55e229cbe38065f579026def2096c03ea59355731ab4e627b327c875b2ece7ac","contentType":"application/json; charset=utf-8"}],"bundle_sha256":"29175f1821b1cde1bb3ba8d7233e9c93bb2621a84d292053931a9941bd5b0bc5","attachment_count":10,"text_attachments":10,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"skills/c0ntr0lledcha0s/managing-projects/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"integrations-apis","category_label":"Integrations"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"integrations-apis","import_tag":"clean-skills-v1","description":"GitHub Projects v2 expertise for creating and managing project boards, fields, views, and items. Auto-invokes when project boards, sprints, kanban workflows, or issue organization is mentioned. Uses GraphQL for advanced project operations.","allowed-tools":"Bash, Read, Grep, Glob"}},"renderedAt":1782979870006}

Managing GitHub Projects (v2) Skill You are a GitHub Projects v2 expert specializing in project board creation, management, and automation. You understand the modern GraphQL-based Projects API and can help users organize their work effectively using boards, views, and custom fields. When to Use This Skill Auto-invoke this skill when the conversation involves: - Creating or managing GitHub project boards - Setting up sprint planning or kanban workflows - Organizing issues and PRs using project boards - Configuring project fields, views, or automation - GraphQL operations for GitHub Projects v2…