claude-autopm 1.20.0 → 1.21.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.
Files changed (44) hide show
  1. package/README.md +255 -878
  2. package/autopm/.claude/agents/README.md +1 -1
  3. package/autopm/.claude/agents/decision-matrices/python-backend-selection.md +25 -25
  4. package/autopm/.claude/agents/decision-matrices/ui-framework-selection.md +43 -43
  5. package/autopm/.claude/agents/devops/github-operations-specialist.md +1 -1
  6. package/autopm/.claude/agents/frameworks/README.md +5 -5
  7. package/autopm/.claude/agents/frameworks/e2e-test-engineer.md +1 -1
  8. package/autopm/.claude/agents/frameworks/nats-messaging-expert.md +1 -1
  9. package/autopm/.claude/agents/frameworks/react-frontend-engineer.md +1 -1
  10. package/autopm/.claude/agents/frameworks/react-ui-expert.md +3 -3
  11. package/autopm/.claude/agents/frameworks/tailwindcss-expert.md +3 -3
  12. package/autopm/.claude/agents/frameworks/ux-design-expert.md +3 -3
  13. package/autopm/.claude/commands/infrastructure/traefik-setup.md +1 -1
  14. package/autopm/.claude/commands/playwright/test-scaffold.md +1 -1
  15. package/autopm/.claude/commands/pm/epic-sync.md +37 -4
  16. package/autopm/.claude/commands/ui/bootstrap-scaffold.md +6 -5
  17. package/autopm/.claude/commands/ui/tailwind-system.md +1 -1
  18. package/autopm/.claude/examples/mcp/playwright-mcp.md +2 -2
  19. package/autopm/.claude/examples/mcp-servers.example.json +2 -2
  20. package/autopm/.claude/hooks/docker-first-enforcement.sh +1 -1
  21. package/autopm/.claude/mcp/playwright-mcp.md +2 -2
  22. package/autopm/.claude/rules/agent-coordination.md +26 -24
  23. package/autopm/.claude/rules/docker-first-development.md +1 -1
  24. package/autopm/.claude/rules/framework-path-rules.md +180 -0
  25. package/autopm/.claude/rules/infrastructure-pipeline.md +1 -1
  26. package/autopm/.claude/rules/ui-development-standards.md +1 -1
  27. package/autopm/.claude/rules/visual-testing.md +3 -3
  28. package/autopm/.claude/scripts/pm/epic-sync/README.md +208 -0
  29. package/autopm/.claude/scripts/pm/epic-sync/create-epic-issue.sh +68 -192
  30. package/autopm/.claude/scripts/pm/epic-sync/create-task-issues.sh +60 -328
  31. package/autopm/.claude/scripts/pm/epic-sync/update-epic-file.sh +61 -354
  32. package/autopm/.claude/scripts/pm/epic-sync/update-references.sh +67 -305
  33. package/autopm/.claude/scripts/pm/epic-sync.sh +137 -0
  34. package/autopm/.claude/teams.json +3 -5
  35. package/autopm/.claude/templates/claude-templates/addons/devops-agents.md +2 -2
  36. package/autopm/.claude/templates/claude-templates/addons/docker-agents.md +4 -4
  37. package/autopm/.claude/templates/claude-templates/addons/minimal-agents.md +1 -1
  38. package/autopm/.claude/templates/issue-decomposition/api.yaml +2 -2
  39. package/autopm/.claude/templates/issue-decomposition/auth.yaml +4 -4
  40. package/autopm/.claude/templates/issue-decomposition/crud.yaml +3 -3
  41. package/autopm/.claude/templates/issue-decomposition/default.yaml +1 -1
  42. package/autopm/.claude/templates/issue-decomposition/ui-feature.yaml +2 -2
  43. package/package.json +4 -3
  44. package/scripts/validate-framework-paths.sh +104 -0
@@ -1,372 +1,79 @@
1
1
  #!/bin/bash
2
- # Update Epic File Script
3
- # Updates epic.md with GitHub URL, timestamp, and real task IDs
2
+ # Update Epic File
3
+ # Updates epic.md with GitHub URL and real task issue numbers
4
4
 
5
5
  set -euo pipefail
6
6
 
7
- # Load libraries
8
7
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9
- source "${SCRIPT_DIR}/../../lib/logging-utils.sh"
10
- source "${SCRIPT_DIR}/../../lib/github-utils.sh"
11
- source "${SCRIPT_DIR}/../../lib/frontmatter-utils.sh"
12
- source "${SCRIPT_DIR}/../../lib/validation-utils.sh"
13
- source "${SCRIPT_DIR}/../../lib/datetime-utils.sh"
8
+ EPIC_NAME="${1:-}"
9
+ EPIC_NUMBER="${2:-}"
14
10
 
15
- # Script configuration
16
- readonly EPIC_NAME="${1:-}"
17
- readonly EPIC_ISSUE_NUMBER="${2:-}"
18
-
19
- # Global variables
20
- declare -g temp_dir=""
21
- declare -g epic_file=""
22
-
23
- # Main function
24
- main() {
25
- print_banner "Epic File Updater" "1.0.0"
26
-
27
- # Validate inputs
28
- log_info "Validating inputs: epic=$EPIC_NAME, epic_issue=$EPIC_ISSUE_NUMBER"
29
- validate_inputs || exit 1
30
-
31
- # Setup workspace
32
- setup_workspace
33
-
34
- # Update epic frontmatter
35
- with_error_handling "Update epic frontmatter" \
36
- update_epic_frontmatter
37
-
38
- # Update Tasks Created section
39
- with_error_handling "Update Tasks Created section" \
40
- update_tasks_created_section
41
-
42
- # Create GitHub mapping file
43
- with_error_handling "Create GitHub mapping file" \
44
- create_github_mapping_file
45
-
46
- # Display results
47
- display_results
48
-
49
- log_success "Epic file update completed successfully"
50
- }
51
-
52
- # Validate script inputs
53
- validate_inputs() {
54
- log_function_entry "validate_inputs"
55
-
56
- validate_epic_name "$EPIC_NAME" || return 1
57
- validate_issue_number "$EPIC_ISSUE_NUMBER" || return 1
58
- validate_epic_structure "$EPIC_NAME" || return 1
59
- validate_github_auth || return 1
60
-
61
- epic_file=".claude/epics/$EPIC_NAME/epic.md"
62
- validate_file_exists "$epic_file" "Epic file" || return 1
63
-
64
- log_function_exit "validate_inputs"
65
- return 0
66
- }
67
-
68
- # Setup temporary workspace
69
- setup_workspace() {
70
- log_function_entry "setup_workspace"
71
-
72
- temp_dir="/tmp/update-epic-$$"
73
-
74
- log_info "Creating workspace: $temp_dir"
75
- mkdir -p "$temp_dir"
76
-
77
- # Cleanup on exit
78
- trap "cleanup_workspace" EXIT
79
-
80
- log_function_exit "setup_workspace"
81
- }
82
-
83
- # Cleanup workspace
84
- cleanup_workspace() {
85
- if [[ -n "$temp_dir" ]] && [[ -d "$temp_dir" ]]; then
86
- log_debug "Cleaning up workspace: $temp_dir"
87
- rm -rf "$temp_dir"
88
- fi
89
- }
90
-
91
- # Update epic frontmatter with GitHub URL and timestamp
92
- update_epic_frontmatter() {
93
- log_function_entry "update_epic_frontmatter"
94
-
95
- # Get repository info
96
- local repo_info
97
- repo_info=$(get_repo_info)
98
- local repo_name
99
- repo_name=$(echo "$repo_info" | grep -o '"nameWithOwner":"[^"]*"' | cut -d'"' -f4)
100
-
101
- local epic_url="https://github.com/$repo_name/issues/$EPIC_ISSUE_NUMBER"
102
- local current_datetime
103
- current_datetime=$(get_current_datetime)
104
-
105
- log_info "Updating epic frontmatter"
106
- log_debug "Repository: $repo_name"
107
- log_debug "Epic URL: $epic_url"
108
- log_debug "Timestamp: $current_datetime"
109
-
110
- # Update frontmatter fields
111
- update_frontmatter_field "$epic_file" "github" "$epic_url"
112
- update_frontmatter_field "$epic_file" "updated" "$current_datetime"
113
-
114
- log_success "Epic frontmatter updated"
115
- log_function_exit "update_epic_frontmatter"
116
- }
117
-
118
- # Update the Tasks Created section with real issue numbers
119
- update_tasks_created_section() {
120
- log_function_entry "update_tasks_created_section"
121
-
122
- local epic_dir=".claude/epics/$EPIC_NAME"
123
- local tasks_section_file="$temp_dir/tasks-section.md"
124
-
125
- # Create new Tasks Created section
126
- cat > "$tasks_section_file" << 'EOF'
127
- ## Tasks Created
128
- EOF
129
-
130
- local task_count=0
131
-
132
- # Add each task with its real issue number
133
- local task_files=()
134
- readarray -t task_files < <(find "$epic_dir" -name '[0-9]*.md' -type f | sort -n)
135
-
136
- for task_file in "${task_files[@]}"; do
137
- [[ -f "$task_file" ]] || continue
138
-
139
- # Get issue number (filename without .md)
140
- local issue_num
141
- issue_num=$(basename "$task_file" .md)
142
-
143
- # Get task name from frontmatter
144
- local task_name
145
- task_name=$(get_frontmatter_field "$task_file" "name" 2>/dev/null || echo "Unknown Task")
146
-
147
- # Get parallel status
148
- local parallel
149
- parallel=$(get_frontmatter_field "$task_file" "parallel" 2>/dev/null || echo "false")
150
-
151
- # Add to tasks section
152
- echo "- [ ] #${issue_num} - ${task_name} (parallel: ${parallel})" >> "$tasks_section_file"
153
- task_count=$((task_count + 1))
154
- log_debug "Added task: #$issue_num - $task_name"
155
- done
156
-
157
- # Calculate and add summary statistics
158
- local parallel_count sequential_count
159
- parallel_count=$(grep -l '^parallel: true' "$epic_dir"/[0-9]*.md 2>/dev/null | wc -l || echo 0)
160
- sequential_count=$((task_count - parallel_count))
161
-
162
- cat >> "$tasks_section_file" << EOF
163
-
164
- Total tasks: ${task_count}
165
- Parallel tasks: ${parallel_count}
166
- Sequential tasks: ${sequential_count}
167
- EOF
168
-
169
- log_info "Generated tasks section: $task_count tasks ($parallel_count parallel, $sequential_count sequential)"
170
-
171
- # Replace the Tasks Created section in epic.md
172
- replace_tasks_created_section "$tasks_section_file"
173
-
174
- log_success "Tasks Created section updated"
175
- log_function_exit "update_tasks_created_section"
176
- }
177
-
178
- # Replace the Tasks Created section in epic.md
179
- replace_tasks_created_section() {
180
- local tasks_section_file="$1"
181
-
182
- log_function_entry "replace_tasks_created_section"
183
-
184
- # Create backup
185
- local backup_file="$epic_file.backup"
186
- cp "$epic_file" "$backup_file"
187
-
188
- # Use awk to replace the section
189
- awk -v tasks_file="$tasks_section_file" '
190
- /^## Tasks Created/ {
191
- skip=1
192
- while ((getline line < tasks_file) > 0) print line
193
- close(tasks_file)
194
- next
195
- }
196
- /^## / && !/^## Tasks Created/ {
197
- skip=0
198
- }
199
- !skip && !/^## Tasks Created/ {
200
- print
201
- }
202
- ' "$backup_file" > "$epic_file"
203
-
204
- # Clean up backup
205
- rm "$backup_file"
206
-
207
- log_debug "Replaced Tasks Created section using awk"
208
- log_function_exit "replace_tasks_created_section"
209
- }
210
-
211
- # Create GitHub mapping file for reference
212
- create_github_mapping_file() {
213
- log_function_entry "create_github_mapping_file"
214
-
215
- local epic_dir=".claude/epics/$EPIC_NAME"
216
- local mapping_file="$epic_dir/github-mapping.md"
217
-
218
- # Get repository info
219
- local repo_info
220
- repo_info=$(get_repo_info)
221
- local repo_name
222
- repo_name=$(echo "$repo_info" | grep -o '"nameWithOwner":"[^"]*"' | cut -d'"' -f4)
223
-
224
- # Create mapping file
225
- cat > "$mapping_file" << EOF
226
- # GitHub Issue Mapping
227
-
228
- Epic: #${EPIC_ISSUE_NUMBER} - https://github.com/${repo_name}/issues/${EPIC_ISSUE_NUMBER}
229
-
230
- Tasks:
231
- EOF
232
-
233
- # Add each task mapping
234
- local task_files=()
235
- readarray -t task_files < <(find "$epic_dir" -name '[0-9]*.md' -type f | sort -n)
236
-
237
- for task_file in "${task_files[@]}"; do
238
- [[ -f "$task_file" ]] || continue
239
-
240
- local issue_num
241
- issue_num=$(basename "$task_file" .md)
242
-
243
- local task_name
244
- task_name=$(get_frontmatter_field "$task_file" "name" 2>/dev/null || echo "Unknown Task")
245
-
246
- echo "- #${issue_num}: ${task_name} - https://github.com/${repo_name}/issues/${issue_num}" >> "$mapping_file"
247
- done
248
-
249
- # Add sync timestamp
250
- local current_datetime
251
- current_datetime=$(get_current_datetime)
252
-
253
- cat >> "$mapping_file" << EOF
254
-
255
- Synced: ${current_datetime}
256
- EOF
257
-
258
- log_info "Created GitHub mapping file: $mapping_file"
259
- log_function_exit "create_github_mapping_file"
260
- }
261
-
262
- # Display update results
263
- display_results() {
264
- local epic_dir=".claude/epics/$EPIC_NAME"
265
-
266
- print_section "✅ Epic File Update Results"
267
-
268
- echo "Epic: $EPIC_NAME"
269
- echo "GitHub Issue: #$EPIC_ISSUE_NUMBER"
11
+ if [[ -z "$EPIC_NAME" ]] || [[ -z "$EPIC_NUMBER" ]]; then
12
+ echo "❌ Error: Epic name and epic number required"
13
+ echo "Usage: $0 <epic_name> <epic_number>"
14
+ exit 1
15
+ fi
270
16
 
271
- # Show updated frontmatter
272
- local epic_url github_field updated_field
273
- github_field=$(get_frontmatter_field "$epic_file" "github" 2>/dev/null || echo "")
274
- updated_field=$(get_frontmatter_field "$epic_file" "updated" 2>/dev/null || echo "")
17
+ EPIC_DIR=".claude/epics/$EPIC_NAME"
18
+ EPIC_FILE="$EPIC_DIR/epic.md"
19
+ MAPPING_FILE="$EPIC_DIR/.task-mapping.txt"
275
20
 
276
- echo ""
277
- echo "Frontmatter Updates:"
278
- echo " GitHub URL: $github_field"
279
- echo " Updated: $updated_field"
21
+ if [[ ! -f "$EPIC_FILE" ]]; then
22
+ echo " Error: Epic file not found: $EPIC_FILE"
23
+ exit 1
24
+ fi
280
25
 
281
- # Show tasks summary
282
- local task_files=()
283
- readarray -t task_files < <(find "$epic_dir" -name '[0-9]*.md' -type f | sort -n)
26
+ # Get repository info
27
+ REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner 2>/dev/null || echo "unknown/repo")
28
+ EPIC_URL="https://github.com/$REPO/issues/$EPIC_NUMBER"
284
29
 
285
- local task_count=${#task_files[@]}
286
- local parallel_count
287
- parallel_count=$(grep -l '^parallel: true' "$epic_dir"/[0-9]*.md 2>/dev/null | wc -l || echo 0)
288
- local sequential_count=$((task_count - parallel_count))
30
+ echo "📄 Updating epic file: $EPIC_FILE"
289
31
 
290
- echo ""
291
- echo "Tasks Summary:"
292
- echo " Total tasks: $task_count"
293
- echo " Parallel tasks: $parallel_count"
294
- echo " Sequential tasks: $sequential_count"
32
+ # Create backup
33
+ cp "$EPIC_FILE" "$EPIC_FILE.backup"
295
34
 
296
- # Show created files
297
- echo ""
298
- echo "Files Updated:"
299
- echo " ✅ $epic_file"
300
- echo " ✅ $epic_dir/github-mapping.md"
35
+ # Update frontmatter
36
+ timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
301
37
 
302
- echo ""
303
- echo "✅ Epic file synchronized with GitHub"
304
- echo "✅ All task references updated with real issue numbers"
305
- echo "✅ Frontmatter updated with GitHub URL and timestamp"
38
+ awk -v url="$EPIC_URL" -v ts="$timestamp" '
39
+ BEGIN { in_front=0; front_done=0 }
40
+ /^---$/ {
41
+ if (!front_done) {
42
+ in_front = !in_front
43
+ if (!in_front) front_done=1
44
+ }
45
+ print
46
+ next
306
47
  }
307
-
308
- # Validate epic structure after update
309
- validate_epic_structure_post_update() {
310
- log_function_entry "validate_epic_structure_post_update"
311
-
312
- # Check that Tasks Created section exists and is properly formatted
313
- if ! grep -q "^## Tasks Created" "$epic_file"; then
314
- log_error "Tasks Created section not found after update"
315
- return 1
316
- fi
317
-
318
- # Check that frontmatter has GitHub URL
319
- local github_url
320
- github_url=$(get_frontmatter_field "$epic_file" "github" 2>/dev/null || echo "")
321
-
322
- if [[ -z "$github_url" ]]; then
323
- log_error "GitHub URL not found in epic frontmatter"
324
- return 1
325
- fi
326
-
327
- # Validate GitHub URL format
328
- if [[ ! "$github_url" =~ ^https://github\.com/.*/issues/[0-9]+$ ]]; then
329
- log_error "Invalid GitHub URL format: $github_url"
330
- return 1
331
- fi
332
-
333
- log_debug "Epic structure validation passed"
334
- log_function_exit "validate_epic_structure_post_update"
335
- return 0
48
+ in_front && /^github:/ {
49
+ print "github: " url
50
+ next
336
51
  }
337
-
338
- # Error handling
339
- handle_error() {
340
- local exit_code=$?
341
- log_error "Script failed with exit code: $exit_code"
342
- log_error "Epic file update failed for: $EPIC_NAME"
343
- exit "$exit_code"
52
+ in_front && /^updated:/ {
53
+ print "updated: " ts
54
+ next
344
55
  }
345
-
346
- # Set up error handling
347
- trap handle_error ERR
348
-
349
- # Validate arguments
350
- if [[ $# -ne 2 ]]; then
351
- echo "Usage: $0 <epic_name> <epic_issue_number>"
352
- echo ""
353
- echo "Updates epic.md file with GitHub URL, timestamp, and real task IDs."
354
- echo ""
355
- echo "Arguments:"
356
- echo " epic_name Name of the epic directory"
357
- echo " epic_issue_number GitHub issue number of the epic"
358
- echo ""
359
- echo "This script will:"
360
- echo " 1. Update epic frontmatter with GitHub URL and timestamp"
361
- echo " 2. Update Tasks Created section with real issue numbers"
362
- echo " 3. Create github-mapping.md file for reference"
363
- echo ""
364
- echo "Examples:"
365
- echo " $0 authentication 123"
366
- echo " $0 user-dashboard 456"
367
- echo ""
368
- exit 1
56
+ { print }
57
+ ' "$EPIC_FILE.backup" > "$EPIC_FILE.tmp"
58
+
59
+ # If mapping file exists, update task references in the body
60
+ if [[ -f "$MAPPING_FILE" ]]; then
61
+ echo " Updating task references with real issue numbers..."
62
+
63
+ # Read mapping and update task references
64
+ while read -r old_name new_number; do
65
+ # Update checkbox items like "- [ ] 001" to "- [ ] #2"
66
+ sed -i "s/- \[ \] $old_name\b/- [ ] #$new_number/g" "$EPIC_FILE.tmp"
67
+ sed -i "s/- \[x\] $old_name\b/- [x] #$new_number/g" "$EPIC_FILE.tmp"
68
+
69
+ # Update task links
70
+ sed -i "s/Task $old_name\b/Task #$new_number/g" "$EPIC_FILE.tmp"
71
+ done < "$MAPPING_FILE"
369
72
  fi
370
73
 
371
- # Run main function
372
- main "$@"
74
+ # Finalize
75
+ mv "$EPIC_FILE.tmp" "$EPIC_FILE"
76
+ rm "$EPIC_FILE.backup"
77
+
78
+ echo "✅ Epic file updated"
79
+ echo " GitHub: $EPIC_URL"