ghpm-issue
PREREQUISITE: Read ../ghpm-shared/SKILL.md for prerequisites and error handling.File a GitHub issue and add it to the project board in one step. Works mid-session (during ghpm-work) or standalone.
Arguments
/ghpm-issue— interactive: asks for title and body/ghpm-issue <title>— uses argument as issue title, asks for optional body
Workflow
Phase 1: Setup
- Startup sequence: Follow the startup sequence in
../ghpm-shared/SKILL.md. This loads config, refreshes cache if stale, and checks for stale sessions. Extract from config:
- config.project — id, owner, number, title - config.repos — eligible repositories - config.workflow — columns, field_id - config.fields — project fields with name, id, type, options - config.conventions — natural language rules (if present)
Phase 2: Gather Info
- Title and body:
- If argument provided, use as title. Ask for an optional body (user can skip). - If no argument, ask for title, then ask for optional body.
- Pick repo:
- If config.repos has one entry → use it. - If config.repos is empty or missing → ask the user to specify a repo in owner/repo format. - If config.repos has multiple entries → present a numbered list and ask.
- Link to active session: Find active session per
../ghpm-shared/references/session.md(match current branch against session files). If found, prepend to the issue body:Related to <repo>#<num> <original body>
Phase 3: Infer Metadata
All inference is best-effort. Skip silently when no confident match exists.
- Infer labels: Fetch the target repo's actual labels:
gh label list -R <repo> --json name,description --jq '.[] | "\(.name)\t\(.description)"'Match the issue title and body against the fetched label names and descriptions (case-insensitive substring/keyword matching). Only use labels that exist on the repo — never assume a label exists. If no labels match confidently, skip. Don't force a match. - Infer initial status: Use
config.workflow.columnsto determine the initial status:
- If config.conventions.status_sync is present, interpret it for new issue context (e.g., if it describes transitions from Planned, that implies new issues start at Planned or earlier). - Otherwise, use the first column in config.workflow.columns as the default. - Never hardcode a column name — always resolve from config.
- Infer project fields: Iterate over
config.fieldsentries wheretypeis"single_select"andoptionsis non-empty. For each field, infer the best option from the issue context (title, body, labels, repo name):
- Compare each options[].name (case-insensitive) against the issue context for a substring or keyword match. - If exactly one option matches confidently, use it. If ambiguous or no match, skip silently. - When in doubt, skip rather than guess.
Phase 4: Confirm and Create
- Confirm: Prompt (
create_issue): Show the resolved issue details — title, repo, labels (if any), initial status, inferred fields — and ask: "Create this issue and add to <project.title>?" Resolve viaprompts.ghpm-issue.create_issueper../ghpm-shared/references/prompts.md. - Create issue:
gh issue create -R <repo> --title "<title>" --body "<body>" [--label <labels>]Extract the issue URL from stdout. Then fetch the node ID:gh issue view <url> --json number,url,id --jq '{number:.number, url:.url, nodeId:.id}' - Add to project:
gh api graphql -f query=' mutation {addProjectV2ItemById(input: {projectId: "<config.project.id>" contentId: "<issue nodeId>"}) {item {id}}}'Extract the project item ID for field mutations. If this fails: The issue still exists on GitHub. Report the URL and provide the manual fallback:Could not add to project. Add manually: gh project item-add <config.project.number> --owner <config.project.owner> --url <issue-url> - Set status: Using the status resolved in step 6:
gh api graphql -f query=' mutation {updateProjectV2ItemFieldValue(input: {projectId: "<config.project.id>" itemId: "<project item ID>" fieldId: "<config.workflow.field_id>" value: {singleSelectOptionId: "<resolved status column id>"}}) {projectV2Item {id}}}'If this fails, continue — the item is on the board, just without a status. - Set project fields: For each field inferred in step 7, set via GraphQL (run mutations in parallel where possible):
gh api graphql -f query=' mutation {updateProjectV2ItemFieldValue(input: {projectId: "<config.project.id>" itemId: "<project item ID>" fieldId: "<field.id>" value: {singleSelectOptionId: "<matched option.id>"}}) {projectV2Item {id}}}'If a mutation fails, continue with remaining fields.
Phase 5: Output
- Format per
../ghpm-shared/references/format.md:Created #<num> "<title>" in <repo> Project: <config.project.title> (<resolved status>) <field.name>: <option.name> (for each field set in step 12) URL: <issue-url>
Prompt Configuration
Per ../ghpm-shared/references/prompts.md. Config lives at prompts.ghpm-issue in .ghpm/config.json.
Action keys: create_issue.
Tips
- This skill does NOT create a work session. Use
/ghpm-work <number>after filing to start working on the new issue.
See Also
- ghpm-shared — Prerequisites and error handling
- ghpm-work — Start a work session on an issue
- ghpm-suggest — Find what to work on next