21 KiB
/ccpm:plan - Smart Planning Command
Token Budget: ~2,450 tokens (vs ~7,000 baseline) | 65% reduction
Intelligent command that creates new tasks, plans existing tasks, or updates plans based on context.
Mode Detection
The command has 3 modes with clear, unambiguous detection:
- CREATE:
plan "title" [project] [jira-ticket]→ Creates new task and plans it - PLAN:
plan WORK-123→ Plans existing task - UPDATE:
plan WORK-123 "changes"→ Updates existing plan
Usage
# Mode 1: CREATE - New task
/ccpm:plan "Add user authentication"
/ccpm:plan "Add dark mode" my-app TRAIN-456
# Mode 2: PLAN - Plan existing
/ccpm:plan PSN-27
# Mode 3: UPDATE - Update plan
/ccpm:plan PSN-27 "Add email notifications too"
/ccpm:plan PSN-27 "Use Redis instead of in-memory cache"
Implementation
Step 1: Parse Arguments & Detect Mode
const args = process.argv.slice(2);
const arg1 = args[0];
const arg2 = args[1];
const arg3 = args[2];
// Issue ID pattern: PROJECT-NUMBER (e.g., PSN-27, WORK-123)
const ISSUE_ID_PATTERN = /^[A-Z]+-\d+$/;
if (!arg1) {
return error(`
❌ Missing arguments
Usage:
/ccpm:plan "Task title" [project] [jira] # Create new
/ccpm:plan WORK-123 # Plan existing
/ccpm:plan WORK-123 "changes" # Update plan
`);
}
// Detect mode
let mode, issueId, title, project, jiraTicket, updateText;
if (ISSUE_ID_PATTERN.test(arg1)) {
// Starts with issue ID
issueId = arg1;
if (arg2) {
mode = 'update';
updateText = arg2;
} else {
mode = 'plan';
}
} else {
// First arg is not issue ID = CREATE mode
mode = 'create';
title = arg1;
project = arg2 || null;
jiraTicket = arg3 || null;
}
console.log(`\n🎯 Mode: ${mode.toUpperCase()}`);
Step 2A: CREATE Mode - Create & Plan New Task
## CREATE: Create new task and plan it
1. Detect/load project configuration:
Task(project-context-manager): `
${project ? `Get context for project: ${project}` : 'Get active project context'}
Format: standard
Include all sections: true
`
Store: projectId, teamId, projectLinearId, defaultLabels, externalPM config
2. Create Linear issue via subagent:
**Use the Task tool to create a new Linear issue:**
Invoke the `ccpm:linear-operations` subagent:
- **Tool**: Task
- **Subagent**: ccpm:linear-operations
- **Prompt**:
operation: create_issue params: team: "{team ID from step 1}" title: "{task title from arguments}" project: "{project Linear ID from step 1}" state: "Backlog" labels: {default labels from step 1} description: | ## Task
{task title}
{if Jira ticket provided: **Jira Reference**: {jiraTicket}}
---
_Planning in progress..._
context: command: "plan" mode: "create"
Store: issue.id, issue.identifier (e.g., PSN-30)
Display: "✅ Created issue: ${issue.identifier}"
3. Gather context (smart agent selection):
Task: `
Plan implementation for: ${title}
${jiraTicket ? `Jira Ticket: ${jiraTicket}\n` : ''}
Your task:
1. If Jira ticket provided, research it and related Confluence docs
2. Analyze codebase to identify files to modify
3. Research best practices using Context7 MCP
4. Create detailed implementation checklist (5-10 items)
5. Estimate complexity (low/medium/high)
6. Identify potential risks or challenges
Provide structured plan with:
- Implementation checklist (actionable subtasks)
- Files to modify (with brief rationale)
- Dependencies and prerequisites
- Testing approach
- Complexity estimate and reasoning
`
Note: Smart-agent-selector automatically chooses optimal agent based on task type
4. Update Linear issue with plan:
**Use the Task tool to update the issue description with the plan:**
Invoke the `ccpm:linear-operations` subagent:
- **Tool**: Task
- **Subagent**: ccpm:linear-operations
- **Prompt**:
operation: update_issue_description params: issueId: "{issue identifier from step 2}" description: | ## Implementation Checklist
{checklist generated from planning result in step 3}
> **Complexity**: {complexity from step 3} | **Estimated**: {estimate from step 3}
---
## Task
{task title}
{if Jira ticket: **Jira**: [{jiraTicket}](url)}
## Files to Modify
{files list from planning result in step 3}
## Research & Context
{research from planning result in step 3}
## Testing Strategy
{testing strategy from planning result in step 3}
---
*Planned via /ccpm:plan*
context: command: "plan"
5. Update issue status and labels:
**Use the Task tool to update the issue status:**
Invoke the `ccpm:linear-operations` subagent:
- **Tool**: Task
- **Subagent**: ccpm:linear-operations
- **Prompt**:
operation: update_issue params: issueId: "{issue identifier from step 2}" state: "Planned" labels: ["planned", "ready"] context: command: "plan"
6. Display completion:
console.log('\n═══════════════════════════════════════');
console.log('✅ Task Created & Planned!');
console.log('═══════════════════════════════════════\n');
console.log(`📋 Issue: ${issue.identifier} - ${title}`);
console.log(`🔗 ${issue.url}`);
console.log(`\n📊 Plan Summary:`);
console.log(` ✅ ${checklistCount} subtasks created`);
console.log(` 📁 ${filesCount} files to modify`);
console.log(` ⚡ Complexity: ${complexity}`);
console.log(`\n💡 Next: /ccpm:work ${issue.identifier}`);
Step 2B: PLAN Mode - Plan Existing Task
## PLAN: Plan existing task
1. Fetch issue via subagent:
**Use the Task tool to fetch the issue from Linear:**
Invoke the `ccpm:linear-operations` subagent:
- **Tool**: Task
- **Subagent**: ccpm:linear-operations
- **Prompt**:
operation: get_issue params: issueId: "{issue ID from arguments}" context: cache: true command: "plan"
Store: issue.id, issue.title, issue.description, issue.state, issue.team
Display: "📋 Planning: ${issue.identifier} - ${issue.title}"
2. Check if already planned:
const hasChecklist = issue.description.includes('## Implementation Checklist');
const isPlanned = issue.state.name === 'Planned' || issue.state.name === 'Ready';
if (hasChecklist && isPlanned) {
console.log('\nℹ️ Task already has a plan. Use one of:');
console.log(` • /ccpm:plan ${issueId} "changes" - Update the plan`);
console.log(` • /ccpm:work ${issueId} - Start implementation`);
return;
}
3. Extract context from description:
// Check for Jira reference
const jiraMatch = issue.description.match(/\*\*Jira.*?\*\*:\s*([A-Z]+-\d+)/);
const jiraTicket = jiraMatch ? jiraMatch[1] : null;
4. Gather planning context (smart agent selection):
Task: `
Create implementation plan for: ${issue.title}
Current description:
${issue.description}
${jiraTicket ? `Jira ticket: ${jiraTicket}\n` : ''}
Your task:
1. ${jiraTicket ? 'Research Jira ticket and related Confluence docs' : 'Use current description as requirements'}
2. Analyze codebase to identify files to modify
3. Research best practices using Context7 MCP
4. Create detailed implementation checklist (5-10 items)
5. Estimate complexity (low/medium/high)
6. Identify potential risks
Provide structured plan with:
- Implementation checklist (specific, actionable items)
- Files to modify with rationale
- Dependencies and prerequisites
- Testing strategy
- Complexity and estimate
`
5. Update issue description with plan:
**Use the Task tool to update the issue description:**
Invoke the `ccpm:linear-operations` subagent:
- **Tool**: Task
- **Subagent**: ccpm:linear-operations
- **Prompt**:
operation: update_issue_description params: issueId: "{issue ID from step 1}" description: | ## Implementation Checklist
{checklist generated from planning result in step 4}
> **Complexity**: {complexity from step 4} | **Estimated**: {estimate from step 4}
---
{original issue description from step 1}
## Files to Modify
{files list from planning result in step 4}
## Research & Context
{research from planning result in step 4}
## Testing Strategy
{testing strategy from planning result in step 4}
---
*Planned via /ccpm:plan*
context: command: "plan"
6. Update status and labels:
**Use the Task tool to update the issue status:**
Invoke the `ccpm:linear-operations` subagent:
- **Tool**: Task
- **Subagent**: ccpm:linear-operations
- **Prompt**:
operation: update_issue params: issueId: "{issue ID from step 1}" state: "Planned" labels: ["planned", "ready"] context: command: "plan"
7. Display completion:
console.log('\n═══════════════════════════════════════');
console.log('✅ Planning Complete!');
console.log('═══════════════════════════════════════\n');
console.log(`📋 Issue: ${issueId} - ${issue.title}`);
console.log(`🔗 ${issue.url}`);
console.log(`\n📊 Plan Added:`);
console.log(` ✅ ${checklistCount} subtasks`);
console.log(` 📁 ${filesCount} files to modify`);
console.log(` ⚡ Complexity: ${complexity}`);
console.log(`\n💡 Next: /ccpm:work ${issueId}`);
Step 2C: UPDATE Mode - Update Existing Plan
## UPDATE: Update existing plan
1. Fetch current plan:
**Use the Task tool to fetch the issue from Linear:**
Invoke the `ccpm:linear-operations` subagent:
- **Tool**: Task
- **Subagent**: ccpm:linear-operations
- **Prompt**:
operation: get_issue params: issueId: "{issue ID from arguments}" context: cache: true command: "plan"
Store: issue with full description, checklist, state
2. Display current plan summary:
console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
console.log(`📋 Current Plan: ${issueId}`);
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
console.log(`🏷️ Title: ${issue.title}`);
console.log(`📊 Status: ${issue.state.name}`);
const checklist = issue.description.match(/- \[([ x])\] .+/g) || [];
const completed = checklist.filter(i => i.includes('[x]')).length;
console.log(`🎯 Progress: ${completed}/${checklist.length} items\n`);
if (checklist.length > 0) {
console.log('Current Checklist:');
checklist.slice(0, 5).forEach((item, idx) => {
const icon = item.includes('[x]') ? '✅' : '⏳';
const text = item.replace(/- \[([ x])\] /, '');
console.log(` ${icon} ${idx + 1}. ${text}`);
});
if (checklist.length > 5) console.log(` ... and ${checklist.length - 5} more\n`);
}
console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
console.log('📝 Update Request');
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
console.log(updateText);
console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
3. Analyze update request:
// Detect change type
const changeType = detectChangeType(updateText);
// Returns: 'scope_change', 'approach_change', 'simplification', 'blocker', 'clarification'
4. Interactive clarification (if needed):
if (requiresClarification(changeType, updateText)) {
const questions = generateClarificationQuestions(changeType, updateText, issue);
AskUserQuestion({
questions: questions // 1-4 targeted questions based on update
});
// Use answers to refine update request
}
5. Generate updated plan with smart agent:
Task: `
Update implementation plan for: ${issue.title}
Update request: ${updateText}
Change type: ${changeType}
${clarification ? `Clarification: ${JSON.stringify(clarification)}` : ''}
Current plan:
${issue.description}
Your task:
1. Analyze the update request and current plan
2. Determine what needs to change (keep/modify/add/remove)
3. Research any new requirements using Context7 MCP
4. Update implementation checklist accordingly
5. Adjust complexity estimate if needed
6. Document the changes made
Provide:
- Updated checklist with changes highlighted
- Change summary (what was kept/modified/added/removed)
- Updated complexity if changed
- Rationale for changes
`
6. Display change preview:
console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
console.log('📝 Proposed Changes');
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
console.log('✅ Kept:');
keptItems.forEach(i => console.log(` • ${i}`));
console.log('\n✏️ Modified:');
modifiedItems.forEach(i => console.log(` • ${i.old} → ${i.new}`));
console.log('\n➕ Added:');
addedItems.forEach(i => console.log(` • ${i}`));
if (removedItems.length > 0) {
console.log('\n❌ Removed:');
removedItems.forEach(i => console.log(` • ${i}`));
}
7. Confirm and update:
AskUserQuestion({
questions: [{
question: "Apply these changes to the plan?",
header: "Confirm",
multiSelect: false,
options: [
{ label: "Yes, apply changes", description: "Update the plan with changes shown above" },
{ label: "Needs adjustment", description: "Refine the changes first" }
]
}]
});
if (confirmed) {
// Use the Task tool to update the issue description
Invoke the `ccpm:linear-operations` subagent:
- **Tool**: Task
- **Subagent**: ccpm:linear-operations
- **Prompt**:
```
operation: update_issue_description
params:
issueId: "{issue ID from step 1}"
description: {updated description from step 5}
context:
command: "plan"
changeType: "{change type from step 3}"
```
// Use the Task tool to add comment documenting the change
Invoke the `ccpm:linear-operations` subagent:
- **Tool**: Task
- **Subagent**: ccpm:linear-operations
- **Prompt**:
```
operation: create_comment
params:
issueId: "{issue ID from step 1}"
body: |
## 📝 Plan Updated
**Change Type**: {change type from step 3}
**Request**: {update text from arguments}
### Changes Made
{change summary from step 5}
---
*Updated via /ccpm:plan*
context:
command: "plan"
```
}
8. Display completion:
console.log('\n✅ Plan Updated!');
console.log(`📋 Issue: ${issueId} - ${issue.title}`);
console.log(`🔗 ${issue.url}`);
console.log(`\n📊 Changes: ${changes.added} added, ${changes.modified} modified, ${changes.removed} removed`);
console.log(`\n💡 Next: /ccpm:work ${issueId}`);
Helper Functions
// Detect change type from update request
function detectChangeType(text) {
const lower = text.toLowerCase();
if (/(add|also|include|plus|additionally)/i.test(lower)) return 'scope_change';
if (/(instead|different|change|use.*not)/i.test(lower)) return 'approach_change';
if (/(remove|don't need|skip|simpler)/i.test(lower)) return 'simplification';
if (/(blocked|can't|doesn't work|issue|problem)/i.test(lower)) return 'blocker';
return 'clarification';
}
// Generate checklist from planning result
function generateChecklist(plan) {
return plan.subtasks.map(task => `- [ ] ${task}`).join('\n');
}
// Format files list
function formatFilesList(files) {
return files.map(f => `- **${f.path}**: ${f.rationale}`).join('\n');
}
// Generate clarification questions based on change type
function generateClarificationQuestions(changeType, updateText, issue) {
// Returns 1-4 AskUserQuestion-formatted questions
// Based on change type and context
}
Error Handling
Invalid Issue ID Format
❌ Invalid issue ID format: proj123
Expected format: PROJ-123
Issue Not Found
❌ Error fetching issue: Issue not found
Suggestions:
- Verify the issue ID is correct
- Check you have access to this Linear team
Missing Title
❌ Missing arguments
Usage:
/ccpm:plan "Task title" [project] [jira] # Create new
/ccpm:plan WORK-123 # Plan existing
/ccpm:plan WORK-123 "changes" # Update plan
Project Configuration Error
❌ Could not detect project configuration
Suggestions:
- Specify project: /ccpm:plan "title" my-project
- Configure project: /ccpm:project:add my-project
Examples
Example 1: CREATE Mode
/ccpm:plan "Add user authentication"
# Output:
# 🎯 Mode: CREATE
#
# ✅ Created issue: PSN-30
# 📋 Planning: PSN-30 - Add user authentication
#
# [Smart agent analyzes requirements...]
#
# ═══════════════════════════════════════
# ✅ Task Created & Planned!
# ═══════════════════════════════════════
#
# 📋 Issue: PSN-30 - Add user authentication
# 🔗 https://linear.app/.../PSN-30
#
# 📊 Plan Summary:
# ✅ 7 subtasks created
# 📁 5 files to modify
# ⚡ Complexity: Medium
#
# 💡 Next: /ccpm:work PSN-30
Example 2: PLAN Mode
/ccpm:plan PSN-29
# Output:
# 🎯 Mode: PLAN
#
# 📋 Planning: PSN-29 - Implement dark mode
#
# [Smart agent creates plan...]
#
# ═══════════════════════════════════════
# ✅ Planning Complete!
# ═══════════════════════════════════════
#
# 📋 Issue: PSN-29 - Implement dark mode
# 🔗 https://linear.app/.../PSN-29
#
# 📊 Plan Added:
# ✅ 6 subtasks
# 📁 8 files to modify
# ⚡ Complexity: Low
#
# 💡 Next: /ccpm:work PSN-29
Example 3: UPDATE Mode
/ccpm:plan PSN-29 "Also add email notifications"
# Output:
# 🎯 Mode: UPDATE
#
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 📋 Current Plan: PSN-29
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#
# 🏷️ Title: Implement dark mode
# 📊 Status: Planned
# 🎯 Progress: 0/6 items
#
# [Shows clarification questions...]
#
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 📝 Proposed Changes
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#
# ✅ Kept: 6 items
# ➕ Added:
# • Set up email service integration
# • Add notification templates
#
# [Confirmation prompt...]
#
# ✅ Plan Updated!
# 📊 Changes: 2 added, 0 modified, 0 removed
Token Budget Breakdown
| Section | Tokens | Notes |
|---|---|---|
| Frontmatter & description | 100 | Minimal metadata |
| Step 1: Parse & detect mode | 200 | Argument parsing |
| Step 2A: CREATE mode | 600 | Create + plan workflow |
| Step 2B: PLAN mode | 550 | Plan existing workflow |
| Step 2C: UPDATE mode | 500 | Update workflow with clarification |
| Helper functions | 150 | Reusable utilities |
| Error handling | 100 | 4 error scenarios |
| Examples | 250 | 3 concise examples |
| Total | ~2,450 | vs ~7,000 baseline (65% reduction) |
Key Optimizations
- ✅ No routing overhead - All 3 modes implemented directly
- ✅ Linear subagent - All Linear ops cached (85-95% hit rate)
- ✅ Smart agent selection - Automatic optimal agent for planning
- ✅ Batch operations - Single update_issue call (state + labels + description)
- ✅ Concise examples - Only 3 essential examples
- ✅ Focused scope - Simplified planning workflow (no full external PM research by default)
Integration with Other Commands
- After planning → Use /ccpm:work to start implementation
- During work → Use /ccpm:sync to save progress
- Before completion → Use /ccpm:verify for quality checks
- Finalize → Use /ccpm:done to create PR and complete
Notes
- Mode detection: Clear, unambiguous patterns (issue ID vs quoted string)
- Smart agents: Automatic selection based on task type (backend/frontend/mobile)
- Project detection: Auto-detects or uses explicit project argument
- Caching: Linear subagent caches all data for 85-95% faster operations
- Error recovery: Structured error messages with actionable suggestions