Agent Skillskinncj/Heimdall › gh-projects

gh-projects

GitHub

管理GitHub Projects v2看板,支持添加Issue卡片、更新字段值及查询状态。优先使用gh CLI,缺失时回退至GraphQL API。

.claude/skills/gh-projects/SKILL.md kinncj/Heimdall

Trigger Scenarios

需要向GitHub项目看板添加Issue 需要更新项目看板的字段值(如状态、类型)

Install

npx skills add kinncj/Heimdall --skill gh-projects -g -y
More Options

Non-standard path

npx skills add https://github.com/kinncj/Heimdall/tree/main/.claude/skills/gh-projects -g -y

Use without installing

npx skills use kinncj/Heimdall@gh-projects

指定 Agent (Claude Code)

npx skills add kinncj/Heimdall --skill gh-projects -a claude-code -g -y

安装 repo 全部 skill

npx skills add kinncj/Heimdall --all -g -y

预览 repo 内 skill

npx skills add kinncj/Heimdall --list

SKILL.md

Frontmatter
{
    "name": "gh-projects",
    "description": "Manage GitHub Projects v2 board: add issues, update field values, and query board state. Use when managing project boards."
}

SKILL: gh-projects

Purpose

Manage GitHub Projects v2 board operations: add issues as cards, update field values (status, type, ADR required), and query board state. Uses gh project CLI where available; falls back to gh api graphql for operations the CLI does not expose.

Inputs

Field Source Example
project_number project.config.yaml 3
project_node_id project.config.yaml "PVT_kwDO..."
issue_node_id gh-issues skill output "I_kwDO..."
issue_number gh-issues skill output 42
field_name project field name "Status"
field_value target option name "In progress"

Read project config

PROJECT_NUMBER=$(python3 -c "
import sys
for line in open('project.config.yaml'):
    if 'project_number:' in line:
        print(line.split(':')[1].strip())
        break
")

PROJECT_NODE=$(python3 -c "
import sys
for line in open('project.config.yaml'):
    if 'project_node_id:' in line:
        print(line.split(':', 1)[1].strip())
        break
")

Add an Issue to the Project Board

# CLI (preferred)
gh project item-add "$PROJECT_NUMBER" \
  --owner "{owner}" \
  --url "https://github.com/{owner}/{repo}/issues/{issue_number}"

# GraphQL fallback (when CLI unavailable or for automation)
gh api graphql -f query='
  mutation($project: ID!, $content: ID!) {
    addProjectV2ItemById(input: {projectId: $project, contentId: $content}) {
      item { id }
    }
  }' \
  -f project="$PROJECT_NODE" \
  -f content="{issue_node_id}" \
  --jq '.data.addProjectV2ItemById.item.id'

Save the returned item_id — required for field updates.

Get Field and Option IDs

Field updates require the field's node ID and the option's node ID (for single-select fields).

FIELDS=$(gh api graphql -f query='
  query($project: ID!) {
    node(id: $project) {
      ... on ProjectV2 {
        fields(first: 20) {
          nodes {
            ... on ProjectV2Field { id name }
            ... on ProjectV2SingleSelectField {
              id name
              options { id name }
            }
          }
        }
      }
    }
  }' \
  -f project="$PROJECT_NODE")

# Extract field ID by name
FIELD_ID=$(echo "$FIELDS" | python3 -c "
import sys, json
d = json.load(sys.stdin)
for f in d['data']['node']['fields']['nodes']:
    if f.get('name') == '{field_name}':
        print(f['id'])
        break
")

# Extract option ID by value (single-select fields)
OPTION_ID=$(echo "$FIELDS" | python3 -c "
import sys, json
d = json.load(sys.stdin)
for f in d['data']['node']['fields']['nodes']:
    if f.get('name') == '{field_name}':
        for opt in f.get('options', []):
            if opt['name'] == '{field_value}':
                print(opt['id'])
                break
")

Update a Single-Select Field (Status, Type, ADR Required)

gh api graphql -f query='
  mutation($project: ID!, $item: ID!, $field: ID!, $option: String!) {
    updateProjectV2ItemFieldValue(input: {
      projectId: $project
      itemId: $item
      fieldId: $field
      value: { singleSelectOptionId: $option }
    }) {
      projectV2Item { id }
    }
  }' \
  -f project="$PROJECT_NODE" \
  -f item="{item_id}" \
  -f field="$FIELD_ID" \
  -f option="$OPTION_ID"

Update a Text Field (Epic, Specialist)

gh api graphql -f query='
  mutation($project: ID!, $item: ID!, $field: ID!, $value: String!) {
    updateProjectV2ItemFieldValue(input: {
      projectId: $project
      itemId: $item
      fieldId: $field
      value: { text: $value }
    }) {
      projectV2Item { id }
    }
  }' \
  -f project="$PROJECT_NODE" \
  -f item="{item_id}" \
  -f field="$FIELD_ID" \
  -f value="{text_value}"

Standard Field Updates by Pipeline Phase

Phase Field Value
Discover Status Todo
Architect Status In progress
Implement Status In progress
Validate Status In Review
Done Status Done

Query Board State

# List all items with status
gh project item-list "$PROJECT_NUMBER" \
  --owner "{owner}" \
  --format json \
  --jq '.items[] | {id, title: .content.title, status: .fieldValues[] | select(.field.name=="Status") | .name}'

Failure Modes

Condition Action
project_node_id missing from config Run maple project to bootstrap. Stop until resolved.
Item already on board Query before adding. gh project item-list and check content URL. Skip if present.
Field ID not found Re-fetch fields. Field names are case-sensitive.
Option ID not found List available options from field metadata. Do not guess.
GraphQL rate limit Wait 60 seconds. Retry once. Log and stop on second failure.

Logging

[gh-projects] ADD    #42  → project #{project_number}  item_id={id}
[gh-projects] UPDATE #42  field=Status  value="In progress"
[gh-projects] SKIP   #42  already on board

Version History

  • f4ea31f Current 2026-07-05 10:40

Same Skill Collection

.claude/skills/a11y-audit/SKILL.md
.claude/skills/component-scaffold/SKILL.md
.claude/skills/cucumber-automation/SKILL.md
.claude/skills/design-tokens/SKILL.md
.claude/skills/docker-patterns/SKILL.md
.claude/skills/finops-review/SKILL.md
.claude/skills/gh-issues/SKILL.md
.claude/skills/gh-labels-milestones/SKILL.md
.claude/skills/gherkin-authoring/SKILL.md
.claude/skills/github-cli/SKILL.md
.claude/skills/humanizer/SKILL.md
.claude/skills/jupyter-patterns/SKILL.md
.claude/skills/karpathy-audit/SKILL.md
.claude/skills/kubernetes-patterns/SKILL.md
.claude/skills/mermaid-diagrams/SKILL.md
.claude/skills/mockup/SKILL.md
.claude/skills/pipeline-runner/SKILL.md
.claude/skills/playwright-cli/SKILL.md
.claude/skills/postgresql-patterns/SKILL.md
.claude/skills/redis-patterns/SKILL.md
.claude/skills/rfc-adr/SKILL.md
.claude/skills/rubber-duck/SKILL.md
.claude/skills/ship-safe/SKILL.md
.claude/skills/spec-kit/SKILL.md
.claude/skills/sre-review/SKILL.md
.claude/skills/story-issue-sync/SKILL.md
.claude/skills/stripe-patterns/SKILL.md
.claude/skills/supabase-patterns/SKILL.md
.claude/skills/tdd-workflow/SKILL.md
.claude/skills/terraform-patterns/SKILL.md
.claude/skills/threat-modeling/SKILL.md
.claude/skills/vercel-patterns/SKILL.md
.claude/skills/visual-identity/SKILL.md
.claude/skills/wireframe/SKILL.md
.cursor/skills/a11y-audit/SKILL.md
.cursor/skills/component-scaffold/SKILL.md
.cursor/skills/cucumber-automation/SKILL.md
.cursor/skills/design-tokens/SKILL.md
.cursor/skills/docker-patterns/SKILL.md
.cursor/skills/finops-review/SKILL.md
.cursor/skills/gh-issues/SKILL.md
.cursor/skills/gh-labels-milestones/SKILL.md
.cursor/skills/gh-projects/SKILL.md
.cursor/skills/gherkin-authoring/SKILL.md
.cursor/skills/github-cli/SKILL.md
.cursor/skills/humanizer/SKILL.md
.cursor/skills/jupyter-patterns/SKILL.md
.cursor/skills/karpathy-audit/SKILL.md
.cursor/skills/kubernetes-patterns/SKILL.md
.cursor/skills/mermaid-diagrams/SKILL.md
.cursor/skills/mockup/SKILL.md
.cursor/skills/pipeline-runner/SKILL.md
.cursor/skills/playwright-cli/SKILL.md
.cursor/skills/postgresql-patterns/SKILL.md
.cursor/skills/redis-patterns/SKILL.md
.cursor/skills/rfc-adr/SKILL.md
.cursor/skills/rubber-duck/SKILL.md
.cursor/skills/ship-safe/SKILL.md
.cursor/skills/spec-kit/SKILL.md
.cursor/skills/sre-review/SKILL.md
.cursor/skills/story-issue-sync/SKILL.md
.cursor/skills/stripe-patterns/SKILL.md
.cursor/skills/supabase-patterns/SKILL.md
.cursor/skills/tdd-workflow/SKILL.md
.cursor/skills/terraform-patterns/SKILL.md
.cursor/skills/threat-modeling/SKILL.md
.cursor/skills/vercel-patterns/SKILL.md
.cursor/skills/visual-identity/SKILL.md
.cursor/skills/wireframe/SKILL.md
.opencode/skills/a11y-audit/SKILL.md
.opencode/skills/component-scaffold/SKILL.md
.opencode/skills/cucumber-automation/SKILL.md
.opencode/skills/design-tokens/SKILL.md
.opencode/skills/docker-patterns/SKILL.md
.opencode/skills/finops-review/SKILL.md
.opencode/skills/gh-issues/SKILL.md
.opencode/skills/gh-labels-milestones/SKILL.md
.opencode/skills/gh-projects/SKILL.md
.opencode/skills/gherkin-authoring/SKILL.md
.opencode/skills/github-cli/SKILL.md
.opencode/skills/humanizer/SKILL.md
.opencode/skills/jupyter-patterns/SKILL.md
.opencode/skills/karpathy-audit/SKILL.md
.opencode/skills/kubernetes-patterns/SKILL.md
.opencode/skills/mermaid-diagrams/SKILL.md
.opencode/skills/mockup/SKILL.md
.opencode/skills/pipeline-runner/SKILL.md
.opencode/skills/playwright-cli/SKILL.md
.opencode/skills/postgresql-patterns/SKILL.md
.opencode/skills/redis-patterns/SKILL.md
.opencode/skills/rfc-adr/SKILL.md
.opencode/skills/rubber-duck/SKILL.md
.opencode/skills/ship-safe/SKILL.md
.opencode/skills/spec-kit/SKILL.md
.opencode/skills/sre-review/SKILL.md
.opencode/skills/story-issue-sync/SKILL.md
.opencode/skills/stripe-patterns/SKILL.md
.opencode/skills/supabase-patterns/SKILL.md
.opencode/skills/tdd-workflow/SKILL.md
.opencode/skills/terraform-patterns/SKILL.md
.opencode/skills/threat-modeling/SKILL.md
.opencode/skills/vercel-patterns/SKILL.md
.opencode/skills/visual-identity/SKILL.md
.opencode/skills/wireframe/SKILL.md

Metadata

Files
0
Version
f4ea31f
Hash
07391ab7
Indexed
2026-07-05 10:40

Главная - Вики-сайт
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-07-09 21:24
浙ICP备14020137号-1 $Гость$