From 00f6f6b79e669e3676fd3c105c2e95b4de587c35 Mon Sep 17 00:00:00 2001 From: kevin rajan Date: Sun, 2 Nov 2025 22:14:08 -0600 Subject: [PATCH 1/7] fix: Rewrite discovery mode command to use Claude Code Task tool MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated discovery_mode_command.md to be a proper Claude Code slash command that: - Uses Task tool to spawn 15 agents in parallel (in ONE message) - No external scripts or npm packages required - Executes entirely within Claude Code session - Clear agent instructions for autonomous research pipeline Inspired by Sakana AI's "The AI Scientist" system with parallel multi-agent coordination for literature review, hypothesis generation, experiments, analysis, and paper writing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../automation/discovery_mode_command.md | 881 ++---------------- 1 file changed, 92 insertions(+), 789 deletions(-) diff --git a/.claude/commands/automation/discovery_mode_command.md b/.claude/commands/automation/discovery_mode_command.md index 7811f1a..9ffbeeb 100644 --- a/.claude/commands/automation/discovery_mode_command.md +++ b/.claude/commands/automation/discovery_mode_command.md @@ -1,810 +1,113 @@ -# Discovery Mode: Autonomous Scientific Research System +# Discovery Mode: Autonomous Scientific Research -## Command Structure +Execute autonomous scientific discovery using parallel multi-agent coordination inspired by Sakana AI's "The AI Scientist" system. -```javascript -claude-flow discovery-mode --config discovery.yaml --output ./research-outputs -``` - -## Core Discovery Mode Configuration - -```yaml -# discovery.yaml -discovery_mode: - name: "Autonomous Scientific Discovery System" - version: "1.0.0" - inspired_by: ["Sakana AI Scientist", "AlphaEvolve", "Voyager", "Eureka"] - - orchestration: - mode: "hive_mind" - lead_agent: "Discovery Orchestrator" - swarm_size: 8-16 - parallel_execution: true - memory_persistence: true - checkpoint_interval: 300 - - research_pipeline: - stages: - - ideation - - literature_review - - hypothesis_generation - - experiment_design - - implementation - - evaluation - - paper_writing - - peer_review_simulation - - agents: - discovery_orchestrator: - model: "claude-opus-4-1" - role: "Lead research coordinator" - capabilities: - - research_planning - - hypothesis_generation - - resource_allocation - - quality_control - - literature_researcher: - model: "claude-sonnet-4" - count: 3 - role: "Deep literature analysis" - capabilities: - - arxiv_search - - paper_analysis - - citation_tracking - - knowledge_synthesis - - hypothesis_generator: - model: "claude-sonnet-4" - count: 2 - role: "Novel hypothesis creation" - capabilities: - - pattern_recognition - - cross_domain_insights - - novelty_assessment - - experiment_designer: - model: "claude-sonnet-4" - count: 2 - role: "Experimental methodology" - capabilities: - - protocol_design - - control_setup - - statistical_planning - - implementation_specialist: - model: "claude-sonnet-4" - count: 4 - role: "Code implementation and testing" - capabilities: - - code_generation - - debugging - - optimization - - benchmarking - - data_analyst: - model: "claude-sonnet-4" - count: 2 - role: "Results analysis" - capabilities: - - statistical_analysis - - visualization - - pattern_detection - - paper_writer: - model: "claude-opus-4-1" - role: "Academic paper generation" - capabilities: - - latex_formatting - - scientific_writing - - figure_generation - - citation_management - - reviewer_simulator: - model: "claude-sonnet-4" - count: 3 - role: "Peer review simulation" - capabilities: - - critical_analysis - - methodology_review - - novelty_assessment - -## Implementation Script - -```python -#!/usr/bin/env python3 -""" -Discovery Mode: Autonomous Scientific Research System -Integrates Claude Flow's hive mind with Sakana AI-inspired research workflows -""" +## Usage -import asyncio -import json -from typing import Dict, List, Any -from dataclasses import dataclass -from datetime import datetime -import yaml -import sqlite3 -from pathlib import Path +``` +/automation:discovery_mode_command "research question" +``` -@dataclass -class ResearchProject: - """Represents a complete research project lifecycle""" - id: str - title: str - domain: str - hypothesis: str - methodology: Dict[str, Any] - experiments: List[Dict] - results: Dict[str, Any] - paper_draft: str - status: str - created_at: datetime - -class DiscoveryMode: - """ - Main orchestrator for autonomous scientific discovery - Implements recursive task decomposition similar to AlphaEvolve - """ - - def __init__(self, config_path: str): - self.config = self.load_config(config_path) - self.memory_db = self.initialize_memory() - self.skill_library = SkillLibrary() - self.swarm = SwarmOrchestrator(self.config['agents']) - self.mcp_servers = self.initialize_mcp_servers() - - def load_config(self, path: str) -> Dict: - """Load discovery mode configuration""" - with open(path, 'r') as f: - return yaml.safe_load(f) - - def initialize_memory(self) -> sqlite3.Connection: - """Initialize persistent memory database""" - conn = sqlite3.connect('.swarm/discovery_memory.db') - conn.execute(''' - CREATE TABLE IF NOT EXISTS research_history ( - id TEXT PRIMARY KEY, - project_data TEXT, - timestamp DATETIME, - success_rate REAL, - citations_generated INTEGER - ) - ''') - conn.execute(''' - CREATE TABLE IF NOT EXISTS skill_library ( - skill_id TEXT PRIMARY KEY, - skill_type TEXT, - implementation TEXT, - success_count INTEGER, - usage_count INTEGER, - last_improved DATETIME - ) - ''') - return conn - - def initialize_mcp_servers(self) -> Dict: - """Initialize MCP servers for tool access""" - return { - 'arxiv': MCPServer('arxiv', port=3001), - 'github': MCPServer('github', port=3002), - 'compute': MCPServer('compute_cluster', port=3003), - 'visualization': MCPServer('plotting', port=3004), - 'latex': MCPServer('latex_compiler', port=3005) - } - - async def discover(self, research_prompt: str) -> ResearchProject: - """ - Main discovery pipeline - orchestrates the entire research process - """ - print(f"🔬 Initiating Discovery Mode for: {research_prompt}") - - # Stage 1: Ideation and Literature Review - research_context = await self.deep_research_phase(research_prompt) - - # Stage 2: Hypothesis Generation - hypotheses = await self.generate_hypotheses(research_context) - selected_hypothesis = await self.evaluate_hypotheses(hypotheses) - - # Stage 3: Recursive Task Decomposition (AlphaEvolve-style) - task_tree = await self.decompose_research_task(selected_hypothesis) - - # Stage 4: Parallel Experiment Execution - experiment_results = await self.execute_experiments_swarm(task_tree) - - # Stage 5: Analysis and Synthesis - analysis = await self.analyze_results(experiment_results) - - # Stage 6: Paper Generation - paper = await self.generate_paper( - hypothesis=selected_hypothesis, - experiments=experiment_results, - analysis=analysis - ) - - # Stage 7: Self-Review and Improvement - reviewed_paper = await self.peer_review_simulation(paper) - - # Stage 8: Skill Library Update (Voyager-style) - await self.update_skill_library(task_tree, experiment_results) - - return ResearchProject( - id=self.generate_project_id(), - title=paper['title'], - domain=research_context['domain'], - hypothesis=selected_hypothesis, - methodology=task_tree, - experiments=experiment_results, - results=analysis, - paper_draft=reviewed_paper, - status='completed', - created_at=datetime.now() - ) - - async def deep_research_phase(self, prompt: str) -> Dict: - """ - Conducts deep research using multiple parallel agents - Similar to Claude's Research feature but with scientific focus - """ - research_agents = [] - - # Spawn specialized research agents - for i in range(3): - agent = self.swarm.spawn_agent( - 'literature_researcher', - task=f"Research aspect {i+1} of: {prompt}" - ) - research_agents.append(agent) - - # Parallel literature search - results = await asyncio.gather(*[ - agent.search_arxiv(prompt), - agent.search_github(prompt), - agent.search_papers_with_code(prompt) - ] for agent in research_agents) - - # Synthesize findings - context = await self.swarm.lead_agent.synthesize_research(results) - - return { - 'domain': self.identify_domain(prompt), - 'existing_work': context['papers'], - 'gaps': context['research_gaps'], - 'datasets': context['available_datasets'], - 'benchmarks': context['relevant_benchmarks'] - } - - async def generate_hypotheses(self, context: Dict) -> List[str]: - """ - Generate novel hypotheses based on research gaps - Uses LLM creativity similar to Eureka's reward design - """ - hypothesis_agents = [] - - for i in range(2): - agent = self.swarm.spawn_agent( - 'hypothesis_generator', - temperature=0.8, # Higher creativity - task=f"Generate novel hypotheses from: {context['gaps']}" - ) - hypothesis_agents.append(agent) - - # Generate diverse hypotheses - hypotheses = await asyncio.gather(*[ - agent.generate_hypothesis(context) - for agent in hypothesis_agents - ]) - - # Cross-pollinate ideas - refined = await self.swarm.lead_agent.refine_hypotheses( - hypotheses, - context['existing_work'] - ) - - return refined - - async def decompose_research_task(self, hypothesis: str) -> Dict: - """ - Recursive task decomposition inspired by AlphaEvolve - Breaks down complex research into manageable subtasks - """ - decomposer = TaskDecomposer(self.skill_library) - - task_tree = await decomposer.decompose( - root_task=f"Test hypothesis: {hypothesis}", - max_depth=4, - branching_factor=3 - ) - - # Optimize task allocation - optimized_tree = await self.optimize_task_allocation(task_tree) - - return optimized_tree - - async def execute_experiments_swarm(self, task_tree: Dict) -> List[Dict]: - """ - Execute experiments using swarm intelligence - Multiple agents work on different aspects in parallel - """ - implementation_agents = [] - - for task in task_tree['leaf_tasks']: - agent = self.swarm.spawn_agent( - 'implementation_specialist', - task=task, - resources=self.allocate_resources(task) - ) - implementation_agents.append(agent) - - # Parallel experiment execution - results = await asyncio.gather(*[ - agent.execute_experiment() - for agent in implementation_agents - ]) - - # Aggregate and validate results - validated = await self.validate_experiments(results) - - return validated - - async def analyze_results(self, experiments: List[Dict]) -> Dict: - """ - Statistical analysis and pattern detection - """ - analysts = [] - - for i in range(2): - agent = self.swarm.spawn_agent( - 'data_analyst', - task=f"Analyze experiment batch {i+1}" - ) - analysts.append(agent) - - analyses = await asyncio.gather(*[ - agent.analyze(experiments) - for agent in analysts - ]) - - # Meta-analysis - meta_analysis = await self.swarm.lead_agent.meta_analyze(analyses) - - return { - 'statistical_significance': meta_analysis['p_values'], - 'effect_sizes': meta_analysis['effect_sizes'], - 'patterns': meta_analysis['discovered_patterns'], - 'visualizations': meta_analysis['figures'] - } - - async def generate_paper( - self, - hypothesis: str, - experiments: List[Dict], - analysis: Dict - ) -> Dict: - """ - Generate complete research paper in LaTeX format - """ - writer = self.swarm.spawn_agent( - 'paper_writer', - task="Write comprehensive research paper" - ) - - paper_sections = await writer.generate_paper( - title=self.generate_title(hypothesis), - abstract=await writer.write_abstract(hypothesis, analysis), - introduction=await writer.write_introduction(hypothesis), - methods=await writer.write_methods(experiments), - results=await writer.write_results(analysis), - discussion=await writer.write_discussion(analysis), - conclusion=await writer.write_conclusion(hypothesis, analysis), - references=await writer.compile_references() - ) - - # Compile LaTeX - compiled_paper = await self.mcp_servers['latex'].compile(paper_sections) - - return compiled_paper - - async def peer_review_simulation(self, paper: Dict) -> str: - """ - Simulate peer review process with multiple reviewer agents - """ - reviewers = [] - - for i in range(3): - reviewer = self.swarm.spawn_agent( - 'reviewer_simulator', - persona=f"Reviewer {i+1} with expertise in {paper['domain']}" - ) - reviewers.append(reviewer) - - reviews = await asyncio.gather(*[ - reviewer.review_paper(paper) - for reviewer in reviewers - ]) - - # Address reviewer concerns - revised_paper = await self.address_reviews(paper, reviews) - - return revised_paper - - async def update_skill_library( - self, - task_tree: Dict, - results: List[Dict] - ): - """ - Update skill library with successful techniques - Implements Voyager-style continuous learning - """ - successful_skills = self.extract_successful_patterns( - task_tree, - results - ) - - for skill in successful_skills: - self.skill_library.add_skill( - skill_type=skill['type'], - implementation=skill['code'], - metadata={ - 'success_rate': skill['success_rate'], - 'domain': skill['domain'], - 'discovered_at': datetime.now() - } - ) - - # Prune unsuccessful skills - await self.skill_library.evolutionary_pruning() - - # Save to persistent memory - self.save_skill_updates() +## How It Works -class SwarmOrchestrator: - """ - Manages the hive mind of research agents - Implements Claude Flow-style distributed intelligence - """ - - def __init__(self, agent_config: Dict): - self.config = agent_config - self.agents = {} - self.queen = self.initialize_queen() - self.message_queue = asyncio.Queue() - - def initialize_queen(self): - """Initialize the Queen agent for hive coordination""" - return QueenAgent( - model='claude-opus-4-1', - role='Master Coordinator', - memory_limit=200000 - ) - - def spawn_agent(self, agent_type: str, **kwargs): - """Spawn a new specialized agent""" - config = self.config[agent_type] - agent = ResearchAgent( - agent_type=agent_type, - model=config['model'], - role=config['role'], - capabilities=config['capabilities'], - **kwargs - ) - self.agents[agent.id] = agent - return agent - - async def coordinate_swarm(self, task: str): - """Coordinate swarm activities through Queen agent""" - plan = await self.queen.create_execution_plan(task) - - # Distribute subtasks - for subtask in plan['subtasks']: - agent = self.select_best_agent(subtask) - await agent.assign_task(subtask) - - # Monitor and adapt - while not self.all_tasks_complete(): - status = await self.collect_status() - adaptations = await self.queen.adapt_strategy(status) - await self.apply_adaptations(adaptations) - await asyncio.sleep(1) - - return await self.collect_results() +When invoked, this command will spawn 15 specialized research agents in parallel using Claude Code's Task tool to: +1. Conduct literature review +2. Generate hypotheses +3. Design and execute experiments +4. Analyze results +5. Write a complete research paper -class SkillLibrary: - """ - Maintains a library of reusable research skills - Similar to Voyager's skill library but for research tasks - """ - - def __init__(self): - self.skills = {} - self.skill_graph = {} # Dependency graph - self.performance_history = {} - - def add_skill(self, skill_type: str, implementation: str, metadata: Dict): - """Add a new skill to the library""" - skill_id = f"{skill_type}_{datetime.now().timestamp()}" - - self.skills[skill_id] = { - 'type': skill_type, - 'implementation': implementation, - 'metadata': metadata, - 'usage_count': 0, - 'success_count': 0, - 'dependencies': self.extract_dependencies(implementation) - } - - self.update_skill_graph(skill_id) - - def get_relevant_skills(self, task: str) -> List[Dict]: - """Retrieve skills relevant to a given task""" - relevant = [] - - for skill_id, skill in self.skills.items(): - relevance = self.calculate_relevance(task, skill) - if relevance > 0.7: - relevant.append({ - 'id': skill_id, - 'skill': skill, - 'relevance': relevance - }) - - return sorted(relevant, key=lambda x: x['relevance'], reverse=True) - - async def evolutionary_pruning(self): - """ - Remove underperforming skills (evolutionary pressure) - Inspired by genetic algorithms - """ - performance_threshold = 0.3 - - skills_to_remove = [] - for skill_id, skill in self.skills.items(): - if skill['usage_count'] > 5: - success_rate = skill['success_count'] / skill['usage_count'] - if success_rate < performance_threshold: - skills_to_remove.append(skill_id) - - for skill_id in skills_to_remove: - del self.skills[skill_id] - - print(f"Pruned {len(skills_to_remove)} underperforming skills") +## Execution Instructions -class TaskDecomposer: - """ - Recursive task decomposition engine - Implements AlphaEvolve-style hierarchical planning - """ - - def __init__(self, skill_library: SkillLibrary): - self.skill_library = skill_library - - async def decompose( - self, - root_task: str, - max_depth: int = 4, - branching_factor: int = 3 - ) -> Dict: - """ - Recursively decompose a task into subtasks - """ - tree = { - 'root': root_task, - 'children': [], - 'leaf_tasks': [], - 'depth': 0 - } - - await self._decompose_recursive( - tree, - root_task, - 0, - max_depth, - branching_factor - ) - - return tree - - async def _decompose_recursive( - self, - tree: Dict, - task: str, - depth: int, - max_depth: int, - branching_factor: int - ): - """Recursive decomposition helper""" - if depth >= max_depth: - tree['leaf_tasks'].append(task) - return - - # Check if we can reuse existing skills - relevant_skills = self.skill_library.get_relevant_skills(task) - - if relevant_skills and relevant_skills[0]['relevance'] > 0.9: - # Reuse existing skill - tree['leaf_tasks'].append({ - 'task': task, - 'skill': relevant_skills[0]['id'] - }) - return - - # Decompose into subtasks - subtasks = await self.generate_subtasks(task, branching_factor) - - for subtask in subtasks: - child = { - 'task': subtask, - 'children': [], - 'depth': depth + 1 - } - tree['children'].append(child) - - await self._decompose_recursive( - child, - subtask, - depth + 1, - max_depth, - branching_factor - ) +Upon receiving a research prompt, **immediately spawn all 15 agents in parallel in ONE message**: -# Main execution -async def main(): - """Main entry point for Discovery Mode""" - import sys - - if len(sys.argv) < 2: - print("Usage: discovery_mode.py ''") - sys.exit(1) - - research_prompt = sys.argv[1] - - # Initialize Discovery Mode - discovery = DiscoveryMode('discovery.yaml') - - # Run autonomous discovery - project = await discovery.discover(research_prompt) - - # Save results - output_dir = Path('./research_outputs') / project.id - output_dir.mkdir(parents=True, exist_ok=True) - - # Save paper - with open(output_dir / 'paper.tex', 'w') as f: - f.write(project.paper_draft) - - # Save experiment data - with open(output_dir / 'experiments.json', 'w') as f: - json.dump(project.experiments, f, indent=2) - - # Save analysis - with open(output_dir / 'analysis.json', 'w') as f: - json.dump(project.results, f, indent=2) - - print(f"✅ Research completed! Results saved to: {output_dir}") - print(f"📄 Paper title: {project.title}") - print(f"🔬 Hypothesis tested: {project.hypothesis}") - -if __name__ == "__main__": - asyncio.run(main()) +```javascript +// Literature Review (3 agents) +Task("researcher", "Search for 15-20 recent papers on [topic]. Extract titles, authors, methods, results. Output JSON to docs/discovery/literature.json") +Task("researcher", "Identify research gaps from literature. Rate by novelty/feasibility/impact. Output to docs/discovery/gaps.json") +Task("researcher", "Analyze trends: emerging methods, future directions. Output to docs/discovery/trends.json") + +// Hypothesis Generation (2 agents) +Task("researcher", "Generate 5-10 novel hypotheses from research gaps. Include methodology and predictions. Output to docs/discovery/hypotheses.json") +Task("reviewer", "Evaluate hypotheses: score novelty/feasibility/impact (1-10). Rank and select top 3. Output to docs/discovery/hypothesis_eval.json") + +// Experiment Design (3 agents) +Task("system-architect", "Design experiment for top hypothesis: methodology, variables, procedures. Output to docs/discovery/experiment_design.md") +Task("coder", "Implement experiment in Python (numpy/pandas/scipy). Save to src/discovery/experiments/experiment.py") +Task("coder", "Create analysis script with statistical tests and visualizations. Save to src/discovery/analysis/analyze.py") + +// Execution & Analysis (2 agents) +Task("coder", "Execute experiment safely using Bash tool. Collect results. Save to docs/discovery/results/data.json") +Task("data_analyst", "Perform statistical analysis: hypothesis tests, effect sizes, confidence intervals, plots. Save to docs/discovery/results/analysis.json") + +// Paper Writing (3 agents) +Task("technical-writer", "Write paper Abstract and Introduction with academic citations. Save to docs/discovery/paper/01_intro.md") +Task("technical-writer", "Write Methods and Results sections with experimental details. Save to docs/discovery/paper/02_methods_results.md") +Task("technical-writer", "Write Discussion and Conclusion with interpretations and future work. Save to docs/discovery/paper/03_discussion.md") + +// Review & Validation (2 agents) +Task("reviewer", "Peer review: assess methodology, statistics, novelty. Rate and provide feedback. Save to docs/discovery/paper/review.md") +Task("reviewer", "Validate quality: completeness, reproducibility, citations. Save to docs/discovery/paper/validation.md") ``` -## Usage Examples +## After Agent Completion -### Example 1: Basic Discovery -```bash -claude-flow discovery-mode \ - --prompt "Investigate novel approaches to reduce hallucination in LLMs" \ - --output ./research/hallucination_study -``` +1. Wait for all 15 agents to finish +2. Read all generated files from docs/discovery/ +3. Combine paper sections into docs/discovery/paper/complete_paper.md +4. Generate LaTeX version at docs/discovery/paper/paper.tex +5. Present summary to user: -### Example 2: Domain-Specific Research -```bash -claude-flow discovery-mode \ - --prompt "Discover optimal reward shaping for robotic manipulation" \ - --domain robotics \ - --experiments 20 \ - --parallel-agents 16 ``` - -### Example 3: Theoretical Research -```bash -claude-flow discovery-mode \ - --prompt "Explore connections between transformer attention and cognitive neuroscience" \ - --mode theoretical \ - --literature-depth extensive +✅ **Discovery Mode Complete!** + +📊 **Research Summary**: +- **Topic**: [research question] +- **Key Finding**: [main result] +- **Significance**: [p-value, effect size] +- **Paper**: docs/discovery/paper/complete_paper.md + +📁 **Outputs**: +- Literature: 18 papers analyzed +- Hypotheses: 5 generated, top 1 tested +- Experiments: Code + results in src/discovery/ +- Paper: 8-page manuscript ready +- Review: 7/10 (Accept with revisions) ``` -## Integration with MCP Servers +## File Organization -```yaml -mcp_integration: - servers: - - name: arxiv_search - endpoint: localhost:3001 - capabilities: ["paper_search", "citation_graph"] - - - name: github_code - endpoint: localhost:3002 - capabilities: ["code_search", "implementation_examples"] - - - name: compute_cluster - endpoint: localhost:3003 - capabilities: ["gpu_allocation", "distributed_training"] - - - name: visualization - endpoint: localhost:3004 - capabilities: ["plotting", "figure_generation"] - - - name: latex_compiler - endpoint: localhost:3005 - capabilities: ["document_compilation", "bibliography_management"] ``` - -## Continuous Improvement Loop - -The system implements several learning mechanisms: - -1. **Skill Evolution** (Voyager-inspired) - - Successful experimental techniques are saved - - Skills improve through usage and refinement - - Underperforming skills are pruned - -2. **Hypothesis Refinement** (Eureka-inspired) - - LLM generates diverse hypotheses - - Best performers are evolved further - - Cross-domain insights are captured - -3. **Task Decomposition** (AlphaEvolve-inspired) - - Complex research broken into manageable tasks - - Parallel execution by specialized agents - - Recursive refinement of approach - -4. **Memory Persistence** - - Research history saved in SQLite - - Patterns extracted for future use - - Cross-project learning enabled - -## Performance Metrics - -Track system performance with these KPIs: - -```python -metrics = { - 'papers_generated': count, - 'novel_insights': significance_score, - 'experiment_success_rate': percentage, - 'skill_library_size': count, - 'average_research_time': hours, - 'peer_review_score': 1-10, - 'citation_potential': predicted_citations -} +docs/discovery/ +├── literature.json (papers) +├── gaps.json (research gaps) +├── trends.json (analysis) +├── hypotheses.json (generated) +├── hypothesis_eval.json (scored) +├── experiment_design.md (methodology) +├── results/ +│ ├── data.json (experimental data) +│ └── analysis.json (statistics) +└── paper/ + ├── 01_intro.md + ├── 02_methods_results.md + ├── 03_discussion.md + ├── complete_paper.md (combined) + ├── paper.tex (LaTeX) + ├── review.md (peer feedback) + └── validation.md (quality check) + +src/discovery/ +├── experiments/experiment.py +└── analysis/analyze.py ``` -## Limitations and Considerations - -1. **Computational Cost**: Full discovery mode uses ~15x tokens of standard chat -2. **Time Requirements**: Complete research cycle takes 2-6 hours -3. **Quality Variance**: Results depend on domain complexity -4. **Human Validation**: Critical findings require human review -5. **Ethical Review**: Generated research should undergo ethical assessment - -## Future Enhancements - -- **Multi-Modal Research**: Integrate image/video analysis -- **Physical Experiments**: Robot control for real-world testing -- **Collaborative Mode**: Multiple human researchers with AI swarm -- **Grant Writing**: Automated funding proposal generation -- **Patent Discovery**: Identify patentable innovations -- **Conference Submission**: Format for specific venues - -## Conclusion +## Critical Rules -This Discovery Mode command integrates the best aspects of: -- Sakana AI's autonomous scientific discovery -- Claude Flow's hive mind orchestration -- Voyager's skill library and continuous learning -- Eureka's evolutionary optimization -- AlphaEvolve's recursive task decomposition +1. **ALWAYS spawn all 15 agents in ONE message** - Parallel execution required +2. **Use Claude Code Task tool** - No external scripts +3. **Clear instructions** - Each agent gets complete context +4. **Wait for completion** - Don't synthesize until all agents finish +5. **Combine outputs** - Create final paper from all sections -The system enables autonomous research with human-in-the-loop validation, continuously improving through experience while maintaining scientific rigor. +This command executes **entirely within Claude Code** using the Task tool for parallel agent execution. From 4db42d55562707af055d5e4306e420fa6934d7a7 Mon Sep 17 00:00:00 2001 From: kevin rajan Date: Wed, 5 Nov 2025 14:04:17 -0600 Subject: [PATCH 2/7] feat: Add pixel-perfect UI recreation workflow with SuperClaude orchestration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename ui-analysis.md to uied-analysis.md for clarity - Update ui/design command with comprehensive 3-phase workflow - Integrate UIED analysis, style guide extraction, and parallel agent orchestration - Add 7 parallel agents for efficient analysis (color, typography, spacing, shadows, borders, components, structure) - Include ASCII layout checkpoint before HTML generation - Enable 2.8-3.6x performance improvement through parallel execution - Use SuperClaude flags: --orchestrate --delegate auto --concurrency 7 --think-hard 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .claude/commands/ui/design.md | 97 ++++++ .claude/commands/ui/uied-analysis.md | 501 +++++++++++++++++++++++++++ .claude/tools/README.md | 83 +++++ .claude/tools/UIED | 1 + .gitmodules | 3 + 5 files changed, 685 insertions(+) create mode 100644 .claude/commands/ui/uied-analysis.md create mode 100644 .claude/tools/README.md create mode 160000 .claude/tools/UIED create mode 100644 .gitmodules diff --git a/.claude/commands/ui/design.md b/.claude/commands/ui/design.md index 83eb8ca..a1a0eaf 100644 --- a/.claude/commands/ui/design.md +++ b/.claude/commands/ui/design.md @@ -1,3 +1,93 @@ +# UI Design - Pixel-Perfect Recreation Workflow + +## Orchestration Mode +When recreating UI from screenshots, use SuperClaude orchestration: +- Enable flags: `--orchestrate --delegate auto --concurrency 7 --think-hard` +- These flags activate parallel agent execution and intelligent coordination +- Memory coordination via hooks for cross-agent communication + +## Workflow Execution + +### Phase 1: Parallel Analysis (Execute in Single Message) +Spawn 7 agents concurrently using Claude Code's Task tool: + +**Agent 1: Structural Analyzer** (code-analyzer) +- Run `/ui/uied-analysis` on the provided image +- Extract component positions, dimensions, and canvas size +- Generate ASCII layout representation showing spatial organization +- Store findings in memory with key: `structural-analysis` + +**Agent 2: Color Analyst** (analyst) +- Analyze the image to extract complete color palette +- Identify: backgrounds, text colors, accents, borders, hover states +- Organize into primary, secondary, neutral, accent categories +- Map to Tailwind color classes +- Store in memory with key: `color-palette` + +**Agent 3: Typography Analyst** (analyst) +- Examine all text elements in the image +- Document font families, sizes, weights, line heights, tracking +- Identify heading hierarchy (h1-h6) and body text styles +- Note any special typography patterns +- Store in memory with key: `typography-system` + +**Agent 4: Spacing Analyst** (analyst) +- Analyze padding, margins, gaps throughout the UI +- Identify spacing scale (4px, 8px, 16px, 24px, etc.) +- Document grid patterns, alignment, and layout structure +- Store in memory with key: `spacing-system` + +**Agent 5: Shadow Analyst** (analyst) +- Extract shadow and elevation patterns from the image +- Document shadow levels (subtle, medium, high) +- Map to Tailwind shadow classes (shadow-sm, shadow-md, etc.) +- Store in memory with key: `shadow-patterns` + +**Agent 6: Border Analyst** (analyst) +- Identify border radius values and patterns +- Document border styles, widths, and colors +- Store in memory with key: `border-patterns` + +**Agent 7: Component Classifier** (analyst) +- Catalog component types (buttons, cards, inputs, navigation, icons) +- Identify interaction states (hover, active, disabled, focus) +- Document component patterns and variants +- Store in memory with key: `component-catalog` + +### Phase 2: Sequential Synthesis (After Phase 1 Completes) + +**Style Guide Synthesizer** (technical-writer) +- Retrieve all Phase 1 memory outputs +- Consolidate into unified design system using `/ui/style-guide` structure +- Create comprehensive style guide document +- Store in memory with key: `style-guide` + +**Layout Architect** (system-architect) +- Retrieve `structural-analysis` and `component-catalog` from memory +- Plan component hierarchy and spatial relationships +- Map UIED positions to semantic HTML structure +- Store in memory with key: `layout-architecture` + +### Phase 2.5: ASCII Layout Output (Checkpoint Before Code Generation) + +**IMPORTANT: Output the ASCII layout representation to the user** +- Retrieve `structural-analysis` from memory +- Display the ASCII layout showing component spatial organization +- Include major sections, component boundaries, and hierarchy +- This serves as a visual checkpoint before HTML generation +- Wait for confirmation or feedback before proceeding to Phase 3 + +### Phase 3: Final Generation + +**HTML/Tailwind Coder** (sparc-coder) +- Retrieve all memory outputs from Phase 1 and Phase 2 +- Use UIED positions for precise component placement +- Apply style guide for consistent design implementation +- Follow layout architecture for proper HTML structure +- Generate pixel-perfect HTML/Tailwind code in single file + +## HTML/Tailwind Output Rules + Only code in HTML/Tailwind in a single code block. Any CSS styles should be in the style attribute. Start with a response, then code and finish with a response. Don't mention about tokens, Tailwind or HTML. @@ -22,3 +112,10 @@ Use 1.5 strokewidth for lucide icons and avoid gradient containers for icons. Use subtle contrast. For logos, use letters only with tight tracking. Avoid a bottom right floating DOWNLOAD button. + +## Performance Expectations +- Phase 1 (parallel): ~30-45 seconds +- Phase 2 (synthesis): ~15-20 seconds +- Phase 2.5 (ASCII output): ~5 seconds +- Phase 3 (generation): ~20-30 seconds +- Total: ~70-100 seconds (2.8-3.6x faster than sequential execution) diff --git a/.claude/commands/ui/uied-analysis.md b/.claude/commands/ui/uied-analysis.md new file mode 100644 index 0000000..9995112 --- /dev/null +++ b/.claude/commands/ui/uied-analysis.md @@ -0,0 +1,501 @@ +--- +description: Analyze UI screenshots and website layouts using UIED (UI Element Detection) to detect and classify text and graphical elements +tags: [ui, analysis, detection, ocr, computer-vision] +--- + +# UI Analysis Command + +Analyze UI screenshots and website layouts using UIED (UI Element Detection) - a hybrid computer vision-based system that detects and classifies text and graphical UI elements. + +## What This Does + +This command uses the UIED repository to: +- Detect and localize UI elements (buttons, images, text, input fields, etc.) +- Extract text content via OCR +- Classify graphical components +- Export structured JSON with element positions and metadata +- Generate annotated images showing detected elements + +## Setup (First Time Only) + +### 1. Initialize UIED Submodule + +The UIED repository is included as a git submodule in `.claude/tools/UIED`. + +```bash +# Initialize and update the submodule (if not already done) +git submodule update --init --recursive +``` + +### 2. Install Dependencies + +```bash +pip install opencv-python pandas numpy requests paddleocr +``` + +### 3. Configure OCR (Choose One) + +**Option A: PaddleOCR (Recommended - Free, Offline)** +- Already installed in step 2 +- Works offline, no API key needed +- Good accuracy for most use cases + +**Option B: Google Cloud Vision (More Accurate, Costs Money)** +1. Get API key from https://cloud.google.com/vision +2. Edit `.claude/tools/UIED/detect_text/ocr.py` line 28 to add your key +3. Note: Google OCR costs money after free tier + +### 4. Verify Installation + +```bash +cd .claude/tools/UIED +python run_single.py +# Should process data/input/497.jpg and create output +cd ../../.. # Return to project root +``` + +## Usage + +I'll help you analyze UI screenshots using UIED and recreate them pixel-perfectly. Here's what I need from you: + +### Single Image Analysis +Provide: +1. **Path to screenshot** (e.g., `./screenshots/app.png`) +2. **UI type** (mobile/web/custom) +3. **Output directory** (optional, defaults to `./uied-output`) + +### Batch Analysis +Provide: +1. **Directory with screenshots** +2. **UI type** (mobile/web/custom) +3. **Output directory** (optional) + +### Pixel-Perfect Recreation +After analysis, I can recreate the UI using: +1. **UIED component positions** (for exact placement) +2. **Original image visual design** (for accurate styling) +3. This ensures the recreation matches the original layout AND design + +### Custom Parameters +If you want to fine-tune detection: +- `min-grad`: Gradient threshold (lower = more details) +- `min-ele-area`: Minimum element area in pixels +- `merge-contained-ele`: Whether to merge nested elements +- `max-word-inline-gap`: Word grouping threshold +- `max-line-gap`: Paragraph detection threshold + +## Analysis Process + +When you provide a UI screenshot, I will: + +### 1. Setup Check + +```bash +# Verify UIED submodule is initialized +if [ ! -d ".claude/tools/UIED/detect_compo" ]; then + echo "⚠️ UIED submodule not initialized." + echo "Run: git submodule update --init --recursive" + exit 1 +fi + +# Verify dependencies +python -c "import cv2, pandas, numpy" 2>/dev/null || { + echo "❌ Missing dependencies. Run: pip install opencv-python pandas numpy paddleocr" + exit 1 +} +``` + +### 2. Prepare Parameters + +```bash +# Set parameters based on UI type +if [ "$UI_TYPE" == "mobile" ]; then + MIN_GRAD=4 + MIN_AREA=50 + MAX_WORD_GAP=6 + MAX_LINE_GAP=1 +elif [ "$UI_TYPE" == "web" ]; then + MIN_GRAD=3 + MIN_AREA=25 + MAX_WORD_GAP=4 + MAX_LINE_GAP=4 +else + # Custom parameters from user + MIN_GRAD=${CUSTOM_MIN_GRAD:-4} + MIN_AREA=${CUSTOM_MIN_AREA:-50} + MAX_WORD_GAP=${CUSTOM_WORD_GAP:-6} + MAX_LINE_GAP=${CUSTOM_LINE_GAP:-1} +fi +``` + +### 3. Create Analysis Script + +I'll create a Python script that uses the UIED submodule: + +```python +#!/usr/bin/env python +import sys +import os +import json +from pathlib import Path + +# Add UIED submodule to path +UIED_PATH = Path(__file__).parent.parent / '.claude' / 'tools' / 'UIED' +sys.path.insert(0, str(UIED_PATH)) + +# Import UIED modules +from detect_compo import ip_region_proposal as ip +from detect_text import text_detection as text +from detect_merge import merge + +def analyze_ui(input_path, output_dir, params): + """Analyze UI screenshot and return structured results""" + + # Create output directory + Path(output_dir).mkdir(parents=True, exist_ok=True) + + # Run detection pipelines + print("🔍 Detecting text elements...") + text.text_detection(input_path, output_dir, method='paddle', show=False) + + print("🎨 Detecting graphical components...") + ip.compo_detection(input_path, output_dir, params, show=False) + + print("🔗 Merging results...") + input_name = Path(input_path).stem + compo_path = os.path.join(output_dir, 'ip', f'{input_name}.json') + ocr_path = os.path.join(output_dir, 'ocr', f'{input_name}.json') + + merge.merge(input_path, compo_path, ocr_path, output_dir, + is_paragraph=params.get('merge-line-to-paragraph', False), + is_remove_bar=params.get('remove-bar', True)) + + # Read merged results + merge_path = os.path.join(output_dir, 'merge', f'{input_name}.json') + with open(merge_path, 'r') as f: + results = json.load(f) + + return results, merge_path + +def summarize_results(results, image_path): + """Generate human-readable summary of detection results""" + compos = results.get('compos', []) + + # Count element types + text_elements = [c for c in compos if c.get('class') == 'Text'] + graphical_elements = [c for c in compos if c.get('class') != 'Text'] + + print("\n" + "="*60) + print(f"📊 UI Analysis Results for: {Path(image_path).name}") + print("="*60) + print(f"\n✅ Total Elements Detected: {len(compos)}") + print(f" 📝 Text Elements: {len(text_elements)}") + print(f" 🎨 Graphical Components: {len(graphical_elements)}") + + if text_elements: + print(f"\n📝 Text Content Found:") + for i, text_el in enumerate(text_elements[:10], 1): # Show first 10 + content = text_el.get('content', 'N/A') + pos = text_el.get('position', {}) + print(f" {i}. \"{content}\" at ({pos.get('column_min', 0)}, {pos.get('row_min', 0)})") + if len(text_elements) > 10: + print(f" ... and {len(text_elements) - 10} more text elements") + + print(f"\n🎨 Component Distribution:") + # Try to show component types if available + component_types = {} + for comp in graphical_elements: + comp_type = comp.get('class', 'Unknown') + component_types[comp_type] = component_types.get(comp_type, 0) + 1 + + for comp_type, count in sorted(component_types.items(), key=lambda x: x[1], reverse=True): + print(f" {comp_type}: {count}") + + print("\n" + "="*60) + +if __name__ == '__main__': + import argparse + + parser = argparse.ArgumentParser() + parser.add_argument('input', help='Input image path') + parser.add_argument('output', help='Output directory') + parser.add_argument('--min-grad', type=int, default=4) + parser.add_argument('--min-area', type=int, default=50) + parser.add_argument('--max-word-gap', type=int, default=6) + parser.add_argument('--max-line-gap', type=int, default=1) + parser.add_argument('--merge-contained', action='store_true', default=True) + parser.add_argument('--merge-paragraphs', action='store_true', default=False) + parser.add_argument('--remove-bar', action='store_true', default=True) + + args = parser.parse_args() + + params = { + 'min-grad': args.min_grad, + 'ffl-block': 5, + 'min-ele-area': args.min_area, + 'merge-contained-ele': args.merge_contained, + 'merge-line-to-paragraph': args.merge_paragraphs, + 'remove-bar': args.remove_bar, + 'max-word-inline-gap': args.max_word_gap, + 'max-line-gap': args.max_line_gap + } + + results, output_path = analyze_ui(args.input, args.output, params) + summarize_results(results, args.input) + + print(f"\n📁 Full results saved to: {output_path}") + print(f"🖼️ Annotated image: {output_path.replace('.json', '.jpg')}") +``` + +### 4. Run Analysis + +I'll execute the analysis with your specified parameters and present the results in a clear, structured format. + +## Output Structure + +After analysis, you'll get: + +``` +{output-directory}/ +├── ip/ # Component detection results +│ ├── {image}.jpg # Annotated with component boxes +│ └── {image}.json # Component coordinates +├── ocr/ # Text detection results +│ ├── {image}.png # Annotated with text boxes +│ └── {image}.json # Text content and positions +└── merge/ # Combined results (USE THIS) + ├── {image}.jpg # Final annotated image + └── {image}.json # All elements unified +``` + +### JSON Format (merge/*.json) + +```json +{ + "compos": [ + { + "id": 0, + "class": "Text", // or "Compo" for graphical + "content": "Button Text", // only for Text elements + "height": 39, + "width": 369, + "position": { + "column_min": 10, + "row_min": 34, + "column_max": 379, + "row_max": 73 + } + } + ] +} +``` + +## Use Cases + +### 1. Accessibility Audit +"Analyze this web page screenshot to identify all interactive elements and check if they have text labels" + +### 2. UI Element Extraction +"Extract all buttons, inputs, and text from this mobile app screenshot for automated testing" + +### 3. Design-to-Code +"Analyze this design mockup and list all UI components with their positions" + +### 4. Batch Website Analysis +"Process all screenshots in the ./screenshots/ folder and generate a report of UI patterns used" + +### 5. Element Hierarchy +"Show me the containment hierarchy of UI elements in this layout" + +## Parameter Tuning Guide + +### For Mobile Apps +- Use `min-grad: 4` (good balance) +- Use `min-ele-area: 50` (avoid tiny elements) +- Use `max-word-inline-gap: 6` (tight word grouping) + +### For Web Pages +- Use `min-grad: 3` (finer details) +- Use `min-ele-area: 25` (detect smaller elements) +- Use `max-word-inline-gap: 4` (looser grouping) + +### For Hand-Drawn UIs +- Use `min-grad: 10` (stronger edges) +- Use `min-ele-area: 100` (ignore noise) +- Disable `merge-contained-ele` (preserve all elements) + +### If You Get Too Many Elements +- Increase `min-grad` (5-10) +- Increase `min-ele-area` (100+) +- Enable `merge-contained-ele` + +### If You Miss Elements +- Decrease `min-grad` (2-3) +- Decrease `min-ele-area` (10-25) +- Disable `remove-bar` (keep all elements) + +## Example Interactions + +### Example 1: Basic Analysis +``` +User: "Analyze ./screenshots/app.png using mobile settings" + +Response: I'll analyze the mobile app screenshot using UIED. + +[Runs analysis with mobile parameters] + +📊 UI Analysis Results for: app.png +================================================== +✅ Total Elements Detected: 47 + 📝 Text Elements: 23 + 🎨 Graphical Components: 24 + +📝 Text Content Found: + 1. "Sign In" at (150, 45) + 2. "Email" at (50, 120) + 3. "Password" at (50, 180) + ... + +🎨 Component Distribution: + Button: 8 + Input: 3 + Image: 13 + +📁 Full results: ./uied-output/merge/app.json +🖼️ Annotated image: ./uied-output/merge/app.jpg +``` + +### Example 2: Batch Analysis +``` +User: "Process all images in ./web-screenshots/ folder" + +Response: I'll batch process all screenshots in the directory. + +[Creates batch script and processes all images] + +✅ Processed 15 images +📊 Summary: + - homepage.png: 52 elements + - product.png: 38 elements + - checkout.png: 41 elements + ... + +All results saved to ./uied-output/ +``` + +### Example 3: Custom Parameters +``` +User: "Analyze design.png but use min-grad=2 to catch fine details" + +Response: I'll analyze with custom parameters for fine detail detection. + +[Runs with custom min-grad=2] + +📊 Detected 127 elements (more than default due to lower threshold) +⚠️ Note: Lower gradient threshold found more elements but may include some noise. +``` + +## Troubleshooting + +### Error: "UIED submodule not initialized" +```bash +# Initialize the submodule +git submodule update --init --recursive +``` + +### Error: "Module not found" +```bash +# Install missing dependencies +pip install opencv-python pandas numpy paddleocr +``` + +### Error: "OCR failed" +- Make sure PaddleOCR is installed: `pip install paddleocr` +- Or configure Google Cloud Vision API in `.claude/tools/UIED/detect_text/ocr.py` + +### Too Many/Few Elements Detected +- Use the parameter tuning guide above +- Try the interactive tuning tool in the UIED directory + +### Slow Processing +- UIED processes ~5-10 seconds per image +- For faster results, use lower resolution images +- Disable OCR if only need component detection + +## Advanced Usage + +### Interactive Parameter Tuning +```bash +cd .claude/tools/UIED +python "run_testing(Used for Adjusting).py" +# Opens GUI with sliders to adjust parameters in real-time +# Find optimal parameters, then use them in the command +cd ../../.. # Return to project root +``` + +### Extract Specific Element Types +```python +# Parse JSON to get only buttons +import json +with open('output/merge/app.json') as f: + data = json.load(f) + +buttons = [c for c in data['compos'] + if 'button' in c.get('class', '').lower()] +``` + +### Generate Element Hierarchy +```python +# Build containment tree +def is_contained(inner, outer): + return (inner['column_min'] >= outer['column_min'] and + inner['column_max'] <= outer['column_max'] and + inner['row_min'] >= outer['row_min'] and + inner['row_max'] <= outer['row_max']) + +def build_hierarchy(elements): + tree = {} + for el in elements: + pos = el['position'] + # Check which elements contain this one + for parent in elements: + if el != parent and is_contained(pos, parent['position']): + tree.setdefault(parent['id'], []).append(el) + return tree +``` + +## Integration with Other Commands + +### With /ui/clone-website +```bash +# 1. Clone website screenshots +/ui/clone-website https://example.com + +# 2. Analyze the screenshots +/ui/ui-analysis ./screenshots/ --type web +``` + +### With /ui/design +```bash +# 1. Analyze existing UI +/ui/ui-analysis app.png + +# 2. Use results to inform new design +/ui/design "Create similar layout with modern styling" +``` + +## Notes + +- **Processing Time**: ~5-10 seconds per image for full pipeline +- **Best Results**: Modern, clean UIs with clear element boundaries +- **OCR Accuracy**: PaddleOCR is good but Google Vision is more accurate (costs money) +- **Parameter Sensitivity**: Different UI types may need parameter adjustment +- **Output Size**: Each analysis generates ~3 images + 3 JSON files +- **Submodule Location**: `.claude/tools/UIED` (managed via git submodule) + +## Resources + +- **UIED Repository**: https://github.com/MulongXie/UIED +- **Research Paper**: [UIED: a hybrid tool for GUI element detection](https://dl.acm.org/doi/10.1145/3368089.3417940) +- **Google Cloud Vision**: https://cloud.google.com/vision (for OCR API key) +- **PaddleOCR**: https://github.com/PaddlePaddle/PaddleOCR (free OCR alternative) diff --git a/.claude/tools/README.md b/.claude/tools/README.md new file mode 100644 index 0000000..10749e1 --- /dev/null +++ b/.claude/tools/README.md @@ -0,0 +1,83 @@ +# Claude Tools Directory + +This directory contains external tools integrated as git submodules for use by Claude commands. + +## Installed Tools + +### UIED (UI Element Detection) + +**Repository**: https://github.com/MulongXie/UIED +**Version**: Tracked as git submodule +**Purpose**: Computer vision-based UI element detection for screenshots and layouts + +**Used by**: +- `/ui/ui-analysis` - Analyze UI screenshots to detect and classify elements + +**Setup**: +```bash +# Initialize submodule (if not already done) +git submodule update --init --recursive + +# Install Python dependencies +pip install opencv-python pandas numpy paddleocr +``` + +**Features**: +- Detects text elements via OCR (PaddleOCR or Google Cloud Vision) +- Detects graphical components via computer vision +- Exports structured JSON with element positions +- Generates annotated images showing detections + +## Managing Submodules + +### Initialize All Submodules +```bash +git submodule update --init --recursive +``` + +### Update a Submodule to Latest Version +```bash +cd .claude/tools/UIED +git pull origin master +cd ../../.. +git add .claude/tools/UIED +git commit -m "Update UIED submodule to latest version" +``` + +### Remove a Submodule +```bash +# Remove from .gitmodules +git config -f .gitmodules --remove-section submodule.{path} + +# Remove from .git/config +git config -f .git/config --remove-section submodule.{path} + +# Remove from working tree +git rm --cached {path} +rm -rf {path} + +# Commit changes +git add .gitmodules +git commit -m "Remove {submodule} submodule" +``` + +## Adding New Tools + +To add a new tool as a submodule: + +```bash +# Add the submodule +git submodule add {repository-url} .claude/tools/{tool-name} + +# Initialize and update +git submodule update --init --recursive + +# Document in this README +``` + +## Notes + +- Submodules are frozen at a specific commit +- Use `git submodule update --remote` to update to latest commit +- Each submodule maintains its own git history +- Submodule commits are tracked in the parent repository diff --git a/.claude/tools/UIED b/.claude/tools/UIED new file mode 160000 index 0000000..0a9862a --- /dev/null +++ b/.claude/tools/UIED @@ -0,0 +1 @@ +Subproject commit 0a9862a7be69c9fd157e19c825a5a9e815f201cd diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..25c0a24 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule ".claude/tools/UIED"] + path = .claude/tools/UIED + url = https://github.com/MulongXie/UIED.git From 05f398edc5c54f76999cb36fddd29dca4c81618f Mon Sep 17 00:00:00 2001 From: kevin rajan Date: Wed, 5 Nov 2025 14:10:23 -0600 Subject: [PATCH 3/7] [claudesquad] update from 'uied' on 05 Nov 25 14:10 CST --- ...inal-a16c4c2967229fa52683443ee0c26903..jpg | Bin 0 -> 217538 bytes ...nal-a16c4c2967229fa52683443ee0c26903..json | 1049 +++++++++++++++++ 2 files changed, 1049 insertions(+) create mode 100644 uied-output/ip/original-a16c4c2967229fa52683443ee0c26903..jpg create mode 100644 uied-output/ip/original-a16c4c2967229fa52683443ee0c26903..json diff --git a/uied-output/ip/original-a16c4c2967229fa52683443ee0c26903..jpg b/uied-output/ip/original-a16c4c2967229fa52683443ee0c26903..jpg new file mode 100644 index 0000000000000000000000000000000000000000..ee37414fccff698ab00e89e7e73f916557122694 GIT binary patch literal 217538 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 Date: Thu, 6 Nov 2025 12:11:12 -0600 Subject: [PATCH 4/7] cleanup: Remove duplicate files from ccpm/ (keep .claude/ as authoritative) - Removed ccpm/commands/pm/ (38 files, duplicates of .claude/commands/pm/) - Removed ccpm/commands/context/ (3 files, duplicates of .claude/commands/context/) - Removed ccpm/rules/ (11 files, duplicates of .claude/rules/) .claude/ is Claude Code's standard directory and remains authoritative. All files verified as identical via MD5 hash comparison. Total space saved: ~315KB (ccpm reduced from 588K to 273K) All deletions recoverable from git history. Remaining in ccpm/: - agents/ (4 unique CCPM-specific agents) - commands/ (3 unique commands + testing subdirectory) - context/README.md - Configuration files (ccpm.config, settings.json.example, etc.) --- ccpm/commands/context/create.md | 161 -------- ccpm/commands/context/prime.md | 146 ------- ccpm/commands/context/update.md | 229 ----------- ccpm/commands/pm/blocked.md | 6 - ccpm/commands/pm/clean.md | 102 ----- ccpm/commands/pm/epic-close.md | 69 ---- ccpm/commands/pm/epic-decompose.md | 230 ----------- ccpm/commands/pm/epic-edit.md | 66 --- ccpm/commands/pm/epic-list.md | 7 - ccpm/commands/pm/epic-merge.md | 261 ------------ ccpm/commands/pm/epic-oneshot.md | 89 ---- ccpm/commands/pm/epic-refresh.md | 108 ----- ccpm/commands/pm/epic-show.md | 6 - ccpm/commands/pm/epic-start-worktree.md | 221 ---------- ccpm/commands/pm/epic-start.md | 247 ------------ ccpm/commands/pm/epic-status.md | 6 - ccpm/commands/pm/epic-sync.md | 468 ---------------------- ccpm/commands/pm/help.md | 6 - ccpm/commands/pm/import.md | 98 ----- ccpm/commands/pm/in-progress.md | 6 - ccpm/commands/pm/init.md | 6 - ccpm/commands/pm/issue-analyze.md | 186 --------- ccpm/commands/pm/issue-close.md | 102 ----- ccpm/commands/pm/issue-edit.md | 76 ---- ccpm/commands/pm/issue-reopen.md | 70 ---- ccpm/commands/pm/issue-show.md | 91 ----- ccpm/commands/pm/issue-start.md | 163 -------- ccpm/commands/pm/issue-status.md | 78 ---- ccpm/commands/pm/issue-sync.md | 292 -------------- ccpm/commands/pm/next.md | 6 - ccpm/commands/pm/prd-edit.md | 65 --- ccpm/commands/pm/prd-list.md | 6 - ccpm/commands/pm/prd-new.md | 148 ------- ccpm/commands/pm/prd-parse.md | 175 -------- ccpm/commands/pm/prd-status.md | 6 - ccpm/commands/pm/search.md | 6 - ccpm/commands/pm/standup.md | 6 - ccpm/commands/pm/status.md | 6 - ccpm/commands/pm/sync.md | 82 ---- ccpm/commands/pm/test-reference-update.md | 134 ------- ccpm/commands/pm/validate.md | 6 - ccpm/rules/agent-coordination.md | 224 ----------- ccpm/rules/branch-operations.md | 147 ------- ccpm/rules/datetime.md | 118 ------ ccpm/rules/frontmatter-operations.md | 58 --- ccpm/rules/github-operations.md | 89 ---- ccpm/rules/path-standards.md | 155 ------- ccpm/rules/standard-patterns.md | 174 -------- ccpm/rules/strip-frontmatter.md | 82 ---- ccpm/rules/test-execution.md | 63 --- ccpm/rules/use-ast-grep.md | 143 ------- ccpm/rules/worktree-operations.md | 136 ------- 52 files changed, 5631 deletions(-) delete mode 100644 ccpm/commands/context/create.md delete mode 100644 ccpm/commands/context/prime.md delete mode 100644 ccpm/commands/context/update.md delete mode 100644 ccpm/commands/pm/blocked.md delete mode 100644 ccpm/commands/pm/clean.md delete mode 100644 ccpm/commands/pm/epic-close.md delete mode 100644 ccpm/commands/pm/epic-decompose.md delete mode 100644 ccpm/commands/pm/epic-edit.md delete mode 100644 ccpm/commands/pm/epic-list.md delete mode 100644 ccpm/commands/pm/epic-merge.md delete mode 100644 ccpm/commands/pm/epic-oneshot.md delete mode 100644 ccpm/commands/pm/epic-refresh.md delete mode 100644 ccpm/commands/pm/epic-show.md delete mode 100644 ccpm/commands/pm/epic-start-worktree.md delete mode 100644 ccpm/commands/pm/epic-start.md delete mode 100644 ccpm/commands/pm/epic-status.md delete mode 100644 ccpm/commands/pm/epic-sync.md delete mode 100644 ccpm/commands/pm/help.md delete mode 100644 ccpm/commands/pm/import.md delete mode 100644 ccpm/commands/pm/in-progress.md delete mode 100644 ccpm/commands/pm/init.md delete mode 100644 ccpm/commands/pm/issue-analyze.md delete mode 100644 ccpm/commands/pm/issue-close.md delete mode 100644 ccpm/commands/pm/issue-edit.md delete mode 100644 ccpm/commands/pm/issue-reopen.md delete mode 100644 ccpm/commands/pm/issue-show.md delete mode 100644 ccpm/commands/pm/issue-start.md delete mode 100644 ccpm/commands/pm/issue-status.md delete mode 100644 ccpm/commands/pm/issue-sync.md delete mode 100644 ccpm/commands/pm/next.md delete mode 100644 ccpm/commands/pm/prd-edit.md delete mode 100644 ccpm/commands/pm/prd-list.md delete mode 100644 ccpm/commands/pm/prd-new.md delete mode 100644 ccpm/commands/pm/prd-parse.md delete mode 100644 ccpm/commands/pm/prd-status.md delete mode 100644 ccpm/commands/pm/search.md delete mode 100644 ccpm/commands/pm/standup.md delete mode 100644 ccpm/commands/pm/status.md delete mode 100644 ccpm/commands/pm/sync.md delete mode 100644 ccpm/commands/pm/test-reference-update.md delete mode 100644 ccpm/commands/pm/validate.md delete mode 100644 ccpm/rules/agent-coordination.md delete mode 100644 ccpm/rules/branch-operations.md delete mode 100644 ccpm/rules/datetime.md delete mode 100644 ccpm/rules/frontmatter-operations.md delete mode 100644 ccpm/rules/github-operations.md delete mode 100644 ccpm/rules/path-standards.md delete mode 100644 ccpm/rules/standard-patterns.md delete mode 100644 ccpm/rules/strip-frontmatter.md delete mode 100644 ccpm/rules/test-execution.md delete mode 100644 ccpm/rules/use-ast-grep.md delete mode 100644 ccpm/rules/worktree-operations.md diff --git a/ccpm/commands/context/create.md b/ccpm/commands/context/create.md deleted file mode 100644 index 2218a15..0000000 --- a/ccpm/commands/context/create.md +++ /dev/null @@ -1,161 +0,0 @@ ---- -allowed-tools: Bash, Read, Write, LS ---- - -# Create Initial Context - -This command creates the initial project context documentation in `.claude/context/` by analyzing the current project state and establishing comprehensive baseline documentation. - -## Required Rules - -**IMPORTANT:** Before executing this command, read and follow: -- `.claude/rules/datetime.md` - For getting real current date/time - -## Preflight Checklist - -Before proceeding, complete these validation steps. -Do not bother the user with preflight checks progress ("I'm not going to ..."). Just do them and move on. - -### 1. Context Directory Check -- Run: `ls -la .claude/context/ 2>/dev/null` -- If directory exists and has files: - - Count existing files: `ls -1 .claude/context/*.md 2>/dev/null | wc -l` - - Ask user: "⚠️ Found {count} existing context files. Overwrite all context? (yes/no)" - - Only proceed with explicit 'yes' confirmation - - If user says no, suggest: "Use /context:update to refresh existing context" - -### 2. Project Type Detection -- Check for project indicators: - - Node.js: `test -f package.json && echo "Node.js project detected"` - - Python: `test -f requirements.txt || test -f pyproject.toml && echo "Python project detected"` - - Rust: `test -f Cargo.toml && echo "Rust project detected"` - - Go: `test -f go.mod && echo "Go project detected"` -- Run: `git status 2>/dev/null` to confirm this is a git repository -- If not a git repo, ask: "⚠️ Not a git repository. Continue anyway? (yes/no)" - -### 3. Directory Creation -- If `.claude/` doesn't exist, create it: `mkdir -p .claude/context/` -- Verify write permissions: `touch .claude/context/.test && rm .claude/context/.test` -- If permission denied, tell user: "❌ Cannot create context directory. Check permissions." - -### 4. Get Current DateTime -- Run: `date -u +"%Y-%m-%dT%H:%M:%SZ"` -- Store this value for use in all context file frontmatter - -## Instructions - -### 1. Pre-Analysis Validation -- Confirm project root directory is correct (presence of .git, package.json, etc.) -- Check for existing documentation that can inform context (README.md, docs/) -- If README.md doesn't exist, ask user for project description - -### 2. Systematic Project Analysis -Gather information in this order: - -**Project Detection:** -- Run: `find . -maxdepth 2 \( -name 'package.json' -o -name 'requirements.txt' -o -name 'pyproject.toml' -o -name 'pom.xml' -o -name 'build.gradle' -o -name 'build.gradle.kts' -o -name '*.sln' -o -name '*.csproj' -o -name 'Gemfile' -o -name 'Cargo.toml' -o -name 'go.mod' -o -name 'composer.json' -o -name 'pubspec.yaml' -o -name 'CMakeLists.txt' -o -name 'Dockerfile' -o -name 'docker-compose.yml' -o -name 'Package.swift' -o -type d -name '*.xcodeproj' -o -type d -name '*.xcworkspace' \) 2>/dev/null` -- Run: `git remote -v 2>/dev/null` to get repository information -- Run: `git branch --show-current 2>/dev/null` to get current branch - -**Codebase Analysis:** -- Run: `find . -type f \( -name '*.js' -o -name '*.ts' -o -name '*.jsx' -o -name '*.tsx' -o -name '*.py' -o -name '*.rs' -o -name '*.go' -o -name '*.php' -o -name '*.swift' -o -name '*.java' -o -name '*.kt' -o -name '*.kts' -o -name '*.cs' -o -name '*.rb' -o -name '*.dart' -o -name '*.c' -o -name '*.h' -o -name '*.cpp' -o -name '*.hpp' -o -name '*.sh' \) 2>/dev/null | head -20` -- Run: `ls -la` to see root directory structure -- Read README.md if it exists - -### 3. Context File Creation with Frontmatter - -Each context file MUST include frontmatter with real datetime: - -```yaml ---- -created: [Use REAL datetime from date command] -last_updated: [Use REAL datetime from date command] -version: 1.0 -author: Claude Code PM System ---- -``` - -Generate the following initial context files: - - `progress.md` - Document current project status, completed work, and immediate next steps - - Include: Current branch, recent commits, outstanding changes - - `project-structure.md` - Map out the directory structure and file organization - - Include: Key directories, file naming patterns, module organization - - `tech-context.md` - Catalog current dependencies, technologies, and development tools - - Include: Language version, framework versions, dev dependencies - - `system-patterns.md` - Identify existing architectural patterns and design decisions - - Include: Design patterns observed, architectural style, data flow - - `product-context.md` - Define product requirements, target users, and core functionality - - Include: User personas, core features, use cases - - `project-brief.md` - Establish project scope, goals, and key objectives - - Include: What it does, why it exists, success criteria - - `project-overview.md` - Provide a high-level summary of features and capabilities - - Include: Feature list, current state, integration points - - `project-vision.md` - Articulate long-term vision and strategic direction - - Include: Future goals, potential expansions, strategic priorities - - `project-style-guide.md` - Document coding standards, conventions, and style preferences - - Include: Naming conventions, file structure patterns, comment style -### 4. Quality Validation - -After creating each file: -- Verify file was created successfully -- Check file is not empty (minimum 10 lines of content) -- Ensure frontmatter is present and valid -- Validate markdown formatting is correct - -### 5. Error Handling - -**Common Issues:** -- **No write permissions:** "❌ Cannot write to .claude/context/. Check permissions." -- **Disk space:** "❌ Insufficient disk space for context files." -- **File creation failed:** "❌ Failed to create {filename}. Error: {error}" - -If any file fails to create: -- Report which files were successfully created -- Provide option to continue with partial context -- Never leave corrupted or incomplete files - -### 6. Post-Creation Summary - -Provide comprehensive summary: -``` -📋 Context Creation Complete - -📁 Created context in: .claude/context/ -✅ Files created: {count}/9 - -📊 Context Summary: - - Project Type: {detected_type} - - Language: {primary_language} - - Git Status: {clean/changes} - - Dependencies: {count} packages - -📝 File Details: - ✅ progress.md ({lines} lines) - Current status and recent work - ✅ project-structure.md ({lines} lines) - Directory organization - [... list all files with line counts and brief description ...] - -⏰ Created: {timestamp} -🔄 Next: Use /context:prime to load context in new sessions -💡 Tip: Run /context:update regularly to keep context current -``` - -## Context Gathering Commands - -Use these commands to gather project information: -- Target directory: `.claude/context/` (create if needed) -- Current git status: `git status --short` -- Recent commits: `git log --oneline -10` -- Project README: Read `README.md` if exists -- Package files: Check for package.json, requirements.txt, pyproject.toml, composer.json, Gemfile, Cargo.toml, go.mod, pom.xml, build.gradle, build.gradle.kts, *.sln, *.csproj, Package.swift, *.xcodeproj, *.xcworkspace, pubspec.yaml, CMakeLists.txt, Dockerfile, or docker-compose.yml etc. -- Documentation scan: `find . -type f -name '*.md' -path '*/docs/*' 2>/dev/null | head -10` -- Test detection: `find . \( -path '*/.*' -prune\) -o \( -type d \( -name 'test' -o -name 'tests' -o -name '__tests__' -o -name 'spec' \) -o -type f \( -name '*[._]test.*' -o -name '*[._]spec.*' -o -name 'test_*.*' -o -name '*_test.*' \)\) 2>/dev/null | head -10` - -## Important Notes - -- **Always use real datetime** from system clock, never placeholders -- **Ask for confirmation** before overwriting existing context -- **Validate each file** is created successfully -- **Provide detailed summary** of what was created -- **Handle errors gracefully** with specific guidance - -$ARGUMENTS diff --git a/ccpm/commands/context/prime.md b/ccpm/commands/context/prime.md deleted file mode 100644 index 45e5684..0000000 --- a/ccpm/commands/context/prime.md +++ /dev/null @@ -1,146 +0,0 @@ ---- -allowed-tools: Bash, Read, LS ---- - -# Prime Context - -This command loads essential context for a new agent session by reading the project context documentation and understanding the codebase structure. - -## Preflight Checklist - -Before proceeding, complete these validation steps. -Do not bother the user with preflight checks progress ("I'm not going to ..."). Just do them and move on. - -### 1. Context Availability Check -- Run: `ls -la .claude/context/ 2>/dev/null` -- If directory doesn't exist or is empty: - - Tell user: "❌ No context found. Please run /context:create first to establish project context." - - Exit gracefully -- Count available context files: `ls -1 .claude/context/*.md 2>/dev/null | wc -l` -- Report: "📁 Found {count} context files to load" - -### 2. File Integrity Check -- For each context file found: - - Verify file is readable: `test -r ".claude/context/{file}" && echo "readable"` - - Check file has content: `test -s ".claude/context/{file}" && echo "has content"` - - Check for valid frontmatter (should start with `---`) -- Report any issues: - - Empty files: "⚠️ {filename} is empty (skipping)" - - Unreadable files: "⚠️ Cannot read {filename} (permission issue)" - - Missing frontmatter: "⚠️ {filename} missing frontmatter (may be corrupted)" - -### 3. Project State Check -- Run: `git status --short 2>/dev/null` to see current state -- Run: `git branch --show-current 2>/dev/null` to get current branch -- Note if not in git repository (context may be less complete) - -## Instructions - -### 1. Context Loading Sequence - -Load context files in priority order for optimal understanding: - -**Priority 1 - Essential Context (load first):** -1. `project-overview.md` - High-level understanding of the project -2. `project-brief.md` - Core purpose and goals -3. `tech-context.md` - Technical stack and dependencies - -**Priority 2 - Current State (load second):** -4. `progress.md` - Current status and recent work -5. `project-structure.md` - Directory and file organization - -**Priority 3 - Deep Context (load third):** -6. `system-patterns.md` - Architecture and design patterns -7. `product-context.md` - User needs and requirements -8. `project-style-guide.md` - Coding conventions -9. `project-vision.md` - Long-term direction - -### 2. Validation During Loading - -For each file loaded: -- Check frontmatter exists and parse: - - `created` date should be valid - - `last_updated` should be ≥ created date - - `version` should be present -- If frontmatter is invalid, note but continue loading content -- Track which files loaded successfully vs failed - -### 3. Supplementary Information - -After loading context files: -- Run: `git ls-files --others --exclude-standard | head -20` to see untracked files -- Read `README.md` if it exists for additional project information -- Check for `.env.example` or similar for environment setup needs - -### 4. Error Recovery - -**If critical files are missing:** -- `project-overview.md` missing: Try to understand from README.md -- `tech-context.md` missing: Analyze project configuration files directly (package.json, requirements.txt, pyproject.toml, composer.json, Gemfile, Cargo.toml, go.mod, pom.xml, build.gradle, build.gradle.kts, *.sln, *.csproj, Package.swift, pubspec.yaml, CMakeLists.txt, etc.) -- `progress.md` missing: Check recent git commits for status - -**If context is incomplete:** -- Inform user which files are missing -- Suggest running `/context:update` to refresh context -- Continue with partial context but note limitations - -### 5. Loading Summary - -Provide comprehensive summary after priming: - -``` -🧠 Context Primed Successfully - -📖 Loaded Context Files: - ✅ Essential: {count}/3 files - ✅ Current State: {count}/2 files - ✅ Deep Context: {count}/4 files - -🔍 Project Understanding: - - Name: {project_name} - - Type: {project_type} - - Language: {primary_language} - - Status: {current_status from progress.md} - - Branch: {git_branch} - -📊 Key Metrics: - - Last Updated: {most_recent_update} - - Context Version: {version} - - Files Loaded: {success_count}/{total_count} - -⚠️ Warnings: - {list any missing files or issues} - -🎯 Ready State: - ✅ Project context loaded - ✅ Current status understood - ✅ Ready for development work - -💡 Project Summary: - {2-3 sentence summary of what the project is and current state} -``` - -### 6. Partial Context Handling - -If some files fail to load: -- Continue with available context -- Clearly note what's missing -- Suggest remediation: - - "Missing technical context - run /context:create to rebuild" - - "Progress file corrupted - run /context:update to refresh" - -### 7. Performance Optimization - -For large contexts: -- Load files in parallel when possible -- Show progress indicator: "Loading context files... {current}/{total}" -- Skip extremely large files (>10000 lines) with warning -- Cache parsed frontmatter for faster subsequent loads - -## Important Notes - -- **Always validate** files before attempting to read -- **Load in priority order** to get essential context first -- **Handle missing files gracefully** - don't fail completely -- **Provide clear summary** of what was loaded and project state -- **Note any issues** that might affect development work diff --git a/ccpm/commands/context/update.md b/ccpm/commands/context/update.md deleted file mode 100644 index 008de8a..0000000 --- a/ccpm/commands/context/update.md +++ /dev/null @@ -1,229 +0,0 @@ ---- -allowed-tools: Bash, Read, Write, LS ---- - -# Update Context - -This command updates the project context documentation in `.claude/context/` to reflect the current state of the project. Run this at the end of each development session to keep context accurate. - -## Required Rules - -**IMPORTANT:** Before executing this command, read and follow: -- `.claude/rules/datetime.md` - For getting real current date/time - -## Preflight Checklist - -Before proceeding, complete these validation steps. -Do not bother the user with preflight checks progress ("I'm not going to ..."). Just do them and move on. - -### 1. Context Validation -- Run: `ls -la .claude/context/ 2>/dev/null` -- If directory doesn't exist or is empty: - - Tell user: "❌ No context to update. Please run /context:create first." - - Exit gracefully -- Count existing files: `ls -1 .claude/context/*.md 2>/dev/null | wc -l` -- Report: "📁 Found {count} context files to check for updates" - -### 2. Change Detection - -Gather information about what has changed: - -**Git Changes:** -- Run: `git status --short` to see uncommitted changes -- Run: `git log --oneline -10` to see recent commits -- Run: `git diff --stat HEAD~5..HEAD 2>/dev/null` to see files changed recently - -**File Modifications:** -- Check context file ages: `find .claude/context -name "*.md" -type f -exec ls -lt {} + | head -5` -- Note which context files are oldest and may need updates - -**Dependency Changes:** -- Node.js: `git diff HEAD~5..HEAD package.json 2>/dev/null` -- Python: `git diff HEAD~5..HEAD requirements.txt pyproject.toml 2>/dev/null` -- Java: `git diff HEAD~5..HEAD pom.xml build.gradle build.gradle.kts 2>/dev/null` -- C#/.NET: `git diff HEAD~5..HEAD *.sln *.csproj 2>/dev/null` -- Ruby: `git diff HEAD~5..HEAD Gemfile Gemfile.lock 2>/dev/null` -- Rust: `git diff HEAD~5..HEAD Cargo.toml Cargo.lock 2>/dev/null` -- Go: `git diff HEAD~5..HEAD go.mod go.sum 2>/dev/null` -- PHP: `git diff HEAD~5..HEAD composer.json composer.lock 2>/dev/null` -- Dart/Flutter: `git diff HEAD~5..HEAD pubspec.yaml pubspec.lock 2>/dev/null` -- Swift: `git diff HEAD~5..HEAD Package.swift Package.resolved 2>/dev/null` -- C/C++: `git diff HEAD~5..HEAD CMakeLists.txt 2>/dev/null` -- Check if new dependencies were added or versions changed across any build system - -### 3. Get Current DateTime -- Run: `date -u +"%Y-%m-%dT%H:%M:%SZ"` -- Store for updating `last_updated` field in modified files - -## Instructions - -### 1. Systematic Change Analysis - -For each context file, determine if updates are needed: - -**Check each file systematically:** -#### `progress.md` - **Always Update** - - Check: Recent commits, current branch, uncommitted changes - - Update: Latest completed work, current blockers, next steps - - Run: `git log --oneline -5` to get recent commit messages - - Include completion percentages if applicable - -#### `project-structure.md` - **Update if Changed** - - Check: `git diff --name-status HEAD~10..HEAD | grep -E '^A'` for new files - - Update: New directories, moved files, structural reorganization - - Only update if significant structural changes occurred - -#### `tech-context.md` - **Update if Dependencies Changed** - - Check: Package files for new dependencies or version changes - - Update: New libraries, upgraded versions, new dev tools - - Include security updates or breaking changes - -#### `system-patterns.md` - **Update if Architecture Changed** - - Check: New design patterns, architectural decisions - - Update: New patterns adopted, refactoring done - - Only update for significant architectural changes - -#### `product-context.md` - **Update if Requirements Changed** - - Check: New features implemented, user feedback incorporated - - Update: New user stories, changed requirements - - Include any pivot in product direction - -#### `project-brief.md` - **Rarely Update** - - Check: Only if fundamental project goals changed - - Update: Major scope changes, new objectives - - Usually remains stable - -#### `project-overview.md` - **Update for Major Milestones** - - Check: Major features completed, significant progress - - Update: Feature status, capability changes - - Update when reaching project milestones - -#### `project-vision.md` - **Rarely Update** - - Check: Strategic direction changes - - Update: Only for major vision shifts - - Usually remains stable - -#### `project-style-guide.md` - **Update if Conventions Changed** - - Check: New linting rules, style decisions - - Update: Convention changes, new patterns adopted - - Include examples of new patterns -### 2. Smart Update Strategy - -**For each file that needs updating:** - -1. **Read existing file** to understand current content -2. **Identify specific sections** that need updates -3. **Preserve frontmatter** but update `last_updated` field: - ```yaml - --- - created: [preserve original] - last_updated: [Use REAL datetime from date command] - version: [increment if major update, e.g., 1.0 → 1.1] - author: Claude Code PM System - --- - ``` -4. **Make targeted updates** - don't rewrite entire file -5. **Add update notes** at the bottom if significant: - ```markdown - ## Update History - - {date}: {summary of what changed} - ``` - -### 3. Update Validation - -After updating each file: -- Verify file still has valid frontmatter -- Check file size is reasonable (not corrupted) -- Ensure markdown formatting is preserved -- Confirm updates accurately reflect changes - -### 4. Skip Optimization - -**Skip files that don't need updates:** -- If no relevant changes detected, skip the file -- Report skipped files in summary -- Don't update timestamp if content unchanged -- This preserves accurate "last modified" information - -### 5. Error Handling - -**Common Issues:** -- **File locked:** "❌ Cannot update {file} - may be open in editor" -- **Permission denied:** "❌ Cannot write to {file} - check permissions" -- **Corrupted file:** "⚠️ {file} appears corrupted - skipping update" -- **Disk space:** "❌ Insufficient disk space for updates" - -If update fails: -- Report which files were successfully updated -- Note which files failed and why -- Preserve original files (don't leave corrupted state) - -### 6. Update Summary - -Provide detailed summary of updates: - -``` -🔄 Context Update Complete - -📊 Update Statistics: - - Files Scanned: {total_count} - - Files Updated: {updated_count} - - Files Skipped: {skipped_count} (no changes needed) - - Errors: {error_count} - -📝 Updated Files: - ✅ progress.md - Updated recent commits, current status - ✅ tech-context.md - Added 3 new dependencies - ✅ project-structure.md - Noted new /utils directory - -⏭️ Skipped Files (no changes): - - project-brief.md (last updated: 5 days ago) - - project-vision.md (last updated: 2 weeks ago) - - system-patterns.md (last updated: 3 days ago) - -⚠️ Issues: - {any warnings or errors} - -⏰ Last Update: {timestamp} -🔄 Next: Run this command regularly to keep context current -💡 Tip: Major changes? Consider running /context:create for full refresh -``` - -### 7. Incremental Update Tracking - -**Track what was updated:** -- Note which sections of each file were modified -- Keep changes focused and surgical -- Don't regenerate unchanged content -- Preserve formatting and structure - -### 8. Performance Optimization - -For large projects: -- Process files in parallel when possible -- Show progress: "Updating context files... {current}/{total}" -- Skip very large files with warning -- Use git diff to quickly identify changed areas - -## Context Gathering Commands - -Use these commands to detect changes: -- Context directory: `.claude/context/` -- Current git status: `git status --short` -- Recent commits: `git log --oneline -10` -- Changed files: `git diff --name-only HEAD~5..HEAD 2>/dev/null` -- Branch info: `git branch --show-current` -- Uncommitted changes: `git diff --stat` -- New untracked files: `git ls-files --others --exclude-standard | head -10` -- Dependency changes: Check package.json, requirements.txt, pyproject.toml, composer.json, Gemfile, Cargo.toml, go.mod, pom.xml, build.gradle, build.gradle.kts, *.sln, *.csproj, Package.swift, pubspec.yaml, CMakeLists.txt, etc. - -## Important Notes - -- **Only update files with actual changes** - preserve accurate timestamps -- **Always use real datetime** from system clock for `last_updated` -- **Make surgical updates** - don't regenerate entire files -- **Validate each update** - ensure files remain valid -- **Provide detailed summary** - show what changed and what didn't -- **Handle errors gracefully** - don't corrupt existing context - -$ARGUMENTS diff --git a/ccpm/commands/pm/blocked.md b/ccpm/commands/pm/blocked.md deleted file mode 100644 index d2cde75..0000000 --- a/ccpm/commands/pm/blocked.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -allowed-tools: Bash(bash ccpm/scripts/pm/blocked.sh) ---- - -Output: -!bash ccpm/scripts/pm/blocked.sh diff --git a/ccpm/commands/pm/clean.md b/ccpm/commands/pm/clean.md deleted file mode 100644 index 58a88e3..0000000 --- a/ccpm/commands/pm/clean.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -allowed-tools: Bash, Read, Write, LS ---- - -# Clean - -Clean up completed work and archive old epics. - -## Usage -``` -/pm:clean [--dry-run] -``` - -Options: -- `--dry-run` - Show what would be cleaned without doing it - -## Instructions - -### 1. Identify Completed Epics - -Find epics with: -- `status: completed` in frontmatter -- All tasks closed -- Last update > 30 days ago - -### 2. Identify Stale Work - -Find: -- Progress files for closed issues -- Update directories for completed work -- Orphaned task files (epic deleted) -- Empty directories - -### 3. Show Cleanup Plan - -``` -🧹 Cleanup Plan - -Completed Epics to Archive: - {epic_name} - Completed {days} days ago - {epic_name} - Completed {days} days ago - -Stale Progress to Remove: - {count} progress files for closed issues - -Empty Directories: - {list_of_empty_dirs} - -Space to Recover: ~{size}KB - -{If --dry-run}: This is a dry run. No changes made. -{Otherwise}: Proceed with cleanup? (yes/no) -``` - -### 4. Execute Cleanup - -If user confirms: - -**Archive Epics:** -```bash -mkdir -p .claude/epics/.archived -mv .claude/epics/{completed_epic} .claude/epics/.archived/ -``` - -**Remove Stale Files:** -- Delete progress files for closed issues > 30 days -- Remove empty update directories -- Clean up orphaned files - -**Create Archive Log:** -Create `.claude/epics/.archived/archive-log.md`: -```markdown -# Archive Log - -## {current_date} -- Archived: {epic_name} (completed {date}) -- Removed: {count} stale progress files -- Cleaned: {count} empty directories -``` - -### 5. Output - -``` -✅ Cleanup Complete - -Archived: - {count} completed epics - -Removed: - {count} stale files - {count} empty directories - -Space recovered: {size}KB - -System is clean and organized. -``` - -## Important Notes - -Always offer --dry-run to preview changes. -Never delete PRDs or incomplete work. -Keep archive log for history. \ No newline at end of file diff --git a/ccpm/commands/pm/epic-close.md b/ccpm/commands/pm/epic-close.md deleted file mode 100644 index db2b181..0000000 --- a/ccpm/commands/pm/epic-close.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -allowed-tools: Bash, Read, Write, LS ---- - -# Epic Close - -Mark an epic as complete when all tasks are done. - -## Usage -``` -/pm:epic-close -``` - -## Instructions - -### 1. Verify All Tasks Complete - -Check all task files in `.claude/epics/$ARGUMENTS/`: -- Verify all have `status: closed` in frontmatter -- If any open tasks found: "❌ Cannot close epic. Open tasks remain: {list}" - -### 2. Update Epic Status - -Get current datetime: `date -u +"%Y-%m-%dT%H:%M:%SZ"` - -Update epic.md frontmatter: -```yaml -status: completed -progress: 100% -updated: {current_datetime} -completed: {current_datetime} -``` - -### 3. Update PRD Status - -If epic references a PRD, update its status to "complete". - -### 4. Close Epic on GitHub - -If epic has GitHub issue: -```bash -gh issue close {epic_issue_number} --comment "✅ Epic completed - all tasks done" -``` - -### 5. Archive Option - -Ask user: "Archive completed epic? (yes/no)" - -If yes: -- Move epic directory to `.claude/epics/.archived/{epic_name}/` -- Create archive summary with completion date - -### 6. Output - -``` -✅ Epic closed: $ARGUMENTS - Tasks completed: {count} - Duration: {days_from_created_to_completed} - -{If archived}: Archived to .claude/epics/.archived/ - -Next epic: Run /pm:next to see priority work -``` - -## Important Notes - -Only close epics with all tasks complete. -Preserve all data when archiving. -Update related PRD status. \ No newline at end of file diff --git a/ccpm/commands/pm/epic-decompose.md b/ccpm/commands/pm/epic-decompose.md deleted file mode 100644 index 2af2572..0000000 --- a/ccpm/commands/pm/epic-decompose.md +++ /dev/null @@ -1,230 +0,0 @@ ---- -allowed-tools: Bash, Read, Write, LS, Task ---- - -# Epic Decompose - -Break epic into concrete, actionable tasks. - -## Usage -``` -/pm:epic-decompose -``` - -## Required Rules - -**IMPORTANT:** Before executing this command, read and follow: -- `.claude/rules/datetime.md` - For getting real current date/time - -## Preflight Checklist - -Before proceeding, complete these validation steps. -Do not bother the user with preflight checks progress ("I'm not going to ..."). Just do them and move on. - -1. **Verify epic exists:** - - Check if `.claude/epics/$ARGUMENTS/epic.md` exists - - If not found, tell user: "❌ Epic not found: $ARGUMENTS. First create it with: /pm:prd-parse $ARGUMENTS" - - Stop execution if epic doesn't exist - -2. **Check for existing tasks:** - - Check if any numbered task files (001.md, 002.md, etc.) already exist in `.claude/epics/$ARGUMENTS/` - - If tasks exist, list them and ask: "⚠️ Found {count} existing tasks. Delete and recreate all tasks? (yes/no)" - - Only proceed with explicit 'yes' confirmation - - If user says no, suggest: "View existing tasks with: /pm:epic-show $ARGUMENTS" - -3. **Validate epic frontmatter:** - - Verify epic has valid frontmatter with: name, status, created, prd - - If invalid, tell user: "❌ Invalid epic frontmatter. Please check: .claude/epics/$ARGUMENTS/epic.md" - -4. **Check epic status:** - - If epic status is already "completed", warn user: "⚠️ Epic is marked as completed. Are you sure you want to decompose it again?" - -## Instructions - -You are decomposing an epic into specific, actionable tasks for: **$ARGUMENTS** - -### 1. Read the Epic -- Load the epic from `.claude/epics/$ARGUMENTS/epic.md` -- Understand the technical approach and requirements -- Review the task breakdown preview - -### 2. Analyze for Parallel Creation - -Determine if tasks can be created in parallel: -- If tasks are mostly independent: Create in parallel using Task agents -- If tasks have complex dependencies: Create sequentially -- For best results: Group independent tasks for parallel creation - -### 3. Parallel Task Creation (When Possible) - -If tasks can be created in parallel, spawn sub-agents: - -```yaml -Task: - description: "Create task files batch {X}" - subagent_type: "general-purpose" - prompt: | - Create task files for epic: $ARGUMENTS - - Tasks to create: - - {list of 3-4 tasks for this batch} - - For each task: - 1. Create file: .claude/epics/$ARGUMENTS/{number}.md - 2. Use exact format with frontmatter and all sections - 3. Follow task breakdown from epic - 4. Set parallel/depends_on fields appropriately - 5. Number sequentially (001.md, 002.md, etc.) - - Return: List of files created -``` - -### 4. Task File Format with Frontmatter -For each task, create a file with this exact structure: - -```markdown ---- -name: [Task Title] -status: open -created: [Current ISO date/time] -updated: [Current ISO date/time] -github: [Will be updated when synced to GitHub] -depends_on: [] # List of task numbers this depends on, e.g., [001, 002] -parallel: true # Can this run in parallel with other tasks? -conflicts_with: [] # Tasks that modify same files, e.g., [003, 004] ---- - -# Task: [Task Title] - -## Description -Clear, concise description of what needs to be done - -## Acceptance Criteria -- [ ] Specific criterion 1 -- [ ] Specific criterion 2 -- [ ] Specific criterion 3 - -## Technical Details -- Implementation approach -- Key considerations -- Code locations/files affected - -## Dependencies -- [ ] Task/Issue dependencies -- [ ] External dependencies - -## Effort Estimate -- Size: XS/S/M/L/XL -- Hours: estimated hours -- Parallel: true/false (can run in parallel with other tasks) - -## Definition of Done -- [ ] Code implemented -- [ ] Tests written and passing -- [ ] Documentation updated -- [ ] Code reviewed -- [ ] Deployed to staging -``` - -### 3. Task Naming Convention -Save tasks as: `.claude/epics/$ARGUMENTS/{task_number}.md` -- Use sequential numbering: 001.md, 002.md, etc. -- Keep task titles short but descriptive - -### 4. Frontmatter Guidelines -- **name**: Use a descriptive task title (without "Task:" prefix) -- **status**: Always start with "open" for new tasks -- **created**: Get REAL current datetime by running: `date -u +"%Y-%m-%dT%H:%M:%SZ"` -- **updated**: Use the same real datetime as created for new tasks -- **github**: Leave placeholder text - will be updated during sync -- **depends_on**: List task numbers that must complete before this can start (e.g., [001, 002]) -- **parallel**: Set to true if this can run alongside other tasks without conflicts -- **conflicts_with**: List task numbers that modify the same files (helps coordination) - -### 5. Task Types to Consider -- **Setup tasks**: Environment, dependencies, scaffolding -- **Data tasks**: Models, schemas, migrations -- **API tasks**: Endpoints, services, integration -- **UI tasks**: Components, pages, styling -- **Testing tasks**: Unit tests, integration tests -- **Documentation tasks**: README, API docs -- **Deployment tasks**: CI/CD, infrastructure - -### 6. Parallelization -Mark tasks with `parallel: true` if they can be worked on simultaneously without conflicts. - -### 7. Execution Strategy - -Choose based on task count and complexity: - -**Small Epic (< 5 tasks)**: Create sequentially for simplicity - -**Medium Epic (5-10 tasks)**: -- Batch into 2-3 groups -- Spawn agents for each batch -- Consolidate results - -**Large Epic (> 10 tasks)**: -- Analyze dependencies first -- Group independent tasks -- Launch parallel agents (max 5 concurrent) -- Create dependent tasks after prerequisites - -Example for parallel execution: -```markdown -Spawning 3 agents for parallel task creation: -- Agent 1: Creating tasks 001-003 (Database layer) -- Agent 2: Creating tasks 004-006 (API layer) -- Agent 3: Creating tasks 007-009 (UI layer) -``` - -### 8. Task Dependency Validation - -When creating tasks with dependencies: -- Ensure referenced dependencies exist (e.g., if Task 003 depends on Task 002, verify 002 was created) -- Check for circular dependencies (Task A → Task B → Task A) -- If dependency issues found, warn but continue: "⚠️ Task dependency warning: {details}" - -### 9. Update Epic with Task Summary -After creating all tasks, update the epic file by adding this section: -```markdown -## Tasks Created -- [ ] 001.md - {Task Title} (parallel: true/false) -- [ ] 002.md - {Task Title} (parallel: true/false) -- etc. - -Total tasks: {count} -Parallel tasks: {parallel_count} -Sequential tasks: {sequential_count} -Estimated total effort: {sum of hours} -``` - -Also update the epic's frontmatter progress if needed (still 0% until tasks actually start). - -### 9. Quality Validation - -Before finalizing tasks, verify: -- [ ] All tasks have clear acceptance criteria -- [ ] Task sizes are reasonable (1-3 days each) -- [ ] Dependencies are logical and achievable -- [ ] Parallel tasks don't conflict with each other -- [ ] Combined tasks cover all epic requirements - -### 10. Post-Decomposition - -After successfully creating tasks: -1. Confirm: "✅ Created {count} tasks for epic: $ARGUMENTS" -2. Show summary: - - Total tasks created - - Parallel vs sequential breakdown - - Total estimated effort -3. Suggest next step: "Ready to sync to GitHub? Run: /pm:epic-sync $ARGUMENTS" - -## Error Recovery - -If any step fails: -- If task creation partially completes, list which tasks were created -- Provide option to clean up partial tasks -- Never leave the epic in an inconsistent state - -Aim for tasks that can be completed in 1-3 days each. Break down larger tasks into smaller, manageable pieces for the "$ARGUMENTS" epic. diff --git a/ccpm/commands/pm/epic-edit.md b/ccpm/commands/pm/epic-edit.md deleted file mode 100644 index 850dd7d..0000000 --- a/ccpm/commands/pm/epic-edit.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -allowed-tools: Read, Write, LS ---- - -# Epic Edit - -Edit epic details after creation. - -## Usage -``` -/pm:epic-edit -``` - -## Instructions - -### 1. Read Current Epic - -Read `.claude/epics/$ARGUMENTS/epic.md`: -- Parse frontmatter -- Read content sections - -### 2. Interactive Edit - -Ask user what to edit: -- Name/Title -- Description/Overview -- Architecture decisions -- Technical approach -- Dependencies -- Success criteria - -### 3. Update Epic File - -Get current datetime: `date -u +"%Y-%m-%dT%H:%M:%SZ"` - -Update epic.md: -- Preserve all frontmatter except `updated` -- Apply user's edits to content -- Update `updated` field with current datetime - -### 4. Option to Update GitHub - -If epic has GitHub URL in frontmatter: -Ask: "Update GitHub issue? (yes/no)" - -If yes: -```bash -gh issue edit {issue_number} --body-file .claude/epics/$ARGUMENTS/epic.md -``` - -### 5. Output - -``` -✅ Updated epic: $ARGUMENTS - Changes made to: {sections_edited} - -{If GitHub updated}: GitHub issue updated ✅ - -View epic: /pm:epic-show $ARGUMENTS -``` - -## Important Notes - -Preserve frontmatter history (created, github URL, etc.). -Don't change task files when editing epic. -Follow `/rules/frontmatter-operations.md`. \ No newline at end of file diff --git a/ccpm/commands/pm/epic-list.md b/ccpm/commands/pm/epic-list.md deleted file mode 100644 index 4fe9b85..0000000 --- a/ccpm/commands/pm/epic-list.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -allowed-tools: Bash(bash ccpm/scripts/pm/epic-list.sh) ---- - -Output: -!bash ccpm/scripts/pm/epic-list.sh - diff --git a/ccpm/commands/pm/epic-merge.md b/ccpm/commands/pm/epic-merge.md deleted file mode 100644 index e0f886e..0000000 --- a/ccpm/commands/pm/epic-merge.md +++ /dev/null @@ -1,261 +0,0 @@ ---- -allowed-tools: Bash, Read, Write ---- - -# Epic Merge - -Merge completed epic from worktree back to main branch. - -## Usage -``` -/pm:epic-merge -``` - -## Quick Check - -1. **Verify worktree exists:** - ```bash - git worktree list | grep "epic-$ARGUMENTS" || echo "❌ No worktree for epic: $ARGUMENTS" - ``` - -2. **Check for active agents:** - Read `.claude/epics/$ARGUMENTS/execution-status.md` - If active agents exist: "⚠️ Active agents detected. Stop them first with: /pm:epic-stop $ARGUMENTS" - -## Instructions - -### 1. Pre-Merge Validation - -Navigate to worktree and check status: -```bash -cd ../epic-$ARGUMENTS - -# Check for uncommitted changes -if [[ $(git status --porcelain) ]]; then - echo "⚠️ Uncommitted changes in worktree:" - git status --short - echo "Commit or stash changes before merging" - exit 1 -fi - -# Check branch status -git fetch origin -git status -sb -``` - -### 2. Run Tests (Optional but Recommended) - -```bash -# Look for test commands based on project type -if [ -f package.json ]; then - npm test || echo "⚠️ Tests failed. Continue anyway? (yes/no)" -elif [ -f pom.xml ]; then - mvn test || echo "⚠️ Tests failed. Continue anyway? (yes/no)" -elif [ -f build.gradle ] || [ -f build.gradle.kts ]; then - ./gradlew test || echo "⚠️ Tests failed. Continue anyway? (yes/no)" -elif [ -f composer.json ]; then - ./vendor/bin/phpunit || echo "⚠️ Tests failed. Continue anyway? (yes/no)" -elif [ -f *.sln ] || [ -f *.csproj ]; then - dotnet test || echo "⚠️ Tests failed. Continue anyway? (yes/no)" -elif [ -f Cargo.toml ]; then - cargo test || echo "⚠️ Tests failed. Continue anyway? (yes/no)" -elif [ -f go.mod ]; then - go test ./... || echo "⚠️ Tests failed. Continue anyway? (yes/no)" -elif [ -f Gemfile ]; then - bundle exec rspec || bundle exec rake test || echo "⚠️ Tests failed. Continue anyway? (yes/no)" -elif [ -f pubspec.yaml ]; then - flutter test || echo "⚠️ Tests failed. Continue anyway? (yes/no)" -elif [ -f Package.swift ]; then - swift test || echo "⚠️ Tests failed. Continue anyway? (yes/no)" -elif [ -f CMakeLists.txt ]; then - cd build && ctest || echo "⚠️ Tests failed. Continue anyway? (yes/no)" -elif [ -f Makefile ]; then - make test || echo "⚠️ Tests failed. Continue anyway? (yes/no)" -fi -``` - -### 3. Update Epic Documentation - -Get current datetime: `date -u +"%Y-%m-%dT%H:%M:%SZ"` - -Update `.claude/epics/$ARGUMENTS/epic.md`: -- Set status to "completed" -- Update completion date -- Add final summary - -### 4. Attempt Merge - -```bash -# Return to main repository -cd {main-repo-path} - -# Ensure main is up to date -git checkout main -git pull origin main - -# Attempt merge -echo "Merging epic/$ARGUMENTS to main..." -git merge epic/$ARGUMENTS --no-ff -m "Merge epic: $ARGUMENTS - -Completed features: -# Generate feature list -feature_list="" -if [ -d ".claude/epics/$ARGUMENTS" ]; then - cd .claude/epics/$ARGUMENTS - for task_file in [0-9]*.md; do - [ -f "$task_file" ] || continue - task_name=$(grep '^name:' "$task_file" | cut -d: -f2 | sed 's/^ *//') - feature_list="$feature_list\n- $task_name" - done - cd - > /dev/null -fi - -echo "$feature_list" - -# Extract epic issue number -epic_github_line=$(grep 'github:' .claude/epics/$ARGUMENTS/epic.md 2>/dev/null || true) -if [ -n "$epic_github_line" ]; then - epic_issue=$(echo "$epic_github_line" | grep -oE '[0-9]+' || true) - if [ -n "$epic_issue" ]; then - echo "\nCloses epic #$epic_issue" - fi -fi" -``` - -### 5. Handle Merge Conflicts - -If merge fails with conflicts: -```bash -# Check conflict status -git status - -echo " -❌ Merge conflicts detected! - -Conflicts in: -$(git diff --name-only --diff-filter=U) - -Options: -1. Resolve manually: - - Edit conflicted files - - git add {files} - - git commit - -2. Abort merge: - git merge --abort - -3. Get help: - /pm:epic-resolve $ARGUMENTS - -Worktree preserved at: ../epic-$ARGUMENTS -" -exit 1 -``` - -### 6. Post-Merge Cleanup - -If merge succeeds: -```bash -# Push to remote -git push origin main - -# Clean up worktree -git worktree remove ../epic-$ARGUMENTS -echo "✅ Worktree removed: ../epic-$ARGUMENTS" - -# Delete branch -git branch -d epic/$ARGUMENTS -git push origin --delete epic/$ARGUMENTS 2>/dev/null || true - -# Archive epic locally -mkdir -p .claude/epics/archived/ -mv .claude/epics/$ARGUMENTS .claude/epics/archived/ -echo "✅ Epic archived: .claude/epics/archived/$ARGUMENTS" -``` - -### 7. Update GitHub Issues - -Close related issues: -```bash -# Get issue numbers from epic -# Extract epic issue number -epic_github_line=$(grep 'github:' .claude/epics/archived/$ARGUMENTS/epic.md 2>/dev/null || true) -if [ -n "$epic_github_line" ]; then - epic_issue=$(echo "$epic_github_line" | grep -oE '[0-9]+$' || true) -else - epic_issue="" -fi - -# Close epic issue -gh issue close $epic_issue -c "Epic completed and merged to main" - -# Close task issues -for task_file in .claude/epics/archived/$ARGUMENTS/[0-9]*.md; do - [ -f "$task_file" ] || continue - # Extract task issue number - task_github_line=$(grep 'github:' "$task_file" 2>/dev/null || true) - if [ -n "$task_github_line" ]; then - issue_num=$(echo "$task_github_line" | grep -oE '[0-9]+$' || true) - else - issue_num="" - fi - if [ ! -z "$issue_num" ]; then - gh issue close $issue_num -c "Completed in epic merge" - fi -done -``` - -### 8. Final Output - -``` -✅ Epic Merged Successfully: $ARGUMENTS - -Summary: - Branch: epic/$ARGUMENTS → main - Commits merged: {count} - Files changed: {count} - Issues closed: {count} - -Cleanup completed: - ✓ Worktree removed - ✓ Branch deleted - ✓ Epic archived - ✓ GitHub issues closed - -Next steps: - - Deploy changes if needed - - Start new epic: /pm:prd-new {feature} - - View completed work: git log --oneline -20 -``` - -## Conflict Resolution Help - -If conflicts need resolution: -``` -The epic branch has conflicts with main. - -This typically happens when: -- Main has changed since epic started -- Multiple epics modified same files -- Dependencies were updated - -To resolve: -1. Open conflicted files -2. Look for <<<<<<< markers -3. Choose correct version or combine -4. Remove conflict markers -5. git add {resolved files} -6. git commit -7. git push - -Or abort and try later: - git merge --abort -``` - -## Important Notes - -- Always check for uncommitted changes first -- Run tests before merging when possible -- Use --no-ff to preserve epic history -- Archive epic data instead of deleting -- Close GitHub issues to maintain sync \ No newline at end of file diff --git a/ccpm/commands/pm/epic-oneshot.md b/ccpm/commands/pm/epic-oneshot.md deleted file mode 100644 index 80f2e06..0000000 --- a/ccpm/commands/pm/epic-oneshot.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -allowed-tools: Read, LS ---- - -# Epic Oneshot - -Decompose epic into tasks and sync to GitHub in one operation. - -## Usage -``` -/pm:epic-oneshot -``` - -## Instructions - -### 1. Validate Prerequisites - -Check that epic exists and hasn't been processed: -```bash -# Epic must exist -test -f .claude/epics/$ARGUMENTS/epic.md || echo "❌ Epic not found. Run: /pm:prd-parse $ARGUMENTS" - -# Check for existing tasks -if ls .claude/epics/$ARGUMENTS/[0-9]*.md 2>/dev/null | grep -q .; then - echo "⚠️ Tasks already exist. This will create duplicates." - echo "Delete existing tasks or use /pm:epic-sync instead." - exit 1 -fi - -# Check if already synced -if grep -q "github:" .claude/epics/$ARGUMENTS/epic.md; then - echo "⚠️ Epic already synced to GitHub." - echo "Use /pm:epic-sync to update." - exit 1 -fi -``` - -### 2. Execute Decompose - -Simply run the decompose command: -``` -Running: /pm:epic-decompose $ARGUMENTS -``` - -This will: -- Read the epic -- Create task files (using parallel agents if appropriate) -- Update epic with task summary - -### 3. Execute Sync - -Immediately follow with sync: -``` -Running: /pm:epic-sync $ARGUMENTS -``` - -This will: -- Create epic issue on GitHub -- Create sub-issues (using parallel agents if appropriate) -- Rename task files to issue IDs -- Create worktree - -### 4. Output - -``` -🚀 Epic Oneshot Complete: $ARGUMENTS - -Step 1: Decomposition ✓ - - Tasks created: {count} - -Step 2: GitHub Sync ✓ - - Epic: #{number} - - Sub-issues created: {count} - - Worktree: ../epic-$ARGUMENTS - -Ready for development! - Start work: /pm:epic-start $ARGUMENTS - Or single task: /pm:issue-start {task_number} -``` - -## Important Notes - -This is simply a convenience wrapper that runs: -1. `/pm:epic-decompose` -2. `/pm:epic-sync` - -Both commands handle their own error checking, parallel execution, and validation. This command just orchestrates them in sequence. - -Use this when you're confident the epic is ready and want to go from epic to GitHub issues in one step. \ No newline at end of file diff --git a/ccpm/commands/pm/epic-refresh.md b/ccpm/commands/pm/epic-refresh.md deleted file mode 100644 index 7fa511e..0000000 --- a/ccpm/commands/pm/epic-refresh.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -allowed-tools: Read, Write, LS ---- - -# Epic Refresh - -Update epic progress based on task states. - -## Usage -``` -/pm:epic-refresh -``` - -## Instructions - -### 1. Count Task Status - -Scan all task files in `.claude/epics/$ARGUMENTS/`: -- Count total tasks -- Count tasks with `status: closed` -- Count tasks with `status: open` -- Count tasks with work in progress - -### 2. Calculate Progress - -``` -progress = (closed_tasks / total_tasks) * 100 -``` - -Round to nearest integer. - -### 3. Update GitHub Task List - -If epic has GitHub issue, sync task checkboxes: - -```bash -# Get epic issue number from epic.md frontmatter -epic_issue={extract_from_github_field} - -if [ ! -z "$epic_issue" ]; then - # Get current epic body - gh issue view $epic_issue --json body -q .body > /tmp/epic-body.md - - # For each task, check its status and update checkbox - for task_file in .claude/epics/$ARGUMENTS/[0-9]*.md; do - # Extract task issue number - task_github_line=$(grep 'github:' "$task_file" 2>/dev/null || true) - if [ -n "$task_github_line" ]; then - task_issue=$(echo "$task_github_line" | grep -oE '[0-9]+$' || true) - else - task_issue="" - fi - task_status=$(grep 'status:' $task_file | cut -d: -f2 | tr -d ' ') - - if [ "$task_status" = "closed" ]; then - # Mark as checked - sed -i "s/- \[ \] #$task_issue/- [x] #$task_issue/" /tmp/epic-body.md - else - # Ensure unchecked (in case manually checked) - sed -i "s/- \[x\] #$task_issue/- [ ] #$task_issue/" /tmp/epic-body.md - fi - done - - # Update epic issue - gh issue edit $epic_issue --body-file /tmp/epic-body.md -fi -``` - -### 4. Determine Epic Status - -- If progress = 0% and no work started: `backlog` -- If progress > 0% and < 100%: `in-progress` -- If progress = 100%: `completed` - -### 5. Update Epic - -Get current datetime: `date -u +"%Y-%m-%dT%H:%M:%SZ"` - -Update epic.md frontmatter: -```yaml -status: {calculated_status} -progress: {calculated_progress}% -updated: {current_datetime} -``` - -### 6. Output - -``` -🔄 Epic refreshed: $ARGUMENTS - -Tasks: - Closed: {closed_count} - Open: {open_count} - Total: {total_count} - -Progress: {old_progress}% → {new_progress}% -Status: {old_status} → {new_status} -GitHub: Task list updated ✓ - -{If complete}: Run /pm:epic-close $ARGUMENTS to close epic -{If in progress}: Run /pm:next to see priority tasks -``` - -## Important Notes - -This is useful after manual task edits or GitHub sync. -Don't modify task files, only epic status. -Preserve all other frontmatter fields. \ No newline at end of file diff --git a/ccpm/commands/pm/epic-show.md b/ccpm/commands/pm/epic-show.md deleted file mode 100644 index d87a264..0000000 --- a/ccpm/commands/pm/epic-show.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -allowed-tools: Bash(bash ccpm/scripts/pm/epic-show.sh $ARGUMENTS) ---- - -Output: -!bash ccpm/scripts/pm/epic-show.sh $ARGUMENTS diff --git a/ccpm/commands/pm/epic-start-worktree.md b/ccpm/commands/pm/epic-start-worktree.md deleted file mode 100644 index 29d6cb5..0000000 --- a/ccpm/commands/pm/epic-start-worktree.md +++ /dev/null @@ -1,221 +0,0 @@ ---- -allowed-tools: Bash, Read, Write, LS, Task ---- - -# Epic Start - -Launch parallel agents to work on epic tasks in a shared worktree. - -## Usage -``` -/pm:epic-start -``` - -## Quick Check - -1. **Verify epic exists:** - ```bash - test -f .claude/epics/$ARGUMENTS/epic.md || echo "❌ Epic not found. Run: /pm:prd-parse $ARGUMENTS" - ``` - -2. **Check GitHub sync:** - Look for `github:` field in epic frontmatter. - If missing: "❌ Epic not synced. Run: /pm:epic-sync $ARGUMENTS first" - -3. **Check for worktree:** - ```bash - git worktree list | grep "epic-$ARGUMENTS" - ``` - -## Instructions - -### 1. Create or Enter Worktree - -Follow `/rules/worktree-operations.md`: - -```bash -# If worktree doesn't exist, create it -if ! git worktree list | grep -q "epic-$ARGUMENTS"; then - git checkout main - git pull origin main - git worktree add ../epic-$ARGUMENTS -b epic/$ARGUMENTS - echo "✅ Created worktree: ../epic-$ARGUMENTS" -else - echo "✅ Using existing worktree: ../epic-$ARGUMENTS" -fi -``` - -### 2. Identify Ready Issues - -Read all task files in `.claude/epics/$ARGUMENTS/`: -- Parse frontmatter for `status`, `depends_on`, `parallel` fields -- Check GitHub issue status if needed -- Build dependency graph - -Categorize issues: -- **Ready**: No unmet dependencies, not started -- **Blocked**: Has unmet dependencies -- **In Progress**: Already being worked on -- **Complete**: Finished - -### 3. Analyze Ready Issues - -For each ready issue without analysis: -```bash -# Check for analysis -if ! test -f .claude/epics/$ARGUMENTS/{issue}-analysis.md; then - echo "Analyzing issue #{issue}..." - # Run analysis (inline or via Task tool) -fi -``` - -### 4. Launch Parallel Agents - -For each ready issue with analysis: - -```markdown -## Starting Issue #{issue}: {title} - -Reading analysis... -Found {count} parallel streams: - - Stream A: {description} (Agent-{id}) - - Stream B: {description} (Agent-{id}) - -Launching agents in worktree: ../epic-$ARGUMENTS/ -``` - -Use Task tool to launch each stream: -```yaml -Task: - description: "Issue #{issue} Stream {X}" - subagent_type: "{agent_type}" - prompt: | - Working in worktree: ../epic-$ARGUMENTS/ - Issue: #{issue} - {title} - Stream: {stream_name} - - Your scope: - - Files: {file_patterns} - - Work: {stream_description} - - Read full requirements from: - - .claude/epics/$ARGUMENTS/{task_file} - - .claude/epics/$ARGUMENTS/{issue}-analysis.md - - Follow coordination rules in /rules/agent-coordination.md - - Commit frequently with message format: - "Issue #{issue}: {specific change}" - - Update progress in: - .claude/epics/$ARGUMENTS/updates/{issue}/stream-{X}.md -``` - -### 5. Track Active Agents - -Create/update `.claude/epics/$ARGUMENTS/execution-status.md`: - -```markdown ---- -started: {datetime} -worktree: ../epic-$ARGUMENTS -branch: epic/$ARGUMENTS ---- - -# Execution Status - -## Active Agents -- Agent-1: Issue #1234 Stream A (Database) - Started {time} -- Agent-2: Issue #1234 Stream B (API) - Started {time} -- Agent-3: Issue #1235 Stream A (UI) - Started {time} - -## Queued Issues -- Issue #1236 - Waiting for #1234 -- Issue #1237 - Waiting for #1235 - -## Completed -- {None yet} -``` - -### 6. Monitor and Coordinate - -Set up monitoring: -```bash -echo " -Agents launched successfully! - -Monitor progress: - /pm:epic-status $ARGUMENTS - -View worktree changes: - cd ../epic-$ARGUMENTS && git status - -Stop all agents: - /pm:epic-stop $ARGUMENTS - -Merge when complete: - /pm:epic-merge $ARGUMENTS -" -``` - -### 7. Handle Dependencies - -As agents complete streams: -- Check if any blocked issues are now ready -- Launch new agents for newly-ready work -- Update execution-status.md - -## Output Format - -``` -🚀 Epic Execution Started: $ARGUMENTS - -Worktree: ../epic-$ARGUMENTS -Branch: epic/$ARGUMENTS - -Launching {total} agents across {issue_count} issues: - -Issue #1234: Database Schema - ├─ Stream A: Schema creation (Agent-1) ✓ Started - └─ Stream B: Migrations (Agent-2) ✓ Started - -Issue #1235: API Endpoints - ├─ Stream A: User endpoints (Agent-3) ✓ Started - ├─ Stream B: Post endpoints (Agent-4) ✓ Started - └─ Stream C: Tests (Agent-5) ⏸ Waiting for A & B - -Blocked Issues (2): - - #1236: UI Components (depends on #1234) - - #1237: Integration (depends on #1235, #1236) - -Monitor with: /pm:epic-status $ARGUMENTS -``` - -## Error Handling - -If agent launch fails: -``` -❌ Failed to start Agent-{id} - Issue: #{issue} - Stream: {stream} - Error: {reason} - -Continue with other agents? (yes/no) -``` - -If worktree creation fails: -``` -❌ Cannot create worktree - {git error message} - -Try: git worktree prune -Or: Check existing worktrees with: git worktree list -``` - -## Important Notes - -- Follow `/rules/worktree-operations.md` for git operations -- Follow `/rules/agent-coordination.md` for parallel work -- Agents work in the SAME worktree (not separate ones) -- Maximum parallel agents should be reasonable (e.g., 5-10) -- Monitor system resources if launching many agents diff --git a/ccpm/commands/pm/epic-start.md b/ccpm/commands/pm/epic-start.md deleted file mode 100644 index 51628a4..0000000 --- a/ccpm/commands/pm/epic-start.md +++ /dev/null @@ -1,247 +0,0 @@ ---- -allowed-tools: Bash, Read, Write, LS, Task ---- - -# Epic Start - -Launch parallel agents to work on epic tasks in a shared branch. - -## Usage -``` -/pm:epic-start -``` - -## Quick Check - -1. **Verify epic exists:** - ```bash - test -f .claude/epics/$ARGUMENTS/epic.md || echo "❌ Epic not found. Run: /pm:prd-parse $ARGUMENTS" - ``` - -2. **Check GitHub sync:** - Look for `github:` field in epic frontmatter. - If missing: "❌ Epic not synced. Run: /pm:epic-sync $ARGUMENTS first" - -3. **Check for branch:** - ```bash - git branch -a | grep "epic/$ARGUMENTS" - ``` - -4. **Check for uncommitted changes:** - ```bash - git status --porcelain - ``` - If output is not empty: "❌ You have uncommitted changes. Please commit or stash them before starting an epic" - -## Instructions - -### 1. Create or Enter Branch - -Follow `/rules/branch-operations.md`: - -```bash -# Check for uncommitted changes -if [ -n "$(git status --porcelain)" ]; then - echo "❌ You have uncommitted changes. Please commit or stash them before starting an epic." - exit 1 -fi - -# If branch doesn't exist, create it -if ! git branch -a | grep -q "epic/$ARGUMENTS"; then - git checkout main - git pull origin main - git checkout -b epic/$ARGUMENTS - git push -u origin epic/$ARGUMENTS - echo "✅ Created branch: epic/$ARGUMENTS" -else - git checkout epic/$ARGUMENTS - git pull origin epic/$ARGUMENTS - echo "✅ Using existing branch: epic/$ARGUMENTS" -fi -``` - -### 2. Identify Ready Issues - -Read all task files in `.claude/epics/$ARGUMENTS/`: -- Parse frontmatter for `status`, `depends_on`, `parallel` fields -- Check GitHub issue status if needed -- Build dependency graph - -Categorize issues: -- **Ready**: No unmet dependencies, not started -- **Blocked**: Has unmet dependencies -- **In Progress**: Already being worked on -- **Complete**: Finished - -### 3. Analyze Ready Issues - -For each ready issue without analysis: -```bash -# Check for analysis -if ! test -f .claude/epics/$ARGUMENTS/{issue}-analysis.md; then - echo "Analyzing issue #{issue}..." - # Run analysis (inline or via Task tool) -fi -``` - -### 4. Launch Parallel Agents - -For each ready issue with analysis: - -```markdown -## Starting Issue #{issue}: {title} - -Reading analysis... -Found {count} parallel streams: - - Stream A: {description} (Agent-{id}) - - Stream B: {description} (Agent-{id}) - -Launching agents in branch: epic/$ARGUMENTS -``` - -Use Task tool to launch each stream: -```yaml -Task: - description: "Issue #{issue} Stream {X}" - subagent_type: "{agent_type}" - prompt: | - Working in branch: epic/$ARGUMENTS - Issue: #{issue} - {title} - Stream: {stream_name} - - Your scope: - - Files: {file_patterns} - - Work: {stream_description} - - Read full requirements from: - - .claude/epics/$ARGUMENTS/{task_file} - - .claude/epics/$ARGUMENTS/{issue}-analysis.md - - Follow coordination rules in /rules/agent-coordination.md - - Commit frequently with message format: - "Issue #{issue}: {specific change}" - - Update progress in: - .claude/epics/$ARGUMENTS/updates/{issue}/stream-{X}.md -``` - -### 5. Track Active Agents - -Create/update `.claude/epics/$ARGUMENTS/execution-status.md`: - -```markdown ---- -started: {datetime} -branch: epic/$ARGUMENTS ---- - -# Execution Status - -## Active Agents -- Agent-1: Issue #1234 Stream A (Database) - Started {time} -- Agent-2: Issue #1234 Stream B (API) - Started {time} -- Agent-3: Issue #1235 Stream A (UI) - Started {time} - -## Queued Issues -- Issue #1236 - Waiting for #1234 -- Issue #1237 - Waiting for #1235 - -## Completed -- {None yet} -``` - -### 6. Monitor and Coordinate - -Set up monitoring: -```bash -echo " -Agents launched successfully! - -Monitor progress: - /pm:epic-status $ARGUMENTS - -View branch changes: - git status - -Stop all agents: - /pm:epic-stop $ARGUMENTS - -Merge when complete: - /pm:epic-merge $ARGUMENTS -" -``` - -### 7. Handle Dependencies - -As agents complete streams: -- Check if any blocked issues are now ready -- Launch new agents for newly-ready work -- Update execution-status.md - -## Output Format - -``` -🚀 Epic Execution Started: $ARGUMENTS - -Branch: epic/$ARGUMENTS - -Launching {total} agents across {issue_count} issues: - -Issue #1234: Database Schema - ├─ Stream A: Schema creation (Agent-1) ✓ Started - └─ Stream B: Migrations (Agent-2) ✓ Started - -Issue #1235: API Endpoints - ├─ Stream A: User endpoints (Agent-3) ✓ Started - ├─ Stream B: Post endpoints (Agent-4) ✓ Started - └─ Stream C: Tests (Agent-5) ⏸ Waiting for A & B - -Blocked Issues (2): - - #1236: UI Components (depends on #1234) - - #1237: Integration (depends on #1235, #1236) - -Monitor with: /pm:epic-status $ARGUMENTS -``` - -## Error Handling - -If agent launch fails: -``` -❌ Failed to start Agent-{id} - Issue: #{issue} - Stream: {stream} - Error: {reason} - -Continue with other agents? (yes/no) -``` - -If uncommitted changes are found: -``` -❌ You have uncommitted changes. Please commit or stash them before starting an epic. - -To commit changes: - git add . - git commit -m "Your commit message" - -To stash changes: - git stash push -m "Work in progress" - # (Later restore with: git stash pop) -``` - -If branch creation fails: -``` -❌ Cannot create branch - {git error message} - -Try: git branch -d epic/$ARGUMENTS -Or: Check existing branches with: git branch -a -``` - -## Important Notes - -- Follow `/rules/branch-operations.md` for git operations -- Follow `/rules/agent-coordination.md` for parallel work -- Agents work in the SAME branch (not separate branches) -- Maximum parallel agents should be reasonable (e.g., 5-10) -- Monitor system resources if launching many agents diff --git a/ccpm/commands/pm/epic-status.md b/ccpm/commands/pm/epic-status.md deleted file mode 100644 index b969b19..0000000 --- a/ccpm/commands/pm/epic-status.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -allowed-tools: Bash(bash ccpm/scripts/pm/epic-status.sh $ARGUMENTS) ---- - -Output: -!bash ccpm/scripts/pm/epic-status.sh $ARGUMENTS diff --git a/ccpm/commands/pm/epic-sync.md b/ccpm/commands/pm/epic-sync.md deleted file mode 100644 index 7c5a26d..0000000 --- a/ccpm/commands/pm/epic-sync.md +++ /dev/null @@ -1,468 +0,0 @@ ---- -allowed-tools: Bash, Read, Write, LS, Task ---- - -# Epic Sync - -Push epic and tasks to GitHub as issues. - -## Usage -``` -/pm:epic-sync -``` - -## Quick Check - -```bash -# Verify epic exists -test -f .claude/epics/$ARGUMENTS/epic.md || echo "❌ Epic not found. Run: /pm:prd-parse $ARGUMENTS" - -# Count task files -ls .claude/epics/$ARGUMENTS/*.md 2>/dev/null | grep -v epic.md | wc -l -``` - -If no tasks found: "❌ No tasks to sync. Run: /pm:epic-decompose $ARGUMENTS" - -## Instructions - -### 0. Check Remote Repository - -Follow `/rules/github-operations.md` to ensure we're not syncing to the CCPM template: - -```bash -# Check if remote origin is the CCPM template repository -remote_url=$(git remote get-url origin 2>/dev/null || echo "") -if [[ "$remote_url" == *"automazeio/ccpm"* ]] || [[ "$remote_url" == *"automazeio/ccpm.git"* ]]; then - echo "❌ ERROR: You're trying to sync with the CCPM template repository!" - echo "" - echo "This repository (automazeio/ccpm) is a template for others to use." - echo "You should NOT create issues or PRs here." - echo "" - echo "To fix this:" - echo "1. Fork this repository to your own GitHub account" - echo "2. Update your remote origin:" - echo " git remote set-url origin https://github.com/YOUR_USERNAME/YOUR_REPO.git" - echo "" - echo "Or if this is a new project:" - echo "1. Create a new repository on GitHub" - echo "2. Update your remote origin:" - echo " git remote set-url origin https://github.com/YOUR_USERNAME/YOUR_REPO.git" - echo "" - echo "Current remote: $remote_url" - exit 1 -fi -``` - -### 1. Create Epic Issue - -#### First, detect the GitHub repository: -```bash -# Get the current repository from git remote -remote_url=$(git remote get-url origin 2>/dev/null || echo "") -REPO=$(echo "$remote_url" | sed 's|.*github.com[:/]||' | sed 's|\.git$||') -[ -z "$REPO" ] && REPO="user/repo" -echo "Creating issues in repository: $REPO" -``` - -Strip frontmatter and prepare GitHub issue body: -```bash -# Extract content without frontmatter -sed '1,/^---$/d; 1,/^---$/d' .claude/epics/$ARGUMENTS/epic.md > /tmp/epic-body-raw.md - -# Remove "## Tasks Created" section and replace with Stats -awk ' - /^## Tasks Created/ { - in_tasks=1 - next - } - /^## / && in_tasks { - in_tasks=0 - # When we hit the next section after Tasks Created, add Stats - if (total_tasks) { - print "## Stats" - print "" - print "Total tasks: " total_tasks - print "Parallel tasks: " parallel_tasks " (can be worked on simultaneously)" - print "Sequential tasks: " sequential_tasks " (have dependencies)" - if (total_effort) print "Estimated total effort: " total_effort " hours" - print "" - } - } - /^Total tasks:/ && in_tasks { total_tasks = $3; next } - /^Parallel tasks:/ && in_tasks { parallel_tasks = $3; next } - /^Sequential tasks:/ && in_tasks { sequential_tasks = $3; next } - /^Estimated total effort:/ && in_tasks { - gsub(/^Estimated total effort: /, "") - total_effort = $0 - next - } - !in_tasks { print } - END { - # If we were still in tasks section at EOF, add stats - if (in_tasks && total_tasks) { - print "## Stats" - print "" - print "Total tasks: " total_tasks - print "Parallel tasks: " parallel_tasks " (can be worked on simultaneously)" - print "Sequential tasks: " sequential_tasks " (have dependencies)" - if (total_effort) print "Estimated total effort: " total_effort - } - } -' /tmp/epic-body-raw.md > /tmp/epic-body.md - -# Determine epic type (feature vs bug) from content -if grep -qi "bug\|fix\|issue\|problem\|error" /tmp/epic-body.md; then - epic_type="bug" -else - epic_type="feature" -fi - -# Create epic issue with labels -epic_number=$(gh issue create \ - --repo "$REPO" \ - --title "Epic: $ARGUMENTS" \ - --body-file /tmp/epic-body.md \ - --label "epic,epic:$ARGUMENTS,$epic_type" \ - --json number -q .number) -``` - -Store the returned issue number for epic frontmatter update. - -### 2. Create Task Sub-Issues - -Check if gh-sub-issue is available: -```bash -if gh extension list | grep -q "yahsan2/gh-sub-issue"; then - use_subissues=true -else - use_subissues=false - echo "⚠️ gh-sub-issue not installed. Using fallback mode." -fi -``` - -Count task files to determine strategy: -```bash -task_count=$(ls .claude/epics/$ARGUMENTS/[0-9][0-9][0-9].md 2>/dev/null | wc -l) -``` - -### For Small Batches (< 5 tasks): Sequential Creation - -```bash -if [ "$task_count" -lt 5 ]; then - # Create sequentially for small batches - for task_file in .claude/epics/$ARGUMENTS/[0-9][0-9][0-9].md; do - [ -f "$task_file" ] || continue - - # Extract task name from frontmatter - task_name=$(grep '^name:' "$task_file" | sed 's/^name: *//') - - # Strip frontmatter from task content - sed '1,/^---$/d; 1,/^---$/d' "$task_file" > /tmp/task-body.md - - # Create sub-issue with labels - if [ "$use_subissues" = true ]; then - task_number=$(gh sub-issue create \ - --parent "$epic_number" \ - --title "$task_name" \ - --body-file /tmp/task-body.md \ - --label "task,epic:$ARGUMENTS" \ - --json number -q .number) - else - task_number=$(gh issue create \ - --repo "$REPO" \ - --title "$task_name" \ - --body-file /tmp/task-body.md \ - --label "task,epic:$ARGUMENTS" \ - --json number -q .number) - fi - - # Record mapping for renaming - echo "$task_file:$task_number" >> /tmp/task-mapping.txt - done - - # After creating all issues, update references and rename files - # This follows the same process as step 3 below -fi -``` - -### For Larger Batches: Parallel Creation - -```bash -if [ "$task_count" -ge 5 ]; then - echo "Creating $task_count sub-issues in parallel..." - - # Check if gh-sub-issue is available for parallel agents - if gh extension list | grep -q "yahsan2/gh-sub-issue"; then - subissue_cmd="gh sub-issue create --parent $epic_number" - else - subissue_cmd="gh issue create --repo \"$REPO\"" - fi - - # Batch tasks for parallel processing - # Spawn agents to create sub-issues in parallel with proper labels - # Each agent must use: --label "task,epic:$ARGUMENTS" -fi -``` - -Use Task tool for parallel creation: -```yaml -Task: - description: "Create GitHub sub-issues batch {X}" - subagent_type: "general-purpose" - prompt: | - Create GitHub sub-issues for tasks in epic $ARGUMENTS - Parent epic issue: #$epic_number - - Tasks to process: - - {list of 3-4 task files} - - For each task file: - 1. Extract task name from frontmatter - 2. Strip frontmatter using: sed '1,/^---$/d; 1,/^---$/d' - 3. Create sub-issue using: - - If gh-sub-issue available: - gh sub-issue create --parent $epic_number --title "$task_name" \ - --body-file /tmp/task-body.md --label "task,epic:$ARGUMENTS" - - Otherwise: - gh issue create --repo "$REPO" --title "$task_name" --body-file /tmp/task-body.md \ - --label "task,epic:$ARGUMENTS" - 4. Record: task_file:issue_number - - IMPORTANT: Always include --label parameter with "task,epic:$ARGUMENTS" - - Return mapping of files to issue numbers. -``` - -Consolidate results from parallel agents: -```bash -# Collect all mappings from agents -cat /tmp/batch-*/mapping.txt >> /tmp/task-mapping.txt - -# IMPORTANT: After consolidation, follow step 3 to: -# 1. Build old->new ID mapping -# 2. Update all task references (depends_on, conflicts_with) -# 3. Rename files with proper frontmatter updates -``` - -### 3. Rename Task Files and Update References - -First, build a mapping of old numbers to new issue IDs: -```bash -# Create mapping from old task numbers (001, 002, etc.) to new issue IDs -> /tmp/id-mapping.txt -while IFS=: read -r task_file task_number; do - # Extract old number from filename (e.g., 001 from 001.md) - old_num=$(basename "$task_file" .md) - echo "$old_num:$task_number" >> /tmp/id-mapping.txt -done < /tmp/task-mapping.txt -``` - -Then rename files and update all references: -```bash -# Process each task file -while IFS=: read -r task_file task_number; do - new_name="$(dirname "$task_file")/${task_number}.md" - - # Read the file content - content=$(cat "$task_file") - - # Update depends_on and conflicts_with references - while IFS=: read -r old_num new_num; do - # Update arrays like [001, 002] to use new issue numbers - content=$(echo "$content" | sed "s/\b$old_num\b/$new_num/g") - done < /tmp/id-mapping.txt - - # Write updated content to new file - echo "$content" > "$new_name" - - # Remove old file if different from new - [ "$task_file" != "$new_name" ] && rm "$task_file" - - # Update github field in frontmatter - # Add the GitHub URL to the frontmatter - repo=$(gh repo view --json nameWithOwner -q .nameWithOwner) - github_url="https://github.com/$repo/issues/$task_number" - - # Update frontmatter with GitHub URL and current timestamp - current_date=$(date -u +"%Y-%m-%dT%H:%M:%SZ") - - # Use sed to update the github and updated fields - sed -i.bak "/^github:/c\github: $github_url" "$new_name" - sed -i.bak "/^updated:/c\updated: $current_date" "$new_name" - rm "${new_name}.bak" -done < /tmp/task-mapping.txt -``` - -### 4. Update Epic with Task List (Fallback Only) - -If NOT using gh-sub-issue, add task list to epic: - -```bash -if [ "$use_subissues" = false ]; then - # Get current epic body - gh issue view ${epic_number} --json body -q .body > /tmp/epic-body.md - - # Append task list - cat >> /tmp/epic-body.md << 'EOF' - - ## Tasks - - [ ] #${task1_number} ${task1_name} - - [ ] #${task2_number} ${task2_name} - - [ ] #${task3_number} ${task3_name} - EOF - - # Update epic issue - gh issue edit ${epic_number} --body-file /tmp/epic-body.md -fi -``` - -With gh-sub-issue, this is automatic! - -### 5. Update Epic File - -Update the epic file with GitHub URL, timestamp, and real task IDs: - -#### 5a. Update Frontmatter -```bash -# Get repo info -repo=$(gh repo view --json nameWithOwner -q .nameWithOwner) -epic_url="https://github.com/$repo/issues/$epic_number" -current_date=$(date -u +"%Y-%m-%dT%H:%M:%SZ") - -# Update epic frontmatter -sed -i.bak "/^github:/c\github: $epic_url" .claude/epics/$ARGUMENTS/epic.md -sed -i.bak "/^updated:/c\updated: $current_date" .claude/epics/$ARGUMENTS/epic.md -rm .claude/epics/$ARGUMENTS/epic.md.bak -``` - -#### 5b. Update Tasks Created Section -```bash -# Create a temporary file with the updated Tasks Created section -cat > /tmp/tasks-section.md << 'EOF' -## Tasks Created -EOF - -# Add each task with its real issue number -for task_file in .claude/epics/$ARGUMENTS/[0-9]*.md; do - [ -f "$task_file" ] || continue - - # Get issue number (filename without .md) - issue_num=$(basename "$task_file" .md) - - # Get task name from frontmatter - task_name=$(grep '^name:' "$task_file" | sed 's/^name: *//') - - # Get parallel status - parallel=$(grep '^parallel:' "$task_file" | sed 's/^parallel: *//') - - # Add to tasks section - echo "- [ ] #${issue_num} - ${task_name} (parallel: ${parallel})" >> /tmp/tasks-section.md -done - -# Add summary statistics -total_count=$(ls .claude/epics/$ARGUMENTS/[0-9]*.md 2>/dev/null | wc -l) -parallel_count=$(grep -l '^parallel: true' .claude/epics/$ARGUMENTS/[0-9]*.md 2>/dev/null | wc -l) -sequential_count=$((total_count - parallel_count)) - -cat >> /tmp/tasks-section.md << EOF - -Total tasks: ${total_count} -Parallel tasks: ${parallel_count} -Sequential tasks: ${sequential_count} -EOF - -# Replace the Tasks Created section in epic.md -# First, create a backup -cp .claude/epics/$ARGUMENTS/epic.md .claude/epics/$ARGUMENTS/epic.md.backup - -# Use awk to replace the section -awk ' - /^## Tasks Created/ { - skip=1 - while ((getline line < "/tmp/tasks-section.md") > 0) print line - close("/tmp/tasks-section.md") - } - /^## / && !/^## Tasks Created/ { skip=0 } - !skip && !/^## Tasks Created/ { print } -' .claude/epics/$ARGUMENTS/epic.md.backup > .claude/epics/$ARGUMENTS/epic.md - -# Clean up -rm .claude/epics/$ARGUMENTS/epic.md.backup -rm /tmp/tasks-section.md -``` - -### 6. Create Mapping File - -Create `.claude/epics/$ARGUMENTS/github-mapping.md`: -```bash -# Create mapping file -cat > .claude/epics/$ARGUMENTS/github-mapping.md << EOF -# GitHub Issue Mapping - -Epic: #${epic_number} - https://github.com/${repo}/issues/${epic_number} - -Tasks: -EOF - -# Add each task mapping -for task_file in .claude/epics/$ARGUMENTS/[0-9]*.md; do - [ -f "$task_file" ] || continue - - issue_num=$(basename "$task_file" .md) - task_name=$(grep '^name:' "$task_file" | sed 's/^name: *//') - - echo "- #${issue_num}: ${task_name} - https://github.com/${repo}/issues/${issue_num}" >> .claude/epics/$ARGUMENTS/github-mapping.md -done - -# Add sync timestamp -echo "" >> .claude/epics/$ARGUMENTS/github-mapping.md -echo "Synced: $(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> .claude/epics/$ARGUMENTS/github-mapping.md -``` - -### 7. Create Worktree - -Follow `/rules/worktree-operations.md` to create development worktree: - -```bash -# Ensure main is current -git checkout main -git pull origin main - -# Create worktree for epic -git worktree add ../epic-$ARGUMENTS -b epic/$ARGUMENTS - -echo "✅ Created worktree: ../epic-$ARGUMENTS" -``` - -### 8. Output - -``` -✅ Synced to GitHub - - Epic: #{epic_number} - {epic_title} - - Tasks: {count} sub-issues created - - Labels applied: epic, task, epic:{name} - - Files renamed: 001.md → {issue_id}.md - - References updated: depends_on/conflicts_with now use issue IDs - - Worktree: ../epic-$ARGUMENTS - -Next steps: - - Start parallel execution: /pm:epic-start $ARGUMENTS - - Or work on single issue: /pm:issue-start {issue_number} - - View epic: https://github.com/{owner}/{repo}/issues/{epic_number} -``` - -## Error Handling - -Follow `/rules/github-operations.md` for GitHub CLI errors. - -If any issue creation fails: -- Report what succeeded -- Note what failed -- Don't attempt rollback (partial sync is fine) - -## Important Notes - -- Trust GitHub CLI authentication -- Don't pre-check for duplicates -- Update frontmatter only after successful creation -- Keep operations simple and atomic diff --git a/ccpm/commands/pm/help.md b/ccpm/commands/pm/help.md deleted file mode 100644 index c06de88..0000000 --- a/ccpm/commands/pm/help.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -allowed-tools: Bash(bash ccpm/scripts/pm/help.sh) ---- - -Output: -!bash ccpm/scripts/pm/help.sh diff --git a/ccpm/commands/pm/import.md b/ccpm/commands/pm/import.md deleted file mode 100644 index dac9c9e..0000000 --- a/ccpm/commands/pm/import.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -allowed-tools: Bash, Read, Write, LS ---- - -# Import - -Import existing GitHub issues into the PM system. - -## Usage -``` -/pm:import [--epic ] [--label