commit 8733af3ef7361c1af6c690f0c0bd021db8db7a29 Author: Zhongwei Li Date: Sat Nov 29 18:50:29 2025 +0800 Initial commit diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..e0ef9b3 --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,15 @@ +{ + "name": "ccpm", + "description": "Complete project management workflow for Claude Code with spec-driven development, GitHub issues, Git worktrees, and parallel AI agents", + "version": "0.0.0-2025.11.28", + "author": { + "name": "Jefferson Nunn", + "email": "contact@jeffersonnunn.com" + }, + "skills": [ + "./skills" + ], + "commands": [ + "./commands" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..3b34e40 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# ccpm + +Complete project management workflow for Claude Code with spec-driven development, GitHub issues, Git worktrees, and parallel AI agents diff --git a/commands/pm-epic-start.md b/commands/pm-epic-start.md new file mode 100644 index 0000000..c1ba908 --- /dev/null +++ b/commands/pm-epic-start.md @@ -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 # Start epic with default setup +/pm epic-start --worktree # Create Git worktree +/pm epic-start --agents # Setup AI agents +/pm epic-start --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 +``` \ No newline at end of file diff --git a/commands/pm-help.js b/commands/pm-help.js new file mode 100644 index 0000000..60cd9e2 --- /dev/null +++ b/commands/pm-help.js @@ -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 '); +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 ` for detailed help on any specific command.'); \ No newline at end of file diff --git a/commands/pm-help.md b/commands/pm-help.md new file mode 100644 index 0000000..b199921 --- /dev/null +++ b/commands/pm-help.md @@ -0,0 +1,31 @@ +# /pm help + +Show help for CCPM commands. + +## Usage: + +```bash +/pm help # Show all available commands +/pm help # Show help for specific command +/pm help # 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 +``` \ No newline at end of file diff --git a/commands/pm-init.js b/commands/pm-init.js new file mode 100644 index 0000000..7596ffc --- /dev/null +++ b/commands/pm-init.js @@ -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'); +} \ No newline at end of file diff --git a/commands/pm-init.md b/commands/pm-init.md new file mode 100644 index 0000000..97cddd6 --- /dev/null +++ b/commands/pm-init.md @@ -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 + + +```bash +mkdir -p ccpm specs worktrees +``` + +โœ… Created directory structure + +## 2. Setting up configuration + + +```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 +``` + + +```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 +``` + + +```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 + + +```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 + + +```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 +``` \ No newline at end of file diff --git a/commands/pm-prd-new.md b/commands/pm-prd-new.md new file mode 100644 index 0000000..d0114b9 --- /dev/null +++ b/commands/pm-prd-new.md @@ -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 +``` \ No newline at end of file diff --git a/commands/pm-prd-parse.md b/commands/pm-prd-parse.md new file mode 100644 index 0000000..ecee691 --- /dev/null +++ b/commands/pm-prd-parse.md @@ -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 # 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 +``` \ No newline at end of file diff --git a/commands/pm-skills-list.md b/commands/pm-skills-list.md new file mode 100644 index 0000000..dfaff31 --- /dev/null +++ b/commands/pm-skills-list.md @@ -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 \ No newline at end of file diff --git a/commands/pm-status.js b/commands/pm-status.js new file mode 100644 index 0000000..5bd304b --- /dev/null +++ b/commands/pm-status.js @@ -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'); \ No newline at end of file diff --git a/commands/pm-status.md b/commands/pm-status.md new file mode 100644 index 0000000..ef84669 --- /dev/null +++ b/commands/pm-status.md @@ -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** + + +```bash +if [ ! -f "ccpm.config.json" ]; then + echo "โŒ CCPM not initialized in this project" + echo "๐Ÿ’ก Run '/pm init' to get started" + exit 1 +fi +``` + + +```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 +``` + + +```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 +``` + + +```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 +``` + + +```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 +``` + + +```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 +``` + + +```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 # Start working on an epic +/pm help # Show all available commands +``` \ No newline at end of file diff --git a/commands/pm.md b/commands/pm.md new file mode 100644 index 0000000..7fbb5e4 --- /dev/null +++ b/commands/pm.md @@ -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 + ``` + +## 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 ` - Edit existing PRD +- `/pm prd-parse` - Parse PRD into GitHub issues + +### ๐Ÿ—๏ธ Epic Management +- `/pm epic-list` - List all epics +- `/pm epic-show ` - Show epic details +- `/pm epic-start ` - Start working on epic +- `/pm epic-start-worktree ` - Start epic in Git worktree +- `/pm epic-status` - Show epic status +- `/pm epic-edit ` - Edit epic details +- `/pm epic-decompose ` - Decompose epic into issues +- `/pm epic-merge ` - Merge completed epic +- `/pm epic-close ` - Close epic +- `/pm epic-oneshot ` - Complete epic in one go +- `/pm epic-refresh ` - 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 ` - Show issue details +- `/pm issue-create` - Create new issue +- `/pm issue-edit ` - Edit existing issue +- `/pm issue-assign ` - Assign issue to user +- `/pm issue-close ` - Close issue +- `/pm issue-sync` - Sync issues with GitHub + +### ๐ŸŒณ Git Worktree Management +- `/pm worktree-create ` - Create new Git worktree +- `/pm worktree-list` - List all worktrees +- `/pm worktree-remove ` - Remove Git worktree +- `/pm worktree-switch ` - Switch to worktree + +### ๐Ÿค– AI Agent Management +- `/pm agent-start ` - Start AI agent for task +- `/pm agent-list` - List running agents +- `/pm agent-stop ` - Stop running agent +- `/pm agent-status` - Show agent status + +Use `/pm help ` for detailed help on any specific command. \ No newline at end of file diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..e042593 --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,101 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:jeffersonwarrior/ccpm:", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "ade8b987f6adc9bcf13481be1c2631e88130d70f", + "treeHash": "cffae9933e575314e0c919926a23557baac6b1ed7995cc7bc758853be3808cbb", + "generatedAt": "2025-11-28T10:18:00.578954Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "ccpm", + "description": "Complete project management workflow for Claude Code with spec-driven development, GitHub issues, Git worktrees, and parallel AI agents", + "version": null + }, + "content": { + "files": [ + { + "path": "README.md", + "sha256": "f037ae13c633a7480d8cf7362d6c572f96dfe194c5549469579f9d5ac0b76a2e" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "bcab63006a4bf84b90d5229fcf380da350a2fcd4d5dd55be6e4728cfcebc0210" + }, + { + "path": "commands/pm-prd-new.md", + "sha256": "c2c435c6e21c14b4ba5c86232800d5ffc8803233555aae33c6a1d37c92fc0ea5" + }, + { + "path": "commands/pm-status.md", + "sha256": "5510de9f2e52b851710d8300f80084decb6dbaa4ecaf9c8bbdc7ac556e811611" + }, + { + "path": "commands/pm-prd-parse.md", + "sha256": "287f51ec093c4b8c8e91c0a72ccddf7c5713b7ea98ca02bb63a7603738eb87cd" + }, + { + "path": "commands/pm-init.js", + "sha256": "6756655a56fcfd298852d9556fec963fecf9305f035a155d092ff9e6372e4280" + }, + { + "path": "commands/pm-help.js", + "sha256": "92cb555b1fb21257cb52b3435a1a2f33abe25c85c7edefb9a4cd8cfaacfc1ad9" + }, + { + "path": "commands/pm-init.md", + "sha256": "0019f136c25e99151f125cf50103fb03337ecb20afbd7681dff8dc8b9f18eef5" + }, + { + "path": "commands/pm-epic-start.md", + "sha256": "a5f5c328d2c93999df62459f8a22287517be5ba61aeba33d73248896cf198599" + }, + { + "path": "commands/pm-help.md", + "sha256": "5fc79ac80001c2ff9ca0eb058215f94edae29db23961313b04700ba1f4345019" + }, + { + "path": "commands/pm-skills-list.md", + "sha256": "ac2438c7e28cfba4c0bc3d940e2632d622e824244d04b0514a06628e7c6ab8e3" + }, + { + "path": "commands/pm.md", + "sha256": "c1bccbc95f2ed6e2d3c1afe24f533d49e6dc5e25df7df463f039751739576c8c" + }, + { + "path": "commands/pm-status.js", + "sha256": "cd1404d33943665c5b9f54850ca343cc389be1a4e8c23ebefb75be8d693ec6d0" + }, + { + "path": "skills/general-purpose/skill.json", + "sha256": "57485bd1a6113de53b97dd622ca7972e8db33f9e6e60001be2c359dd2e451d79" + }, + { + "path": "skills/statusline-setup/skill.json", + "sha256": "0316a47287a66e30e5db16f35aa1d068db227c71db7b9b358236ea2d8f030279" + }, + { + "path": "skills/Explore/skill.json", + "sha256": "c4f5eae16bce263cc2053b57830918d220b2c417272019523db3b0b6d1786bee" + }, + { + "path": "skills/output-style-setup/skill.json", + "sha256": "4a4f9854cfdc6b3d6f6c84d27dc966d1b3a59879078646d08727555222d37bc0" + } + ], + "dirSha256": "cffae9933e575314e0c919926a23557baac6b1ed7995cc7bc758853be3808cbb" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file diff --git a/skills/Explore/skill.json b/skills/Explore/skill.json new file mode 100644 index 0000000..8c8e0ff --- /dev/null +++ b/skills/Explore/skill.json @@ -0,0 +1,5 @@ +{ + "name": "Explore", + "description": "Fast agent specialized for exploring codebases. Use this when you need to quickly find files by patterns (eg. \"src/components/**/*.tsx\"), search code for keywords (eg. \"API endpoints\"), or answer questions about the codebase (eg. \"how do API endpoints work?\"). When calling this agent, specify the desired thoroughness level: \"quick\" for basic searches, \"medium\" for moderate exploration, or \"very thorough\" for comprehensive analysis across multiple locations and naming conventions.", + "tools": ["Glob", "Grep", "Read", "Bash"] +} \ No newline at end of file diff --git a/skills/general-purpose/skill.json b/skills/general-purpose/skill.json new file mode 100644 index 0000000..28dce4e --- /dev/null +++ b/skills/general-purpose/skill.json @@ -0,0 +1,5 @@ +{ + "name": "general-purpose", + "description": "General-purpose agent for researching complex questions, searching for code, and executing multi-step tasks autonomously.", + "tools": "*" +} \ No newline at end of file diff --git a/skills/output-style-setup/skill.json b/skills/output-style-setup/skill.json new file mode 100644 index 0000000..086630c --- /dev/null +++ b/skills/output-style-setup/skill.json @@ -0,0 +1,5 @@ +{ + "name": "output-style-setup", + "description": "Use this agent to create a Claude Code output style.", + "tools": ["Read", "Write", "Edit", "Glob", "Grep"] +} \ No newline at end of file diff --git a/skills/statusline-setup/skill.json b/skills/statusline-setup/skill.json new file mode 100644 index 0000000..402cfb1 --- /dev/null +++ b/skills/statusline-setup/skill.json @@ -0,0 +1,5 @@ +{ + "name": "statusline-setup", + "description": "Use this agent to configure the user's Claude Code status line setting.", + "tools": ["Read", "Edit"] +} \ No newline at end of file