Add GitHub issue pipelines and prompts using gh CLI

gh-issue-impl, gh-issue-research, gh-issue-rewrite, gh-issue-update
pipelines with corresponding prompts for fetch-assess, plan,
implement, and create-pr steps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-25 17:02:42 +01:00
parent fc24f9a8ab
commit 22370827ee
16 changed files with 1453 additions and 0 deletions

View File

@@ -0,0 +1,121 @@
kind: WavePipeline
metadata:
name: gh-issue-impl
description: "Implement a GitHub issue end-to-end: fetch, assess, plan, implement, create PR"
input:
source: cli
schema:
type: string
description: "GitHub repository and issue number"
example: "re-cinq/wave 42"
steps:
- id: fetch-assess
persona: implementer
workspace:
type: worktree
branch: "{{ pipeline_id }}"
exec:
type: prompt
source_path: .wave/prompts/github-issue-impl/fetch-assess.md
output_artifacts:
- name: assessment
path: .wave/output/issue-assessment.json
type: json
handover:
contract:
type: json_schema
source: .wave/output/issue-assessment.json
schema_path: .wave/contracts/issue-assessment.schema.json
must_pass: true
on_failure: retry
max_retries: 2
- id: plan
persona: implementer
dependencies: [fetch-assess]
memory:
inject_artifacts:
- step: fetch-assess
artifact: assessment
as: issue_assessment
workspace:
type: worktree
branch: "{{ pipeline_id }}"
base: main
exec:
type: prompt
source_path: .wave/prompts/github-issue-impl/plan.md
output_artifacts:
- name: impl-plan
path: .wave/output/impl-plan.json
type: json
handover:
contract:
type: json_schema
source: .wave/output/impl-plan.json
schema_path: .wave/contracts/issue-impl-plan.schema.json
must_pass: true
on_failure: retry
max_retries: 2
- id: implement
persona: craftsman
dependencies: [plan]
memory:
inject_artifacts:
- step: fetch-assess
artifact: assessment
as: issue_assessment
- step: plan
artifact: impl-plan
as: plan
workspace:
type: worktree
branch: "{{ pipeline_id }}"
exec:
type: prompt
source_path: .wave/prompts/github-issue-impl/implement.md
handover:
contract:
type: test_suite
command: "{{ project.test_command }}"
must_pass: true
on_failure: retry
max_retries: 3
compaction:
trigger: "token_limit_80%"
persona: summarizer
- id: create-pr
persona: craftsman
dependencies: [implement]
memory:
inject_artifacts:
- step: fetch-assess
artifact: assessment
as: issue_assessment
workspace:
type: worktree
branch: "{{ pipeline_id }}"
exec:
type: prompt
source_path: .wave/prompts/github-issue-impl/create-pr.md
output_artifacts:
- name: pr-result
path: .wave/output/pr-result.json
type: json
handover:
contract:
type: json_schema
source: .wave/output/pr-result.json
schema_path: .wave/contracts/pr-result.schema.json
must_pass: true
on_failure: retry
max_retries: 2
outcomes:
- type: pr
extract_from: .wave/output/pr-result.json
json_path: .pr_url
label: "Pull Request"

View File

@@ -0,0 +1,255 @@
kind: WavePipeline
metadata:
name: gh-issue-research
description: Research a GitHub issue and post findings as a comment
release: true
input:
source: cli
example: "re-cinq/wave 42"
schema:
type: string
description: "GitHub repository and issue number (e.g. 'owner/repo number')"
steps:
- id: fetch-issue
persona: github-analyst
workspace:
type: worktree
branch: "{{ pipeline_id }}"
exec:
type: prompt
source: |
Fetch the GitHub issue specified in the input: {{ input }}
The input format is "owner/repo issue_number" (e.g., "re-cinq/CFOAgent 112").
Parse the input to extract the repository and issue number.
Use the gh CLI to fetch the issue:
gh issue view <number> --repo <owner/repo> --json number,title,body,labels,state,author,createdAt,url,comments
Parse the output and produce structured JSON with the issue content.
Include repository information in the output.
output_artifacts:
- name: issue-content
path: .wave/output/issue-content.json
type: json
handover:
contract:
type: json_schema
source: .wave/output/issue-content.json
schema_path: .wave/contracts/issue-content.schema.json
on_failure: retry
max_retries: 3
- id: analyze-topics
persona: researcher
dependencies: [fetch-issue]
memory:
inject_artifacts:
- step: fetch-issue
artifact: issue-content
as: issue
workspace:
type: worktree
branch: "{{ pipeline_id }}"
exec:
type: prompt
source: |
Analyze the GitHub issue and extract research topics.
Identify:
1. Key technical questions that need external research
2. Domain concepts that require clarification
3. External dependencies, libraries, or tools to investigate
4. Similar problems/solutions that might provide guidance
For each topic, provide:
- A unique ID (TOPIC-001, TOPIC-002, etc.)
- A clear title
- Specific questions to answer (1-5 questions per topic)
- Search keywords for web research
- Priority (critical/high/medium/low based on relevance to solving the issue)
- Category (technical/documentation/best_practices/security/performance/compatibility/other)
Focus on topics that will provide actionable insights for the issue author.
Limit to 10 most important topics.
output_artifacts:
- name: topics
path: .wave/output/research-topics.json
type: json
handover:
contract:
type: json_schema
source: .wave/output/research-topics.json
schema_path: .wave/contracts/research-topics.schema.json
on_failure: retry
max_retries: 2
- id: research-topics
persona: researcher
dependencies: [analyze-topics]
memory:
inject_artifacts:
- step: fetch-issue
artifact: issue-content
as: issue
- step: analyze-topics
artifact: topics
as: research_plan
workspace:
type: worktree
branch: "{{ pipeline_id }}"
exec:
type: prompt
source: |
Research the topics identified in the research plan.
For each topic in the research plan:
1. Execute web searches using the provided keywords
2. Evaluate source credibility (official docs > authoritative > community)
3. Extract relevant findings with key points
4. Include direct quotes where helpful
5. Rate your confidence in the answer (high/medium/low/inconclusive)
For each finding:
- Assign a unique ID (FINDING-001, FINDING-002, etc.)
- Provide a summary (20-2000 characters)
- List key points as bullet items
- Include source URL, title, and type
- Rate relevance to the topic (0-1)
Always include source URLs for attribution.
If a topic yields no useful results, mark confidence as "inconclusive".
Document any gaps in the research.
output_artifacts:
- name: findings
path: .wave/output/research-findings.json
type: json
handover:
contract:
type: json_schema
source: .wave/output/research-findings.json
schema_path: .wave/contracts/research-findings.schema.json
on_failure: retry
max_retries: 2
- id: synthesize-report
persona: summarizer
dependencies: [research-topics]
memory:
inject_artifacts:
- step: fetch-issue
artifact: issue-content
as: original_issue
- step: research-topics
artifact: findings
as: research
workspace:
type: worktree
branch: "{{ pipeline_id }}"
exec:
type: prompt
source: |
Synthesize the research findings into a coherent report for the GitHub issue.
Create a well-structured research report that includes:
1. Executive Summary:
- Brief overview (50-1000 chars)
- Key findings (1-7 bullet points)
- Primary recommendation
- Confidence assessment (high/medium/low)
2. Detailed Findings:
- Organize by topic/section
- Include code examples where relevant
- Reference sources using SRC-### IDs
3. Recommendations:
- Actionable items with IDs (REC-001, REC-002, etc.)
- Priority and effort estimates
- Maximum 10 recommendations
4. Sources:
- List all sources with IDs (SRC-001, SRC-002, etc.)
- Include URL, title, type, and reliability
5. Pre-rendered Markdown:
- Generate complete markdown_content field ready for GitHub comment
- Use proper headers, bullet points, and formatting
- Include a header: "## Research Findings (Wave Pipeline)"
- End with sources section
output_artifacts:
- name: report
path: .wave/output/research-report.json
type: json
handover:
contract:
type: json_schema
source: .wave/output/research-report.json
schema_path: .wave/contracts/research-report.schema.json
on_failure: retry
max_retries: 2
- id: post-comment
persona: github-commenter
dependencies: [synthesize-report]
memory:
inject_artifacts:
- step: fetch-issue
artifact: issue-content
as: issue
- step: synthesize-report
artifact: report
as: report
workspace:
type: worktree
branch: "{{ pipeline_id }}"
exec:
type: prompt
source: |
Post the research report as a comment on the GitHub issue.
Steps:
1. Read the issue details to get the repository and issue number
2. Read the report to get the markdown_content
3. Write the markdown content to a file, then use gh CLI to post the comment:
# Write to file to avoid shell escaping issues with large markdown
cat > /tmp/comment-body.md << 'COMMENT_EOF'
<markdown_content>
COMMENT_EOF
gh issue comment <number> --repo <owner/repo> --body-file /tmp/comment-body.md
4. Add a footer to the comment:
---
*Generated by [Wave](https://github.com/re-cinq/wave) issue-research pipeline*
5. Capture the result and verify success
6. If successful, extract the comment URL from the output
Record the result with:
- success: true/false
- issue_reference: issue number and repository
- comment: id, url, body_length (if successful)
- error: code, message, retryable (if failed)
- timestamp: current time
output_artifacts:
- name: comment-result
path: .wave/output/comment-result.json
type: json
outcomes:
- type: url
extract_from: .wave/output/comment-result.json
json_path: .comment.url
label: "Research Comment"
handover:
contract:
type: json_schema
source: .wave/output/comment-result.json
schema_path: .wave/contracts/comment-result.schema.json
on_failure: retry
max_retries: 3

View File

@@ -0,0 +1,187 @@
kind: WavePipeline
metadata:
name: gh-issue-rewrite
description: "Analyze and rewrite poorly documented GitHub issues"
release: true
input:
source: cli
example: "re-cinq/wave 42"
schema:
type: string
description: "GitHub repository, optionally with issue number (e.g. 'owner/repo' or 'owner/repo 42')"
steps:
- id: scan-issues
persona: github-analyst
workspace:
type: worktree
branch: "{{ pipeline_id }}"
exec:
type: prompt
source: |
MANDATORY: You MUST call the Bash tool. NEVER say "gh CLI not installed" without trying.
Input: {{ input }}
Parse the input to determine the mode:
- If the input contains a number after the repo (e.g. "re-cinq/wave 42"), this is SINGLE ISSUE mode.
Extract the repo (first token) and issue number (second token).
- If the input is just a repo (e.g. "re-cinq/wave"), this is BATCH mode.
Execute these commands using the Bash tool:
1. gh --version
2a. SINGLE ISSUE mode: Parse the repo and number from {{ input }}, then run:
gh issue view <NUMBER> --repo <REPO> --json number,title,body,labels,url
2b. BATCH mode: gh issue list --repo {{ input }} --limit 10 --json number,title,body,labels,url
After getting REAL results from Bash, analyze issues and score them.
In single issue mode, analyze the one issue. In batch mode, analyze all returned issues.
output_artifacts:
- name: issue_analysis
path: .wave/artifact.json
type: json
required: true
handover:
max_retries: 1
contract:
type: json_schema
schema_path: .wave/contracts/github-issue-analysis.schema.json
validate: true
must_pass: true
allow_recovery: true
recovery_level: progressive
progressive_validation: false
- id: plan-enhancements
persona: github-analyst
dependencies: [scan-issues]
memory:
inject_artifacts:
- step: scan-issues
artifact: issue_analysis
as: analysis
workspace:
type: worktree
branch: "{{ pipeline_id }}"
exec:
type: prompt
source: |
The analysis artifact contains poor_quality_issues from the scan step.
For EACH issue in poor_quality_issues, use gh CLI to fetch the current body:
gh issue view <NUMBER> --repo {{ input }} --json body
Then create an enhancement plan with:
- issue_number: the issue number
- suggested_title: improved title (or keep original if good)
- body_template: enhanced body text (improve the existing body, add missing sections)
- suggested_labels: appropriate labels
- enhancements: list of changes being made
Create an enhancement plan with fields:
issues_to_enhance (array of issue_number, suggested_title, body_template,
suggested_labels, enhancements) and total_to_enhance.
output_artifacts:
- name: enhancement_plan
path: .wave/artifact.json
type: json
required: true
handover:
max_retries: 1
contract:
type: json_schema
schema_path: .wave/contracts/github-enhancement-plan.schema.json
validate: true
must_pass: true
allow_recovery: true
recovery_level: progressive
progressive_validation: false
- id: apply-enhancements
persona: github-enhancer
dependencies: [plan-enhancements]
memory:
inject_artifacts:
- step: plan-enhancements
artifact: enhancement_plan
as: plan
workspace:
type: worktree
branch: "{{ pipeline_id }}"
exec:
type: prompt
source: |
CRITICAL: You MUST use the Bash tool for all commands. Do NOT generate fake output.
Step 1: Use Bash tool to verify gh works:
gh --version
Step 2: For EACH issue in the plan, use Bash tool to apply changes:
- If suggested_title differs from current: gh issue edit <N> --repo {{ input }} --title "suggested_title"
- If body_template is provided: gh issue edit <N> --repo {{ input }} --body "body_template"
- If suggested_labels: gh issue edit <N> --repo {{ input }} --add-label "label1,label2"
Step 4: For each issue, capture the URL: gh issue view <N> --repo {{ input }} --json url --jq .url
Step 5: Record the results with fields: enhanced_issues (each with issue_number,
success, changes_made, url), total_attempted, total_successful, total_failed.
output_artifacts:
- name: enhancement_results
path: .wave/artifact.json
type: json
required: true
outcomes:
- type: issue
extract_from: .wave/artifact.json
json_path: .enhanced_issues[0].url
label: "Enhanced Issue"
handover:
max_retries: 1
contract:
type: json_schema
schema_path: .wave/contracts/github-enhancement-results.schema.json
validate: true
must_pass: true
allow_recovery: true
recovery_level: progressive
progressive_validation: false
- id: verify-enhancements
persona: github-analyst
dependencies: [apply-enhancements]
memory:
inject_artifacts:
- step: apply-enhancements
artifact: enhancement_results
as: results
- step: scan-issues
artifact: issue_analysis
as: original_analysis
workspace:
type: worktree
branch: "{{ pipeline_id }}"
exec:
type: prompt
source: |
For each enhanced issue, verify with: gh issue view <N> --repo {{ input }} --json title,labels
Compile a verification report with fields:
total_enhanced, successful_enhancements, failed_enhancements, and summary.
output_artifacts:
- name: verification_report
path: .wave/artifact.json
type: json
required: true
handover:
max_retries: 1
contract:
type: json_schema
schema_path: .wave/contracts/github-verification-report.schema.json
validate: true
must_pass: true
allow_recovery: true
recovery_level: progressive
progressive_validation: false

View File

@@ -0,0 +1,184 @@
kind: WavePipeline
metadata:
name: gh-issue-update
description: "Refresh a stale GitHub issue by comparing it against recent codebase changes"
release: true
input:
source: cli
example: "re-cinq/wave 45 -- acceptance criteria are outdated after the worktree refactor"
schema:
type: string
description: "owner/repo number [-- optional criticism or direction]"
steps:
- id: gather-context
persona: github-analyst
workspace:
type: worktree
branch: "{{ pipeline_id }}"
exec:
type: prompt
source: |
MANDATORY: You MUST call the Bash tool. NEVER say "gh CLI not installed" without trying.
Input: {{ input }}
Parse the input:
- Split on " -- " to separate the repo+number from optional criticism.
- The first part is "<owner/repo> <number>". Extract REPO (first token) and NUMBER (second token).
- If there is text after " -- ", that is the user's CRITICISM about what's wrong with the issue.
- If there is no " -- ", criticism is empty.
Execute these commands using the Bash tool:
1. gh --version
2. Fetch the full issue:
gh issue view NUMBER --repo REPO --json number,title,body,labels,url,createdAt,comments
3. Get commits since the issue was created (cap at 100):
git log --since="<createdAt>" --oneline -100
4. Get releases since the issue was created:
gh release list --repo REPO --limit 20
Then filter to only releases after the issue's createdAt date.
5. Scan the issue body for file path references (anything matching patterns like
`internal/...`, `cmd/...`, `.wave/...`, or backtick-quoted paths).
For each referenced file, check if it still exists using `ls -la <path>`.
6. Read CLAUDE.md for current project context:
Read the file CLAUDE.md from the repository root.
After gathering ALL data, produce a JSON result matching the contract schema.
output_artifacts:
- name: issue_context
path: .wave/artifact.json
type: json
required: true
handover:
max_retries: 1
contract:
type: json_schema
schema_path: .wave/contracts/issue-update-context.schema.json
validate: true
must_pass: true
allow_recovery: true
recovery_level: progressive
progressive_validation: false
- id: draft-update
persona: github-analyst
dependencies: [gather-context]
memory:
inject_artifacts:
- step: gather-context
artifact: issue_context
as: context
workspace:
type: worktree
branch: "{{ pipeline_id }}"
exec:
type: prompt
source: |
MANDATORY: You MUST call the Bash tool for any commands. NEVER generate fake output.
The context artifact contains the gathered issue context.
Your task: Compare the original issue against the codebase changes and draft an updated version.
Step 1: Analyze each section of the issue body. Classify each as:
- STILL_VALID: Content is accurate and up-to-date
- OUTDATED: Content references old behavior, removed files, or superseded patterns
- INCOMPLETE: Content is partially correct but missing recent developments
- WRONG: Content is factually incorrect given current codebase state
Step 2: If there is user criticism (non-empty "criticism" field), address EVERY point raised.
The criticism takes priority — it represents what the issue author thinks is wrong.
Step 3: Draft the updated issue:
- Preserve sections classified as STILL_VALID (do not rewrite what works)
- Rewrite OUTDATED and WRONG sections to reflect current reality
- Expand INCOMPLETE sections with missing information
- If the title needs updating, draft a new title
- Append a "---\n**Changes since original**" section at the bottom listing what changed and why
Step 4: If file paths in the issue body are now missing (from referenced_files.missing),
update or remove those references.
Produce a JSON result matching the contract schema.
output_artifacts:
- name: update_draft
path: .wave/artifact.json
type: json
required: true
handover:
max_retries: 1
contract:
type: json_schema
schema_path: .wave/contracts/issue-update-draft.schema.json
validate: true
must_pass: true
allow_recovery: true
recovery_level: progressive
progressive_validation: false
- id: apply-update
persona: github-enhancer
dependencies: [draft-update]
memory:
inject_artifacts:
- step: draft-update
artifact: update_draft
as: draft
- step: gather-context
artifact: issue_context
as: context
workspace:
type: worktree
branch: "{{ pipeline_id }}"
exec:
type: prompt
source: |
CRITICAL: You MUST use the Bash tool for all commands. Do NOT generate fake output.
Step 1: Use Bash tool to verify gh works:
gh --version
Step 2: Extract the repo as "<owner>/<name>" and the issue number from the available artifacts.
Step 3: Apply the update:
- If title_changed is true:
gh issue edit <NUMBER> --repo <REPO> --title "<updated_title>"
- Write the updated_body to a temp file, then apply it:
Write updated_body to /tmp/issue-body.md
gh issue edit <NUMBER> --repo <REPO> --body-file /tmp/issue-body.md
- Clean up /tmp/issue-body.md after applying.
Step 4: Verify the update was applied:
gh issue view <NUMBER> --repo <REPO> --json number,title,body,url
Compare the returned title and body against what was intended. Flag any discrepancies.
Step 5: Record the results as a JSON object matching the contract schema.
output_artifacts:
- name: update_result
path: .wave/artifact.json
type: json
required: true
outcomes:
- type: issue
extract_from: .wave/artifact.json
json_path: .url
label: "Updated Issue"
handover:
max_retries: 1
contract:
type: json_schema
schema_path: .wave/contracts/issue-update-result.schema.json
validate: true
must_pass: true
allow_recovery: true
recovery_level: progressive
progressive_validation: false