Repository: automazeio/ccpm Branch: main Commit: 7d7e4623bc6d Files: 25 Total size: 86.0 KB Directory structure: gitextract_ix8zt55d/ ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md └── skill/ └── ccpm/ ├── SKILL.md └── references/ ├── conventions.md ├── execute.md ├── plan.md ├── scripts/ │ ├── blocked.sh │ ├── epic-list.sh │ ├── epic-show.sh │ ├── epic-status.sh │ ├── help.sh │ ├── in-progress.sh │ ├── init.sh │ ├── next.sh │ ├── prd-list.sh │ ├── prd-status.sh │ ├── search.sh │ ├── standup.sh │ ├── status.sh │ └── validate.sh ├── structure.md ├── sync.md └── track.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ skill/ccpm-workspace/ skill/ccpm/evals/ ccpm-talk/ CCPM_CLI_REWRITE_PRD.md ccpm-cli-prd.md video ================================================ FILE: CHANGELOG.md ================================================ # CCPM Changelog ## [2025-01-24] - Major Cleanup & Issue Resolution Release ### 🎯 Overview Resolved 10 of 12 open GitHub issues, modernized command syntax, improved documentation, and enhanced system accuracy. This release focuses on stability, usability, and addressing community feedback. ### ✨ Added - **Local Mode Support** ([#201](https://github.com/automazeio/ccpm/issues/201)) - Created `LOCAL_MODE.md` with comprehensive offline workflow guide - All core commands (prd-new, prd-parse, epic-decompose) work without GitHub - Clear distinction between local-only vs GitHub-dependent commands - **Automatic GitHub Label Creation** ([#544](https://github.com/automazeio/ccpm/issues/544)) - Enhanced `init.sh` to automatically create `epic` and `task` labels - Proper colors: `epic` (green #0E8A16), `task` (blue #1D76DB) - Eliminates manual label setup during project initialization - **Context Creation Accuracy Safeguards** ([#48](https://github.com/automazeio/ccpm/issues/48)) - Added mandatory self-verification checkpoints in context commands - Implemented evidence-based analysis requirements - Added uncertainty flagging with `⚠️ Assumption - requires verification` - Enhanced both `/context:create` and `/context:update` with accuracy validation ### 🔄 Changed - **Modernized Command Syntax** ([#531](https://github.com/automazeio/ccpm/issues/531)) - Updated 14 PM command files to use concise `!bash` execution pattern - Simplified `allowed-tools` frontmatter declarations - Reduced token usage and improved Claude Code compatibility - **Comprehensive README Overhaul** ([#323](https://github.com/automazeio/ccpm/issues/323)) - Clarified PRD vs Epic terminology and definitions - Streamlined workflow explanations and removed redundant sections - Fixed installation instructions and troubleshooting guidance - Improved overall structure and navigation ### 📋 Research & Community Engagement - **Multi-Tracker Support Analysis** ([#200](https://github.com/automazeio/ccpm/issues/200)) - Researched CLI availability for Linear, Trello, Azure DevOps, Jira - Identified Linear as best first alternative to GitHub Issues - Provided detailed implementation roadmap for future development - **GitLab Support Research** ([#588](https://github.com/automazeio/ccpm/issues/588)) - Confirmed strong `glab` CLI support for GitLab integration - Invited community contributor to submit existing GitLab implementation as PR - Updated project roadmap to include GitLab as priority platform ### 🐛 Clarified Platform Limitations - **Windows Shell Compatibility** ([#609](https://github.com/automazeio/ccpm/issues/609)) - Documented as Claude Code platform limitation (requires POSIX shell) - Provided workarounds and alternative solutions - **Codex CLI Integration** ([#585](https://github.com/automazeio/ccpm/issues/585)) - Explained future multi-AI provider support in new CLI architecture - **Parallel Worker Agent Behavior** ([#530](https://github.com/automazeio/ccpm/issues/530)) - Clarified agent role as coordinator, not direct coder - Provided implementation guidance and workarounds ### 🔒 Security - **Privacy Documentation Fix** ([#630](https://github.com/automazeio/ccpm/issues/630)) - Verified resolution via PR #631 (remove real repository references) ### 💡 Proposed Features - **Bug Handling Workflow** ([#654](https://github.com/automazeio/ccpm/issues/654)) - Designed `/pm:attach-bug` command for automated bug tracking - Proposed lightweight sub-issue integration with existing infrastructure - Community feedback requested on implementation approach ### 📊 Issues Resolved **Closed**: 10 issues **Active Proposals**: 1 issue (#654) **Remaining Open**: 1 issue (#653) #### Closed Issues: - [#630](https://github.com/automazeio/ccpm/issues/630) - Privacy: Remove real repo references ✅ - [#609](https://github.com/automazeio/ccpm/issues/609) - Windows shell error (platform limitation) ✅ - [#585](https://github.com/automazeio/ccpm/issues/585) - Codex CLI compatibility (architecture update) ✅ - [#571](https://github.com/automazeio/ccpm/issues/571) - Figma MCP support (platform feature) ✅ - [#531](https://github.com/automazeio/ccpm/issues/531) - Use !bash in custom slash commands ✅ - [#323](https://github.com/automazeio/ccpm/issues/323) - Improve README.md ✅ - [#201](https://github.com/automazeio/ccpm/issues/201) - Local-only mode support ✅ - [#200](https://github.com/automazeio/ccpm/issues/200) - Multi-tracker support research ✅ - [#588](https://github.com/automazeio/ccpm/issues/588) - GitLab support research ✅ - [#48](https://github.com/automazeio/ccpm/issues/48) - Context creation inaccuracies ✅ - [#530](https://github.com/automazeio/ccpm/issues/530) - Parallel worker coding operations ✅ - [#544](https://github.com/automazeio/ccpm/issues/544) - Auto-create labels during init ✅ - [#947](https://github.com/automazeio/ccpm/issues/947) - Project roadmap update ✅ ### 🛠️ Technical Details - **Files Modified**: 16 core files + documentation - **New Files**: `LOCAL_MODE.md`, `CONTEXT_ACCURACY.md` - **Commands Updated**: All 14 PM slash commands modernized - **Backward Compatibility**: Fully maintained - **Dependencies**: No new external dependencies added ### 🏗️ Project Health - **Issue Resolution Rate**: 83% (10/12 issues closed) - **Documentation Coverage**: Significantly improved - **Community Engagement**: Active contributor invitation and feedback solicitation - **Code Quality**: Enhanced accuracy safeguards and validation ### 🚀 Next Steps 1. Community feedback on bug handling proposal (#654) 2. GitLab integration PR review and merge 3. Linear platform integration (pending demand) 4. Enhanced testing and validation workflows --- *This release represents a major stability and usability milestone for CCPM, addressing the majority of outstanding community issues while establishing a foundation for future multi-platform support.* ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2025 Ran Aroussi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # CCPM – The Project Manager Agent [![Agent Skills](https://img.shields.io/badge/Agent_Skills-compatible-4b3baf)](https://agentskills.io)   [![Eval Score](https://img.shields.io/badge/eval_score-100%25-brightgreen)](#proven-results)   [![GitHub Issues](https://img.shields.io/badge/+-GitHub%20Issues-1f2328)](https://github.com/automazeio/ccpm)   [![MIT License](https://img.shields.io/badge/License-MIT-28a745)](LICENSE)   [![Follow on 𝕏](https://img.shields.io/badge/𝕏-@aroussi-1c9bf0)](http://x.com/intent/follow?screen_name=aroussi)   [![Star this repo](https://img.shields.io/github/stars/automazeio/ccpm.svg?style=social&label=Star%20this%20repo&maxAge=60)](https://github.com/automazeio/ccpm) ### Spec-driven development for AI agents – ship ~~faster~~ _better_ using PRDs, GitHub issues, and multiple agents running in parallel. Stop losing context. Stop blocking on tasks. Stop shipping bugs. CCPM gives your AI agent a structured PM brain: turn ideas into PRDs, PRDs into epics, epics into GitHub issues, and issues into production code — with full traceability at every step. --- > [!IMPORTANT] > 📢 **CCPM is now an AGENT SKILL!** It works with any [Agent Skills–compatible](https://agentskills.io) harness that supports skills: **Claude Code, Codex, OpenCode, Factory, Amp, Cursor, and more.** --- ![CCPM](screenshot.webp) ## Table of Contents - [Background](#background) - [The Workflow](#the-workflow) - [What Makes This Different](#what-makes-this-different) - [Why GitHub Issues](#why-github-issues) - [Core Principle: No Vibe Coding](#core-principle-no-vibe-coding) - [The Parallel Execution System](#the-parallel-execution-system) - [Key Features & Benefits](#key-features--benefits) - [Install](#install) - [Usage](#usage) - [Workflow Phases](#workflow-phases) - [Skill Structure](#skill-structure) - [Example Flow](#example-flow) - [Proven Results](#proven-results) - [Local vs Remote](#local-vs-remote) - [Technical Notes](#technical-notes) - [Who's Behind this Project](#whos-behind-this-project) --- > [!NOTE] > Check out **[proof](https://github.com/automazeio/proof)** to get your agents capture visual proof of work of terminal output, browser interactions, and mobile simulator recordings. --- ## Background Every team struggles with the same problems: - **Context evaporates** between sessions, forcing constant re-discovery - **Parallel work creates conflicts** when multiple agents touch the same code - **Requirements drift** as verbal decisions override written specs - **Progress becomes invisible** until the very end CCPM solves all of that. --- ## The Workflow ```mermaid graph LR A[PRD Creation] --> B[Epic Planning] B --> C[Task Decomposition] C --> D[GitHub Sync] D --> E[Parallel Execution] ``` ### See It In Action ``` "I want to build a notification system — where do we start?" → Guided brainstorming + PRD creation "break down the notification-system epic" → Parallelizable task files with dependencies "sync the notification-system epic to GitHub" → Epic issue + sub-issues + worktree "start working on issue 42" → Parallel stream analysis + multiple agents launched "what's our standup for today?" → Instant report from project files ``` --- ## What Makes This Different | Traditional AI Development | CCPM | |---|---| | Context lost between sessions | **Persistent context** across all work | | One agent, one task | **Parallel agents** on independent streams | | Vibe coding from memory | **Spec-driven** with full traceability | | Progress hidden in chat logs | **Transparent audit trail** in GitHub | | Scattered status updates | **Structured standup, blocked, next** | --- ## Why GitHub Issues Most AI coding workflows operate in isolation — a single session with no shared state. CCPM uses GitHub Issues as the source of truth, which unlocks something fundamentally different: **Team collaboration** — multiple agents (or humans) work on the same project simultaneously. Progress is visible in real-time through issue comments. **Seamless handoffs** — an agent can start a task, a human can finish it, or vice versa. No "what did the AI do?" meetings. **Single source of truth** — no separate databases or project management tools. Issue state is project state. Comments are the audit trail. **Works with what you have** — no dependency on GitHub Projects. Integrates with existing labels, milestones, and PR workflows. --- ## Core Principle: No Vibe Coding > **Every line of code must trace back to a specification.** CCPM enforces a strict 5-phase discipline: 1. **🧠 Brainstorm** — think deeper than comfortable 2. **📝 Document** — write specs that leave nothing to interpretation 3. **📐 Plan** — architect with explicit technical decisions 4. **⚡ Execute** — build exactly what was specified 5. **📊 Track** — maintain transparent progress at every step No shortcuts. No assumptions. No regrets. --- ## The Parallel Execution System ### Issues Aren't Atomic Traditional thinking: **one issue = one agent = one task** Reality: a single "Implement user authentication" issue is actually: - **Agent 1**: Database tables and migrations - **Agent 2**: Service layer and business logic - **Agent 3**: API endpoints and middleware - **Agent 4**: UI components and forms - **Agent 5**: Test suites and documentation All running **simultaneously** in the same worktree. ### The Math of Velocity | Approach | Agents working | Wall time | |---|---|---| | Traditional (serial) | 1 | 5x | | CCPM (parallel streams) | 5 | 1x | ### Context Stays Clean Each agent handles its own context in isolation. Your main conversation becomes the conductor — it never drowns in implementation details. Agents read from `.claude/epics/` and commit progress back through Git. --- ## Key Features & Benefits **🧠 Context preservation** — project state lives in files, not in your head or chat history. Start a session anywhere, any time. **⚡ Parallel execution** — tasks marked `parallel: true` run concurrently across multiple agents without conflicts. **🔗 GitHub native** — works with tools your team already uses. No dependency on the Projects API. **📊 Full traceability** — every decision documented. PRD → Epic → Task → Issue → Code → Commit. **🤖 Deterministic ops run as scripts** — status, standup, search, validate all run as bash scripts: fast, consistent, no LLM token cost. **🌐 Harness-agnostic** — follows the [agentskills.io](https://agentskills.io) open standard. Works with Factory, Claude Code, Amp, OpenCode, Codex, Cursor, and more. --- ## Install CCPM is a standard [Agent Skill](https://agentskills.io). Point your harness at `skill/ccpm/` — that's it. ### Clone the repo ```bash git clone https://github.com/automazeio/ccpm.git ``` ### Factory / Droid ```bash # Symlink into your skills directory ln -s /path/to/ccpm/skill/ccpm ~/.factory/skills/ccpm ``` ### Claude Code In your project root, add a `skills/` directory and symlink or copy the skill: ```bash ln -s /path/to/ccpm/skill/ccpm .claude/skills/ccpm ``` ### Any other Agent Skills–compatible harness Point it at `skill/ccpm/`. It follows the [agentskills.io](https://agentskills.io) standard and works out of the box. ### Prerequisites - `git` and `gh` CLI (authenticated: `gh auth login`) - A GitHub repository for your project --- ## Usage CCPM activates automatically when your agent detects PM intent. Just talk naturally — no special syntax needed. ### Natural language triggers | What you say | What happens | |---|---| | "I want to build X" / "let's plan X" | Brainstorming + PRD creation | | "parse the X PRD" / "create an epic for X" | PRD → technical epic | | "break down the X epic" | Epic decomposition into tasks | | "sync the X epic to GitHub" | Issues created, worktree set up | | "start working on issue N" | Analysis + parallel agents launched | | "standup" / "what's our status" | Bash script runs instantly | | "what's next" / "what's blocked" | Priority queue from project files | | "close issue N" | Local + GitHub updated | | "merge the X epic" | Tests, merge, cleanup | --- ## Workflow Phases ### 1. Plan — Capture requirements ``` "I want to build a notification system — push, email, and in-app" ``` CCPM conducts guided brainstorming before writing anything. It asks about the problem, users, success criteria, constraints, and what's out of scope — then creates a structured PRD at `.claude/prds/.md`. When ready: "parse the notification-system PRD" → produces a technical epic at `.claude/epics/notification-system/epic.md` with architecture decisions, technical approach, and task preview. ### 2. Structure — Break it down ``` "break down the notification-system epic into tasks" ``` Each task gets a file with acceptance criteria, effort estimate, `depends_on`, `parallel`, and `conflicts_with` metadata. Tasks are intelligently batched for parallel creation. ≤10 tasks per epic by default. ### 3. Sync — Push to GitHub ``` "sync the notification-system epic to GitHub" ``` Creates an epic issue, creates sub-issues for each task, renames local files to match GitHub issue numbers, sets up a dedicated worktree (`../epic-notification-system/`), and creates a mapping file for reference. ### 4. Execute — Start building ``` "start working on issue 42" ``` Analyzes the issue for independent work streams, launches parallel agents scoped to their own files, and sets up progress tracking. Each agent commits with `Issue #N: description` and coordinates through Git. ### 5. Track — Know where things stand ``` "standup" / "what's blocked" / "what's next" ``` All tracking operations run as bash scripts — instant output, no LLM overhead. The scripts scan `.claude/epics/` and report what's in progress, what's next, and what's blocked. --- ## Skill Structure ``` skill/ccpm/ ├── SKILL.md # Entry point — detects intent, routes to reference └── references/ ├── plan.md # PRD writing + parsing to epic ├── structure.md # Epic decomposition into tasks ├── sync.md # GitHub sync, progress comments, close, merge ├── execute.md # Issue analysis + parallel agent launch ├── track.md # Status, standup, search, next, blocked ├── conventions.md # File formats, frontmatter schemas, git rules └── scripts/ # Bash scripts for deterministic operations ├── status.sh ├── standup.sh ├── epic-list.sh ├── search.sh └── ... # 14 scripts total ``` Your project files live in `.claude/` in your project root: ``` .claude/ ├── prds/ # Product requirement documents ├── epics/ │ └── / │ ├── epic.md # Technical epic │ ├── .md # Task files (named by GitHub issue number after sync) │ ├── -analysis.md # Parallel work stream analysis │ └── updates/ # Agent progress tracking └── (archived epics) ``` Files are the source of truth — plain markdown that lives in your repo, no external services. --- ## Example Flow ``` You: "I want to build a payment integration with Stripe — subscriptions and one-time charges" CCPM: Asks 5 clarifying questions about scope, users, success criteria... You: [answers] CCPM: ✅ PRD created: .claude/prds/payment-integration.md Ready to create the technical epic? You: "yes, parse it" CCPM: ✅ Epic created: .claude/epics/payment-integration/epic.md 8 task categories identified. Ready to decompose? You: "break it down" CCPM: ✅ Created 7 tasks — 5 parallel, 2 sequential Ready to push to GitHub? You: "sync it" CCPM: ✅ Epic #1234 created ✅ 7 sub-issues created (#1235–#1241) ✅ Worktree: ../epic-payment-integration/ You: "start working on issue 1235" CCPM: Analyzed 3 parallel streams: Stream A: Stripe client setup ✓ Started Stream B: Webhook handler ✓ Started Stream C: Database models ⏸ Waiting on A You: "what's our standup?" CCPM: [runs standup.sh instantly] 📅 Daily Standup — 2026-03-18 🔄 In Progress: Issue #1235 (payment-integration) — 60% ⏭️ Next: Issue #1236 — Subscription billing logic 📊 Tasks: 2 in progress, 5 open, 0 closed ``` --- ## Proven Results Teams using this system report: - **89% less time** lost to context switching - **5–8 parallel tasks** vs 1 previously - **75% reduction** in bug rates — due to detailed task breakdown before coding - **Up to 3× faster** feature delivery ### Benchmark In structured evals comparing CCPM-equipped agents vs baseline (no skill): | Scenario | With CCPM | Without | |---|---|---| | PRD creation (brainstorm-first, correct paths) | ✅ 4/4 | ❌ 2/4 | | Issue execution (analysis + worktree checks) | ✅ 4/4 | ❌ 0/4 | | Standup (runs script, real data) | ✅ 3/3 | ❌ 1/3 | | **Overall** | **100%** | **27.7%** | --- ## Local vs Remote | Operation | Local | GitHub | |---|---|---| | PRD creation | ✅ | — | | Implementation planning | ✅ | — | | Task breakdown | ✅ | ✅ (on sync) | | Execution | ✅ | — | | Progress updates | ✅ | ✅ (on sync) | | Final deliverables | — | ✅ | --- ## Technical Notes **GitHub integration** — uses `gh-sub-issue` extension for proper parent-child relationships. Falls back to task lists if not installed. Install with: `gh extension install yahsan2/gh-sub-issue` **File naming** — tasks start as `001.md`, `002.md` during decomposition. After GitHub sync, renamed to `{issue-id}.md` (e.g. `1234.md`). Issue #1234 = file `1234.md`. **Design decisions** — intentionally avoids GitHub Projects API complexity. All operations work on local files first for speed. GitHub sync is explicit and controlled. Worktrees provide clean git isolation for parallel work. **Looking for v1?** — The original `/pm:*` Claude Code slash command system is preserved on the [`v1` branch](https://github.com/automazeio/ccpm/tree/v1). --- ## Who's behind this project CCPM was developed at [Automaze](https://automaze.io) **for developers who ship, by developers who ship**. If CCPM helps your team ship better software: - ⭐ **[Star this repository](https://github.com/automazeio/ccpm)** to show your support - 🐦 **[Follow @aroussi on X](https://x.com/aroussi)** for updates and tips --- > [!TIP] > **Ship faster with Automaze.** We partner with founders to bring their vision to life, scale their business, and optimize for success. > **[Visit Automaze to book a call ›](https://automaze.io)** --- ![Star History Chart](https://api.star-history.com/svg?repos=automazeio/ccpm) ================================================ FILE: skill/ccpm/SKILL.md ================================================ --- name: ccpm description: "CCPM - spec-driven project management: PRD → Epic → GitHub Issues → parallel agents → shipped code. Use this skill for anything in the software delivery lifecycle: writing a PRD ('write a PRD for X', 'let's plan X', 'scope this out'), parsing a PRD into an epic, decomposing an epic into tasks, syncing to GitHub ('sync the X epic', 'push tasks to github'), starting work on an issue ('start working on issue N', 'let's work on issue N'), analyzing parallel work streams, running standups ('standup', 'run the standup'), checking status ('what's next', 'what's blocked', 'what are we working on'), closing issues, or merging an epic. Use ccpm any time the user is talking about shipping a feature, managing work, or tracking progress — even if they don't say 'ccpm' or 'PRD'. Do NOT use for: debugging code, writing tests, reviewing PRs, or raw GitHub issue/PR operations with no delivery context." --- # CCPM - Claude Code Project Manager A spec-driven development workflow: PRD → Epic → GitHub Issues → Parallel Agents → Shipped Code. ## Core Philosophy Requirements live in files, not heads. Every feature starts as a PRD, becomes a technical epic, decomposes into GitHub issues, and gets executed by parallel agents with full traceability. ## File Conventions Before doing anything, read `references/conventions.md` for path standards, frontmatter schemas, and GitHub operation rules. These apply to all phases. ## The Five Phases ### 1. Plan — Capture requirements **When**: User wants to define a new feature, product requirement, or scope of work. **Read**: `references/plan.md` **Covers**: Writing PRDs through guided brainstorming, converting PRDs to technical epics. ### 2. Structure — Break it down **When**: An epic exists and needs to be decomposed into concrete tasks. **Read**: `references/structure.md` **Covers**: Epic decomposition into numbered task files with dependencies and parallelization. ### 3. Sync — Push to GitHub **When**: Local epic/tasks need to become GitHub issues, progress needs to be posted as comments, or a bug is found and needs a linked issue created. **Read**: `references/sync.md` **Covers**: Epic sync (epic + tasks → GitHub issues), issue sync (progress comments), closing issues/epics, bug reporting against completed issues. ### 4. Execute — Start building **When**: User wants to start working on one or more GitHub issues with parallel agents. **Read**: `references/execute.md` **Covers**: Issue analysis (parallel work stream identification), launching parallel agents, coordinating worktrees. ### 5. Track — Know where things stand **When**: User asks for status, standup report, what's blocked, what's next, or needs to validate state. **Read**: `references/track.md` **Covers**: Status, standup, search, in-progress, next priority, blocked items, validation. --- ## Script-First Rule For deterministic operations — anything that reads and reports without needing reasoning — always run the bash script directly rather than doing the work manually: | What the user wants | Script to run | |---|---| | Project status | `bash references/scripts/status.sh` | | Standup report | `bash references/scripts/standup.sh` | | List all epics | `bash references/scripts/epic-list.sh` | | Show epic details | `bash references/scripts/epic-show.sh ` | | Epic status | `bash references/scripts/epic-status.sh ` | | List PRDs | `bash references/scripts/prd-list.sh` | | PRD status | `bash references/scripts/prd-status.sh` | | Search issues/tasks | `bash references/scripts/search.sh ` | | What's in progress | `bash references/scripts/in-progress.sh` | | What's next | `bash references/scripts/next.sh` | | What's blocked | `bash references/scripts/blocked.sh` | | Validate project state | `bash references/scripts/validate.sh` | Use the LLM for work that requires reasoning: writing PRDs, analyzing parallelism, launching agents, synthesizing updates. --- ## Quick Reference ``` Plan a feature: "I want to build X" or "create a PRD for X" Parse to epic: "turn the X PRD into an epic" Decompose: "break down the X epic into tasks" Sync to GitHub: "push the X epic to GitHub" Start an issue: "start working on issue 42" Check status: "what's our status" / "standup" What's next: "what should I work on next" Merge epic: "merge the X epic" Report a bug: "found a bug in issue 42" / "testing issue 42 revealed X" ``` ================================================ FILE: skill/ccpm/references/conventions.md ================================================ # Conventions — File Formats, Paths & Rules Read this before doing any file operations across all phases. --- ## Directory Structure ``` .claude/ ├── prds/ │ └── .md # Product requirement documents ├── epics/ │ ├── / │ │ ├── epic.md # Technical epic │ │ ├── .md # Task files (named by GitHub issue number after sync) │ │ ├── -analysis.md # Parallel work stream analysis │ │ ├── github-mapping.md # Issue number → URL mapping │ │ ├── execution-status.md # Active agents tracker │ │ └── updates/ │ │ └── / │ │ ├── stream-A.md # Per-agent progress │ │ ├── progress.md # Overall issue progress │ │ └── execution.md # Execution state │ └── archived/ │ └── / # Completed epics └── context/ # Project context docs (separate system) ``` --- ## Frontmatter Schemas ### PRD (.claude/prds/.md) ```yaml --- name: # kebab-case, matches filename description: # used in lists and summaries status: backlog | active | completed created: # date -u +"%Y-%m-%dT%H:%M:%SZ" --- ``` ### Epic (.claude/epics//epic.md) ```yaml --- name: status: backlog | in-progress | completed created: updated: progress: 0% # recalculated when tasks close prd: .claude/prds/.md github: https://github.com///issues/ # set on sync --- ``` ### Task (.claude/epics//.md) ```yaml --- name: status: open | in-progress | closed created: updated: github: https://github.com///issues/ # set on sync depends_on: [] # issue numbers this must wait for parallel: true # can run concurrently with non-conflicting tasks conflicts_with: [] # issue numbers that touch the same files --- ``` ### Progress (.claude/epics//updates//progress.md) ```yaml --- issue: started: last_sync: completion: 0% --- ``` --- ## Datetime Rule Always get real current datetime from the system — never use placeholder text: ```bash date -u +"%Y-%m-%dT%H:%M:%SZ" ``` --- ## Frontmatter Update Pattern When updating a single frontmatter field in an existing file: ```bash sed -i.bak "/^:/c\\: " rm .bak ``` When stripping frontmatter to get body content for GitHub: ```bash sed '1,/^---$/d; 1,/^---$/d' > /tmp/body.md ``` --- ## GitHub Operations ### Repository Safety Check (run before any write operation) ```bash remote_url=$(git remote get-url origin 2>/dev/null || echo "") if [[ "$remote_url" == *"automazeio/ccpm"* ]]; then echo "❌ Cannot write to the CCPM template repository." echo "Update remote: git remote set-url origin https://github.com/YOUR/REPO.git" exit 1 fi REPO=$(echo "$remote_url" | sed 's|.*github.com[:/]||' | sed 's|\.git$||') ``` ### Authentication Don't pre-check authentication. Run the `gh` command and handle failure: ```bash gh || echo "❌ GitHub CLI failed. Run: gh auth login" ``` ### Getting Issue Numbers ```bash # From a task file's github field: grep 'github:' | grep -oE '[0-9]+$' ``` --- ## Git / Worktree Conventions - One branch per epic: `epic/` - Worktrees live at `../epic-/` (sibling to project root) - Always start branches from an up-to-date main: ```bash git checkout main && git pull origin main git worktree add ../epic- -b epic/ ``` - Commit format inside epics: `Issue #: ` - Never use `--force` in any git operation --- ## Naming Conventions - Feature names: kebab-case, lowercase, letters/numbers/hyphens, starts with a letter - Task files before sync: `001.md`, `002.md`, ... (sequential) - Task files after sync: renamed to GitHub issue number (e.g., `1234.md`) - Labels applied on sync: `epic`, `epic:`, `feature` (for epics); `task`, `epic:` (for tasks) --- ## Epic Progress Calculation ```bash total=$(ls .claude/epics//[0-9]*.md 2>/dev/null | wc -l) closed=$(grep -l '^status: closed' .claude/epics//[0-9]*.md 2>/dev/null | wc -l) progress=$((closed * 100 / total)) ``` Update epic frontmatter when any task closes. ================================================ FILE: skill/ccpm/references/execute.md ================================================ # Execute — Start Building with Parallel Agents This phase covers analyzing GitHub issues for parallel work streams and launching agents to execute them. --- ## Issue Analysis **Trigger**: User wants to understand how to parallelize work on an issue before starting. ### Preflight - Find the local task file: check `.claude/epics/*/.md` first, then search for `github:.*issues/` in frontmatter. - If not found: "❌ No local task for issue #. Run a sync first." ### Process Get issue details: `gh issue view --json title,body,labels` Read the local task file fully. Identify independent work streams by asking: - Which files will be created/modified? - Which changes can happen simultaneously without conflict? - What are the dependencies between changes? **Common stream patterns:** - Database Layer: schema, migrations, models - Service Layer: business logic, data access - API Layer: endpoints, validation, middleware - UI Layer: components, pages, styles - Test Layer: unit tests, integration tests Create `.claude/epics//-analysis.md`: ```markdown --- issue: title: analyzed: <run: date -u +"%Y-%m-%dT%H:%M:%SZ"> estimated_hours: <total> parallelization_factor: <1.0-5.0> --- # Parallel Work Analysis: Issue #<N> ## Overview ## Parallel Streams ### Stream A: <Name> **Scope**: **Files**: **Can Start**: immediately **Estimated Hours**: **Dependencies**: none ### Stream B: <Name> **Scope**: **Files**: **Can Start**: after Stream A **Dependencies**: Stream A ## Coordination Points ### Shared Files ### Sequential Requirements ## Conflict Risk Assessment ## Parallelization Strategy ## Expected Timeline - With parallel execution: <max_stream_hours>h wall time - Without: <sum_all_hours>h - Efficiency gain: <pct>% ``` **Output**: "✅ Analysis complete for issue #<N> — N parallel streams identified. Ready to start? Say: start issue <N>" --- ## Starting an Issue **Trigger**: User wants to begin work on a specific GitHub issue. ### Preflight 1. Verify issue exists and is open: `gh issue view <N> --json state,title,labels,body` 2. Find local task file (as above). 3. Check for analysis file: `.claude/epics/*/<N>-analysis.md` — if missing, run analysis first (or do both in sequence: analyze then start). 4. Verify epic worktree exists: `git worktree list | grep "epic-<name>"` — if not: "❌ No worktree. Sync the epic first." ### Process **Step 1 — Read the analysis**, identify which streams can start immediately vs. which have dependencies. **Step 2 — Create progress tracking:** ```bash mkdir -p .claude/epics/<epic>/updates/<N> current_date=$(date -u +"%Y-%m-%dT%H:%M:%SZ") ``` Create `.claude/epics/<epic>/updates/<N>/stream-<X>.md` for each stream: ```markdown --- issue: <N> stream: <stream_name> started: <datetime> status: in_progress --- ## Scope ## Progress - Starting implementation ``` **Step 3 — Launch parallel agents** for each stream that can start immediately: ```yaml Task: description: "Issue #<N> Stream <X>" subagent_type: "general-purpose" prompt: | You are working on Issue #<N> in the epic worktree at: ../epic-<name>/ Your stream: <stream_name> Your scope — files to modify: <file_patterns> Work to complete: <stream_description> Instructions: 1. Read full task from: .claude/epics/<epic>/<N>.md 2. Read analysis from: .claude/epics/<epic>/<N>-analysis.md 3. Work ONLY in your assigned files 4. Commit frequently: "Issue #<N>: <specific change>" 5. Update progress in: .claude/epics/<epic>/updates/<N>/stream-<X>.md 6. If you need to touch files outside your scope, note it in your progress file and wait 7. Never use --force on git operations Complete your stream's work and mark status: completed when done. ``` Streams with unmet dependencies are queued — launch them as their dependencies complete. **Step 4 — Assign on GitHub:** ```bash gh issue edit <N> --add-assignee @me --add-label "in-progress" ``` **Step 5 — Create execution status file** at `.claude/epics/<epic>/updates/<N>/execution.md`: ```markdown ## Active Streams - Stream A: <name> — Started <time> - Stream B: <name> — Started <time> ## Queued - Stream C: <name> — Waiting on Stream A ## Completed (none yet) ``` **Output:** ``` ✅ Started work on issue #<N> Launched N agents: Stream A: <name> ✓ Started Stream B: <name> ✓ Started Stream C: <name> ⏸ Waiting (depends on A) Monitor: check progress in .claude/epics/<epic>/updates/<N>/ Sync updates: "sync issue <N>" ``` --- ## Starting a Full Epic **Trigger**: User wants to launch parallel agents across all ready issues in an epic at once. ### Preflight - Verify `.claude/epics/<name>/epic.md` exists and has a `github:` field (i.e., it's been synced). - Check for uncommitted changes: `git status --porcelain` — block if dirty. - Verify epic branch exists: `git branch -a | grep "epic/<name>"` ### Process **Step 1 — Read all task files** in `.claude/epics/<name>/`. Parse frontmatter for `status`, `depends_on`, `parallel`. **Step 2 — Categorize tasks:** - Ready: status=open, no unmet depends_on - Blocked: has unmet depends_on - In Progress: already has an execution file - Complete: status=closed **Step 3 — Analyze any ready tasks** that don't have an analysis file yet (run issue analysis inline). **Step 4 — Launch agents** for all ready tasks following the same per-issue agent launch pattern above. **Step 5 — Create/update** `.claude/epics/<name>/execution-status.md` with all active agents and queued issues. **Step 6 — As agents complete**, check if blocked issues are now unblocked and launch those agents. --- ## Agent Coordination Rules When multiple agents work in the same worktree simultaneously: - Each agent works only on files in its assigned stream scope. - Agents commit frequently with `Issue #<N>: <description>` format. - Before modifying a shared file, check `git status <file>` — if another agent has it modified, wait and pull first. - Agents sync via commits: `git pull --rebase origin epic/<name>` before starting new file work. - Conflicts are never auto-resolved — agents report them and pause. - No `--force` flags ever. Shared files that commonly need coordination (types, config, package.json) should be handled by one designated stream; others pull after that commit. ================================================ FILE: skill/ccpm/references/plan.md ================================================ # Plan — Capture Requirements This phase turns an idea into a structured PRD, then converts the PRD into a technical epic ready for decomposition. --- ## Writing a PRD **Trigger**: User wants to plan a new feature, product requirement, or area of work. ### Preflight - Check if `.claude/prds/<name>.md` already exists — if so, confirm overwrite before proceeding. - Ensure `.claude/prds/` directory exists; create it if not. - Feature name must be kebab-case (lowercase, letters/numbers/hyphens, starts with a letter). If not: "❌ Feature name must be kebab-case. Example: user-auth, payment-v2" ### Process Conduct a genuine brainstorming session before writing anything. Ask the user: - What problem does this solve? - Who are the users affected? - What does success look like? - What's explicitly out of scope? - What are the constraints (tech, time, resources)? Then write `.claude/prds/<name>.md` with this frontmatter and structure: ```markdown --- name: <feature-name> description: <one-line summary> status: backlog created: <run: date -u +"%Y-%m-%dT%H:%M:%SZ"> --- # PRD: <feature-name> ## Executive Summary ## Problem Statement ## User Stories ## Functional Requirements ## Non-Functional Requirements ## Success Criteria ## Constraints & Assumptions ## Out of Scope ## Dependencies ``` **Quality gates before saving:** - No placeholder text in any section - User stories include acceptance criteria - Success criteria are measurable - Out of scope is explicitly listed **After creation**: Confirm "✅ PRD created: `.claude/prds/<name>.md`" and suggest: "Ready to create technical epic? Say: parse the <name> PRD" --- ## Parsing a PRD into a Technical Epic **Trigger**: User wants to convert an existing PRD into a technical implementation plan. ### Preflight - Verify `.claude/prds/<name>.md` exists with valid frontmatter (name, description, status, created). - Check if `.claude/epics/<name>/epic.md` already exists — confirm overwrite if so. ### Process Read the PRD fully, then produce `.claude/epics/<name>/epic.md`: ```markdown --- name: <feature-name> status: backlog created: <run: date -u +"%Y-%m-%dT%H:%M:%SZ"> progress: 0% prd: .claude/prds/<name>.md github: (will be set on sync) --- # Epic: <feature-name> ## Overview ## Architecture Decisions ## Technical Approach ### Frontend Components ### Backend Services ### Infrastructure ## Implementation Strategy ## Task Breakdown Preview ## Dependencies ## Success Criteria (Technical) ## Estimated Effort ``` **Key constraints:** - Aim for ≤10 tasks total — prefer simplicity over completeness. - Look for ways to leverage existing functionality before creating new code. - Identify parallelization opportunities in the task breakdown preview. **After creation**: Confirm "✅ Epic created: `.claude/epics/<name>/epic.md`" and suggest: "Ready to decompose into tasks? Say: decompose the <name> epic" --- ## Editing a PRD or Epic Read the file first, make targeted edits preserving all frontmatter. Update the `updated` frontmatter field with current datetime. ================================================ FILE: skill/ccpm/references/scripts/blocked.sh ================================================ #!/bin/bash echo "Getting tasks..." echo "" echo "" echo "🚫 Blocked Tasks" echo "================" echo "" found=0 for epic_dir in .claude/epics/*/; do [ -d "$epic_dir" ] || continue epic_name=$(basename "$epic_dir") for task_file in "$epic_dir"/[0-9]*.md; do [ -f "$task_file" ] || continue # Check if task is open status=$(grep "^status:" "$task_file" | head -1 | sed 's/^status: *//') if [ "$status" != "open" ] && [ -n "$status" ]; then continue fi # Check for dependencies deps_line=$(grep "^depends_on:" "$task_file" | head -1) if [ -n "$deps_line" ]; then deps=$(echo "$deps_line" | sed 's/^depends_on: *//' | sed 's/^\[//' | sed 's/\]$//' | sed 's/,/ /g' | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//') [ -z "$deps" ] && deps="" else deps="" fi if [ -n "$deps" ] && [ "$deps" != "depends_on:" ]; then task_name=$(grep "^name:" "$task_file" | head -1 | sed 's/^name: *//') task_num=$(basename "$task_file" .md) echo "⏸️ Task #$task_num - $task_name" echo " Epic: $epic_name" echo " Blocked by: [$deps]" # Check status of dependencies open_deps="" for dep in $deps; do dep_file="$epic_dir$dep.md" if [ -f "$dep_file" ]; then dep_status=$(grep "^status:" "$dep_file" | head -1 | sed 's/^status: *//') [ "$dep_status" = "open" ] && open_deps="$open_deps #$dep" fi done [ -n "$open_deps" ] && echo " Waiting for:$open_deps" echo "" ((found++)) fi done done if [ $found -eq 0 ]; then echo "No blocked tasks found!" echo "" echo "💡 All tasks with dependencies are either completed or in progress." else echo "📊 Total blocked: $found tasks" fi exit 0 ================================================ FILE: skill/ccpm/references/scripts/epic-list.sh ================================================ #!/bin/bash echo "Getting epics..." echo "" echo "" [ ! -d ".claude/epics" ] && echo "📁 No epics directory found. Create your first epic with: /pm:prd-parse <feature-name>" && exit 0 [ -z "$(ls -d .claude/epics/*/ 2>/dev/null)" ] && echo "📁 No epics found. Create your first epic with: /pm:prd-parse <feature-name>" && exit 0 echo "📚 Project Epics" echo "================" echo "" # Initialize arrays to store epics by status planning_epics="" in_progress_epics="" completed_epics="" # Process all epics for dir in .claude/epics/*/; do [ -d "$dir" ] || continue [ -f "$dir/epic.md" ] || continue # Extract metadata n=$(grep "^name:" "$dir/epic.md" | head -1 | sed 's/^name: *//') s=$(grep "^status:" "$dir/epic.md" | head -1 | sed 's/^status: *//' | tr '[:upper:]' '[:lower:]') p=$(grep "^progress:" "$dir/epic.md" | head -1 | sed 's/^progress: *//') g=$(grep "^github:" "$dir/epic.md" | head -1 | sed 's/^github: *//') # Defaults [ -z "$n" ] && n=$(basename "$dir") [ -z "$p" ] && p="0%" # Count tasks t=$(ls "$dir"/[0-9]*.md 2>/dev/null | wc -l) # Format output with GitHub issue number if available if [ -n "$g" ]; then i=$(echo "$g" | grep -o '/[0-9]*$' | tr -d '/') entry=" 📋 ${dir}epic.md (#$i) - $p complete ($t tasks)" else entry=" 📋 ${dir}epic.md - $p complete ($t tasks)" fi # Categorize by status (handle various status values) case "$s" in planning|draft|"") planning_epics="${planning_epics}${entry}\n" ;; in-progress|in_progress|active|started) in_progress_epics="${in_progress_epics}${entry}\n" ;; completed|complete|done|closed|finished) completed_epics="${completed_epics}${entry}\n" ;; *) # Default to planning for unknown statuses planning_epics="${planning_epics}${entry}\n" ;; esac done # Display categorized epics echo "📝 Planning:" if [ -n "$planning_epics" ]; then echo -e "$planning_epics" | sed '/^$/d' else echo " (none)" fi echo "" echo "🚀 In Progress:" if [ -n "$in_progress_epics" ]; then echo -e "$in_progress_epics" | sed '/^$/d' else echo " (none)" fi echo "" echo "✅ Completed:" if [ -n "$completed_epics" ]; then echo -e "$completed_epics" | sed '/^$/d' else echo " (none)" fi # Summary echo "" echo "📊 Summary" total=$(ls -d .claude/epics/*/ 2>/dev/null | wc -l) tasks=$(find .claude/epics -name "[0-9]*.md" 2>/dev/null | wc -l) echo " Total epics: $total" echo " Total tasks: $tasks" exit 0 ================================================ FILE: skill/ccpm/references/scripts/epic-show.sh ================================================ #!/bin/bash epic_name="$1" if [ -z "$epic_name" ]; then echo "❌ Please provide an epic name" echo "Usage: /pm:epic-show <epic-name>" exit 1 fi echo "Getting epic..." echo "" echo "" epic_dir=".claude/epics/$epic_name" epic_file="$epic_dir/epic.md" if [ ! -f "$epic_file" ]; then echo "❌ Epic not found: $epic_name" echo "" echo "Available epics:" for dir in .claude/epics/*/; do [ -d "$dir" ] && echo " • $(basename "$dir")" done exit 1 fi # Display epic details echo "📚 Epic: $epic_name" echo "================================" echo "" # Extract metadata status=$(grep "^status:" "$epic_file" | head -1 | sed 's/^status: *//') progress=$(grep "^progress:" "$epic_file" | head -1 | sed 's/^progress: *//') github=$(grep "^github:" "$epic_file" | head -1 | sed 's/^github: *//') created=$(grep "^created:" "$epic_file" | head -1 | sed 's/^created: *//') echo "📊 Metadata:" echo " Status: ${status:-planning}" echo " Progress: ${progress:-0%}" [ -n "$github" ] && echo " GitHub: $github" echo " Created: ${created:-unknown}" echo "" # Show tasks echo "📝 Tasks:" task_count=0 open_count=0 closed_count=0 for task_file in "$epic_dir"/[0-9]*.md; do [ -f "$task_file" ] || continue task_num=$(basename "$task_file" .md) task_name=$(grep "^name:" "$task_file" | head -1 | sed 's/^name: *//') task_status=$(grep "^status:" "$task_file" | head -1 | sed 's/^status: *//') parallel=$(grep "^parallel:" "$task_file" | head -1 | sed 's/^parallel: *//') if [ "$task_status" = "closed" ] || [ "$task_status" = "completed" ]; then echo " ✅ #$task_num - $task_name" ((closed_count++)) else echo " ⬜ #$task_num - $task_name" [ "$parallel" = "true" ] && echo -n " (parallel)" ((open_count++)) fi ((task_count++)) done if [ $task_count -eq 0 ]; then echo " No tasks created yet" echo " Run: /pm:epic-decompose $epic_name" fi echo "" echo "📈 Statistics:" echo " Total tasks: $task_count" echo " Open: $open_count" echo " Closed: $closed_count" [ $task_count -gt 0 ] && echo " Completion: $((closed_count * 100 / task_count))%" # Next actions echo "" echo "💡 Actions:" [ $task_count -eq 0 ] && echo " • Decompose into tasks: /pm:epic-decompose $epic_name" [ -z "$github" ] && [ $task_count -gt 0 ] && echo " • Sync to GitHub: /pm:epic-sync $epic_name" [ -n "$github" ] && [ "$status" != "completed" ] && echo " • Start work: /pm:epic-start $epic_name" exit 0 ================================================ FILE: skill/ccpm/references/scripts/epic-status.sh ================================================ #!/bin/bash echo "Getting status..." echo "" echo "" epic_name="$1" if [ -z "$epic_name" ]; then echo "❌ Please specify an epic name" echo "Usage: /pm:epic-status <epic-name>" echo "" echo "Available epics:" for dir in .claude/epics/*/; do [ -d "$dir" ] && echo " • $(basename "$dir")" done exit 1 else # Show status for specific epic epic_dir=".claude/epics/$epic_name" epic_file="$epic_dir/epic.md" if [ ! -f "$epic_file" ]; then echo "❌ Epic not found: $epic_name" echo "" echo "Available epics:" for dir in .claude/epics/*/; do [ -d "$dir" ] && echo " • $(basename "$dir")" done exit 1 fi echo "📚 Epic Status: $epic_name" echo "================================" echo "" # Extract metadata status=$(grep "^status:" "$epic_file" | head -1 | sed 's/^status: *//') progress=$(grep "^progress:" "$epic_file" | head -1 | sed 's/^progress: *//') github=$(grep "^github:" "$epic_file" | head -1 | sed 's/^github: *//') # Count tasks total=0 open=0 closed=0 blocked=0 # Use find to safely iterate over task files for task_file in "$epic_dir"/[0-9]*.md; do [ -f "$task_file" ] || continue ((total++)) task_status=$(grep "^status:" "$task_file" | head -1 | sed 's/^status: *//') deps=$(grep "^depends_on:" "$task_file" | head -1 | sed 's/^depends_on: *\[//' | sed 's/\]//') if [ "$task_status" = "closed" ] || [ "$task_status" = "completed" ]; then ((closed++)) elif [ -n "$deps" ] && [ "$deps" != "depends_on:" ]; then ((blocked++)) else ((open++)) fi done # Display progress bar if [ $total -gt 0 ]; then percent=$((closed * 100 / total)) filled=$((percent * 20 / 100)) empty=$((20 - filled)) echo -n "Progress: [" [ $filled -gt 0 ] && printf '%0.s█' $(seq 1 $filled) [ $empty -gt 0 ] && printf '%0.s░' $(seq 1 $empty) echo "] $percent%" else echo "Progress: No tasks created" fi echo "" echo "📊 Breakdown:" echo " Total tasks: $total" echo " ✅ Completed: $closed" echo " 🔄 Available: $open" echo " ⏸️ Blocked: $blocked" [ -n "$github" ] && echo "" [ -n "$github" ] && echo "🔗 GitHub: $github" fi exit 0 ================================================ FILE: skill/ccpm/references/scripts/help.sh ================================================ #!/bin/bash echo "Helping..." echo "" echo "" echo "📚 Claude Code PM - Project Management System" echo "=============================================" echo "" echo "🎯 Quick Start Workflow" echo " 1. /pm:prd-new <name> - Create a new PRD" echo " 2. /pm:prd-parse <name> - Convert PRD to epic" echo " 3. /pm:epic-decompose <name> - Break into tasks" echo " 4. /pm:epic-sync <name> - Push to GitHub" echo " 5. /pm:epic-start <name> - Start parallel execution" echo "" echo "📄 PRD Commands" echo " /pm:prd-new <name> - Launch brainstorming for new product requirement" echo " /pm:prd-parse <name> - Convert PRD to implementation epic" echo " /pm:prd-list - List all PRDs" echo " /pm:prd-edit <name> - Edit existing PRD" echo " /pm:prd-status - Show PRD implementation status" echo "" echo "📚 Epic Commands" echo " /pm:epic-decompose <name> - Break epic into task files" echo " /pm:epic-sync <name> - Push epic and tasks to GitHub" echo " /pm:epic-oneshot <name> - Decompose and sync in one command" echo " /pm:epic-list - List all epics" echo " /pm:epic-show <name> - Display epic and its tasks" echo " /pm:epic-status [name] - Show epic progress" echo " /pm:epic-close <name> - Mark epic as complete" echo " /pm:epic-edit <name> - Edit epic details" echo " /pm:epic-refresh <name> - Update epic progress from tasks" echo " /pm:epic-start <name> - Launch parallel agent execution" echo "" echo "📝 Issue Commands" echo " /pm:issue-show <num> - Display issue and sub-issues" echo " /pm:issue-status <num> - Check issue status" echo " /pm:issue-start <num> - Begin work with specialized agent" echo " /pm:issue-sync <num> - Push updates to GitHub" echo " /pm:issue-close <num> - Mark issue as complete" echo " /pm:issue-reopen <num> - Reopen closed issue" echo " /pm:issue-edit <num> - Edit issue details" echo " /pm:issue-analyze <num> - Analyze for parallel work streams" echo "" echo "🔄 Workflow Commands" echo " /pm:next - Show next priority tasks" echo " /pm:status - Overall project dashboard" echo " /pm:standup - Daily standup report" echo " /pm:blocked - Show blocked tasks" echo " /pm:in-progress - List work in progress" echo "" echo "🔗 Sync Commands" echo " /pm:sync - Full bidirectional sync with GitHub" echo " /pm:import <issue> - Import existing GitHub issues" echo "" echo "🔧 Maintenance Commands" echo " /pm:validate - Check system integrity" echo " /pm:clean - Archive completed work" echo " /pm:search <query> - Search across all content" echo "" echo "⚙️ Setup Commands" echo " /pm:init - Install dependencies and configure GitHub" echo " /pm:help - Show this help message" echo "" echo "💡 Tips" echo " • Use /pm:next to find available work" echo " • Run /pm:status for quick overview" echo " • Epic workflow: prd-new → prd-parse → epic-decompose → epic-sync" echo " • View README.md for complete documentation" exit 0 ================================================ FILE: skill/ccpm/references/scripts/in-progress.sh ================================================ #!/bin/bash echo "Getting status..." echo "" echo "" echo "🔄 In Progress Work" echo "===================" echo "" # Check for active work in updates directories found=0 if [ -d ".claude/epics" ]; then for updates_dir in .claude/epics/*/updates/*/; do [ -d "$updates_dir" ] || continue issue_num=$(basename "$updates_dir") epic_name=$(basename $(dirname $(dirname "$updates_dir"))) if [ -f "$updates_dir/progress.md" ]; then completion=$(grep "^completion:" "$updates_dir/progress.md" | head -1 | sed 's/^completion: *//') [ -z "$completion" ] && completion="0%" # Get task name from the task file task_file=".claude/epics/$epic_name/$issue_num.md" if [ -f "$task_file" ]; then task_name=$(grep "^name:" "$task_file" | head -1 | sed 's/^name: *//') else task_name="Unknown task" fi echo "📝 Issue #$issue_num - $task_name" echo " Epic: $epic_name" echo " Progress: $completion complete" # Check for recent updates if [ -f "$updates_dir/progress.md" ]; then last_update=$(grep "^last_sync:" "$updates_dir/progress.md" | head -1 | sed 's/^last_sync: *//') [ -n "$last_update" ] && echo " Last update: $last_update" fi echo "" ((found++)) fi done fi # Also check for in-progress epics echo "📚 Active Epics:" for epic_dir in .claude/epics/*/; do [ -d "$epic_dir" ] || continue [ -f "$epic_dir/epic.md" ] || continue status=$(grep "^status:" "$epic_dir/epic.md" | head -1 | sed 's/^status: *//') if [ "$status" = "in-progress" ] || [ "$status" = "active" ]; then epic_name=$(grep "^name:" "$epic_dir/epic.md" | head -1 | sed 's/^name: *//') progress=$(grep "^progress:" "$epic_dir/epic.md" | head -1 | sed 's/^progress: *//') [ -z "$epic_name" ] && epic_name=$(basename "$epic_dir") [ -z "$progress" ] && progress="0%" echo " • $epic_name - $progress complete" fi done echo "" if [ $found -eq 0 ]; then echo "No active work items found." echo "" echo "💡 Start work with: /pm:next" else echo "📊 Total active items: $found" fi exit 0 ================================================ FILE: skill/ccpm/references/scripts/init.sh ================================================ #!/bin/bash echo "Initializing..." echo "" echo "" echo " ██████╗ ██████╗██████╗ ███╗ ███╗" echo "██╔════╝██╔════╝██╔══██╗████╗ ████║" echo "██║ ██║ ██████╔╝██╔████╔██║" echo "╚██████╗╚██████╗██║ ██║ ╚═╝ ██║" echo " ╚═════╝ ╚═════╝╚═╝ ╚═╝ ╚═╝" echo "┌─────────────────────────────────┐" echo "│ Claude Code Project Management │" echo "│ by https://x.com/aroussi │" echo "└─────────────────────────────────┘" echo "https://github.com/automazeio/ccpm" echo "" echo "" echo "🚀 Initializing Claude Code PM System" echo "======================================" echo "" # Check for required tools echo "🔍 Checking dependencies..." # Check gh CLI if command -v gh &> /dev/null; then echo " ✅ GitHub CLI (gh) installed" else echo " ❌ GitHub CLI (gh) not found" echo "" echo " Installing gh..." if command -v brew &> /dev/null; then brew install gh elif command -v apt-get &> /dev/null; then sudo apt-get update && sudo apt-get install gh else echo " Please install GitHub CLI manually: https://cli.github.com/" exit 1 fi fi # Check gh auth status echo "" echo "🔐 Checking GitHub authentication..." if gh auth status &> /dev/null; then echo " ✅ GitHub authenticated" else echo " ⚠️ GitHub not authenticated" echo " Running: gh auth login" gh auth login fi # Check for gh-sub-issue extension echo "" echo "📦 Checking gh extensions..." if gh extension list | grep -q "yahsan2/gh-sub-issue"; then echo " ✅ gh-sub-issue extension installed" else echo " 📥 Installing gh-sub-issue extension..." gh extension install yahsan2/gh-sub-issue fi # Create directory structure echo "" echo "📁 Creating directory structure..." mkdir -p .claude/prds mkdir -p .claude/epics mkdir -p .claude/rules mkdir -p .claude/agents mkdir -p .claude/scripts/pm echo " ✅ Directories created" # Copy scripts if in main repo if [ -d "scripts/pm" ] && [ ! "$(pwd)" = *"/.claude"* ]; then echo "" echo "📝 Copying PM scripts..." cp -r scripts/pm/* .claude/scripts/pm/ chmod +x .claude/scripts/pm/*.sh echo " ✅ Scripts copied and made executable" fi # Check for git echo "" echo "🔗 Checking Git configuration..." if git rev-parse --git-dir > /dev/null 2>&1; then echo " ✅ Git repository detected" # Check remote if git remote -v | grep -q origin; then remote_url=$(git remote get-url origin) echo " ✅ Remote configured: $remote_url" # Check if remote is the CCPM template repository if [[ "$remote_url" == *"automazeio/ccpm"* ]] || [[ "$remote_url" == *"automazeio/ccpm.git"* ]]; then echo "" echo " ⚠️ WARNING: Your remote origin points to the CCPM template repository!" echo " This means any issues you create will go to the template repo, not your project." echo "" echo " To fix this:" echo " 1. Fork the repository or create your own on GitHub" echo " 2. Update your remote:" echo " git remote set-url origin https://github.com/YOUR_USERNAME/YOUR_REPO.git" echo "" else # Create GitHub labels if this is a GitHub repository if gh repo view &> /dev/null; then echo "" echo "🏷️ Creating GitHub labels..." # Create base labels with improved error handling epic_created=false task_created=false if gh label create "epic" --color "0E8A16" --description "Epic issue containing multiple related tasks" --force 2>/dev/null; then epic_created=true elif gh label list 2>/dev/null | grep -q "^epic"; then epic_created=true # Label already exists fi if gh label create "task" --color "1D76DB" --description "Individual task within an epic" --force 2>/dev/null; then task_created=true elif gh label list 2>/dev/null | grep -q "^task"; then task_created=true # Label already exists fi # Report results if $epic_created && $task_created; then echo " ✅ GitHub labels created (epic, task)" elif $epic_created || $task_created; then echo " ⚠️ Some GitHub labels created (epic: $epic_created, task: $task_created)" else echo " ❌ Could not create GitHub labels (check repository permissions)" fi else echo " ℹ️ Not a GitHub repository - skipping label creation" fi fi else echo " ⚠️ No remote configured" echo " Add with: git remote add origin <url>" fi else echo " ⚠️ Not a git repository" echo " Initialize with: git init" fi # Create CLAUDE.md if it doesn't exist if [ ! -f "CLAUDE.md" ]; then echo "" echo "📄 Creating CLAUDE.md..." cat > CLAUDE.md << 'EOF' # CLAUDE.md > Think carefully and implement the most concise solution that changes as little code as possible. ## Project-Specific Instructions Add your project-specific instructions here. ## Testing Always run tests before committing: - `npm test` or equivalent for your stack ## Code Style Follow existing patterns in the codebase. EOF echo " ✅ CLAUDE.md created" fi # Summary echo "" echo "✅ Initialization Complete!" echo "==========================" echo "" echo "📊 System Status:" gh --version | head -1 echo " Extensions: $(gh extension list | wc -l) installed" echo " Auth: $(gh auth status 2>&1 | grep -o 'Logged in to [^ ]*' || echo 'Not authenticated')" echo "" echo "🎯 Next Steps:" echo " 1. Create your first PRD: /pm:prd-new <feature-name>" echo " 2. View help: /pm:help" echo " 3. Check status: /pm:status" echo "" echo "📚 Documentation: README.md" exit 0 ================================================ FILE: skill/ccpm/references/scripts/next.sh ================================================ #!/bin/bash echo "Getting status..." echo "" echo "" echo "📋 Next Available Tasks" echo "=======================" echo "" # Find tasks that are open and have no dependencies or whose dependencies are closed found=0 for epic_dir in .claude/epics/*/; do [ -d "$epic_dir" ] || continue epic_name=$(basename "$epic_dir") for task_file in "$epic_dir"/[0-9]*.md; do [ -f "$task_file" ] || continue # Check if task is open status=$(grep "^status:" "$task_file" | head -1 | sed 's/^status: *//') if [ "$status" != "open" ] && [ -n "$status" ]; then continue fi # Check dependencies deps_line=$(grep "^depends_on:" "$task_file" | head -1) if [ -n "$deps_line" ]; then deps=$(echo "$deps_line" | sed 's/^depends_on: *//' | sed 's/^\[//' | sed 's/\]$//' | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//') [ -z "$deps" ] && deps="" else deps="" fi # If no dependencies or empty, task is available if [ -z "$deps" ] || [ "$deps" = "depends_on:" ]; then task_name=$(grep "^name:" "$task_file" | head -1 | sed 's/^name: *//') task_num=$(basename "$task_file" .md) parallel=$(grep "^parallel:" "$task_file" | head -1 | sed 's/^parallel: *//') echo "✅ Ready: #$task_num - $task_name" echo " Epic: $epic_name" [ "$parallel" = "true" ] && echo " 🔄 Can run in parallel" echo "" ((found++)) fi done done if [ $found -eq 0 ]; then echo "No available tasks found." echo "" echo "💡 Suggestions:" echo " • Check blocked tasks: /pm:blocked" echo " • View all tasks: /pm:epic-list" fi echo "" echo "📊 Summary: $found tasks ready to start" exit 0 ================================================ FILE: skill/ccpm/references/scripts/prd-list.sh ================================================ # !/bin/bash # Check if PRD directory exists if [ ! -d ".claude/prds" ]; then echo "📁 No PRD directory found. Create your first PRD with: /pm:prd-new <feature-name>" exit 0 fi # Check for PRD files if ! ls .claude/prds/*.md >/dev/null 2>&1; then echo "📁 No PRDs found. Create your first PRD with: /pm:prd-new <feature-name>" exit 0 fi # Initialize counters backlog_count=0 in_progress_count=0 implemented_count=0 total_count=0 echo "Getting PRDs..." echo "" echo "" echo "📋 PRD List" echo "===========" echo "" # Display by status groups echo "🔍 Backlog PRDs:" for file in .claude/prds/*.md; do [ -f "$file" ] || continue status=$(grep "^status:" "$file" | head -1 | sed 's/^status: *//') if [ "$status" = "backlog" ] || [ "$status" = "draft" ] || [ -z "$status" ]; then name=$(grep "^name:" "$file" | head -1 | sed 's/^name: *//') desc=$(grep "^description:" "$file" | head -1 | sed 's/^description: *//') [ -z "$name" ] && name=$(basename "$file" .md) [ -z "$desc" ] && desc="No description" # echo " 📋 $name - $desc" echo " 📋 $file - $desc" ((backlog_count++)) fi ((total_count++)) done [ $backlog_count -eq 0 ] && echo " (none)" echo "" echo "🔄 In-Progress PRDs:" for file in .claude/prds/*.md; do [ -f "$file" ] || continue status=$(grep "^status:" "$file" | head -1 | sed 's/^status: *//') if [ "$status" = "in-progress" ] || [ "$status" = "active" ]; then name=$(grep "^name:" "$file" | head -1 | sed 's/^name: *//') desc=$(grep "^description:" "$file" | head -1 | sed 's/^description: *//') [ -z "$name" ] && name=$(basename "$file" .md) [ -z "$desc" ] && desc="No description" # echo " 📋 $name - $desc" echo " 📋 $file - $desc" ((in_progress_count++)) fi done [ $in_progress_count -eq 0 ] && echo " (none)" echo "" echo "✅ Implemented PRDs:" for file in .claude/prds/*.md; do [ -f "$file" ] || continue status=$(grep "^status:" "$file" | head -1 | sed 's/^status: *//') if [ "$status" = "implemented" ] || [ "$status" = "completed" ] || [ "$status" = "done" ]; then name=$(grep "^name:" "$file" | head -1 | sed 's/^name: *//') desc=$(grep "^description:" "$file" | head -1 | sed 's/^description: *//') [ -z "$name" ] && name=$(basename "$file" .md) [ -z "$desc" ] && desc="No description" # echo " 📋 $name - $desc" echo " 📋 $file - $desc" ((implemented_count++)) fi done [ $implemented_count -eq 0 ] && echo " (none)" # Display summary echo "" echo "📊 PRD Summary" echo " Total PRDs: $total_count" echo " Backlog: $backlog_count" echo " In-Progress: $in_progress_count" echo " Implemented: $implemented_count" exit 0 ================================================ FILE: skill/ccpm/references/scripts/prd-status.sh ================================================ #!/bin/bash echo "📄 PRD Status Report" echo "====================" echo "" if [ ! -d ".claude/prds" ]; then echo "No PRD directory found." exit 0 fi total=$(ls .claude/prds/*.md 2>/dev/null | wc -l) [ $total -eq 0 ] && echo "No PRDs found." && exit 0 # Count by status backlog=0 in_progress=0 implemented=0 for file in .claude/prds/*.md; do [ -f "$file" ] || continue status=$(grep "^status:" "$file" | head -1 | sed 's/^status: *//') case "$status" in backlog|draft|"") ((backlog++)) ;; in-progress|active) ((in_progress++)) ;; implemented|completed|done) ((implemented++)) ;; *) ((backlog++)) ;; esac done echo "Getting status..." echo "" echo "" # Display chart echo "📊 Distribution:" echo "================" echo "" echo " Backlog: $(printf '%-3d' $backlog) [$(printf '%0.s█' $(seq 1 $((backlog*20/total))))]" echo " In Progress: $(printf '%-3d' $in_progress) [$(printf '%0.s█' $(seq 1 $((in_progress*20/total))))]" echo " Implemented: $(printf '%-3d' $implemented) [$(printf '%0.s█' $(seq 1 $((implemented*20/total))))]" echo "" echo " Total PRDs: $total" # Recent activity echo "" echo "📅 Recent PRDs (last 5 modified):" ls -t .claude/prds/*.md 2>/dev/null | head -5 | while read file; do name=$(grep "^name:" "$file" | head -1 | sed 's/^name: *//') [ -z "$name" ] && name=$(basename "$file" .md) echo " • $name" done # Suggestions echo "" echo "💡 Next Actions:" [ $backlog -gt 0 ] && echo " • Parse backlog PRDs to epics: /pm:prd-parse <name>" [ $in_progress -gt 0 ] && echo " • Check progress on active PRDs: /pm:epic-status <name>" [ $total -eq 0 ] && echo " • Create your first PRD: /pm:prd-new <name>" exit 0 ================================================ FILE: skill/ccpm/references/scripts/search.sh ================================================ #!/bin/bash query="$1" if [ -z "$query" ]; then echo "❌ Please provide a search query" echo "Usage: /pm:search <query>" exit 1 fi echo "Searching for '$query'..." echo "" echo "" echo "🔍 Search results for: '$query'" echo "================================" echo "" # Search in PRDs if [ -d ".claude/prds" ]; then echo "📄 PRDs:" results=$(grep -l -i "$query" .claude/prds/*.md 2>/dev/null) if [ -n "$results" ]; then for file in $results; do name=$(basename "$file" .md) matches=$(grep -c -i "$query" "$file") echo " • $name ($matches matches)" done else echo " No matches" fi echo "" fi # Search in Epics if [ -d ".claude/epics" ]; then echo "📚 Epics:" results=$(find .claude/epics -name "epic.md" -exec grep -l -i "$query" {} \; 2>/dev/null) if [ -n "$results" ]; then for file in $results; do epic_name=$(basename $(dirname "$file")) matches=$(grep -c -i "$query" "$file") echo " • $epic_name ($matches matches)" done else echo " No matches" fi echo "" fi # Search in Tasks if [ -d ".claude/epics" ]; then echo "📝 Tasks:" results=$(find .claude/epics -name "[0-9]*.md" -exec grep -l -i "$query" {} \; 2>/dev/null | head -10) if [ -n "$results" ]; then for file in $results; do epic_name=$(basename $(dirname "$file")) task_num=$(basename "$file" .md) echo " • Task #$task_num in $epic_name" done else echo " No matches" fi fi # Summary total=$(find .claude -name "*.md" -exec grep -l -i "$query" {} \; 2>/dev/null | wc -l) echo "" echo "📊 Total files with matches: $total" exit 0 ================================================ FILE: skill/ccpm/references/scripts/standup.sh ================================================ #!/bin/bash echo "📅 Daily Standup - $(date '+%Y-%m-%d')" echo "================================" echo "" today=$(date '+%Y-%m-%d') echo "Getting status..." echo "" echo "" echo "📝 Today's Activity:" echo "====================" echo "" # Find files modified today recent_files=$(find .claude -name "*.md" -mtime -1 2>/dev/null) if [ -n "$recent_files" ]; then # Count by type prd_count=$(echo "$recent_files" | grep -c "/prds/" 2>/dev/null | tr -d '[:space:]') epic_count=$(echo "$recent_files" | grep -c "/epic.md" 2>/dev/null | tr -d '[:space:]') task_count=$(echo "$recent_files" | grep -c "/[0-9]*.md" 2>/dev/null | tr -d '[:space:]') update_count=$(echo "$recent_files" | grep -c "/updates/" 2>/dev/null | tr -d '[:space:]') prd_count=${prd_count:-0}; epic_count=${epic_count:-0}; task_count=${task_count:-0}; update_count=${update_count:-0} [ "$prd_count" -gt 0 ] && echo " • Modified $prd_count PRD(s)" [ "$epic_count" -gt 0 ] && echo " • Updated $epic_count epic(s)" [ "$task_count" -gt 0 ] && echo " • Worked on $task_count task(s)" [ "$update_count" -gt 0 ] && echo " • Posted $update_count progress update(s)" else echo " No activity recorded today" fi echo "" echo "🔄 Currently In Progress:" # Show active work items for updates_dir in .claude/epics/*/updates/*/; do [ -d "$updates_dir" ] || continue if [ -f "$updates_dir/progress.md" ]; then issue_num=$(basename "$updates_dir") epic_name=$(basename $(dirname $(dirname "$updates_dir"))) completion=$(grep "^completion:" "$updates_dir/progress.md" | head -1 | sed 's/^completion: *//') echo " • Issue #$issue_num ($epic_name) - ${completion:-0%} complete" fi done echo "" echo "⏭️ Next Available Tasks:" # Show top 3 available tasks count=0 for epic_dir in .claude/epics/*/; do [ -d "$epic_dir" ] || continue for task_file in "$epic_dir"/[0-9]*.md; do [ -f "$task_file" ] || continue status=$(grep "^status:" "$task_file" | head -1 | sed 's/^status: *//') if [ "$status" != "open" ] && [ -n "$status" ]; then continue fi deps_line=$(grep "^depends_on:" "$task_file" | head -1) if [ -n "$deps_line" ]; then deps=$(echo "$deps_line" | sed 's/^depends_on: *//' | sed 's/^\[//' | sed 's/\]$//' | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//') [ -z "$deps" ] && deps="" else deps="" fi if [ -z "$deps" ] || [ "$deps" = "depends_on:" ]; then task_name=$(grep "^name:" "$task_file" | head -1 | sed 's/^name: *//') task_num=$(basename "$task_file" .md) echo " • #$task_num - $task_name" ((count++)) [ $count -ge 3 ] && break 2 fi done done echo "" echo "📊 Quick Stats:" total_tasks=$(find .claude/epics -name "[0-9]*.md" 2>/dev/null | wc -l) open_tasks=$(find .claude/epics -name "[0-9]*.md" -exec grep -l "^status: *open" {} \; 2>/dev/null | wc -l) closed_tasks=$(find .claude/epics -name "[0-9]*.md" -exec grep -l "^status: *closed" {} \; 2>/dev/null | wc -l) echo " Tasks: $open_tasks open, $closed_tasks closed, $total_tasks total" exit 0 ================================================ FILE: skill/ccpm/references/scripts/status.sh ================================================ #!/bin/bash echo "Getting status..." echo "" echo "" echo "📊 Project Status" echo "================" echo "" echo "📄 PRDs:" if [ -d ".claude/prds" ]; then total=$(ls .claude/prds/*.md 2>/dev/null | wc -l) echo " Total: $total" else echo " No PRDs found" fi echo "" echo "📚 Epics:" if [ -d ".claude/epics" ]; then total=$(ls -d .claude/epics/*/ 2>/dev/null | grep -v '/archived/$' | wc -l) echo " Total: $total" else echo " No epics found" fi echo "" echo "📝 Tasks:" if [ -d ".claude/epics" ]; then total=$(find .claude/epics -path "*/archived/*" -prune -o -name "[0-9]*.md" -print 2>/dev/null | wc -l) open=$(find .claude/epics -path "*/archived/*" -prune -o -name "[0-9]*.md" -print 2>/dev/null | xargs grep -l "^status: *open" 2>/dev/null | wc -l) closed=$(find .claude/epics -path "*/archived/*" -prune -o -name "[0-9]*.md" -print 2>/dev/null | xargs grep -l "^status: *closed" 2>/dev/null | wc -l) echo " Open: $open" echo " Closed: $closed" echo " Total: $total" else echo " No tasks found" fi exit 0 ================================================ FILE: skill/ccpm/references/scripts/validate.sh ================================================ #!/bin/bash echo "Validating PM System..." echo "" echo "" echo "🔍 Validating PM System" echo "=======================" echo "" errors=0 warnings=0 # Check directory structure echo "📁 Directory Structure:" [ -d ".claude" ] && echo " ✅ .claude directory exists" || { echo " ❌ .claude directory missing"; ((errors++)); } [ -d ".claude/prds" ] && echo " ✅ PRDs directory exists" || echo " ⚠️ PRDs directory missing" [ -d ".claude/epics" ] && echo " ✅ Epics directory exists" || echo " ⚠️ Epics directory missing" [ -d ".claude/rules" ] && echo " ✅ Rules directory exists" || echo " ⚠️ Rules directory missing" echo "" # Check for orphaned files echo "🗂️ Data Integrity:" # Check epics have epic.md files for epic_dir in .claude/epics/*/; do [ -d "$epic_dir" ] || continue if [ ! -f "$epic_dir/epic.md" ]; then echo " ⚠️ Missing epic.md in $(basename "$epic_dir")" ((warnings++)) fi done # Check for tasks without epics orphaned=$(find .claude -name "[0-9]*.md" -not -path ".claude/epics/*/*" 2>/dev/null | wc -l) [ $orphaned -gt 0 ] && echo " ⚠️ Found $orphaned orphaned task files" && ((warnings++)) # Check for broken references echo "" echo "🔗 Reference Check:" for task_file in .claude/epics/*/[0-9]*.md; do [ -f "$task_file" ] || continue deps_line=$(grep "^depends_on:" "$task_file" | head -1) if [ -n "$deps_line" ]; then deps=$(echo "$deps_line" | sed 's/^depends_on: *//' | sed 's/^\[//' | sed 's/\]$//' | sed 's/,/ /g' | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//') [ -z "$deps" ] && deps="" else deps="" fi if [ -n "$deps" ] && [ "$deps" != "depends_on:" ]; then epic_dir=$(dirname "$task_file") for dep in $deps; do if [ ! -f "$epic_dir/$dep.md" ]; then echo " ⚠️ Task $(basename "$task_file" .md) references missing task: $dep" ((warnings++)) fi done fi done if [ $warnings -eq 0 ] && [ $errors -eq 0 ]; then echo " ✅ All references valid" fi # Check frontmatter echo "" echo "📝 Frontmatter Validation:" invalid=0 for file in $(find .claude -name "*.md" -path "*/epics/*" -o -path "*/prds/*" 2>/dev/null); do if ! grep -q "^---" "$file"; then echo " ⚠️ Missing frontmatter: $(basename "$file")" ((invalid++)) fi done [ $invalid -eq 0 ] && echo " ✅ All files have frontmatter" # Summary echo "" echo "📊 Validation Summary:" echo " Errors: $errors" echo " Warnings: $warnings" echo " Invalid files: $invalid" if [ $errors -eq 0 ] && [ $warnings -eq 0 ] && [ $invalid -eq 0 ]; then echo "" echo "✅ System is healthy!" else echo "" echo "💡 Run /pm:clean to fix some issues automatically" fi exit 0 ================================================ FILE: skill/ccpm/references/structure.md ================================================ # Structure — Break Down an Epic This phase converts a technical epic into concrete, numbered task files with dependency and parallelization metadata. --- ## Epic Decomposition **Trigger**: User wants to break an epic into actionable tasks. ### Preflight - Verify `.claude/epics/<name>/epic.md` exists with valid frontmatter. - If numbered task files (001.md, 002.md...) already exist in the epic directory, list them and confirm deletion before recreating. - If epic status is "completed", warn the user before proceeding. ### Process Read the epic fully. Analyze for parallelism — which pieces of work can happen simultaneously without file conflicts? **Task types to consider:** - Setup: environment, scaffolding, dependencies - Data: models, schemas, migrations - API: endpoints, services, integration - UI: components, pages, styling - Tests: unit, integration, e2e - Docs: README, API docs, changelogs **Parallelization strategy by epic size:** - Small (<5 tasks): create sequentially - Medium (5–10 tasks): batch into 2–3 groups, spawn parallel Task agents - Large (>10 tasks): analyze dependencies first, launch parallel agents (max 5 concurrent), create dependent tasks after prerequisites For parallel creation, use the Task tool: ```yaml Task: description: "Create task files batch N" subagent_type: "general-purpose" prompt: | Create task files for epic: <name> Tasks to create: [list 3-4 tasks] Save to: .claude/epics/<name>/001.md, 002.md, etc. Follow the task file format exactly. Return: list of files created. ``` ### Task File Format ```markdown --- name: <Task Title> status: open created: <run: date -u +"%Y-%m-%dT%H:%M:%SZ"> updated: <same as created> github: (will be set on sync) depends_on: [] parallel: true conflicts_with: [] --- # Task: <Task Title> ## Description ## Acceptance Criteria - [ ] ## Technical Details ## Dependencies ## Effort Estimate - Size: XS/S/M/L/XL - Hours: N ## Definition of Done - [ ] Code implemented - [ ] Tests written and passing - [ ] Code reviewed ``` **Numbering**: sequential 001.md, 002.md, etc. Tasks are renamed to GitHub issue numbers after sync — do not hard-code dependencies by filename, use the `depends_on` array. ### After Creating All Tasks Append a summary to the epic file: ```markdown ## Tasks Created - [ ] 001.md - <Title> (parallel: true/false) - [ ] 002.md - <Title> (parallel: true/false) Total tasks: N Parallel tasks: N Sequential tasks: N Estimated total effort: N hours ``` **After completion**: Confirm "✅ Created N tasks for epic: <name>" and suggest: "Ready to push to GitHub? Say: sync the <name> epic" --- ## Dependency Rules - `depends_on` lists task numbers that must complete before this task can start. - `parallel: true` means the task can run concurrently with others it doesn't conflict with. - `conflicts_with` lists tasks that touch the same files — these cannot run in parallel. - Circular dependencies are an error — check before finalizing. ================================================ FILE: skill/ccpm/references/sync.md ================================================ # Sync — Push to GitHub & Track Progress This phase covers pushing local epics/tasks to GitHub as issues, syncing progress as comments, and closing issues when work is done. --- ## Repository Safety Check **Always run this before any GitHub write operation:** ```bash remote_url=$(git remote get-url origin 2>/dev/null || echo "") if [[ "$remote_url" == *"automazeio/ccpm"* ]]; then echo "❌ Cannot sync to the CCPM template repository." echo "Update remote: git remote set-url origin https://github.com/YOUR/REPO.git" exit 1 fi REPO=$(echo "$remote_url" | sed 's|.*github.com[:/]||' | sed 's|\.git$||') ``` --- ## Epic Sync — Push Epic + Tasks to GitHub **Trigger**: User wants to push a local epic and its tasks to GitHub as issues. ### Preflight - Verify `.claude/epics/<name>/epic.md` exists. - Verify numbered task files exist — if none: "❌ No tasks to sync. Decompose the epic first." ### Process **Step 1 — Create epic issue:** Strip frontmatter from epic.md, then: ```bash sed '1,/^---$/d; 1,/^---$/d' .claude/epics/<name>/epic.md > /tmp/epic-body.md epic_number=$(gh issue create \ --repo "$REPO" \ --title "Epic: <name>" \ --body-file /tmp/epic-body.md \ --label "epic,epic:<name>,feature" \ --json number -q .number) ``` **Step 2 — Create task sub-issues:** Check if `gh-sub-issue` extension is available: ```bash if gh extension list | grep -q "yahsan2/gh-sub-issue"; then use_subissues=true fi ``` For <5 tasks: create sequentially. For ≥5 tasks: use parallel Task agents (3-4 tasks per batch). Per task: ```bash sed '1,/^---$/d; 1,/^---$/d' <task_file> > /tmp/task-body.md task_number=$(gh issue create \ --repo "$REPO" \ --title "<task_name>" \ --body-file /tmp/task-body.md \ --label "task,epic:<name>" \ --json number -q .number) # or with sub-issues: # gh sub-issue create --parent $epic_number ... ``` **Step 3 — Rename task files and update references:** After all issues are created, rename `001.md` → `<issue_number>.md` and update all `depends_on`/`conflicts_with` arrays to use real issue numbers (not sequential numbers). ```bash # Build old→new mapping, then for each task file: sed -i.bak "s/\b001\b/<new_num_1>/g" <file> # repeat for each mapping mv 001.md <new_num>.md ``` **Step 4 — Update frontmatter:** ```bash current_date=$(date -u +"%Y-%m-%dT%H:%M:%SZ") # Update github: and updated: fields in epic.md and each task file github_url="https://github.com/$REPO/issues/<number>" sed -i.bak "/^github:/c\\github: $github_url" <file> sed -i.bak "/^updated:/c\\updated: $current_date" <file> rm <file>.bak ``` **Step 5 — Create worktree for the epic:** ```bash git checkout main && git pull origin main git worktree add ../epic-<name> -b epic/<name> ``` **Step 6 — Create github-mapping.md:** ```markdown # GitHub Issue Mapping Epic: #<N> - https://github.com/<repo>/issues/<N> Tasks: - #<N>: <title> - https://github.com/<repo>/issues/<N> Synced: <datetime> ``` **Output:** ``` ✅ Synced epic <name> to GitHub Epic: #<N> Tasks: N sub-issues Worktree: ../epic-<name> Next: "start working on issue <N>" or "start the <name> epic" ``` --- ## Issue Sync — Post Progress to GitHub **Trigger**: User wants to sync local development progress to a GitHub issue as a comment. ### Preflight - Verify issue exists: `gh issue view <N> --json state` - Check `.claude/epics/*/updates/<N>/` exists with a `progress.md` file. - Check `last_sync` in progress.md — if synced <5 minutes ago, confirm before proceeding. ### Process Gather updates from `.claude/epics/<epic>/updates/<N>/` (progress.md, notes.md, commits.md). Format and post a comment: ```bash gh issue comment <N> --body-file /tmp/update-comment.md ``` Comment format: ```markdown ## 🔄 Progress Update - <date> ### ✅ Completed Work ### 🔄 In Progress ### 📝 Technical Notes ### 📊 Acceptance Criteria Status ### 🚀 Next Steps ### ⚠️ Blockers --- *Progress: N% | Synced at <timestamp>* ``` After posting: update `last_sync` in progress.md frontmatter, update `updated` in the task file. Add sync marker to local files to prevent duplicate comments: ```markdown <!-- SYNCED: <datetime> --> ``` --- ## Closing an Issue **Trigger**: User marks a task complete. ### Process 1. Find the local task file (`.claude/epics/*/<N>.md`). 2. Update frontmatter: `status: closed`, `updated: <now>`. 3. Post completion comment: ```bash echo "✅ Task completed — all acceptance criteria met." | gh issue comment <N> --body-file - gh issue close <N> ``` 4. Check off the task in the epic issue body: ```bash gh issue view <epic_N> --json body -q .body > /tmp/epic-body.md sed -i "s/- \[ \] #<N>/- [x] #<N>/" /tmp/epic-body.md gh issue edit <epic_N> --body-file /tmp/epic-body.md ``` 5. Recalculate and update epic progress: `progress = closed_tasks / total_tasks * 100` --- ## Merging an Epic **Trigger**: User wants to merge a completed epic back to main. ### Preflight - Verify worktree `../epic-<name>` exists. - Check for uncommitted changes in the worktree — block if dirty. - Warn if any task issues are still open. ### Process ```bash # From worktree: run project tests if detectable cd ../epic-<name> # detect and run: npm test / pytest / cargo test / go test / etc. # From main repo: git checkout main && git pull origin main git merge epic/<name> --no-ff -m "Merge epic: <name>" git push origin main # Cleanup git worktree remove ../epic-<name> git branch -d epic/<name> git push origin --delete epic/<name> # Archive mkdir -p .claude/epics/archived/ mv .claude/epics/<name> .claude/epics/archived/ # Close GitHub issues epic_issue=$(grep 'github:' .claude/epics/archived/<name>/epic.md | grep -oE '[0-9]+$') gh issue close $epic_issue -c "Epic completed and merged to main" ``` Update epic.md frontmatter: `status: completed`. --- ## Reporting a Bug Against a Completed Issue **Trigger**: User finds a bug while testing a completed or in-progress issue — e.g. "found a bug in issue 42", "email validation is broken, came up while testing issue 42". The workflow should stay automated: create a linked bug task without losing context from the original issue. ### Process **Step 1 — Read the original issue for context:** ```bash gh issue view <original_N> --json title,body,labels ``` Also read the local task file if it exists: `.claude/epics/*/<original_N>.md` **Step 2 — Create a local bug task file:** ```markdown --- name: Bug: <short description> status: open created: <run: date -u +"%Y-%m-%dT%H:%M:%SZ"> updated: <same> github: (will be set on sync) depends_on: [] parallel: false conflicts_with: [] bug_for: <original_N> --- # Bug: <short description> ## Context Found while working on / testing issue #<original_N>: <original title> ## Description <what's broken> ## Steps to Reproduce <steps> ## Expected vs Actual - Expected: - Actual: ## Acceptance Criteria - [ ] Bug is fixed - [ ] Original issue #<original_N> behaviour is unaffected ## Effort Estimate - Size: XS/S ``` Save to `.claude/epics/<same_epic_as_original>/bug-<original_N>-<slug>.md` **Step 3 — Create a linked GitHub issue:** ```bash gh issue create \ --repo "$REPO" \ --title "Bug: <short description>" \ --body "$(cat /tmp/bug-body.md)" \ --label "bug,epic:<epic_name>" \ --json number -q .number ``` The issue body should open with `Fixes / follow-up to #<original_N>` so GitHub auto-links them. **Step 4 — Update the local file** with the GitHub issue number and rename to `<new_N>.md`. **Output:** ``` ✅ Bug issue created: #<new_N> — "Bug: <short description>" Linked to: #<original_N> Epic: <epic_name> Start fixing it: "start working on issue <new_N>" ``` ================================================ FILE: skill/ccpm/references/track.md ================================================ # Track — Know Where Things Stand Tracking operations use bash scripts directly for speed and consistency. The LLM is not needed for these — just run the script and present the output. --- ## Script-First Rule All tracking operations have a corresponding bash script. Run the script; do not reconstruct the output manually. Scripts live in `references/scripts/` relative to this skill, but need to run from the **project root** (where `.claude/` lives). Run them as: ```bash bash <skill_path>/references/scripts/<script>.sh [args] ``` Or if ccpm is installed project-locally: ```bash bash ccpm/scripts/pm/<script>.sh [args] ``` --- ## Project Status **Trigger**: "what's our status", "project status", "overview" ```bash bash references/scripts/status.sh ``` Shows: active epics, open issues count, recent activity. --- ## Standup Report **Trigger**: "standup", "daily standup", "what did we do", "morning update" ```bash bash references/scripts/standup.sh ``` Shows: what was completed yesterday, what's in progress today, any blockers. --- ## List Epics **Trigger**: "list epics", "show epics", "what epics do we have" ```bash bash references/scripts/epic-list.sh ``` --- ## Show Epic Details **Trigger**: "show the <name> epic", "epic details for <name>" ```bash bash references/scripts/epic-show.sh <name> ``` --- ## Epic Status **Trigger**: "status of the <name> epic", "how far along is <name>" ```bash bash references/scripts/epic-status.sh <name> ``` Shows: task completion breakdown, active agents, blocking issues. --- ## List PRDs **Trigger**: "list PRDs", "what PRDs do we have", "show backlog" ```bash bash references/scripts/prd-list.sh ``` --- ## PRD Status **Trigger**: "PRD status", "which PRDs are parsed", "what's in backlog" ```bash bash references/scripts/prd-status.sh ``` --- ## Search **Trigger**: "search for <query>", "find issues about <topic>", "look for <term>" ```bash bash references/scripts/search.sh "<query>" ``` Searches local task files, PRDs, and epics for the query term. --- ## What's In Progress **Trigger**: "what's in progress", "what are we working on", "active work" ```bash bash references/scripts/in-progress.sh ``` --- ## What's Next **Trigger**: "what should I work on next", "what's next", "next priority" ```bash bash references/scripts/next.sh ``` Shows highest-priority open tasks with no blocking dependencies. --- ## What's Blocked **Trigger**: "what's blocked", "any blockers", "what can't we move on" ```bash bash references/scripts/blocked.sh ``` --- ## Validate Project State **Trigger**: "validate", "check project state", "is everything consistent" ```bash bash references/scripts/validate.sh ``` Checks: frontmatter consistency, orphaned files, missing GitHub links, dependency integrity. --- ## When Scripts Fail If a script fails or the output needs interpretation (e.g., an error in the output, or the user asks "what does this mean"), then step in to explain. But always run the script first — don't guess at what status/standup output would look like. If `.claude/` directory doesn't exist at all, the project hasn't been initialized. Direct the user to run: ```bash bash references/scripts/init.sh ```