Interact with project management tools (GitHub Issues, Jira, ClickUp, Linear). Use when creating tickets, updating status, adding comments, or linking PRs to tasks.
How this skill is triggered — by the user, by Claude, or both
Slash command
/keller-solutions-core:managing-tickets <tool> <operation> [options]<tool> <operation> [options]The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Unified interface for interacting with project management tools across the development workflow.
Unified interface for interacting with project management tools across the development workflow.
One skill for all ticket operations, regardless of the tool.
Whether your project uses GitHub Issues, Jira, ClickUp, or Linear, this skill provides consistent patterns for creating, reading, updating, and linking tickets.
Before performing ticket operations, detect which tool the project uses.
# Check for GitHub Issues (most common)
gh issue list --limit 1 2>/dev/null && echo "TOOL=github"
# Check for Linear
[ -f ".linear" ] && echo "TOOL=linear"
# Check for Jira
([ -f ".jira" ] || grep -q "jira" .env 2>/dev/null) && echo "TOOL=jira"
# Check for ClickUp (file, .env, or environment variable)
[ -f ".clickup" ] && echo "TOOL=clickup"
grep -q "clickup" .env 2>/dev/null && echo "TOOL=clickup"
[ -n "$CLICKUP_API_TOKEN" ] && echo "TOOL=clickup"
.linear config file.jira or jira references in .env.clickup, env file, or CLICKUP_API_TOKENFor tools requiring API tokens, use 1Password CLI:
# ClickUp token from 1Password (Private vault)
CLICKUP_API_TOKEN="${CLICKUP_API_TOKEN:-$(op read "op://Private/CLICKUP_API_TOKEN/credential")}"
# Jira token from 1Password
JIRA_API_TOKEN="${JIRA_API_TOKEN:-$(op read "op://Private/JIRA_API_TOKEN/credential")}"
# Linear token from 1Password
LINEAR_API_KEY="${LINEAR_API_KEY:-$(op read "op://Private/LINEAR_API_KEY/credential")}"
Alternatively, set tokens in .env (not committed):
CLICKUP_API_TOKEN=pk_xxx
JIRA_API_TOKEN=xxx
LINEAR_API_KEY=lin_api_xxx
GitHub Issues uses the gh CLI, which handles authentication automatically.
gh issue create \
--title "User sees project list on dashboard" \
--body "$(cat <<'EOF'
**In order to** quickly resume work on recent audits
**As a** returning user on the dashboard
**I want** to see my projects listed by last activity
## Acceptance Criteria
- [ ] Projects section header is visible
- [ ] Each project shows name and last scan date
- [ ] Projects are sorted by last activity (most recent first)
- [ ] Clicking a project navigates to the project detail page
- [ ] Empty state shown when no projects exist
EOF
)"
# View issue details
gh issue view [ISSUE_NUMBER] --json title,body,labels,state
# List issues
gh issue list --limit 20
gh issue list --label "bug"
gh issue list --assignee "@me"
# Add status label (for GitHub Projects integration)
gh issue edit [ISSUE_NUMBER] --add-label "status:in-progress"
gh issue edit [ISSUE_NUMBER] --remove-label "status:in-progress" --add-label "status:in-review"
# Close issue
gh issue close [ISSUE_NUMBER]
# Reopen issue
gh issue reopen [ISSUE_NUMBER]
gh issue comment [ISSUE_NUMBER] --body "PR created: https://github.com/owner/repo/pull/123"
gh issue comment [ISSUE_NUMBER] --body "Released in v1.1.0"
# Add labels during creation
gh issue create --title "..." --body "..." --label "feature"
# Add labels to existing issue
gh issue edit [ISSUE_NUMBER] --add-label "bug"
Common labels:
feature - New functionalitybug - Something brokenchore - Maintenance taskepic:[name] - Links to parent epic# In PR body, reference the issue
# Refs #123
# Closes #123 (auto-closes on merge)
# Fixes #123 (auto-closes on merge)
Jira uses the jira-cli.
jira issue create \
--type Story \
--summary "User sees project list on dashboard" \
--body "$(cat <<'EOF'
*In order to* quickly resume work on recent audits
*As a* returning user on the dashboard
*I want* to see my projects listed by last activity
h2. Acceptance Criteria
* Projects section header is visible
* Each project shows name and last scan date
* Projects are sorted by last activity (most recent first)
* Clicking a project navigates to the project detail page
* Empty state shown when no projects exist
EOF
)"
# View issue
jira issue view [ISSUE_KEY]
# List issues
jira issue list
jira issue list --jql "assignee = currentUser() AND status = 'In Progress'"
# Transition issue to new status
jira issue move [ISSUE_KEY] "In Progress"
jira issue move [ISSUE_KEY] "In Review"
jira issue move [ISSUE_KEY] "Done"
jira issue comment add [ISSUE_KEY] "PR created: https://github.com/owner/repo/pull/123"
# Add PR link as comment
jira issue comment add [ISSUE_KEY] "PR: https://github.com/owner/repo/pull/123"
# Or use Jira's GitHub integration if configured
ClickUp uses REST API calls with curl.
# Token from env var or 1Password
CLICKUP_API_TOKEN="${CLICKUP_API_TOKEN:-$(op read "op://Private/CLICKUP_API_TOKEN/credential")}"
# Find your list ID from ClickUp URL or via API
CLICKUP_LIST_ID="your_list_id"
curl -X POST "https://api.clickup.com/api/v2/list/${CLICKUP_LIST_ID}/task" \
-H "Authorization: ${CLICKUP_API_TOKEN}" \
-H "Content-Type: application/json" \
-d "$(cat <<'EOF'
{
"name": "User sees project list on dashboard",
"markdown_description": "**In order to** quickly resume work on recent audits\n**As a** returning user on the dashboard\n**I want** to see my projects listed by last activity\n\n## Acceptance Criteria\n\n- [ ] Projects section header is visible\n- [ ] Each project shows name and last scan date\n- [ ] Projects are sorted by last activity\n- [ ] Clicking a project navigates to detail page\n- [ ] Empty state shown when no projects exist"
}
EOF
)"
# Get task by ID (find ID in ClickUp URL: https://app.clickup.com/t/[TASK_ID])
curl -s "https://api.clickup.com/api/v2/task/[TASK_ID]" \
-H "Authorization: ${CLICKUP_API_TOKEN}" | jq '.name, .status.status'
# List tasks in a list
curl -s "https://api.clickup.com/api/v2/list/${CLICKUP_LIST_ID}/task" \
-H "Authorization: ${CLICKUP_API_TOKEN}" | jq '.tasks[] | {id, name, status: .status.status}'
# Update task status (status names vary by workspace)
curl -X PUT "https://api.clickup.com/api/v2/task/[TASK_ID]" \
-H "Authorization: ${CLICKUP_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"status": "in progress"}'
# Common status names: "to do", "in progress", "in review", "complete"
curl -X POST "https://api.clickup.com/api/v2/task/[TASK_ID]/comment" \
-H "Authorization: ${CLICKUP_API_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"comment_text\": \"PR created: ${PR_URL}\"}"
# Add PR link as comment
curl -X POST "https://api.clickup.com/api/v2/task/[TASK_ID]/comment" \
-H "Authorization: ${CLICKUP_API_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"comment_text\": \"PR created: ${PR_URL}\"}"
# Update status to "in review"
curl -X PUT "https://api.clickup.com/api/v2/task/[TASK_ID]" \
-H "Authorization: ${CLICKUP_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"status": "in review"}'
Linear uses GraphQL API or the linear CLI.
# Token from env var or 1Password
LINEAR_API_KEY="${LINEAR_API_KEY:-$(op read "op://Private/LINEAR_API_KEY/credential")}"
# Using Linear CLI
linear issue create \
--title "User sees project list on dashboard" \
--description "$(cat <<'EOF'
**In order to** quickly resume work on recent audits
**As a** returning user on the dashboard
**I want** to see my projects listed by last activity
## Acceptance Criteria
- [ ] Projects section header is visible
- [ ] Each project shows name and last scan date
- [ ] Projects are sorted by last activity
EOF
)"
# Using API
curl -X POST https://api.linear.app/graphql \
-H "Authorization: ${LINEAR_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"query": "mutation { issueCreate(input: { title: \"User sees project list\", teamId: \"TEAM_ID\" }) { issue { id identifier } } }"
}'
# Using Linear CLI
linear issue view [ISSUE_ID]
# List issues
linear issue list
# Using Linear CLI
linear issue update [ISSUE_ID] --state "In Progress"
linear issue update [ISSUE_ID] --state "In Review"
# Using API
curl -X POST https://api.linear.app/graphql \
-H "Authorization: ${LINEAR_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"query": "mutation { commentCreate(input: { issueId: \"ISSUE_ID\", body: \"PR created\" }) { comment { id } } }"
}'
This skill is referenced by other keller-solutions-core skills:
| Skill | Uses This For |
|---|---|
/ks-plan | Creating tickets from stories |
/ks-produce | Updating status to "In Progress" |
/ks-present | Linking PRs and updating to "In Review" |
/ks-publish | Adding release comments |
Standard workflow status progression:
To Do → In Progress → In Review → Done
Update status at these milestones:
| Milestone | Status | Triggered By |
|---|---|---|
| Work started | In Progress | /ks-produce |
| PR created | In Review | /ks-present |
| PR merged | Done | Product owner (manual) |
gh issue create --title "..." --body "..."
gh issue view [NUMBER]
gh issue edit [NUMBER] --add-label "status:in-progress"
gh issue comment [NUMBER] --body "..."
gh issue close [NUMBER]
jira issue create --type Story --summary "..." --body "..."
jira issue view [KEY]
jira issue move [KEY] "In Progress"
jira issue comment add [KEY] "..."
# Create: POST /list/{id}/task
# Read: GET /task/{id}
# Update: PUT /task/{id}
# Comment: POST /task/{id}/comment
linear issue create --title "..."
linear issue view [ID]
linear issue update [ID] --state "In Progress"
npx claudepluginhub keller-solutions/kslabs-marketplace --plugin keller-solutions-coreGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.