A GitHub CLI extension for project management with GitHub Projects (v2) and Issues. Streamline requirements definition, prioritization, task decomposition, and progress tracking from the command line.
- 📊 Project Management - List, create, update, and view issues in GitHub Projects v2
- 📥 Issue Intake - Find and add issues not in project with
gh issue listcompatible interface - 🔍 Issue Triage - Bulk process issues with configurable rules and interactive mode
- ➗ Issue Splitting - Decompose issues into sub-issues using GitHub's native hierarchy
- 🎯 Field Management - Update Status and Priority fields directly from CLI
- 🔗 Project Board Integration - Direct links to GitHub Projects board views
- 🚀 Dry-run Mode - Preview changes before applying them
- 🎨 Multiple output formats - Table, JSON, CSV, and web browser views
gh extension install yahsan2/gh-pmgh extension upgrade pm- GitHub CLI 2.0.0 or later
- GitHub account with repository and project permissions
- Access to GitHub Projects (v2)
gh-sub-issueextension for split command:gh extension install yahsan2/gh-sub-issue
The init command creates a .gh-pm.yml configuration file with automatic project detection and metadata caching for faster operations.
# Interactive initialization (auto-detects current repository and lists available projects)
gh pm initFeatures:
- 🔍 Auto-detection - Automatically detects current repository and associated projects
- 📊 Project selection - Interactive selection from available projects
- 🚀 Metadata caching - Caches project/field/option IDs for faster API operations
- 🔧 Smart field mapping - Automatically maps common status/priority values (e.g., "Backlog" → "todo", "P0" → "critical")
- ✅ Validation - Verifies project access and field availability
# Create a new issue with priority
gh pm create --title "Implement authentication" --priority p1 --label "backend"
# View issue details with project metadata
gh pm view 123
# Move issue to In Progress status
gh pm move 123 --status in_progress
# Find and add issues not in project
gh pm intake --label bug --apply "status:backlog,priority:p2"
# Split issue into sub-issues
gh pm split 123 --from=body
# Run triage to bulk update issues
gh pm triage tracked
# Preview triage changes without applying
gh pm triage estimate --listgh pm init- Initialize configuration with project detection
gh pm list- List issues in project with filteringgh pm intake- Find and add issues not in projectgh pm create- Create new issue with project metadatagh pm view- View issue details with project infogh pm move- Update issue status/priority
gh pm split- Split issue into sub-issuesgh pm triage- Bulk process issues with rules
Initialize a new configuration file with automatic project detection and field mapping.
Options:
--project <name>- Specify project name or number--org <name>- Organization name (for org projects)--repo <owner/repo>- Repository (can be specified multiple times)--skip-metadata- Skip fetching project metadata (creates simpler config)--interactive- Interactive mode (default: true)
What it does:
- Detects current repository - Automatically identifies the current Git repository
- Lists available projects - Shows all projects associated with the repository or organization
- Fetches project fields - Retrieves Status and Priority fields from the selected project
- Maps field values - Automatically maps values like "Backlog" → "todo", "P0" → "critical"
- Caches metadata - Stores project and field IDs for faster API operations
- Creates config file - Generates
.gh-pm.ymlwith all settings
Example workflow:
$ gh pm init
Detecting projects for repository yahsan2/gh-pm...
Available projects from repository yahsan2/gh-pm:
----------------------------------------------------------------------
1. gh-pm project #8
URL: https://github.com/users/yahsan2/projects/8
----------------------------------------------------------------------
Select a project (0-1): 1
✓ Selected project: gh-pm project (#8)
Fetching project fields...
✓ Project metadata captured for faster operations
Found Status field with the following options:
1. Backlog
2. Ready
3. In progress
4. In review
5. Done
Found Priority field with the following options:
1. P0
2. P1
3. P2
✓ Configuration saved to .gh-pm.ymlgh pm list command displays issues in the project with a gh issue list compatible interface. It also supports filtering by project-specific fields (Status, Priority, etc.).
Basic Usage:
# List all open issues in project
gh pm list
# Use alias 'ls'
gh pm ls
# Filter by state
gh pm list --state closed
gh pm list --state all
# Filter by project fields
gh pm list --status "in_progress"
gh pm list --priority "p0,p1"
# Filter by labels
gh pm list --label bug --label enhancement
# Filter by assignee
gh pm list --assignee @me
gh pm list --assignee octocat
# Filter by author
gh pm list --author johndoe
# Filter by milestone
gh pm list --milestone "v1.0"
# Search with query
gh pm list --search "authentication error"
# Limit results (default: 30)
gh pm list --limit 100
# Combined filters
gh pm list --state open --label bug --priority p0 --assignee @meOutput Formats:
# Output as JSON
gh pm list --json number,title,status,priority,assignees,labels
# Output all fields as JSON
gh pm list --json
# Process JSON with jq (coming soon)
gh pm list --json number,title --jq '.[] | select(.number > 100)'
# Format with Go template (coming soon)
gh pm list --json number,title --template '{{range .}}#{{.number}}: {{.title}}{{"\n"}}{{end}}'
# Open project board in web browser
gh pm list --webFilter Options:
--state, -s- Issue state (open/closed/all, default: open)--label, -l- Filter by label (multiple allowed)--assignee, -a- Filter by assignee (@mefor self)--author, -A- Filter by author--milestone, -m- Milestone number or title--search, -S- Text search (title and body)--mention- Filter by mentioned user--app- Filter by GitHub App author--limit, -L- Maximum number to fetch (default: 30)
Project-specific Filters:
--status- Filter by project Status field--priority- Filter by project Priority field (comma-separated for multiple)
Output Example:
# TITLE STATUS PRIORITY ASSIGNEES LABELS
1 Implement authentication system In Progress P0 user1 bug, enhancement
2 Add user dashboard Backlog P1 user2 feature
3 Fix database connection timeout Done P2 - bug
gh pm intake finds and adds issues not in the project with a gh issue list compatible interface. Automatically excludes issues already in the project.
Key Features:
- 🔍 Flexible filtering - Filter issues by labels, assignee, author, state, and more
- 🚫 Duplicate prevention - Automatically excludes issues already in the project
- 📊 Bulk addition - Add multiple issues to the project at once
- 🏷️ Field configuration - Set Status and Priority fields when adding issues
- 👀 Preview mode - Use
--dry-runto preview changes without applying them
Usage Examples:
# List all open issues not in project
gh pm intake
# Filter by labels (multiple allowed)
gh pm intake --label bug --label enhancement
# Add your assigned issues
gh pm intake --assignee @me
# Search with query
gh pm intake --search "authentication error"
# Set project fields when adding
gh pm intake --apply "status:backlog,priority:p2"
# Dry-run mode (preview without adding)
gh pm intake --dry-run
# Filter by author
gh pm intake --author octocat
# Filter by milestone
gh pm intake --milestone "v1.0"
# Specify state (open, closed, all)
gh pm intake --state all
# Limit number of issues
gh pm intake --limit 50Filter Options:
--label, -l- Filter by label (multiple allowed)--assignee, -a- Filter by assignee (@mefor self)--author, -A- Filter by author--state, -s- Issue state (open/closed/all, default: open)--milestone, -m- Milestone number or title--search, -S- GitHub search query--mention- Filter by mentioned user--app- Filter by GitHub App author--limit, -L- Maximum number of issues to fetch (default: 100)
Additional Options:
--dry-run- Show what would be added without making changes--apply- Field values to set when adding (e.g.,status:backlog,priority:p2)
Process Flow:
- Search for issues using specified filters (
gh issue listcompatible) - Fetch issues already in the project
- Exclude duplicates to create list of issues to add
- Display target issues and request confirmation
- After confirmation, add issues to project
- Set field values specified by
--apply
Example: Add bug-labeled issues with priority P2
$ gh pm intake --label bug --apply "status:backlog,priority:p2"
Fetching issues with filters...
Found 5 issues from search
Found 3 issues not in project:
#45: Authentication fails on mobile
#67: Database connection timeout
#89: UI rendering issue in dark mode
Add 3 issues to project? (y/N): y
Adding issue #45 to project... ✓
Adding issue #67 to project... ✓
Adding issue #89 to project... ✓
Successfully added 3/3 issues to project# Basic creation (will use defaults from .gh-pm.yml)
gh pm create --title "Add user dashboard"
# With full details
gh pm create \
--title "Implement REST API" \
--body "Create RESTful endpoints for user management" \
--priority p0 \
--status ready \
--assignee "@me" \
--label "api,backend" \
--milestone "v1.0"
# Interactive mode (opens gh issue create interactively)
gh pm create --interactive
# Create from template
gh pm create --template bug
# Batch creation from file
gh pm create --from-file issues.yml# View issue with project metadata
gh pm view 123
# View with project URL (shows GitHub Projects board URL)
gh pm view 123 --quiet # Only shows URLs
# Open in web browser (opens project board view)
gh pm view 123 --web
# View with comments
gh pm view 123 --comments
# View in different output formats
gh pm view 123 --output json
gh pm view 123 --output csv
# View issue in specific repository
gh pm view 456 --repo owner/repo# Update single field
gh pm move 123 --status in_review
# Update multiple fields
gh pm move 123 --status in_progress --priority p0
# Available status values (based on your project configuration)
gh pm move 15 --status ready
gh pm move 42 --status done
# Available priority values (based on your project configuration)
gh pm move 123 --priority p1 # High priority
gh pm move 456 --priority p2 # Medium priority
# Quiet mode (minimal output)
gh pm move 123 --status done --quiet
# Specify repository explicitly
gh pm move 123 --status ready --repo owner/repoAvailable Field Values:
The exact field values depend on your project configuration (.gh-pm.yml):
- Status:
backlog,ready,in_progress,in_review,done - Priority:
p0(Critical),p1(High),p2(Medium), etc.
Important Notes:
- The issue must already be added to the configured project
- Field values are case-sensitive and must match your project configuration
- Use
gh pm initto see available values for your project
Decompose parent issues into sub-issues using GitHub's native issue hierarchy feature. This command automatically creates linked sub-issues from task lists, maintaining parent-child relationships for better project organization.
Requirements:
- Requires
gh-sub-issueextension:gh extension install yahsan2/gh-sub-issue - The command will prompt for installation if the extension is not found
# Split from issue body checklist
gh pm split 123 --from=body
# Split from a file containing tasks
gh pm split 123 --from=./tasks.md
# Split from stdin
cat tasks.md | gh pm split 123
# Split from JSON array
gh pm split 123 '["Task 1", "Task 2", "Task 3"]'
# Split from command arguments
gh pm split 123 "Design API" "Implement backend" "Write tests"
# Specify repository explicitly
gh pm split 123 --from=body --repo owner/repoFeatures:
- 🔍 Duplicate Detection - Automatically checks existing sub-issues to avoid duplicates
- 🏷️ Label Inheritance - Sub-issues inherit labels from the parent (except meta labels)
- 👥 Assignee Inheritance - Sub-issues inherit assignees from the parent
- 🎯 Milestone Inheritance - Sub-issues inherit milestone from the parent
- 🔗 Native GitHub Integration - Uses GitHub's built-in sub-issue hierarchy
- ✅ Checklist Support - Recognizes GitHub-style checkboxes (
- [ ]format)
Input Formats:
-
Issue Body (
--from=body): Extracts checklist items from the parent issue's description- [ ] Design database schema - [ ] Implement API endpoints - [ ] Write unit tests
-
File Input (
--from=./file.md): Reads tasks from a markdown file with checklist format -
JSON Array: Pass tasks as a JSON array
gh pm split 123 '["Task 1", "Task 2", "Task 3"]' -
Command Arguments: Pass tasks directly as arguments
gh pm split 123 "First task" "Second task" "Third task"
-
Stdin: Pipe tasks from another command
echo "- [ ] Task 1\n- [ ] Task 2" | gh pm split 123
Example Output:
Checking for existing sub-issues and creating new ones for issue #123...
Found 2 existing sub-issues for issue #123
⏭️ Skipping (already exists): Design database schema
✓ Created sub-issue #124: Implement API endpoints
✓ Created sub-issue #125: Write unit tests
Skipped 1 task that already has sub-issues
Notes:
- Sub-issues are automatically linked to the parent using GitHub's native hierarchy
- The parent issue can be viewed with all sub-issues in GitHub's web interface
- Duplicate detection prevents creating the same sub-issue multiple times
- Sub-issues can be managed independently while maintaining their relationship to the parent
# Run a triage configuration
gh pm triage tracked # Applies labels and project fields to untracked issues
# Preview what would be changed (dry-run)
gh pm triage estimate --list
gh pm triage estimate --dry-run # Same as --list
# Interactive triage (prompts for each issue)
gh pm triage estimate # If configured with interactive fields
# Ad-hoc triage with query and apply (without configuration file)
gh pm triage --query="status:backlog -has:estimate" --apply="status:in_progress"
# Preview what would be changed without applying
gh pm triage --query="status:backlog" --apply="priority:p1" --list
# Ad-hoc triage with interactive mode for specific fields
gh pm triage --query="status:backlog" --interactive="status,estimate"
gh pm triage --query="-has:priority" --interactive="priority"
# List issues matching query without any changes
gh pm triage --query="status:backlog -has:estimate" --listTriage Configuration Example (.gh-pm.yml):
triage:
# Auto-add tracking label and set defaults
tracked:
query: "is:issue is:open -label:pm-tracked"
instruction: "Starting triage for untracked issues. This will add the pm-tracked label and set default project fields."
apply:
labels:
- pm-tracked
fields:
priority: p1
status: backlog
interactive:
status: true # Prompt for status selection
# Interactive estimation
estimate:
query: "is:issue is:open status:backlog -has:estimate"
instruction: "Review issues that need estimation. Please provide time estimates for planning purposes."
apply: {}
interactive:
estimate: true # Prompt for estimate entryConfiguration Fields:
query: GitHub search query to find issues to triageinstruction: Optional message displayed at the start of triage operation (useful for providing context or instructions to users)apply.labels: Labels to automatically add to matching issuesapply.fields: Project field values to automatically setinteractive.status: Prompt for status selection for each issueinteractive.estimate: Prompt for estimate entry for each issue
Query Syntax Extensions:
gh-pm extends GitHub's standard search syntax with project-specific filters:
- Field filters:
status:backlog,priority:critical- Filter by project field values (case-insensitive) - Field exclusion (gh-pm exclusive):
-has:estimate- Find issues missing a field value - Label exclusion:
-label:bug- Exclude issues with specific labels - Combined queries:
status:backlog -has:estimate -label:blocked - Config field names: Use either actual field names (
Status:backlog) or config names (status:backlog)
Note: The -has: operator is a gh-pm extension not available in standard GitHub search. It uses GraphQL to filter issues missing specific project field values.
Interactive Field Support:
When using --interactive, the following field types are currently supported:
SINGLE_SELECT- Select from predefined options (e.g., Status, Priority)TEXT- Free-form text input (e.g., custom text fields)NUMBER- Numeric values (e.g., story points, hours)
Planned Support (In Development): The following field types are planned for future releases:
ITERATION- Select project iterations (#29)DATE- Date picker with format validation (#30)MILESTONE- Select repository milestones (#31)ASSIGNEES- Assign users to issues (#32)LABELS- Add/remove issue labels (#33)
Not planned for interactive mode:
REPOSITORY,LINKED_PULL_REQUESTS- These are read-only fields
# Project settings
project:
name: "My Project"
number: 1 # or project ID
org: "my-organization" # optional
# Repository settings
repositories:
- owner/repo1
- owner/repo2
# Default values
defaults:
priority: medium
status: "Todo"
labels:
- "pm-tracked"
# Custom fields mapping (automatically populated from project)
fields:
priority:
field: "Priority"
values:
p0: "P0" # Critical
p1: "P1" # High
p2: "P2" # Medium
status:
field: "Status"
values:
backlog: "Backlog"
ready: "Ready"
in_progress: "In progress"
in_review: "In review"
done: "Done"
# Metadata cache (auto-generated by init command)
metadata:
project:
id: "PVT_kwHOAAlRwM4BBvYB" # Project node ID for API calls
fields:
status:
id: "PVTSSF_lAHOAAlRwM4BBvYBzg0KEU0"
options:
todo: "f75ad846"
ready: "61e4505c"
in_progress: "47fc9ee4"
in_review: "df73e18b"
done: "98236657"
priority:
id: "PVTSSF_lAHOAAlRwM4BBvYBzg0KEX4"
options:
critical: "79628723"
high: "0a877460"
medium: "da944a9c"gh-pm automatically generates correct GitHub Projects board URLs for all issues. These URLs open directly in the project board view, making it easy to navigate between CLI and web interfaces.
- User projects:
https://github.com/users/{owner}/projects/{number}?pane=issue&itemId={id} - Organization projects:
https://github.com/orgs/{org}/projects/{number}?pane=issue&itemId={id}
gh pm view [issue]- Shows project URL in outputgh pm view [issue] --quiet- Shows only the project URLgh pm view [issue] --web- Opens project board in browsergh pm triage [name] --list- Shows project URLs for all affected issuesgh pm create- Returns project URL after creation
┌─────┬──────────────────────┬──────────┬────────────┬──────────┐
│ # │ Title │ Priority │ Status │ Assignee │
├─────┼──────────────────────┼──────────┼────────────┼──────────┤
│ 123 │ Implement auth │ High │ In Progress│ @johndoe │
│ 124 │ Add user dashboard │ Medium │ Todo │ @janedoe │
└─────┴──────────────────────┴──────────┴────────────┴──────────┘
{
"issues": [
{
"number": 123,
"title": "Implement auth",
"priority": "high",
"status": "in_progress",
"assignee": "johndoe"
}
]
}number,title,priority,status,assignee
123,"Implement auth",high,in_progress,johndoe
124,"Add user dashboard",medium,todo,janedoe
# Check authentication
gh auth status
# Re-authenticate
gh auth login
# Use specific token
export GH_TOKEN=your_token_here- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
# Clone repository
git clone https://github.com/yahsan2/gh-pm.git
cd gh-pm
# Install dependencies
npm install # or appropriate package manager
# Run tests
npm test
# Build
npm run build- Issue creation with project metadata (
gh pm create) - Project initialization with auto-detection (
gh pm init) - Issue status & priority updates (
gh pm move) - Issue viewing with project metadata and URLs (
gh pm view) - Issue intake with gh issue list compatible interface (
gh pm intake) - Triage operations for bulk issue processing (
gh pm triage) - Issue splitting into sub-issues with duplicate detection (
gh pm split) - Configuration management with field mapping
- Multiple output formats (table, JSON, CSV)
- Project URL generation for direct GitHub Projects board access
- Dry-run mode for previewing changes before applying
- Issue listing and filtering (
gh pm list) - Bulk operations and CSV import/export
- Progress tracking and reporting (
gh pm status) - Sprint management features
- Sprint management (
gh pm sprint ...) - Gantt chart visualization
- Time tracking integration
- Custom workflow automation
- AI-powered task suggestions
- Mobile companion app
- Slack/Discord integration
MIT License - see LICENSE file for details
- Built on GitHub CLI
- Inspired by modern project management best practices
- Thanks to all contributors and users
Made with ❤️ for GitHub project managers