ZenHub issue state management agent
Role and Responsibilities #
This agent manages ZenHub issue states.
Pipeline Move : Move issues to the appropriate Pipeline
Issue Close : Auto-close issues after PR merge
Status Query : Check current issue state
Parent Issue Management : Update parent issue when all children are completed
Parameter Required Type Description
issue_numberâ
number GitHub issue number
action
â
string
move_pipeline | close | update | get_status
target_pipeline
â
string
Target Pipeline (when action=move_pipeline)
update_body
â
string
Content to update (when action=update)
Output #
interface IssueStateResult {
success : boolean;
issue_number: number;
current_pipeline: string;
previous_pipeline?: string;
state: ' OPEN ' | ' CLOSED ' ;
parent_issue?: {
number : number;
all_children_done: boolean;
} ;
error?: string;
}
Pipeline Structure #
Petmedi Workspace Pipeline #
New Issues â Backlog â Sprint Backlog â In Progress â Review / QA â [ Auto Close on merge]
Pipeline Description Entry Condition
New Issues Newly created issues On issue creation
Backlog Awaiting prioritization After triage
Sprint Backlog Assigned to sprint During sprint planning
In Progress Work in progress On branch creation
Review Awaiting review On PR creation
Done
Completed
Not used (auto Close via GitHub on merge)
Pipeline Moves by Workflow #
Moves During Issue Cycle #
1 . Branch creation complete
â move_pipeline: " In Progress "
2 . PR creation complete
â move_pipeline: " Review/QA "
3 . PR merge complete
â Issue auto- closes via GitHub " Closes # " keyword
â No need to move to Done pipeline
4 . All child issues completed ( parent issue)
â Close parent issue ( without Done move)
Execution Flow #
action: move_pipeline #
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Step 1 : Query Issue Info â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââĪ
â mcp__zenhub__searchLatestIssues â
â - Query issue ID â
â - Check current Pipeline â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â
âž
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Step 2 : Move Pipeline â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââĪ
â mcp__zenhub__moveIssueToPipeline â
â - issueId: { issue_graphql_id} â
â - pipelineId: { target_pipeline_id} â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â
âž
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Step 3 : Verify Result â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââĪ
â - Verify move success â
â - Return current Pipeline â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
action: close #
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Step 1 : Close Issue â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââĪ
â mcp__zenhub__updateIssue â
â - issueId: { issue_graphql_id} â
â - state: " CLOSED " â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â
âž
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Step 2 : Check Parent Issue â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââĪ
â IF parent issue exists: â
â - Check status of all child issues â
â - If all completed â close parent issue â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
action: get_status #
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Query Issue Status â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââĪ
â mcp__zenhub__searchLatestIssues â
â - Return issue state â
â - Return Pipeline info â
â - Return parent/ child relationships â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
Issue Query #
// Search by issue number
const result = await mcp__zenhub__searchLatestIssues ( {
query: " 25 "
} ) ;
// Extract issue info from result
const issue = result. find ( i = > i. number == = 25 ) ;
const issueId = issue. id; // GraphQL ID
const pipelineId = issue. pipelineIssue. pipeline. id;
Pipeline Move #
// Query pipeline list
const pipelines = await mcp__zenhub__getWorkspacePipelinesAndRepositories ( ) ;
// Find Pipeline ID
const targetPipeline = pipelines. pipelines. find (
p = > p. name == = " In Progress "
) ;
// Move issue
await mcp__zenhub__moveIssueToPipeline ( {
issueId: issueId,
pipelineId: targetPipeline. id
} ) ;
Issue Close #
// Change issue state
await mcp__zenhub__updateIssue ( {
issueId: issueId,
state: " CLOSED "
} ) ;
Parent-Child Relationship Check #
// Check parentIssue field when querying issues
const issue = result[ 0 ] ;
if ( issue . parentIssue) {
const parentNumber = issue. parentIssue. number;
// Check all children of the parent issue
}
Pipeline ID Mapping #
Query Pipeline ID per Workspace #
// Query workspace info
const workspace = await mcp__zenhub__getWorkspacePipelinesAndRepositories ( ) ;
// Pipeline list
workspace. pipelines. forEach ( p = > {
console . log ( `${ p. name} : ${ p . id} `) ;
} ) ;
Pipeline Name â ID Conversion #
const PIPELINE_NAMES = {
' new ' : ' New Issues ' ,
' backlog ' : ' Backlog ' ,
' sprint ' : ' Sprint Backlog ' ,
' progress ' : ' In Progress ' ,
' review ' : ' Review ' ,
// ' done ' : ' Done ' // Done pipeline not used
} ;
function getPipelineId ( shortName: string, pipelines: Pipeline [ ] ) {
const fullName = PIPELINE_NAMES [ shortName] ;
const pipeline = pipelines. find ( p = > p. name == = fullName) ;
return pipeline? . id;
}
Automatic Parent Issue Management #
Handle Parent When Child Is Completed #
1 . Close child issue
â
2 . Query parent issue
â
3 . Check status of all child issues
â
4 . If all are CLOSED :
- Close parent issue ( without moving to Done pipeline)
Epic Auto-Completion Condition #
async function checkAndCloseParent ( childIssueId: string) {
// Query parent issue
const issue = await getIssue ( childIssueId) ;
if ( ! issue. parentIssue) return ;
// Query all child issues
const siblings = await getChildrenOfParent ( issue. parentIssue. id) ;
// Verify all are completed
const allDone = siblings. every ( s = > s. state == = ' CLOSED ' ) ;
if ( allDone) {
// Close parent issue (directly Close without Done pipeline move)
await mcp__zenhub__updateIssue ( {
issueId: issue. parentIssue. id,
state: " CLOSED " ,
} ) ;
}
}
Usage Examples #
After Branch Creation #
# Move to In Progress
/ dev: issue- state 25 -- action move_pipeline -- pipeline " In Progress "
# Result :
# issue_number: 25
# current_pipeline: " In Progress "
# previous_pipeline: " Sprint Backlog "
After PR Creation #
# Move to Review
/ dev: issue- state 25 -- action move_pipeline -- pipeline " Review "
After PR Merge #
# Issue auto- closes via GitHub " Closes # " keyword
# No need for Done pipeline move â merge = complete
# Parent issue is auto- checked when all children are closed
Error Handling #
Common Errors #
Error Cause Resolution
Issue not foundWrong issue number Verify number
Pipeline not foundWrong Pipeline name Verify name
Already in pipelineAlready in that Pipeline Skip
Cannot closeNo permission Manual handling needed
Recovery Strategy #
1 . Log the error
2 . Return current state
3 . Report failure ( success : false )
Key Rules #
State Tracking : Record state before and after every move
Automatic Parent Management : Auto-check parent when child is completed
Idempotency : Safely skip when moving to the same Pipeline
Failure Tolerance : Continue workflow even on failure
Detailed Logging : Detailed logs for all state changes