claude-autopm 1.20.1 → 1.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +255 -878
- package/autopm/.claude/agents/cloud/gcp-cloud-functions-engineer.md +5 -10
- package/autopm/.claude/agents/cloud/gemini-api-expert.md +1 -1
- package/autopm/.claude/agents/cloud/openai-python-expert.md +1 -1
- package/autopm/.claude/agents/cloud/terraform-infrastructure-expert.md +7 -11
- package/autopm/.claude/agents/core/mcp-manager.md +7 -0
- package/autopm/.claude/agents/data/airflow-orchestration-expert.md +1 -1
- package/autopm/.claude/agents/data/kedro-pipeline-expert.md +1 -1
- package/autopm/.claude/agents/data/langgraph-workflow-expert.md +1 -1
- package/autopm/.claude/agents/databases/bigquery-expert.md +1 -1
- package/autopm/.claude/agents/databases/cosmosdb-expert.md +1 -1
- package/autopm/.claude/agents/databases/mongodb-expert.md +1 -1
- package/autopm/.claude/agents/databases/postgresql-expert.md +1 -1
- package/autopm/.claude/agents/databases/redis-expert.md +1 -1
- package/autopm/.claude/agents/decision-matrices/playwright-testing-selection.md +6 -0
- package/autopm/.claude/agents/decision-matrices/python-backend-selection.md +7 -0
- package/autopm/.claude/agents/decision-matrices/ui-framework-selection.md +7 -0
- package/autopm/.claude/agents/devops/azure-devops-specialist.md +1 -1
- package/autopm/.claude/agents/devops/github-operations-specialist.md +7 -0
- package/autopm/.claude/agents/devops/mcp-context-manager.md +7 -0
- package/autopm/.claude/agents/devops/ssh-operations-expert.md +1 -1
- package/autopm/.claude/agents/devops/traefik-proxy-expert.md +1 -1
- package/autopm/.claude/agents/frameworks/nats-messaging-expert.md +1 -1
- package/autopm/.claude/agents/frameworks/react-frontend-engineer.md +1 -1
- package/autopm/.claude/agents/languages/bash-scripting-expert.md +1 -1
- package/autopm/.claude/agents/languages/javascript-frontend-engineer.md +1 -1
- package/autopm/.claude/agents/languages/nodejs-backend-engineer.md +3 -7
- package/autopm/.claude/agents/languages/python-backend-engineer.md +1 -1
- package/autopm/.claude/commands/ai/langgraph-workflow.md +17 -0
- package/autopm/.claude/commands/ai/openai-chat.md +17 -0
- package/autopm/.claude/commands/azure/active-work.md +17 -0
- package/autopm/.claude/commands/azure/aliases.md +17 -0
- package/autopm/.claude/commands/azure/blocked-items.md +17 -0
- package/autopm/.claude/commands/azure/clean.md +17 -0
- package/autopm/.claude/commands/azure/docs-query.md +17 -0
- package/autopm/.claude/commands/azure/feature-decompose.md +17 -0
- package/autopm/.claude/commands/azure/feature-list.md +17 -0
- package/autopm/.claude/commands/azure/feature-new.md +17 -0
- package/autopm/.claude/commands/azure/feature-show.md +17 -0
- package/autopm/.claude/commands/azure/feature-start.md +17 -0
- package/autopm/.claude/commands/azure/fix-integration-example.md +17 -0
- package/autopm/.claude/commands/azure/help.md +17 -0
- package/autopm/.claude/commands/azure/import-us.md +17 -0
- package/autopm/.claude/commands/azure/init.md +17 -0
- package/autopm/.claude/commands/azure/next-task.md +17 -0
- package/autopm/.claude/commands/azure/search.md +17 -0
- package/autopm/.claude/commands/azure/sprint-status.md +17 -0
- package/autopm/.claude/commands/azure/standup.md +17 -0
- package/autopm/.claude/commands/azure/sync-all.md +17 -0
- package/autopm/.claude/commands/azure/task-analyze.md +17 -0
- package/autopm/.claude/commands/azure/task-close.md +17 -0
- package/autopm/.claude/commands/azure/task-edit.md +17 -0
- package/autopm/.claude/commands/azure/task-list.md +17 -0
- package/autopm/.claude/commands/azure/task-new.md +17 -0
- package/autopm/.claude/commands/azure/task-reopen.md +17 -0
- package/autopm/.claude/commands/azure/task-show.md +17 -0
- package/autopm/.claude/commands/azure/task-start.md +17 -0
- package/autopm/.claude/commands/azure/task-status.md +17 -0
- package/autopm/.claude/commands/azure/task-sync.md +17 -0
- package/autopm/.claude/commands/azure/us-edit.md +17 -0
- package/autopm/.claude/commands/azure/us-list.md +17 -0
- package/autopm/.claude/commands/azure/us-new.md +17 -0
- package/autopm/.claude/commands/azure/us-parse.md +17 -0
- package/autopm/.claude/commands/azure/us-show.md +17 -0
- package/autopm/.claude/commands/azure/us-status.md +17 -0
- package/autopm/.claude/commands/azure/validate.md +17 -0
- package/autopm/.claude/commands/azure/work-item-sync.md +17 -0
- package/autopm/.claude/commands/cloud/infra-deploy.md +17 -0
- package/autopm/.claude/commands/config/toggle-features.md +15 -0
- package/autopm/.claude/commands/context/create.md +16 -0
- package/autopm/.claude/commands/context/prime.md +16 -0
- package/autopm/.claude/commands/context/update.md +16 -0
- package/autopm/.claude/commands/github/workflow-create.md +17 -0
- package/autopm/.claude/commands/infrastructure/ssh-security.md +17 -0
- package/autopm/.claude/commands/infrastructure/traefik-setup.md +17 -0
- package/autopm/.claude/commands/kubernetes/deploy.md +16 -0
- package/autopm/.claude/commands/mcp/context-setup.md +17 -0
- package/autopm/.claude/commands/mcp/docs-refresh.md +17 -0
- package/autopm/.claude/commands/playwright/test-scaffold.md +17 -0
- package/autopm/.claude/commands/pm/blocked.md +17 -0
- package/autopm/.claude/commands/pm/clean.md +17 -0
- package/autopm/.claude/commands/pm/context.md +17 -0
- package/autopm/.claude/commands/pm/epic-close.md +17 -0
- package/autopm/.claude/commands/pm/epic-decompose.md +16 -0
- package/autopm/.claude/commands/pm/epic-edit.md +17 -0
- package/autopm/.claude/commands/pm/epic-list.md +17 -0
- package/autopm/.claude/commands/pm/epic-merge.md +17 -0
- package/autopm/.claude/commands/pm/epic-oneshot.md +17 -0
- package/autopm/.claude/commands/pm/epic-refresh.md +17 -0
- package/autopm/.claude/commands/pm/epic-show.md +17 -0
- package/autopm/.claude/commands/pm/epic-split.md +17 -0
- package/autopm/.claude/commands/pm/epic-start.md +17 -0
- package/autopm/.claude/commands/pm/epic-status.md +17 -0
- package/autopm/.claude/commands/pm/epic-sync-modular.md +17 -0
- package/autopm/.claude/commands/pm/epic-sync-original.md +17 -0
- package/autopm/.claude/commands/pm/epic-sync.md +54 -4
- package/autopm/.claude/commands/pm/help.md +17 -0
- package/autopm/.claude/commands/pm/import.md +17 -0
- package/autopm/.claude/commands/pm/in-progress.md +17 -0
- package/autopm/.claude/commands/pm/init.md +17 -0
- package/autopm/.claude/commands/pm/issue-analyze.md +17 -0
- package/autopm/.claude/commands/pm/issue-close.md +17 -0
- package/autopm/.claude/commands/pm/issue-edit.md +17 -0
- package/autopm/.claude/commands/pm/issue-reopen.md +17 -0
- package/autopm/.claude/commands/pm/issue-show.md +17 -0
- package/autopm/.claude/commands/pm/issue-start.md +16 -0
- package/autopm/.claude/commands/pm/issue-status.md +17 -0
- package/autopm/.claude/commands/pm/issue-sync.md +17 -0
- package/autopm/.claude/commands/pm/next.md +17 -0
- package/autopm/.claude/commands/pm/prd-edit.md +17 -0
- package/autopm/.claude/commands/pm/prd-list.md +17 -0
- package/autopm/.claude/commands/pm/prd-new.md +16 -0
- package/autopm/.claude/commands/pm/prd-parse.md +17 -0
- package/autopm/.claude/commands/pm/prd-status.md +17 -0
- package/autopm/.claude/commands/pm/search.md +17 -0
- package/autopm/.claude/commands/pm/standup.md +17 -0
- package/autopm/.claude/commands/pm/status.md +17 -0
- package/autopm/.claude/commands/pm/sync.md +17 -0
- package/autopm/.claude/commands/pm/test-reference-update.md +17 -0
- package/autopm/.claude/commands/pm/validate.md +17 -0
- package/autopm/.claude/commands/pm/what-next.md +17 -0
- package/autopm/.claude/commands/python/api-scaffold.md +17 -0
- package/autopm/.claude/commands/python/docs-query.md +17 -0
- package/autopm/.claude/commands/react/app-scaffold.md +17 -0
- package/autopm/.claude/commands/testing/prime.md +17 -0
- package/autopm/.claude/commands/testing/run.md +17 -0
- package/autopm/.claude/commands/ui/bootstrap-scaffold.md +17 -0
- package/autopm/.claude/commands/ui/tailwind-system.md +17 -0
- package/autopm/.claude/hooks/pre-agent-context7.js +224 -0
- package/autopm/.claude/hooks/pre-command-context7.js +229 -0
- package/autopm/.claude/rules/context7-enforcement.md +292 -0
- package/autopm/.claude/rules/framework-path-rules.md +180 -0
- package/autopm/.claude/scripts/pm/epic-sync/README.md +208 -0
- package/autopm/.claude/scripts/pm/epic-sync/create-epic-issue.sh +68 -192
- package/autopm/.claude/scripts/pm/epic-sync/create-task-issues.sh +60 -328
- package/autopm/.claude/scripts/pm/epic-sync/update-epic-file.sh +61 -354
- package/autopm/.claude/scripts/pm/epic-sync/update-references.sh +67 -305
- package/autopm/.claude/scripts/pm/epic-sync.sh +137 -0
- package/package.json +4 -2
- package/scripts/add-context7-to-commands.js +351 -0
- package/scripts/validate-framework-paths.sh +104 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# Epic Sync Modular Scripts
|
|
2
|
+
|
|
3
|
+
This directory contains the modular implementation of the epic-sync workflow that pushes epics and tasks to GitHub as issues.
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
The epic-sync process is split into 4 specialized scripts:
|
|
8
|
+
|
|
9
|
+
1. **create-epic-issue.sh** - Creates the main epic GitHub issue
|
|
10
|
+
2. **create-task-issues.sh** - Creates GitHub issues for all tasks
|
|
11
|
+
3. **update-references.sh** - Renames task files to match GitHub issue numbers
|
|
12
|
+
4. **update-epic-file.sh** - Updates epic.md with real issue numbers
|
|
13
|
+
|
|
14
|
+
## Orchestration
|
|
15
|
+
|
|
16
|
+
The **recommended way** to use these scripts is via the orchestration script:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# From project root
|
|
20
|
+
bash .claude/scripts/pm/epic-sync.sh <epic_name>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
This automatically runs all 4 steps in the correct order.
|
|
24
|
+
|
|
25
|
+
## Individual Scripts
|
|
26
|
+
|
|
27
|
+
### 1. create-epic-issue.sh
|
|
28
|
+
|
|
29
|
+
**Purpose:** Creates the main GitHub issue for the epic
|
|
30
|
+
|
|
31
|
+
**Input:**
|
|
32
|
+
- Epic name (e.g., `postgresql-connection-module`)
|
|
33
|
+
|
|
34
|
+
**Output:**
|
|
35
|
+
- GitHub issue number (stdout)
|
|
36
|
+
|
|
37
|
+
**What it does:**
|
|
38
|
+
- Strips frontmatter from epic.md
|
|
39
|
+
- Counts tasks in epic directory
|
|
40
|
+
- Detects epic type (bug vs feature)
|
|
41
|
+
- Creates GitHub issue with proper labels
|
|
42
|
+
- Returns epic issue number
|
|
43
|
+
|
|
44
|
+
**Usage:**
|
|
45
|
+
```bash
|
|
46
|
+
epic_number=$(bash .claude/scripts/pm/epic-sync/create-epic-issue.sh "my-feature")
|
|
47
|
+
echo "Epic created: #$epic_number"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 2. create-task-issues.sh
|
|
51
|
+
|
|
52
|
+
**Purpose:** Creates GitHub issues for all task files
|
|
53
|
+
|
|
54
|
+
**Input:**
|
|
55
|
+
- Epic name
|
|
56
|
+
- Epic issue number (from step 1)
|
|
57
|
+
|
|
58
|
+
**Output:**
|
|
59
|
+
- Path to task mapping file (stdout)
|
|
60
|
+
|
|
61
|
+
**What it does:**
|
|
62
|
+
- Finds all `[0-9]*.md` files in epic directory
|
|
63
|
+
- Strips frontmatter from each task
|
|
64
|
+
- Creates GitHub issue for each task
|
|
65
|
+
- Labels with `task,epic:<epic_name>`
|
|
66
|
+
- Saves mapping of old_name -> issue_number to `.task-mapping.txt`
|
|
67
|
+
- **Mapping file is saved in epic directory** (persistent, not in /tmp)
|
|
68
|
+
|
|
69
|
+
**Usage:**
|
|
70
|
+
```bash
|
|
71
|
+
mapping=$(bash .claude/scripts/pm/epic-sync/create-task-issues.sh "my-feature" "42")
|
|
72
|
+
echo "Mapping saved: $mapping"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Important:** The mapping file is saved as `.claude/epics/<epic>/.task-mapping.txt` for use in subsequent steps.
|
|
76
|
+
|
|
77
|
+
### 3. update-references.sh
|
|
78
|
+
|
|
79
|
+
**Purpose:** Renames task files to GitHub issue numbers and updates frontmatter
|
|
80
|
+
|
|
81
|
+
**Input:**
|
|
82
|
+
- Epic name
|
|
83
|
+
- Path to task mapping file (from step 2)
|
|
84
|
+
|
|
85
|
+
**Output:**
|
|
86
|
+
- None (modifies files in place)
|
|
87
|
+
|
|
88
|
+
**What it does:**
|
|
89
|
+
- Reads `.task-mapping.txt` file
|
|
90
|
+
- For each mapping (e.g., `001 -> 2`):
|
|
91
|
+
- Renames `001.md` to `2.md`
|
|
92
|
+
- Updates frontmatter with GitHub URL
|
|
93
|
+
- Updates frontmatter timestamp
|
|
94
|
+
- Creates backups during rename (removed on success)
|
|
95
|
+
|
|
96
|
+
**Usage:**
|
|
97
|
+
```bash
|
|
98
|
+
bash .claude/scripts/pm/epic-sync/update-references.sh "my-feature" ".claude/epics/my-feature/.task-mapping.txt"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Before:**
|
|
102
|
+
```
|
|
103
|
+
.claude/epics/my-feature/
|
|
104
|
+
├── 001.md (github: [Will be updated...])
|
|
105
|
+
├── 002.md (github: [Will be updated...])
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**After:**
|
|
109
|
+
```
|
|
110
|
+
.claude/epics/my-feature/
|
|
111
|
+
├── 2.md (github: https://github.com/user/repo/issues/2)
|
|
112
|
+
├── 3.md (github: https://github.com/user/repo/issues/3)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 4. update-epic-file.sh
|
|
116
|
+
|
|
117
|
+
**Purpose:** Updates epic.md with GitHub URL and real task references
|
|
118
|
+
|
|
119
|
+
**Input:**
|
|
120
|
+
- Epic name
|
|
121
|
+
- Epic issue number
|
|
122
|
+
|
|
123
|
+
**Output:**
|
|
124
|
+
- None (modifies epic.md in place)
|
|
125
|
+
|
|
126
|
+
**What it does:**
|
|
127
|
+
- Updates epic.md frontmatter with GitHub URL
|
|
128
|
+
- Updates timestamp
|
|
129
|
+
- Reads `.task-mapping.txt`
|
|
130
|
+
- Replaces task references (e.g., `- [ ] 001` → `- [ ] #2`)
|
|
131
|
+
- Creates backup during update (removed on success)
|
|
132
|
+
|
|
133
|
+
**Usage:**
|
|
134
|
+
```bash
|
|
135
|
+
bash .claude/scripts/pm/epic-sync/update-epic-file.sh "my-feature" "42"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## File Persistence Fix
|
|
139
|
+
|
|
140
|
+
**IMPORTANT:** The task mapping file is saved to a **persistent location**:
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
.claude/epics/<epic_name>/.task-mapping.txt
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
This fixes the bug where the mapping file was being saved to `/tmp` and deleted before subsequent scripts could use it.
|
|
147
|
+
|
|
148
|
+
## Error Handling
|
|
149
|
+
|
|
150
|
+
All scripts use `set -euo pipefail` for robust error handling:
|
|
151
|
+
- `-e`: Exit on error
|
|
152
|
+
- `-u`: Error on undefined variables
|
|
153
|
+
- `-o pipefail`: Fail if any command in pipeline fails
|
|
154
|
+
|
|
155
|
+
## Testing
|
|
156
|
+
|
|
157
|
+
Test individual scripts:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
# Create a test epic first
|
|
161
|
+
mkdir -p .claude/epics/test-epic
|
|
162
|
+
echo "---\ntitle: Test\n---\n# Test Epic" > .claude/epics/test-epic/epic.md
|
|
163
|
+
echo "---\ntitle: Task 1\n---\n# Task 1" > .claude/epics/test-epic/001.md
|
|
164
|
+
echo "---\ntitle: Task 2\n---\n# Task 2" > .claude/epics/test-epic/002.md
|
|
165
|
+
|
|
166
|
+
# Run orchestration script
|
|
167
|
+
bash .claude/scripts/pm/epic-sync.sh test-epic
|
|
168
|
+
|
|
169
|
+
# Verify files were renamed
|
|
170
|
+
ls .claude/epics/test-epic/
|
|
171
|
+
# Should show: epic.md, <issue_number>.md files
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Dependencies
|
|
175
|
+
|
|
176
|
+
- **bash** >= 4.0
|
|
177
|
+
- **gh** (GitHub CLI) - authenticated
|
|
178
|
+
- **awk** - for frontmatter processing
|
|
179
|
+
- **find** - for file discovery
|
|
180
|
+
- **grep** - for pattern matching
|
|
181
|
+
|
|
182
|
+
## Common Issues
|
|
183
|
+
|
|
184
|
+
### "Template repository detected"
|
|
185
|
+
```bash
|
|
186
|
+
# Fix: Set correct remote
|
|
187
|
+
git remote set-url origin https://github.com/YOUR_USERNAME/YOUR_REPO.git
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### "GitHub CLI not authenticated"
|
|
191
|
+
```bash
|
|
192
|
+
gh auth login
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### "Mapping file not found"
|
|
196
|
+
- Ensure step 2 completed successfully
|
|
197
|
+
- Check `.claude/epics/<epic>/.task-mapping.txt` exists
|
|
198
|
+
|
|
199
|
+
### "Task files still numbered 001, 002..."
|
|
200
|
+
- Step 3 (update-references.sh) may not have run
|
|
201
|
+
- Check for errors in step 2 output
|
|
202
|
+
- Run orchestration script instead of individual scripts
|
|
203
|
+
|
|
204
|
+
## Related Files
|
|
205
|
+
|
|
206
|
+
- **/.claude/commands/pm/epic-sync.md** - Command documentation
|
|
207
|
+
- **/.claude/commands/pm/issue-start.md** - Works with renamed files
|
|
208
|
+
- **/.claude/commands/pm/issue-analyze.md** - Expects GitHub issue numbers
|
|
@@ -1,201 +1,77 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# Create Epic Issue
|
|
3
|
-
#
|
|
2
|
+
# Create Epic Issue
|
|
3
|
+
# Creates the main GitHub issue for an epic with proper labels and stats
|
|
4
4
|
|
|
5
5
|
set -euo pipefail
|
|
6
6
|
|
|
7
|
-
# Load libraries
|
|
8
7
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
# Script configuration
|
|
15
|
-
readonly EPIC_NAME="${1:-}"
|
|
16
|
-
|
|
17
|
-
# Main function
|
|
18
|
-
main() {
|
|
19
|
-
print_banner "Epic Issue Creator" "1.0.0"
|
|
20
|
-
|
|
21
|
-
# Validate inputs
|
|
22
|
-
log_info "Validating epic: $EPIC_NAME"
|
|
23
|
-
validate_epic_name "$EPIC_NAME" || exit 1
|
|
24
|
-
validate_epic_structure "$EPIC_NAME" || exit 1
|
|
25
|
-
|
|
26
|
-
# Check GitHub authentication and repo protection
|
|
27
|
-
validate_github_auth || exit 1
|
|
28
|
-
check_repo_protection || exit 1
|
|
29
|
-
|
|
30
|
-
local epic_file=".claude/epics/$EPIC_NAME/epic.md"
|
|
31
|
-
local temp_dir="/tmp/epic-sync-$$"
|
|
32
|
-
|
|
33
|
-
log_info "Creating temporary workspace: $temp_dir"
|
|
34
|
-
mkdir -p "$temp_dir"
|
|
35
|
-
|
|
36
|
-
# Ensure cleanup on exit
|
|
37
|
-
trap "rm -rf '$temp_dir'" EXIT
|
|
38
|
-
|
|
39
|
-
# Process epic content
|
|
40
|
-
with_error_handling "Strip frontmatter from epic" \
|
|
41
|
-
strip_frontmatter "$epic_file" "$temp_dir/epic-body-raw.md"
|
|
42
|
-
|
|
43
|
-
with_error_handling "Process epic content and stats" \
|
|
44
|
-
process_epic_content "$temp_dir/epic-body-raw.md" "$temp_dir/epic-body.md"
|
|
45
|
-
|
|
46
|
-
with_error_handling "Determine epic type" \
|
|
47
|
-
epic_type=$(determine_epic_type "$temp_dir/epic-body.md")
|
|
48
|
-
|
|
49
|
-
with_error_handling "Create GitHub epic issue" \
|
|
50
|
-
issue_number=$(create_epic_github_issue "$temp_dir/epic-body.md" "$epic_type")
|
|
51
|
-
|
|
52
|
-
# Output result
|
|
53
|
-
local repo_info
|
|
54
|
-
repo_info=$(get_repo_info)
|
|
55
|
-
local repo_name
|
|
56
|
-
repo_name=$(echo "$repo_info" | grep -o '"nameWithOwner":"[^"]*"' | cut -d'"' -f4)
|
|
57
|
-
|
|
58
|
-
log_success "Epic issue created successfully!"
|
|
59
|
-
echo "Epic Issue: #${issue_number}"
|
|
60
|
-
echo "URL: https://github.com/${repo_name}/issues/${issue_number}"
|
|
61
|
-
echo "$issue_number" # For script consumption
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
# Process epic content and replace Tasks Created section with Stats
|
|
65
|
-
process_epic_content() {
|
|
66
|
-
local input_file="$1"
|
|
67
|
-
local output_file="$2"
|
|
68
|
-
|
|
69
|
-
log_function_entry "process_epic_content" "$input_file" "$output_file"
|
|
70
|
-
|
|
71
|
-
# Count tasks in epic directory
|
|
72
|
-
local epic_dir=".claude/epics/$EPIC_NAME"
|
|
73
|
-
local total_tasks parallel_tasks sequential_tasks total_effort
|
|
74
|
-
|
|
75
|
-
total_tasks=$(find "$epic_dir" -name '[0-9][0-9][0-9].md' -type f | wc -l)
|
|
76
|
-
parallel_tasks=$(grep -l '^parallel: true' "$epic_dir"/[0-9][0-9][0-9].md 2>/dev/null | wc -l || echo 0)
|
|
77
|
-
sequential_tasks=$((total_tasks - parallel_tasks))
|
|
78
|
-
|
|
79
|
-
# Try to calculate total effort from task files
|
|
80
|
-
total_effort=$(calculate_total_effort "$epic_dir")
|
|
81
|
-
|
|
82
|
-
# Process content with awk to replace Tasks Created section
|
|
83
|
-
awk -v total_tasks="$total_tasks" \
|
|
84
|
-
-v parallel_tasks="$parallel_tasks" \
|
|
85
|
-
-v sequential_tasks="$sequential_tasks" \
|
|
86
|
-
-v total_effort="$total_effort" '
|
|
87
|
-
/^## Tasks Created/ {
|
|
88
|
-
in_tasks=1
|
|
89
|
-
next
|
|
90
|
-
}
|
|
91
|
-
/^## / && in_tasks {
|
|
92
|
-
in_tasks=0
|
|
93
|
-
# Add Stats section
|
|
94
|
-
print "## Stats"
|
|
95
|
-
print ""
|
|
96
|
-
print "Total tasks: " total_tasks
|
|
97
|
-
print "Parallel tasks: " parallel_tasks " (can be worked on simultaneously)"
|
|
98
|
-
print "Sequential tasks: " sequential_tasks " (have dependencies)"
|
|
99
|
-
if (total_effort) print "Estimated total effort: " total_effort " hours"
|
|
100
|
-
print ""
|
|
101
|
-
}
|
|
102
|
-
/^Total tasks:/ && in_tasks { next }
|
|
103
|
-
/^Parallel tasks:/ && in_tasks { next }
|
|
104
|
-
/^Sequential tasks:/ && in_tasks { next }
|
|
105
|
-
/^Estimated total effort:/ && in_tasks { next }
|
|
106
|
-
!in_tasks { print }
|
|
107
|
-
END {
|
|
108
|
-
# If we were still in tasks section at EOF, add stats
|
|
109
|
-
if (in_tasks) {
|
|
110
|
-
print "## Stats"
|
|
111
|
-
print ""
|
|
112
|
-
print "Total tasks: " total_tasks
|
|
113
|
-
print "Parallel tasks: " parallel_tasks " (can be worked on simultaneously)"
|
|
114
|
-
print "Sequential tasks: " sequential_tasks " (have dependencies)"
|
|
115
|
-
if (total_effort) print "Estimated total effort: " total_effort " hours"
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
' "$input_file" > "$output_file"
|
|
119
|
-
|
|
120
|
-
log_debug "Processed epic content with stats: $total_tasks total, $parallel_tasks parallel"
|
|
121
|
-
log_function_exit "process_epic_content"
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
# Calculate total effort from task files
|
|
125
|
-
calculate_total_effort() {
|
|
126
|
-
local epic_dir="$1"
|
|
127
|
-
local total_effort=0
|
|
128
|
-
|
|
129
|
-
for task_file in "$epic_dir"/[0-9][0-9][0-9].md; do
|
|
130
|
-
[[ -f "$task_file" ]] || continue
|
|
131
|
-
|
|
132
|
-
local effort
|
|
133
|
-
effort=$(get_frontmatter_field "$task_file" "effort" 2>/dev/null || echo "")
|
|
134
|
-
|
|
135
|
-
if [[ "$effort" =~ ^[0-9]+$ ]]; then
|
|
136
|
-
total_effort=$((total_effort + effort))
|
|
137
|
-
fi
|
|
138
|
-
done
|
|
139
|
-
|
|
140
|
-
if [[ "$total_effort" -gt 0 ]]; then
|
|
141
|
-
echo "$total_effort"
|
|
142
|
-
fi
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
# Determine epic type from content
|
|
146
|
-
determine_epic_type() {
|
|
147
|
-
local content_file="$1"
|
|
148
|
-
|
|
149
|
-
log_function_entry "determine_epic_type" "$content_file"
|
|
150
|
-
|
|
151
|
-
if grep -qi "bug\|fix\|issue\|problem\|error\|hotfix\|patch" "$content_file"; then
|
|
152
|
-
echo "bug"
|
|
153
|
-
else
|
|
154
|
-
echo "feature"
|
|
155
|
-
fi
|
|
156
|
-
|
|
157
|
-
log_function_exit "determine_epic_type"
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
# Create GitHub epic issue with proper labels
|
|
161
|
-
create_epic_github_issue() {
|
|
162
|
-
local body_file="$1"
|
|
163
|
-
local epic_type="$2"
|
|
164
|
-
|
|
165
|
-
log_function_entry "create_epic_github_issue" "$body_file" "$epic_type"
|
|
166
|
-
|
|
167
|
-
local title="Epic: $EPIC_NAME"
|
|
168
|
-
local labels="epic,epic:$EPIC_NAME,$epic_type"
|
|
169
|
-
|
|
170
|
-
local issue_number
|
|
171
|
-
issue_number=$(create_github_issue "$title" "$body_file" "$labels")
|
|
172
|
-
|
|
173
|
-
log_function_exit "create_epic_github_issue" 0
|
|
174
|
-
echo "$issue_number"
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
# Error handling
|
|
178
|
-
handle_error() {
|
|
179
|
-
local exit_code=$?
|
|
180
|
-
log_error "Script failed with exit code: $exit_code"
|
|
181
|
-
log_error "Epic issue creation failed for: $EPIC_NAME"
|
|
182
|
-
exit "$exit_code"
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
# Set up error handling
|
|
186
|
-
trap handle_error ERR
|
|
187
|
-
|
|
188
|
-
# Validate arguments
|
|
189
|
-
if [[ $# -ne 1 ]]; then
|
|
8
|
+
EPIC_NAME="${1:-}"
|
|
9
|
+
|
|
10
|
+
if [[ -z "$EPIC_NAME" ]]; then
|
|
11
|
+
echo "❌ Error: Epic name required"
|
|
190
12
|
echo "Usage: $0 <epic_name>"
|
|
191
|
-
echo ""
|
|
192
|
-
echo "Creates a GitHub issue for the specified epic."
|
|
193
|
-
echo ""
|
|
194
|
-
echo "Example:"
|
|
195
|
-
echo " $0 authentication"
|
|
196
|
-
echo ""
|
|
197
13
|
exit 1
|
|
198
14
|
fi
|
|
199
15
|
|
|
200
|
-
#
|
|
201
|
-
|
|
16
|
+
# Source utilities if they exist
|
|
17
|
+
if [[ -f "$SCRIPT_DIR/../../lib/github-utils.sh" ]]; then
|
|
18
|
+
source "$SCRIPT_DIR/../../lib/github-utils.sh"
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
EPIC_FILE=".claude/epics/$EPIC_NAME/epic.md"
|
|
22
|
+
|
|
23
|
+
if [[ ! -f "$EPIC_FILE" ]]; then
|
|
24
|
+
echo "❌ Error: Epic file not found: $EPIC_FILE"
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
# Check GitHub CLI
|
|
29
|
+
if ! command -v gh &> /dev/null; then
|
|
30
|
+
echo "❌ Error: GitHub CLI (gh) not installed"
|
|
31
|
+
exit 1
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# Check authentication
|
|
35
|
+
if ! gh auth status &> /dev/null; then
|
|
36
|
+
echo "❌ Error: GitHub CLI not authenticated. Run: gh auth login"
|
|
37
|
+
exit 1
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# Strip frontmatter and get content
|
|
41
|
+
epic_content=$(awk 'BEGIN{p=0} /^---$/{p++; next} p==2{print}' "$EPIC_FILE")
|
|
42
|
+
|
|
43
|
+
# Count tasks
|
|
44
|
+
task_count=$(find ".claude/epics/$EPIC_NAME" -name "[0-9]*.md" -type f 2>/dev/null | wc -l)
|
|
45
|
+
|
|
46
|
+
# Detect epic type (bug vs feature)
|
|
47
|
+
if echo "$epic_content" | grep -qi "bug\|fix\|error\|issue"; then
|
|
48
|
+
labels="epic,bug"
|
|
49
|
+
else
|
|
50
|
+
labels="epic,feature"
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Create issue
|
|
54
|
+
echo "📝 Creating epic issue for: $EPIC_NAME"
|
|
55
|
+
echo " Tasks: $task_count"
|
|
56
|
+
echo " Labels: $labels"
|
|
57
|
+
|
|
58
|
+
# Create the issue
|
|
59
|
+
epic_number=$(gh issue create \
|
|
60
|
+
--title "Epic: $EPIC_NAME" \
|
|
61
|
+
--body "$epic_content
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
**Epic Statistics:**
|
|
65
|
+
- Tasks: $task_count
|
|
66
|
+
- Status: Planning
|
|
67
|
+
- Created: $(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
68
|
+
" \
|
|
69
|
+
--label "$labels" \
|
|
70
|
+
2>&1 | grep -oP '(?<=#)[0-9]+' | head -1)
|
|
71
|
+
|
|
72
|
+
if [[ -z "$epic_number" ]]; then
|
|
73
|
+
echo "❌ Error: Failed to create epic issue"
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
echo "$epic_number"
|