Files
gh-duongdev-ccpm/commands/complete:finalize.md
2025-11-29 18:24:24 +08:00

357 lines
9.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
description: Finalize completed task - sync with Jira, create PR, clean up
allowed-tools: [Bash, LinearMCP, AtlassianMCP, SlackMCP]
argument-hint: <linear-issue-id>
---
# Finalizing Task: $1
## 💡 Hint: Try the New Natural Command
For a simpler workflow, consider using:
```bash
/ccpm:done [issue-id]
```
**Benefits:**
- Auto-detects issue from git branch if not provided
- Includes pre-flight safety checks (uncommitted changes, branch pushed, etc.)
- Part of the 6-command natural workflow
- See: [Quick Start Guide](./README.md#quick-start)
This command still works perfectly! The hint is just a suggestion.
---
## 🚨 CRITICAL: Safety Rules
**READ FIRST**: ``$CCPM_COMMANDS_DIR/SAFETY_RULES.md``
⛔ **WILL ASK FOR CONFIRMATION** before posting to Jira, Slack, or creating PR!
## Workflow
### Step 1: Verify Task is Complete
Use **Linear MCP** to get issue: $1
**A) Check Status**
Verify status is "Done" or "Verification" (passed).
If status is "In Progress" or "Backlog":
- Display: ⚠️ Task status is "$status". Run `/ccpm:verification:verify $1` first.
- Exit
**B) Parse and Verify Checklist Completion**
Look for checklist in description using markers:
```markdown
<!-- ccpm-checklist-start -->
- [ ] Task 1
- [x] Task 2
<!-- ccpm-checklist-end -->
```
Or find "## ✅ Implementation Checklist" header.
**Calculate completion:**
- Total items: Count all `- [ ]` and `- [x]` lines
- Checked items: Count `- [x]` lines only
- Percentage: (checked / total) × 100
**If completion < 100%:**
Display incomplete items:
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⛔ Cannot Finalize: Checklist Incomplete
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Progress: X% (Y/Z completed)
❌ Remaining Items:
- [ ] Task 3: Description
- [ ] Task 5: Description
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🔧 Actions Required
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Complete remaining items
2. Update checklist: /ccpm:utils:update-checklist $1
3. Then run finalize again: /ccpm:complete:finalize $1
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```
**BLOCK finalization and exit.**
**If completion = 100%:**
Display:
```
✅ Checklist complete! (100% - Z/Z items)
```
Continue to Step 2.
**C) Check for "blocked" label**
If "blocked" label exists:
- Display: ⚠️ Task has "blocked" label. Resolve blockers before finalizing.
- Exit
**If all verifications pass:**
- Continue to Step 2
### Step 2: Generate Completion Summary
Create summary from Linear description and checklist:
```markdown
## Implementation Summary for $1
### What Was Implemented
[Extract from checklist items marked complete]
### Files Modified
[Extract file paths mentioned in description/comments]
### Tests Added
[Extract test information]
### Related Links
- Linear: [link]
- Jira: [link]
- PRs: [links if exist]
```
### Step 3: Interactive Finalization Choices
Use **AskUserQuestion**:
```javascript
{
questions: [
{
question: "Do you want to create a Pull Request?",
header: "Create PR",
multiSelect: false,
options: [
{label: "Yes, Create PR", description: "Generate PR with description"},
{label: "No, Skip PR", description: "I'll create it manually later"}
]
},
{
question: "Do you want to update Jira status?",
header: "Sync Jira",
multiSelect: false,
options: [
{label: "Yes, Update Jira", description: "Mark Jira ticket as Done"},
{label: "No, Skip Jira", description: "I'll update manually"}
]
},
{
question: "Do you want to notify team in Slack?",
header: "Notify Team",
multiSelect: false,
options: [
{label: "Yes, Notify Slack", description: "Post completion message"},
{label: "No, Skip Slack", description: "No notification needed"}
]
}
]
}
```
### Step 4: Execute Chosen Actions
**If Create PR chosen**:
- Generate PR title from Linear title
- Generate PR description from implementation summary
- Suggest command: `gh pr create --title "..." --body "..."`
- Show command for user approval
**If Update Jira chosen**:
- **ASK FOR CONFIRMATION** with preview:
```
🚨 CONFIRMATION REQUIRED
I will update Jira ticket [JIRA-ID] to status "Done" with comment:
---
Completed in Linear: [WORK-123]
[Implementation summary]
---
Proceed? (yes/no)
```
- If yes → Use Atlassian MCP to update
**If Notify Slack chosen**:
- **ASK FOR CONFIRMATION** with preview:
```
🚨 CONFIRMATION REQUIRED
I will post to #[channel]:
---
✅ [Linear title] is complete!
[Brief summary]
Linear: [link]
---
Proceed? (yes/no)
```
- If yes → Use Slack MCP to post
### Step 5: Update Linear Status and Labels
**READ**: `commands/_shared-linear-helpers.md`
Use **Linear MCP** to mark task as complete:
```javascript
try {
// Get team ID from issue
const teamId = issue.team.id;
// Get valid "Done" state ID
const doneStateId = await getValidStateId(teamId, "Done");
// Get or create "done" label
const doneLabel = await getOrCreateLabel(teamId, "done", {
color: "#4cb782",
description: "CCPM: Task completed successfully"
});
// Get current labels
const currentLabels = issue.labels || [];
const currentLabelIds = currentLabels.map(l => l.id);
// Find labels to remove
const implementationLabel = currentLabels.find(l =>
l.name.toLowerCase() === "implementation"
);
const verificationLabel = currentLabels.find(l =>
l.name.toLowerCase() === "verification"
);
const blockedLabel = currentLabels.find(l =>
l.name.toLowerCase() === "blocked"
);
// Build new label list: remove workflow labels, add done
let newLabelIds = currentLabelIds.filter(id =>
id !== implementationLabel?.id &&
id !== verificationLabel?.id &&
id !== blockedLabel?.id
);
// Add done label if not already present
if (!currentLabels.some(l => l.name.toLowerCase() === "done")) {
newLabelIds.push(doneLabel.id);
}
// Update issue with Done status and final labels
await mcp__agent-mcp-gateway__execute_tool({
server: "linear",
tool: "update_issue",
args: {
id: issue.id,
stateId: doneStateId,
labelIds: newLabelIds
}
});
console.log("✅ Linear issue finalized:");
console.log(" Status: Done");
console.log(" Labels: done (removed implementation, verification, blocked)");
} catch (error) {
console.error("⚠️ Failed to update Linear issue:", error.message);
console.warn("⚠️ Task is complete but status may not be updated in Linear.");
console.log(" You can manually update status to Done if needed.");
}
```
**Add completion timestamp comment**:
```javascript
const finalComment = `## 🎉 Task Completed and Finalized
**Completion Time**: ${new Date().toISOString()}
### Actions Taken:
${prCreated ? '✅ Pull Request created' : '⏭️ PR creation skipped'}
${jiraUpdated ? '✅ Jira status updated to Done' : '⏭️ Jira update skipped'}
${slackNotified ? '✅ Team notified in Slack' : '⏭️ Slack notification skipped'}
### Final Status:
- Linear: Done ✅
- All workflow labels cleaned up
- Task marked as complete
---
**This task is now closed and archived.** 🎊
`;
try {
await mcp__agent-mcp-gateway__execute_tool({
server: "linear",
tool: "create_comment",
args: {
issueId: issue.id,
body: finalComment
}
});
console.log("✅ Completion comment added to Linear");
} catch (error) {
console.error("⚠️ Failed to add comment:", error.message);
// Not critical, continue
}
```
### Step 6: Show Final Summary
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎉 Task Finalized: $1
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ Linear: Updated to Done
[✅/⏭️ ] Pull Request: [Created/Skipped]
[✅/⏭️ ] Jira: [Updated/Skipped]
[✅/⏭️ ] Slack: [Notified/Skipped]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
💡 What's Next?
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```
Use **AskUserQuestion** for next action:
```javascript
{
questions: [{
question: "Task complete! What would you like to do next?",
header: "Next Action",
multiSelect: false,
options: [
{label: "Create New Task", description: "Start a new task"},
{label: "View Project Report", description: "See project progress"},
{label: "Pick Another Task", description: "Work on existing task"},
{label: "Done for Now", description: "Exit"}
]
}]
}
```
## Notes
- Always asks for confirmation before external writes
- Generates helpful PR descriptions
- Keeps team informed (if desired)
- Suggests next productive action