Initial commit
This commit is contained in:
72
commands/pm-epic-start.md
Normal file
72
commands/pm-epic-start.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# /pm epic-start
|
||||
|
||||
Start working on an epic by creating a dedicated development environment.
|
||||
|
||||
This command sets up everything you need to start developing an epic: Git worktree, task list, and optionally AI agents to help with the work.
|
||||
|
||||
## What it does:
|
||||
|
||||
### 🌳 Environment Setup
|
||||
- Creates dedicated Git worktree for the epic
|
||||
- Switches to epic-specific branch
|
||||
- Sets up development environment
|
||||
|
||||
### 📋 Task Preparation
|
||||
- Lists all issues in the epic
|
||||
- Organizes tasks by priority and dependencies
|
||||
- Creates task tracking structure
|
||||
|
||||
### 🤖 AI Agent Setup (optional)
|
||||
- Creates specialized AI agents for the epic
|
||||
- Sets up parallel development agents
|
||||
- Configures code review and testing agents
|
||||
|
||||
### 📊 Progress Tracking
|
||||
- Initializes epic progress tracking
|
||||
- Sets up milestones and checkpoints
|
||||
- Creates status reporting
|
||||
|
||||
## Usage:
|
||||
|
||||
```bash
|
||||
/pm epic-start <epic-name> # Start epic with default setup
|
||||
/pm epic-start <epic-name> --worktree # Create Git worktree
|
||||
/pm epic-start <epic-name> --agents # Setup AI agents
|
||||
/pm epic-start <epic-name> --solo # Single developer mode
|
||||
```
|
||||
|
||||
## Example:
|
||||
|
||||
```bash
|
||||
/pm epic-start user-authentication
|
||||
```
|
||||
|
||||
Output:
|
||||
```
|
||||
🚀 Starting epic: user-authentication
|
||||
|
||||
🌳 Creating development environment...
|
||||
✅ Created worktree: worktrees/user-authentication
|
||||
✅ Switched to branch: epic/user-authentication
|
||||
✅ Set up development tools
|
||||
|
||||
📋 Epic tasks (8 issues):
|
||||
🔄 #145 Create login form UI (in progress)
|
||||
⏳ #146 Implement OAuth2 integration
|
||||
⏳ #147 Add user registration flow
|
||||
⏳ #148 Password reset functionality
|
||||
⏳ #149 User profile management
|
||||
⏳ #150 Session handling
|
||||
⏳ #151 Security validation
|
||||
⏳ #152 Unit and integration tests
|
||||
|
||||
🤖 AI agents ready:
|
||||
🎨 UI/UX designer agent
|
||||
💻 Backend developer agent
|
||||
🔍 Code reviewer agent
|
||||
🧪 QA tester agent
|
||||
|
||||
📊 Progress tracking initialized
|
||||
🎯 Ready to start development!
|
||||
Next step: Start working on issue #145
|
||||
```
|
||||
138
commands/pm-help.js
Normal file
138
commands/pm-help.js
Normal file
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* /pm help - Show help for CCPM commands
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Get all command files from the commands directory
|
||||
const commandsDir = path.join(__dirname);
|
||||
const commandFiles = fs.readdirSync(commandsDir)
|
||||
.filter(file => file.startsWith('pm-') && (file.endsWith('.md') || file.endsWith('.js')))
|
||||
.map(file => file.replace(/\.(md|js)$/, ''));
|
||||
|
||||
console.log('# CCPM - Claude Code Project Management\n');
|
||||
console.log('Complete project management workflow for spec-driven development, GitHub issues, Git worktrees, and parallel AI agents.\n');
|
||||
|
||||
console.log('## Quick Start\n');
|
||||
console.log('1. Initialize CCPM in your project:');
|
||||
console.log(' ```bash');
|
||||
console.log(' /pm init');
|
||||
console.log(' ```\n');
|
||||
|
||||
console.log('2. Create your first PRD:');
|
||||
console.log(' ```bash');
|
||||
console.log(' /pm prd-new');
|
||||
console.log(' ```\n');
|
||||
|
||||
console.log('3. Parse PRD into issues:');
|
||||
console.log(' ```bash');
|
||||
console.log(' /pm prd-parse');
|
||||
console.log(' ```\n');
|
||||
|
||||
console.log('4. Start working:');
|
||||
console.log(' ```bash');
|
||||
console.log(' /pm epic-start <epic-name>');
|
||||
console.log(' ```\n');
|
||||
|
||||
console.log('## Available Commands\n');
|
||||
|
||||
const categories = {
|
||||
'setup': '🔧 Setup & Configuration',
|
||||
'prd': '📄 PRD (Product Requirements Document) Management',
|
||||
'epic': '🏗️ Epic Management',
|
||||
'issue': '🎫 Issue Management',
|
||||
'worktree': '🌳 Git Worktree Management',
|
||||
'agent': '🤖 AI Agent Management',
|
||||
'skills': '🎯 Skills and AI Agent Management'
|
||||
};
|
||||
|
||||
const commandCategories = {
|
||||
'init': 'setup',
|
||||
'help': 'setup',
|
||||
'status': 'setup',
|
||||
'validate': 'setup',
|
||||
'sync': 'setup',
|
||||
'prd-new': 'prd',
|
||||
'prd-list': 'prd',
|
||||
'prd-status': 'prd',
|
||||
'prd-edit': 'prd',
|
||||
'prd-parse': 'prd',
|
||||
'epic-list': 'epic',
|
||||
'epic-show': 'epic',
|
||||
'epic-start': 'epic',
|
||||
'epic-start-worktree': 'epic',
|
||||
'epic-status': 'epic',
|
||||
'epic-edit': 'epic',
|
||||
'epic-decompose': 'epic',
|
||||
'epic-merge': 'epic',
|
||||
'epic-close': 'epic',
|
||||
'epic-oneshot': 'epic',
|
||||
'epic-refresh': 'epic',
|
||||
'epic-sync': 'epic',
|
||||
'issue-list': 'issue',
|
||||
'issue-show': 'issue',
|
||||
'issue-create': 'issue',
|
||||
'issue-edit': 'issue',
|
||||
'issue-assign': 'issue',
|
||||
'issue-close': 'issue',
|
||||
'issue-reopen': 'issue',
|
||||
'issue-sync': 'issue',
|
||||
'worktree-create': 'worktree',
|
||||
'worktree-list': 'worktree',
|
||||
'worktree-remove': 'worktree',
|
||||
'worktree-switch': 'worktree',
|
||||
'agent-start': 'agent',
|
||||
'agent-list': 'agent',
|
||||
'agent-stop': 'agent',
|
||||
'agent-status': 'agent',
|
||||
'skills-list': 'skills'
|
||||
};
|
||||
|
||||
// Group commands by category (remove duplicates)
|
||||
const groupedCommands = {};
|
||||
Object.keys(categories).forEach(category => {
|
||||
groupedCommands[category] = [];
|
||||
});
|
||||
|
||||
const uniqueCommands = [...new Set(commandFiles)];
|
||||
uniqueCommands.forEach(command => {
|
||||
const category = commandCategories[command] || 'setup';
|
||||
if (groupedCommands[category]) {
|
||||
groupedCommands[category].push(command);
|
||||
}
|
||||
});
|
||||
|
||||
// Display commands by category
|
||||
Object.keys(categories).forEach(category => {
|
||||
if (groupedCommands[category].length > 0) {
|
||||
console.log(`### ${categories[category]}`);
|
||||
groupedCommands[category].forEach(command => {
|
||||
const commandFile = path.join(commandsDir, `${command}.md`);
|
||||
let description = '';
|
||||
if (fs.existsSync(commandFile)) {
|
||||
const content = fs.readFileSync(commandFile, 'utf8');
|
||||
const firstLine = content.split('\n')[0];
|
||||
if (firstLine.startsWith('# ')) {
|
||||
description = firstLine.substring(2).trim();
|
||||
}
|
||||
} else {
|
||||
// Try to get description from JS file if no md file exists
|
||||
const jsCommandFile = path.join(commandsDir, `${command}.js`);
|
||||
if (fs.existsSync(jsCommandFile)) {
|
||||
const jsContent = fs.readFileSync(jsCommandFile, 'utf8');
|
||||
const jsComment = jsContent.split('\n')[1];
|
||||
if (jsComment && jsComment.trim().startsWith('*')) {
|
||||
description = jsComment.trim().replace(/^\*\s*/, '');
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(`- \`/pm ${command}\` - ${description || command}`);
|
||||
});
|
||||
console.log('');
|
||||
}
|
||||
});
|
||||
|
||||
console.log('Use `/pm help <command>` for detailed help on any specific command.');
|
||||
31
commands/pm-help.md
Normal file
31
commands/pm-help.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# /pm help
|
||||
|
||||
Show help for CCPM commands.
|
||||
|
||||
## Usage:
|
||||
|
||||
```bash
|
||||
/pm help # Show all available commands
|
||||
/pm help <command> # Show help for specific command
|
||||
/pm help <category> # Show help for command category
|
||||
```
|
||||
|
||||
## Categories:
|
||||
|
||||
- `setup` - Setup and configuration commands
|
||||
- `prd` - PRD (Product Requirements Document) management
|
||||
- `epic` - Epic management
|
||||
- `issue` - Issue management
|
||||
- `worktree` - Git worktree management
|
||||
- `agent` - AI agent management
|
||||
- `skills` - Skills and AI agent management
|
||||
|
||||
## Examples:
|
||||
|
||||
```bash
|
||||
/pm help # Show all commands
|
||||
/pm help init # Show help for init command
|
||||
/pm help prd # Show PRD management commands
|
||||
/pm help epic-start # Show help for epic-start command
|
||||
/pm help skills # Show skills management commands
|
||||
```
|
||||
133
commands/pm-init.js
Normal file
133
commands/pm-init.js
Normal file
@@ -0,0 +1,133 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* /pm init - Initialize CCPM in current project
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
console.log('🚀 Initializing CCPM Plugin...');
|
||||
|
||||
try {
|
||||
// Check if ccpm directory already exists
|
||||
const ccpmDir = path.join(process.cwd(), 'ccpm');
|
||||
if (fs.existsSync(ccpmDir)) {
|
||||
console.log('✅ CCPM already installed');
|
||||
showStatus();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create directory structure
|
||||
console.log('📁 Creating CCPM directory structure...');
|
||||
fs.mkdirSync(path.join(process.cwd(), 'ccpm'), { recursive: true });
|
||||
fs.mkdirSync(path.join(process.cwd(), 'specs'), { recursive: true });
|
||||
fs.mkdirSync(path.join(process.cwd(), 'worktrees'), { recursive: true });
|
||||
|
||||
// Create configuration file
|
||||
const config = {
|
||||
project: {
|
||||
name: require('../package.json').name || path.basename(process.cwd()),
|
||||
description: '',
|
||||
version: '1.0.0',
|
||||
repository: {
|
||||
url: '',
|
||||
owner: '',
|
||||
name: '',
|
||||
defaultBranch: 'main'
|
||||
}
|
||||
},
|
||||
directories: {
|
||||
ccpm: 'ccpm',
|
||||
specs: 'specs',
|
||||
worktrees: 'worktrees'
|
||||
},
|
||||
github: {
|
||||
enabled: false,
|
||||
issueLabels: [
|
||||
'epic',
|
||||
'feature',
|
||||
'bug',
|
||||
'enhancement',
|
||||
'documentation',
|
||||
'testing',
|
||||
'infrastructure'
|
||||
],
|
||||
priorities: ['low', 'medium', 'high', 'critical'],
|
||||
statuses: ['backlog', 'in-progress', 'review', 'done']
|
||||
},
|
||||
workflow: {
|
||||
branchNaming: {
|
||||
epic: 'epic/{name}',
|
||||
feature: 'feature/{name}',
|
||||
bugfix: 'bugfix/{name}',
|
||||
hotfix: 'hotfix/{name}'
|
||||
},
|
||||
autoAssignIssues: true,
|
||||
requireReviewForMerge: true
|
||||
},
|
||||
ai: {
|
||||
maxConcurrentAgents: 3,
|
||||
defaultAgentModel: 'sonnet-4-5',
|
||||
timeoutMinutes: 30
|
||||
},
|
||||
created: new Date().toISOString(),
|
||||
lastUpdated: new Date().toISOString()
|
||||
};
|
||||
|
||||
const state = {
|
||||
project: {
|
||||
status: 'initialized',
|
||||
currentEpic: null,
|
||||
activeIssues: [],
|
||||
activeWorktrees: []
|
||||
},
|
||||
prs: {
|
||||
active: [],
|
||||
draft: [],
|
||||
completed: []
|
||||
},
|
||||
agents: {
|
||||
running: [],
|
||||
completed: []
|
||||
},
|
||||
github: {
|
||||
lastSync: null,
|
||||
syncEnabled: true
|
||||
},
|
||||
stats: {
|
||||
totalEpics: 0,
|
||||
completedEpics: 0,
|
||||
totalIssues: 0,
|
||||
completedIssues: 0
|
||||
},
|
||||
initializedAt: new Date().toISOString(),
|
||||
lastActivity: new Date().toISOString()
|
||||
};
|
||||
|
||||
fs.writeFileSync(path.join(ccpmDir, 'ccpm.config.json'), JSON.stringify(config, null, 2));
|
||||
fs.writeFileSync(path.join(ccpmDir, 'state.json'), JSON.stringify(state, null, 2));
|
||||
|
||||
console.log('✅ CCPM Plugin initialized successfully!');
|
||||
showStatus();
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to initialize CCPM Plugin:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function showStatus() {
|
||||
const ccpmDir = path.join(process.cwd(), 'ccpm');
|
||||
const configPath = path.join(ccpmDir, 'ccpm.config.json');
|
||||
|
||||
console.log('\n📊 CCPM Plugin Status:');
|
||||
console.log(` Version: ${require('../package.json').version || '1.0.6'}`);
|
||||
console.log(` Installation: ✅ Installed`);
|
||||
console.log(` Path: ${ccpmDir}`);
|
||||
console.log(` Config: ${fs.existsSync(configPath) ? '✅ Found' : '❌ Missing'}`);
|
||||
|
||||
console.log('\n🎯 Quick Start:');
|
||||
console.log(' /pm help - Show all available commands');
|
||||
console.log(' /pm status - Show current project status');
|
||||
console.log(' /pm prd-new - Create your first PRD');
|
||||
}
|
||||
317
commands/pm-init.md
Normal file
317
commands/pm-init.md
Normal file
@@ -0,0 +1,317 @@
|
||||
# /pm init
|
||||
|
||||
Initialize CCPM (Claude Code Project Management) in the current project.
|
||||
|
||||
This command sets up the necessary directory structure, configuration files, and Git integration for CCPM to work properly.
|
||||
|
||||
---
|
||||
|
||||
🚀 Initializing CCPM in project...
|
||||
|
||||
## 1. Creating project structure
|
||||
|
||||
<!-- Create necessary directories -->
|
||||
```bash
|
||||
mkdir -p ccpm specs worktrees
|
||||
```
|
||||
|
||||
✅ Created directory structure
|
||||
|
||||
## 2. Setting up configuration
|
||||
|
||||
<!-- Create main configuration file if it doesn't exist -->
|
||||
```bash
|
||||
if [ ! -f "ccpm.config.json" ]; then
|
||||
cat > ccpm.config.json << 'EOF'
|
||||
{
|
||||
"project": {
|
||||
"name": "$(basename $(pwd))",
|
||||
"description": "CCPM managed project",
|
||||
"repository": {
|
||||
"url": "$(git config --get remote.origin.url 2>/dev/null || echo '')",
|
||||
"defaultBranch": "main"
|
||||
}
|
||||
},
|
||||
"directories": {
|
||||
"ccpm": "ccpm",
|
||||
"specs": "specs",
|
||||
"worktrees": "worktrees"
|
||||
},
|
||||
"github": {
|
||||
"enabled": true,
|
||||
"issueLabels": [
|
||||
"epic",
|
||||
"feature",
|
||||
"bug",
|
||||
"enhancement",
|
||||
"documentation",
|
||||
"testing",
|
||||
"infrastructure"
|
||||
],
|
||||
"priorities": ["low", "medium", "high", "critical"],
|
||||
"statuses": ["backlog", "in-progress", "review", "done"]
|
||||
},
|
||||
"workflow": {
|
||||
"branchNaming": {
|
||||
"epic": "epic/{name}",
|
||||
"feature": "feature/{name}",
|
||||
"bugfix": "bugfix/{name}",
|
||||
"hotfix": "hotfix/{name}"
|
||||
},
|
||||
"autoAssignIssues": true,
|
||||
"requireReviewForMerge": true
|
||||
},
|
||||
"ai": {
|
||||
"maxConcurrentAgents": 3,
|
||||
"defaultAgentModel": "sonnet-4-5",
|
||||
"timeoutMinutes": 30
|
||||
},
|
||||
"created": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
||||
"lastUpdated": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
}
|
||||
EOF
|
||||
echo "✅ Created ccpm.config.json"
|
||||
else
|
||||
echo "✅ ccpm.config.json already exists"
|
||||
fi
|
||||
```
|
||||
|
||||
<!-- Create state file -->
|
||||
```bash
|
||||
if [ ! -f "ccpm/state.json" ]; then
|
||||
cat > ccpm/state.json << 'EOF'
|
||||
{
|
||||
"project": {
|
||||
"status": "initialized",
|
||||
"currentEpic": null,
|
||||
"activeIssues": [],
|
||||
"activeWorktrees": []
|
||||
},
|
||||
"prs": {
|
||||
"active": [],
|
||||
"draft": [],
|
||||
"completed": []
|
||||
},
|
||||
"agents": {
|
||||
"running": [],
|
||||
"completed": []
|
||||
},
|
||||
"github": {
|
||||
"lastSync": null,
|
||||
"syncEnabled": true
|
||||
},
|
||||
"stats": {
|
||||
"totalEpics": 0,
|
||||
"completedEpics": 0,
|
||||
"totalIssues": 0,
|
||||
"completedIssues": 0
|
||||
},
|
||||
"initializedAt": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
||||
"lastActivity": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
}
|
||||
EOF
|
||||
echo "✅ Created ccpm/state.json"
|
||||
else
|
||||
echo "✅ ccpm/state.json already exists"
|
||||
fi
|
||||
```
|
||||
|
||||
<!-- Create GitHub integration config -->
|
||||
```bash
|
||||
if [ ! -f "ccpm/github.json" ]; then
|
||||
# Check if GitHub CLI is available and authenticated
|
||||
if command -v gh >/dev/null 2>&1 && gh auth status >/dev/null 2>&1; then
|
||||
GITHUB_USER=$(gh api user --jq '.login')
|
||||
REPO_URL=$(git config --get remote.origin.url 2>/dev/null || echo '')
|
||||
|
||||
cat > ccpm/github.json << EOF
|
||||
{
|
||||
"repository": {
|
||||
"owner": "$(echo $REPO_URL | sed -n 's/.*github.com[:/]\([^/]*\)\/.*/\1/p' || echo '$GITHUB_USER')",
|
||||
"name": "$(basename $(git rev-parse --show-toplevel 2>/dev/null || echo $(pwd)))",
|
||||
"url": "$REPO_URL",
|
||||
"defaultBranch": "main",
|
||||
"isPrivate": false
|
||||
},
|
||||
"authentication": {
|
||||
"cliInstalled": true,
|
||||
"authenticated": true,
|
||||
"user": "$GITHUB_USER",
|
||||
"tokenScopes": ["gist", "read:org", "repo"]
|
||||
},
|
||||
"integration": {
|
||||
"enabled": true,
|
||||
"autoSync": true,
|
||||
"createIssuesFromPRD": true,
|
||||
"linkIssuesToCommits": true
|
||||
},
|
||||
"labels": {
|
||||
"epic": {
|
||||
"name": "epic",
|
||||
"color": "FF6B6B",
|
||||
"description": "Large feature that spans multiple issues"
|
||||
},
|
||||
"feature": {
|
||||
"name": "feature",
|
||||
"color": "0079BF",
|
||||
"description": "New functionality or feature"
|
||||
},
|
||||
"bug": {
|
||||
"name": "bug",
|
||||
"color": "E11D21",
|
||||
"description": "Something isn't working"
|
||||
},
|
||||
"enhancement": {
|
||||
"name": "enhancement",
|
||||
"color": "84B6EB",
|
||||
"description": "Improvement to existing functionality"
|
||||
},
|
||||
"documentation": {
|
||||
"name": "documentation",
|
||||
"color": "FCE74C",
|
||||
"description": "Improvements to documentation"
|
||||
},
|
||||
"testing": {
|
||||
"name": "testing",
|
||||
"color": "5319E7",
|
||||
"description": "Test coverage and testing improvements"
|
||||
},
|
||||
"infrastructure": {
|
||||
"name": "infrastructure",
|
||||
"color": "6CC644",
|
||||
"description": "Infrastructure and deployment improvements"
|
||||
}
|
||||
},
|
||||
"lastSync": null,
|
||||
"configuredAt": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
}
|
||||
EOF
|
||||
echo "✅ Created ccpm/github.json with GitHub integration"
|
||||
else
|
||||
echo "⚠️ GitHub CLI not available - creating basic GitHub config"
|
||||
cat > ccpm/github.json << 'EOF'
|
||||
{
|
||||
"repository": {
|
||||
"owner": "",
|
||||
"name": "$(basename $(pwd))",
|
||||
"url": "",
|
||||
"defaultBranch": "main",
|
||||
"isPrivate": false
|
||||
},
|
||||
"authentication": {
|
||||
"cliInstalled": false,
|
||||
"authenticated": false
|
||||
},
|
||||
"integration": {
|
||||
"enabled": false,
|
||||
"autoSync": false
|
||||
},
|
||||
"configuredAt": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
}
|
||||
EOF
|
||||
echo "✅ Created basic ccpm/github.json"
|
||||
fi
|
||||
else
|
||||
echo "✅ ccpm/github.json already exists"
|
||||
fi
|
||||
```
|
||||
|
||||
## 3. Setting up documentation
|
||||
|
||||
<!-- Create specs README -->
|
||||
```bash
|
||||
if [ ! -f "specs/README.md" ]; then
|
||||
cat > specs/README.md << 'EOF'
|
||||
# CCPM Specs Directory
|
||||
|
||||
This directory contains Product Requirements Documents (PRDs) and technical specifications for the project.
|
||||
|
||||
## Structure
|
||||
|
||||
- `prds/` - Product Requirements Documents
|
||||
- `technical/` - Technical specifications
|
||||
- `templates/` - Document templates
|
||||
|
||||
## Creating New PRDs
|
||||
|
||||
Use the CCPM command to create new PRDs:
|
||||
\`\`\`bash
|
||||
/pm prd-new
|
||||
\`\`\`
|
||||
|
||||
## PRD Format
|
||||
|
||||
PRDs should follow the standard format:
|
||||
- Executive Summary
|
||||
- Problem Statement
|
||||
- Success Metrics
|
||||
- User Stories
|
||||
- Technical Requirements
|
||||
- Acceptance Criteria
|
||||
EOF
|
||||
echo "✅ Created specs/README.md"
|
||||
else
|
||||
echo "✅ specs/README.md already exists"
|
||||
fi
|
||||
```
|
||||
|
||||
## 4. Validating installation
|
||||
|
||||
<!-- Validate configuration files -->
|
||||
```bash
|
||||
echo "🔍 Validating installation..."
|
||||
|
||||
# Check if all files were created successfully
|
||||
if [ -f "ccpm.config.json" ] && python3 -m json.tool ccpm.config.json >/dev/null 2>&1; then
|
||||
echo "✅ ccpm.config.json is valid JSON"
|
||||
else
|
||||
echo "❌ ccpm.config.json is missing or invalid"
|
||||
fi
|
||||
|
||||
if [ -f "ccpm/state.json" ] && python3 -m json.tool ccpm/state.json >/dev/null 2>&1; then
|
||||
echo "✅ state.json is valid JSON"
|
||||
else
|
||||
echo "❌ state.json is missing or invalid"
|
||||
fi
|
||||
|
||||
if [ -f "ccpm/github.json" ] && python3 -m json.tool ccpm/github.json >/dev/null 2>&1; then
|
||||
echo "✅ github.json is valid JSON"
|
||||
else
|
||||
echo "❌ github.json is missing or invalid"
|
||||
fi
|
||||
|
||||
# Check directories
|
||||
for dir in ccpm specs worktrees; do
|
||||
if [ -d "$dir" ]; then
|
||||
echo "✅ Directory $dir/ exists"
|
||||
else
|
||||
echo "❌ Directory $dir/ missing"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
📊 **Project initialized successfully!**
|
||||
|
||||
✅ **Created project structure**
|
||||
- ccpm/ - Local CCPM configuration and state
|
||||
- specs/ - Directory for PRDs and specifications
|
||||
- worktrees/ - Directory for Git worktrees
|
||||
|
||||
✅ **Generated configuration files**
|
||||
- ccpm.config.json - Main project configuration
|
||||
- ccpm/github.json - GitHub integration settings
|
||||
- ccpm/state.json - Current project state tracking
|
||||
|
||||
✅ **Set up GitHub integration**
|
||||
- Repository detection and configuration
|
||||
- GitHub CLI authentication check
|
||||
- Issue labels and workflows
|
||||
|
||||
🎯 **Next steps:**
|
||||
```bash
|
||||
/pm prd-new # Create your first PRD
|
||||
/pm status # Check project status
|
||||
/pm help # See all available commands
|
||||
```
|
||||
68
commands/pm-prd-new.md
Normal file
68
commands/pm-prd-new.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# /pm prd-new
|
||||
|
||||
Create a new Product Requirements Document (PRD).
|
||||
|
||||
This command guides you through creating a comprehensive PRD that can be parsed into GitHub issues and development epics.
|
||||
|
||||
## What it helps you create:
|
||||
|
||||
### 📋 PRD Structure
|
||||
1. **Project Overview**
|
||||
- Product name and description
|
||||
- Target users and use cases
|
||||
- Success metrics
|
||||
|
||||
2. **Feature Requirements**
|
||||
- User stories and acceptance criteria
|
||||
- Technical requirements
|
||||
- Design specifications
|
||||
|
||||
3. **Implementation Plan**
|
||||
- Priority ranking
|
||||
- Dependencies
|
||||
- Timeline estimates
|
||||
|
||||
4. **Success Metrics**
|
||||
- KPIs and OKRs
|
||||
- Performance criteria
|
||||
- Quality standards
|
||||
|
||||
## Usage:
|
||||
|
||||
```bash
|
||||
/pm prd-new # Interactive PRD creation
|
||||
/pm prd-new --template # Use PRD template
|
||||
/pm prd-new --name "My Feature" # Create with specific name
|
||||
```
|
||||
|
||||
## Interactive prompts:
|
||||
|
||||
The command will guide you through:
|
||||
- Product name and description
|
||||
- Target audience and user personas
|
||||
- Core features and user stories
|
||||
- Technical requirements and constraints
|
||||
- Success criteria and metrics
|
||||
- Timeline and milestones
|
||||
|
||||
## Example:
|
||||
|
||||
```bash
|
||||
/pm prd-new
|
||||
```
|
||||
|
||||
Output:
|
||||
```
|
||||
📝 Creating new PRD...
|
||||
|
||||
🏷️ Product name: User Authentication System
|
||||
📝 Description: Secure user login and registration
|
||||
👥 Target users: End users, administrators
|
||||
⭐ Key features: OAuth, 2FA, password reset
|
||||
🎯 Success metrics: 99.9% uptime, <2s login time
|
||||
|
||||
✅ PRD created: specs/user-authentication-system.md
|
||||
📊 Next steps:
|
||||
/pm prd-edit user-authentication-system # Edit details
|
||||
/pm prd-parse # Parse into issues
|
||||
```
|
||||
68
commands/pm-prd-parse.md
Normal file
68
commands/pm-prd-parse.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# /pm prd-parse
|
||||
|
||||
Parse a PRD (Product Requirements Document) into GitHub issues and development epics.
|
||||
|
||||
This command analyzes your PRD file and automatically creates structured GitHub issues organized by epics, complete with user stories, acceptance criteria, and implementation details.
|
||||
|
||||
## What it does:
|
||||
|
||||
### 📊 PRD Analysis
|
||||
- Parses PRD structure and content
|
||||
- Identifies features and user stories
|
||||
- Extracts acceptance criteria and requirements
|
||||
|
||||
### 🏗️ Epic Generation
|
||||
- Creates epics based on major features
|
||||
- Organizes issues under appropriate epics
|
||||
- Sets up milestones and dependencies
|
||||
|
||||
### 🎫 Issue Creation
|
||||
- Creates detailed GitHub issues
|
||||
- Includes user stories and acceptance criteria
|
||||
- Assigns labels, priorities, and estimates
|
||||
- Sets up issue dependencies
|
||||
|
||||
### 🔄 GitHub Integration
|
||||
- Creates issues in GitHub repository
|
||||
- Links related issues and epics
|
||||
- Updates project boards if configured
|
||||
|
||||
## Usage:
|
||||
|
||||
```bash
|
||||
/pm prd-parse # Parse latest PRD
|
||||
/pm prd-parse --name <prd-name> # Parse specific PRD
|
||||
/pm prd-parse --dry-run # Show what would be created
|
||||
/pm prd-parse --force # Re-parse existing PRD
|
||||
```
|
||||
|
||||
## Example:
|
||||
|
||||
```bash
|
||||
/pm prd-parse
|
||||
```
|
||||
|
||||
Output:
|
||||
```
|
||||
📊 Parsing PRD: user-authentication-system.md
|
||||
|
||||
✅ Found 3 major features
|
||||
✅ Extracted 12 user stories
|
||||
✅ Generated 15 issues
|
||||
|
||||
🏗️ Epics created:
|
||||
✅ user-authentication (8 issues)
|
||||
✅ user-profile (4 issues)
|
||||
✅ security-features (3 issues)
|
||||
|
||||
🎫 Issues created on GitHub:
|
||||
#145 Create login form UI
|
||||
#146 Implement OAuth2 integration
|
||||
#147 Add user registration flow
|
||||
...
|
||||
|
||||
📊 Summary:
|
||||
3 epics, 15 issues created
|
||||
Estimated effort: 3 weeks
|
||||
Ready for development with: /pm epic-start user-authentication
|
||||
```
|
||||
32
commands/pm-skills-list.md
Normal file
32
commands/pm-skills-list.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# /pm skills-list
|
||||
|
||||
List available skills in the CCPM plugin.
|
||||
|
||||
## Usage:
|
||||
|
||||
```bash
|
||||
/pm skills-list # List all available skills
|
||||
```
|
||||
|
||||
## Description:
|
||||
|
||||
This command displays all AI skills that are currently available in the CCPM plugin. Skills are specialized AI agents that can perform specific tasks.
|
||||
|
||||
## Available Skills:
|
||||
|
||||
- **general-purpose** - General-purpose agent for researching complex questions, searching for code, and executing multi-step tasks
|
||||
- **statusline-setup** - Configure the user's Claude Code status line setting
|
||||
- **output-style-setup** - Create and manage Claude Code output styles
|
||||
- **Explore** - Fast agent specialized for exploring codebases and finding files by patterns
|
||||
|
||||
## Examples:
|
||||
|
||||
```bash
|
||||
/pm skills-list # List all skills
|
||||
/pm help skills # Show more skills help
|
||||
```
|
||||
|
||||
## Related Commands:
|
||||
|
||||
- `/pm help skills` - Show help for skills management
|
||||
- `/pm agent-list` - List AI agent management commands
|
||||
56
commands/pm-status.js
Normal file
56
commands/pm-status.js
Normal file
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* /pm status - Show current project status
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
console.log('📊 CCPM Plugin Status:');
|
||||
|
||||
const ccpmDir = path.join(process.cwd(), 'ccpm');
|
||||
console.log(` Version: 1.0.5`);
|
||||
console.log(` Installation: ${fs.existsSync(ccpmDir) ? '✅ Installed' : '❌ Not found'}`);
|
||||
console.log(` Path: ${ccpmDir}`);
|
||||
|
||||
if (fs.existsSync(ccpmDir)) {
|
||||
const configPath = path.join(ccpmDir, 'ccpm.config.json');
|
||||
console.log(` Config: ${fs.existsSync(configPath) ? '✅ Found' : '⚠️ Not configured'}`);
|
||||
|
||||
// Check if GitHub is configured
|
||||
if (fs.existsSync(configPath)) {
|
||||
try {
|
||||
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
||||
console.log(` GitHub: ${config.github.enabled ? '✅ Configured' : '⚠️ Not configured'}`);
|
||||
if (config.github.enabled) {
|
||||
console.log(` Repository: ${config.github.owner}/${config.github.repo}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(` Config: ⚠️ Error reading config`);
|
||||
}
|
||||
}
|
||||
|
||||
// Check specs directory
|
||||
const specsDir = path.join(process.cwd(), 'specs');
|
||||
console.log(` Specs: ${fs.existsSync(specsDir) ? '✅ Found' : '⚠️ Not found'}`);
|
||||
|
||||
// Check worktrees directory
|
||||
const worktreesDir = path.join(process.cwd(), 'worktrees');
|
||||
console.log(` Worktrees: ${fs.existsSync(worktreesDir) ? '✅ Found' : '⚠️ Not found'}`);
|
||||
|
||||
// Check for PRDs
|
||||
if (fs.existsSync(specsDir)) {
|
||||
try {
|
||||
const prdFiles = fs.readdirSync(specsDir).filter(file => file.endsWith('.md'));
|
||||
console.log(` PRDs: ${prdFiles.length} found`);
|
||||
} catch (error) {
|
||||
console.log(` PRDs: ⚠️ Error reading specs`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\n🎯 Quick Start:');
|
||||
console.log(' /pm help - Show all available commands');
|
||||
console.log(' /pm prd-new - Create your first PRD');
|
||||
console.log(' /pm epic-list - List all epics');
|
||||
186
commands/pm-status.md
Normal file
186
commands/pm-status.md
Normal file
@@ -0,0 +1,186 @@
|
||||
# /pm status
|
||||
|
||||
Show current project status and overview.
|
||||
|
||||
This command displays the current state of your CCPM project, including active epics, issues, PRDs, and overall progress.
|
||||
|
||||
---
|
||||
|
||||
📊 **CCPM Project Status**
|
||||
|
||||
<!-- Check if CCPM is initialized -->
|
||||
```bash
|
||||
if [ ! -f "ccpm.config.json" ]; then
|
||||
echo "❌ CCPM not initialized in this project"
|
||||
echo "💡 Run '/pm init' to get started"
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
<!-- Load configuration and show project overview -->
|
||||
```bash
|
||||
echo "🏗️ Project: $(python3 -c "import json; print(json.load(open('ccpm.config.json'))['project']['name'])" 2>/dev/null || echo 'Unknown')"
|
||||
|
||||
# Get repository info
|
||||
REPO_URL=$(python3 -c "import json; data=json.load(open('ccpm.config.json')); print(data['project']['repository']['url'] if data['project'].get('repository') and data['project']['repository'].get('url') else 'Not configured')" 2>/dev/null || echo 'Not configured')
|
||||
if [ "$REPO_URL" != "Not configured" ]; then
|
||||
echo "📍 Repository: $REPO_URL"
|
||||
else
|
||||
echo "📍 Repository: Not configured"
|
||||
fi
|
||||
|
||||
# Check GitHub integration
|
||||
if [ -f "ccpm/github.json" ]; then
|
||||
GITHUB_ENABLED=$(python3 -c "import json; print(json.load(open('ccpm/github.json')).get('integration', {}).get('enabled', False))" 2>/dev/null || echo "False")
|
||||
if [ "$GITHUB_ENABLED" = "True" ]; then
|
||||
echo "🔗 GitHub: ✅ Connected"
|
||||
else
|
||||
echo "🔗 GitHub: ⚠️ Not configured"
|
||||
fi
|
||||
else
|
||||
echo "🔗 GitHub: ❌ Not set up"
|
||||
fi
|
||||
```
|
||||
|
||||
<!-- Show project statistics -->
|
||||
```bash
|
||||
if [ -f "ccpm/state.json" ]; then
|
||||
echo ""
|
||||
echo "📈 Project Statistics:"
|
||||
|
||||
# Read stats from state file
|
||||
python3 -c "
|
||||
import json
|
||||
try:
|
||||
data = json.load(open('ccpm/state.json'))
|
||||
stats = data.get('stats', {})
|
||||
print(f' 📋 Total Epics: {stats.get("totalEpics", 0)}')
|
||||
print(f' ✅ Completed Epics: {stats.get("completedEpics", 0)}')
|
||||
print(f' 🎫 Total Issues: {stats.get("totalIssues", 0)}')
|
||||
print(f' ✅ Completed Issues: {stats.get("completedIssues", 0)}')
|
||||
|
||||
# Calculate progress
|
||||
total = stats.get('totalEpics', 0)
|
||||
completed = stats.get('completedEpics', 0)
|
||||
if total > 0:
|
||||
progress = int((completed / total) * 100)
|
||||
print(f' 📊 Progress: {progress}% complete')
|
||||
else:
|
||||
print(f' 📊 Progress: Not started')
|
||||
|
||||
# Show current status
|
||||
project_status = data.get('project', {}).get('status', 'unknown')
|
||||
print(f' 🎯 Status: {project_status}')
|
||||
|
||||
except Exception as e:
|
||||
print(f' ⚠️ Could not read statistics: {e}')
|
||||
"
|
||||
else
|
||||
echo "⚠️ State file not found"
|
||||
fi
|
||||
```
|
||||
|
||||
<!-- Show active worktrees -->
|
||||
```bash
|
||||
echo ""
|
||||
echo "🌳 Git Status:"
|
||||
|
||||
# Current branch
|
||||
CURRENT_BRANCH=$(git branch --show-current 2>/dev/null || echo "Not in git repository")
|
||||
echo " 📍 Current Branch: $CURRENT_BRANCH"
|
||||
|
||||
# Git status
|
||||
if git rev-parse --git-dir >/dev/null 2>&1; then
|
||||
if [ -z "$(git status --porcelain)" ]; then
|
||||
echo " ✅ Working Directory: Clean"
|
||||
else
|
||||
CHANGED_FILES=$(git status --porcelain | wc -l | tr -d ' ')
|
||||
echo " 🔄 Working Directory: $CHANGED_FILES files changed"
|
||||
fi
|
||||
else
|
||||
echo " ⚠️ Not a git repository"
|
||||
fi
|
||||
|
||||
# Worktrees
|
||||
if [ -d "worktrees" ]; then
|
||||
WORKTREE_COUNT=$(find worktrees -maxdepth 1 -type d 2>/dev/null | wc -l | tr -d ' ')
|
||||
WORKTREE_COUNT=$((WORKTREE_COUNT - 1)) # Subtract 1 for the worktrees directory itself
|
||||
if [ $WORKTREE_COUNT -gt 0 ]; then
|
||||
echo " 🌲 Active Worktrees: $WORKTREE_COUNT"
|
||||
else
|
||||
echo " 🌲 Active Worktrees: None"
|
||||
fi
|
||||
else
|
||||
echo " 🌲 Active Worktrees: Directory not found"
|
||||
fi
|
||||
```
|
||||
|
||||
<!-- Show directory structure -->
|
||||
```bash
|
||||
echo ""
|
||||
echo "📁 CCPM Directory Structure:"
|
||||
|
||||
for dir in ccpm specs worktrees; do
|
||||
if [ -d "$dir" ]; then
|
||||
ITEM_COUNT=$(find "$dir" -type f 2>/dev/null | wc -l | tr -d ' ')
|
||||
echo " ✅ $dir/ ($ITEM_COUNT files)"
|
||||
else
|
||||
echo " ❌ $dir/ (missing)"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
<!-- Show configuration files status -->
|
||||
```bash
|
||||
echo ""
|
||||
echo "⚙️ Configuration Files:"
|
||||
|
||||
for config_file in ccpm.config.json ccpm/state.json ccpm/github.json; do
|
||||
if [ -f "$config_file" ]; then
|
||||
if python3 -m json.tool "$config_file" >/dev/null 2>&1; then
|
||||
echo " ✅ $config_file (valid JSON)"
|
||||
else
|
||||
echo " ⚠️ $config_file (invalid JSON)"
|
||||
fi
|
||||
else
|
||||
echo " ❌ $config_file (missing)"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
<!-- Show recent activity -->
|
||||
```bash
|
||||
echo ""
|
||||
echo "🕐 Recent Activity:"
|
||||
|
||||
if [ -f "ccpm/state.json" ]; then
|
||||
LAST_ACTIVITY=$(python3 -c "
|
||||
import json
|
||||
try:
|
||||
data = json.load(open('ccpm/state.json'))
|
||||
last_activity = data.get('lastActivity', '')
|
||||
if last_activity:
|
||||
print(last_activity)
|
||||
else:
|
||||
print('No activity recorded')
|
||||
except:
|
||||
print('Could not read activity')
|
||||
" 2>/dev/null || echo "Unknown")
|
||||
|
||||
echo " 📅 Last Activity: $LAST_ACTIVITY"
|
||||
else
|
||||
echo " 📅 Last Activity: Unknown"
|
||||
fi
|
||||
|
||||
# Show current time
|
||||
echo " 🕐 Current Time: $(date)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
💡 **Quick Actions:**
|
||||
```bash
|
||||
/pm prd-new # Create a new PRD
|
||||
/pm epic-start <name> # Start working on an epic
|
||||
/pm help # Show all available commands
|
||||
```
|
||||
78
commands/pm.md
Normal file
78
commands/pm.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# CCPM - Claude Code Project Management
|
||||
|
||||
Complete project management workflow for spec-driven development, GitHub issues, Git worktrees, and parallel AI agents.
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. Initialize CCPM in your project:
|
||||
```bash
|
||||
/pm init
|
||||
```
|
||||
|
||||
2. Create your first PRD:
|
||||
```bash
|
||||
/pm prd-new
|
||||
```
|
||||
|
||||
3. Parse PRD into issues:
|
||||
```bash
|
||||
/pm prd-parse
|
||||
```
|
||||
|
||||
4. Start working:
|
||||
```bash
|
||||
/pm epic-start <epic-name>
|
||||
```
|
||||
|
||||
## Available Commands
|
||||
|
||||
### 🔧 Setup & Configuration
|
||||
- `/pm init` - Initialize CCPM in current project
|
||||
- `/pm help` - Show all available commands
|
||||
- `/pm status` - Show current project status
|
||||
- `/pm validate` - Validate project configuration
|
||||
- `/pm sync` - Sync with GitHub issues
|
||||
|
||||
### 📄 PRD (Product Requirements Document) Management
|
||||
- `/pm prd-new` - Create new PRD
|
||||
- `/pm prd-list` - List all PRDs
|
||||
- `/pm prd-status` - Show PRD status
|
||||
- `/pm prd-edit <name>` - Edit existing PRD
|
||||
- `/pm prd-parse` - Parse PRD into GitHub issues
|
||||
|
||||
### 🏗️ Epic Management
|
||||
- `/pm epic-list` - List all epics
|
||||
- `/pm epic-show <name>` - Show epic details
|
||||
- `/pm epic-start <name>` - Start working on epic
|
||||
- `/pm epic-start-worktree <name>` - Start epic in Git worktree
|
||||
- `/pm epic-status` - Show epic status
|
||||
- `/pm epic-edit <name>` - Edit epic details
|
||||
- `/pm epic-decompose <name>` - Decompose epic into issues
|
||||
- `/pm epic-merge <name>` - Merge completed epic
|
||||
- `/pm epic-close <name>` - Close epic
|
||||
- `/pm epic-oneshot <name>` - Complete epic in one go
|
||||
- `/pm epic-refresh <name>` - Refresh epic with latest changes
|
||||
- `/pm epic-sync` - Sync all epics with GitHub
|
||||
|
||||
### 🎫 Issue Management
|
||||
- `/pm issue-list` - List all issues (filtered by status)
|
||||
- `/pm issue-show <number>` - Show issue details
|
||||
- `/pm issue-create` - Create new issue
|
||||
- `/pm issue-edit <number>` - Edit existing issue
|
||||
- `/pm issue-assign <number> <user>` - Assign issue to user
|
||||
- `/pm issue-close <number>` - Close issue
|
||||
- `/pm issue-sync` - Sync issues with GitHub
|
||||
|
||||
### 🌳 Git Worktree Management
|
||||
- `/pm worktree-create <branch>` - Create new Git worktree
|
||||
- `/pm worktree-list` - List all worktrees
|
||||
- `/pm worktree-remove <branch>` - Remove Git worktree
|
||||
- `/pm worktree-switch <branch>` - Switch to worktree
|
||||
|
||||
### 🤖 AI Agent Management
|
||||
- `/pm agent-start <task>` - Start AI agent for task
|
||||
- `/pm agent-list` - List running agents
|
||||
- `/pm agent-stop <id>` - Stop running agent
|
||||
- `/pm agent-status` - Show agent status
|
||||
|
||||
Use `/pm help <command>` for detailed help on any specific command.
|
||||
Reference in New Issue
Block a user