specweave 0.24.8 → 0.24.9

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 (130) hide show
  1. package/dist/src/cli/commands/init.d.ts.map +1 -1
  2. package/dist/src/cli/commands/init.js +3 -1
  3. package/dist/src/cli/commands/init.js.map +1 -1
  4. package/dist/src/cli/helpers/issue-tracker/github-multi-repo.d.ts.map +1 -1
  5. package/dist/src/cli/helpers/issue-tracker/github-multi-repo.js +18 -2
  6. package/dist/src/cli/helpers/issue-tracker/github-multi-repo.js.map +1 -1
  7. package/dist/src/core/repo-structure/git-error-handler.d.ts +1 -1
  8. package/dist/src/core/repo-structure/git-error-handler.d.ts.map +1 -1
  9. package/dist/src/core/repo-structure/git-provider.d.ts +1 -1
  10. package/dist/src/core/repo-structure/git-provider.d.ts.map +1 -1
  11. package/dist/src/core/repo-structure/platform-registry.d.ts.map +1 -1
  12. package/dist/src/core/repo-structure/platform-registry.js +20 -9
  13. package/dist/src/core/repo-structure/platform-registry.js.map +1 -1
  14. package/dist/src/core/repo-structure/prompt-consolidator.d.ts +13 -1
  15. package/dist/src/core/repo-structure/prompt-consolidator.d.ts.map +1 -1
  16. package/dist/src/core/repo-structure/prompt-consolidator.js +38 -5
  17. package/dist/src/core/repo-structure/prompt-consolidator.js.map +1 -1
  18. package/dist/src/core/repo-structure/providers/azure-devops-provider.d.ts +64 -0
  19. package/dist/src/core/repo-structure/providers/azure-devops-provider.d.ts.map +1 -0
  20. package/dist/src/core/repo-structure/providers/azure-devops-provider.js +263 -0
  21. package/dist/src/core/repo-structure/providers/azure-devops-provider.js.map +1 -0
  22. package/dist/src/core/repo-structure/providers/bitbucket-provider.d.ts +12 -11
  23. package/dist/src/core/repo-structure/providers/bitbucket-provider.d.ts.map +1 -1
  24. package/dist/src/core/repo-structure/providers/bitbucket-provider.js +164 -30
  25. package/dist/src/core/repo-structure/providers/bitbucket-provider.js.map +1 -1
  26. package/dist/src/core/repo-structure/providers/gitlab-provider.d.ts +10 -9
  27. package/dist/src/core/repo-structure/providers/gitlab-provider.d.ts.map +1 -1
  28. package/dist/src/core/repo-structure/providers/gitlab-provider.js +182 -28
  29. package/dist/src/core/repo-structure/providers/gitlab-provider.js.map +1 -1
  30. package/dist/src/core/repo-structure/providers/index.d.ts +3 -1
  31. package/dist/src/core/repo-structure/providers/index.d.ts.map +1 -1
  32. package/dist/src/core/repo-structure/providers/index.js +10 -2
  33. package/dist/src/core/repo-structure/providers/index.js.map +1 -1
  34. package/dist/src/core/repo-structure/providers/local-provider.d.ts +61 -0
  35. package/dist/src/core/repo-structure/providers/local-provider.d.ts.map +1 -0
  36. package/dist/src/core/repo-structure/providers/local-provider.js +148 -0
  37. package/dist/src/core/repo-structure/providers/local-provider.js.map +1 -0
  38. package/dist/src/core/repo-structure/repo-structure-manager.d.ts +11 -1
  39. package/dist/src/core/repo-structure/repo-structure-manager.d.ts.map +1 -1
  40. package/dist/src/core/repo-structure/repo-structure-manager.js +268 -84
  41. package/dist/src/core/repo-structure/repo-structure-manager.js.map +1 -1
  42. package/package.json +1 -1
  43. package/plugins/specweave/agents/pm/AGENT.md.bak +1893 -0
  44. package/plugins/specweave/hooks/docs-changed.sh.backup +79 -0
  45. package/plugins/specweave/hooks/human-input-required.sh.backup +75 -0
  46. package/plugins/specweave/hooks/lib/migrate-increment-work.sh.bak +245 -0
  47. package/plugins/specweave/hooks/lib/sync-spec-content.sh.bak +149 -0
  48. package/plugins/specweave/hooks/lib/validate-spec-status.sh.bak +163 -0
  49. package/plugins/specweave/hooks/post-first-increment.sh.backup +61 -0
  50. package/plugins/specweave/hooks/post-first-increment.sh.bak +61 -0
  51. package/plugins/specweave/hooks/post-increment-change.sh.backup +98 -0
  52. package/plugins/specweave/hooks/post-increment-completion.sh.backup +231 -0
  53. package/plugins/specweave/hooks/post-increment-planning.sh.backup +1048 -0
  54. package/plugins/specweave/hooks/post-increment-status-change.sh.backup +147 -0
  55. package/plugins/specweave/hooks/post-spec-update.sh.backup +158 -0
  56. package/plugins/specweave/hooks/post-spec-update.sh.bak +158 -0
  57. package/plugins/specweave/hooks/post-task-completion.sh +69 -175
  58. package/plugins/specweave/hooks/post-user-story-complete.sh.backup +179 -0
  59. package/plugins/specweave/hooks/post-user-story-complete.sh.bak +179 -0
  60. package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +83 -0
  61. package/plugins/specweave/hooks/pre-command-deduplication.sh.bak +83 -0
  62. package/plugins/specweave/hooks/pre-implementation.sh.backup +67 -0
  63. package/plugins/specweave/hooks/pre-task-completion.sh.backup +194 -0
  64. package/plugins/specweave/hooks/pre-tool-use.sh.backup +133 -0
  65. package/plugins/specweave/hooks/user-prompt-submit.sh.backup +386 -0
  66. package/plugins/specweave/hooks/user-prompt-submit.sh.bak +386 -0
  67. package/plugins/specweave/lib/hooks/auto-transition.js.bak +50 -0
  68. package/plugins/specweave/lib/hooks/auto-transition.ts.bak +84 -0
  69. package/plugins/specweave/lib/hooks/consolidated-sync.js +183 -0
  70. package/plugins/specweave/lib/hooks/git-diff-analyzer.d.js.bak +0 -0
  71. package/plugins/specweave/lib/hooks/git-diff-analyzer.d.ts.bak +89 -0
  72. package/plugins/specweave/lib/hooks/git-diff-analyzer.js.bak +142 -0
  73. package/plugins/specweave/lib/hooks/git-diff-analyzer.ts.bak +269 -0
  74. package/plugins/specweave/lib/hooks/invoke-translator-skill.d.js.bak +0 -0
  75. package/plugins/specweave/lib/hooks/invoke-translator-skill.d.ts.bak +60 -0
  76. package/plugins/specweave/lib/hooks/invoke-translator-skill.js.bak +155 -0
  77. package/plugins/specweave/lib/hooks/invoke-translator-skill.ts.bak +264 -0
  78. package/plugins/specweave/lib/hooks/prepare-reflection-context.d.js.bak +0 -0
  79. package/plugins/specweave/lib/hooks/prepare-reflection-context.d.ts.bak +42 -0
  80. package/plugins/specweave/lib/hooks/prepare-reflection-context.js.bak +110 -0
  81. package/plugins/specweave/lib/hooks/prepare-reflection-context.ts.bak +178 -0
  82. package/plugins/specweave/lib/hooks/reflection-config-loader.d.js.bak +0 -0
  83. package/plugins/specweave/lib/hooks/reflection-config-loader.d.ts.bak +45 -0
  84. package/plugins/specweave/lib/hooks/reflection-config-loader.js.bak +92 -0
  85. package/plugins/specweave/lib/hooks/reflection-config-loader.ts.bak +156 -0
  86. package/plugins/specweave/lib/hooks/reflection-parser.d.js.bak +0 -0
  87. package/plugins/specweave/lib/hooks/reflection-parser.d.ts.bak +33 -0
  88. package/plugins/specweave/lib/hooks/reflection-parser.js.bak +301 -0
  89. package/plugins/specweave/lib/hooks/reflection-parser.ts.bak +484 -0
  90. package/plugins/specweave/lib/hooks/reflection-prompt-builder.d.js.bak +0 -0
  91. package/plugins/specweave/lib/hooks/reflection-prompt-builder.d.ts.bak +56 -0
  92. package/plugins/specweave/lib/hooks/reflection-prompt-builder.js.bak +182 -0
  93. package/plugins/specweave/lib/hooks/reflection-prompt-builder.ts.bak +306 -0
  94. package/plugins/specweave/lib/hooks/reflection-storage.d.js.bak +0 -0
  95. package/plugins/specweave/lib/hooks/reflection-storage.d.ts.bak +64 -0
  96. package/plugins/specweave/lib/hooks/reflection-storage.js.bak +231 -0
  97. package/plugins/specweave/lib/hooks/reflection-storage.ts.bak +369 -0
  98. package/plugins/specweave/lib/hooks/run-self-reflection.d.js.bak +0 -0
  99. package/plugins/specweave/lib/hooks/run-self-reflection.d.ts.bak +43 -0
  100. package/plugins/specweave/lib/hooks/run-self-reflection.js.bak +132 -0
  101. package/plugins/specweave/lib/hooks/run-self-reflection.ts.bak +258 -0
  102. package/plugins/specweave/lib/hooks/sync-cache.js.bak +294 -0
  103. package/plugins/specweave/lib/hooks/sync-living-docs.d.js.bak +1 -0
  104. package/plugins/specweave/lib/hooks/sync-living-docs.d.ts.bak +27 -0
  105. package/plugins/specweave/lib/hooks/sync-living-docs.js.bak +339 -0
  106. package/plugins/specweave/lib/hooks/sync-us-tasks.js.bak +476 -0
  107. package/plugins/specweave/lib/hooks/translate-file.d.js.bak +0 -0
  108. package/plugins/specweave/lib/hooks/translate-file.d.ts.bak +59 -0
  109. package/plugins/specweave/lib/hooks/translate-file.js.bak +289 -0
  110. package/plugins/specweave/lib/hooks/translate-file.ts.bak +428 -0
  111. package/plugins/specweave/lib/hooks/translate-living-docs.d.js.bak +0 -0
  112. package/plugins/specweave/lib/hooks/translate-living-docs.d.ts.bak +13 -0
  113. package/plugins/specweave/lib/hooks/translate-living-docs.js.bak +119 -0
  114. package/plugins/specweave/lib/hooks/translate-living-docs.ts.bak +224 -0
  115. package/plugins/specweave/lib/hooks/update-ac-status.js.bak +51 -0
  116. package/plugins/specweave/lib/hooks/update-ac-status.ts.bak +103 -0
  117. package/plugins/specweave/lib/hooks/update-tasks-md.d.js.bak +1 -0
  118. package/plugins/specweave/lib/hooks/update-tasks-md.d.ts.bak +29 -0
  119. package/plugins/specweave/lib/hooks/update-tasks-md.js.bak +296 -0
  120. package/plugins/specweave/lib/hooks/update-tasks-md.ts.bak +489 -0
  121. package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +353 -0
  122. package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +172 -0
  123. package/plugins/specweave-ado/lib/ado-multi-project-sync.js +1 -0
  124. package/plugins/specweave-ado/lib/enhanced-ado-sync.js +170 -0
  125. package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +424 -0
  126. package/plugins/specweave-github/hooks/post-task-completion.sh.backup +258 -0
  127. package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +172 -0
  128. package/plugins/specweave-jira/lib/enhanced-jira-sync.js +3 -3
  129. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +540 -0
  130. package/plugins/specweave-release/hooks/post-task-completion.sh.backup +110 -0
@@ -81,34 +81,11 @@ if [[ -f "$CIRCUIT_BREAKER_FILE" ]]; then
81
81
  fi
82
82
  fi
83
83
 
84
- # FILE LOCK: Only allow 1 post-task-completion hook at a time
85
- LOCK_FILE=".specweave/state/.hook-post-task.lock"
86
- LOCK_TIMEOUT=10 # seconds (longer than others because this does more work)
87
-
88
- LOCK_ACQUIRED=false
89
- for i in {1..10}; do
90
- if mkdir "$LOCK_FILE" 2>/dev/null; then
91
- LOCK_ACQUIRED=true
92
- trap 'rmdir "$LOCK_FILE" 2>/dev/null || true' EXIT
93
- break
94
- fi
95
-
96
- # Check for stale lock
97
- if [[ -d "$LOCK_FILE" ]]; then
98
- LOCK_AGE=$(($(date +%s) - $(stat -f "%m" "$LOCK_FILE" 2>/dev/null || echo 0)))
99
- if (( LOCK_AGE > LOCK_TIMEOUT )); then
100
- rmdir "$LOCK_FILE" 2>/dev/null || true
101
- continue
102
- fi
103
- fi
104
-
105
- sleep 0.2
106
- done
107
-
108
- if [[ "$LOCK_ACQUIRED" == "false" ]]; then
109
- # Another instance is running, skip
110
- exit 0
111
- fi
84
+ # FILE LOCK: Skip - lock moved INSIDE background subshell (v0.24.4 fix)
85
+ # Why: Lock must protect the ACTUAL work, not just the script startup
86
+ # Old behavior: Lock released when main script exits (before background work completes)
87
+ # New behavior: Lock held until background work completes (inside subshell)
88
+ # This prevents race conditions where rapid TodoWrite calls spawn multiple concurrent processes
112
89
 
113
90
  # ============================================================================
114
91
  # CONFIGURATION
@@ -250,6 +227,45 @@ fi
250
227
  (
251
228
  set +e # Disable error propagation in background job
252
229
 
230
+ # ============================================================================
231
+ # FILE LOCK (v0.24.4): Protect ACTUAL background work, not just script startup
232
+ # ============================================================================
233
+ # CRITICAL FIX: Lock was previously in main script, released before work completed
234
+ # NOW: Lock is INSIDE background subshell, held until ALL work completes
235
+ # This prevents race conditions from rapid TodoWrite calls
236
+
237
+ LOCK_FILE=".specweave/state/.hook-post-task.lock"
238
+ LOCK_TIMEOUT=30 # seconds (longer timeout for background work)
239
+
240
+ LOCK_ACQUIRED=false
241
+ for i in {1..30}; do
242
+ if mkdir "$LOCK_FILE" 2>/dev/null; then
243
+ LOCK_ACQUIRED=true
244
+ # Ensure lock is removed when background job exits
245
+ trap 'rmdir "$LOCK_FILE" 2>/dev/null || true' EXIT
246
+ break
247
+ fi
248
+
249
+ # Check for stale lock
250
+ if [[ -d "$LOCK_FILE" ]]; then
251
+ LOCK_AGE=$(($(date +%s) - $(stat -f "%m" "$LOCK_FILE" 2>/dev/null || echo 0)))
252
+ if (( LOCK_AGE > LOCK_TIMEOUT )); then
253
+ echo "[$(date)] 🔓 Removing stale lock (age: ${LOCK_AGE}s)" >> "$DEBUG_LOG" 2>/dev/null || true
254
+ rmdir "$LOCK_FILE" 2>/dev/null || true
255
+ continue
256
+ fi
257
+ fi
258
+
259
+ sleep 1 # Wait longer between attempts (background work can take time)
260
+ done
261
+
262
+ if [[ "$LOCK_ACQUIRED" == "false" ]]; then
263
+ echo "[$(date)] â­ī¸ Another sync in progress, skipping (lock held)" >> "$DEBUG_LOG" 2>/dev/null || true
264
+ exit 0
265
+ fi
266
+
267
+ echo "[$(date)] 🔒 Lock acquired, starting background work" >> "$DEBUG_LOG" 2>/dev/null || true
268
+
253
269
  # ============================================================================
254
270
  # CRITICAL FIX: Read active increments from state file (NOT time-based detection)
255
271
  # ============================================================================
@@ -331,161 +347,39 @@ fi
331
347
  fi
332
348
 
333
349
  # ============================================================================
334
- # 1. UPDATE TASKS.MD
350
+ # CONSOLIDATED SYNC (v0.24.4 - PERFORMANCE OPTIMIZATION)
335
351
  # ============================================================================
336
- if [ -f ".specweave/increments/$CURRENT_INCREMENT/tasks.md" ]; then
337
- echo "[$(date)] 📝 Updating tasks.md" >> "$DEBUG_LOG" 2>/dev/null || true
338
-
339
- UPDATE_TASKS_SCRIPT=""
340
- if [ -f "$PROJECT_ROOT/plugins/specweave/lib/hooks/update-tasks-md.js" ]; then
341
- UPDATE_TASKS_SCRIPT="$PROJECT_ROOT/plugins/specweave/lib/hooks/update-tasks-md.js"
342
- elif [ -f "$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/update-tasks-md.js" ]; then
343
- UPDATE_TASKS_SCRIPT="$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/update-tasks-md.js"
344
- elif [ -f "$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/update-tasks-md.js" ]; then
345
- UPDATE_TASKS_SCRIPT="$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/update-tasks-md.js"
346
- elif [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/lib/hooks/update-tasks-md.js" ]; then
347
- UPDATE_TASKS_SCRIPT="${CLAUDE_PLUGIN_ROOT}/lib/hooks/update-tasks-md.js"
348
- fi
349
-
350
- if [ -n "$UPDATE_TASKS_SCRIPT" ]; then
351
- if node "$UPDATE_TASKS_SCRIPT" "$CURRENT_INCREMENT" >> "$DEBUG_LOG" 2>&1; then
352
- echo "[$(date)] ✅ tasks.md updated" >> "$DEBUG_LOG" 2>/dev/null || true
353
- ANY_SUCCESS=true
354
- else
355
- echo "[$(date)] âš ī¸ tasks.md update failed (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
356
- fi
357
- fi
358
- fi
359
-
360
- # ============================================================================
361
- # 2. SYNC LIVING DOCS
352
+ # REPLACES: 5-6 separate Node.js spawns with SINGLE consolidated process
353
+ # BEFORE: update-tasks-md.js, sync-living-docs.js, update-ac-status.js,
354
+ # translate-living-docs.js, prepare-reflection-context.js
355
+ # AFTER: consolidated-sync.js (runs all operations sequentially)
356
+ # IMPACT: 83% reduction in process spawning overhead
362
357
  # ============================================================================
363
- # Skip if increment is archived
364
- if [ ! -d ".specweave/increments/_archive/$CURRENT_INCREMENT" ]; then
365
- echo "[$(date)] 📚 Syncing living docs" >> "$DEBUG_LOG" 2>/dev/null || true
366
-
367
- # Extract feature ID and project ID
368
- FEATURE_ID=""
369
- SPEC_MD_PATH=".specweave/increments/$CURRENT_INCREMENT/spec.md"
370
358
 
371
- if [ -f "$SPEC_MD_PATH" ]; then
372
- FEATURE_ID=$(awk 'BEGIN{in_fm=0}/^---$/{if(in_fm==0){in_fm=1;next}else{exit}}in_fm==1&&/^epic:/{gsub(/^epic:[ \t]*/,"");gsub(/["'\'']/,"");print;exit}' "$SPEC_MD_PATH" | tr -d '\r\n')
373
- fi
374
-
375
- PROJECT_ID="default"
376
- if [ -f ".specweave/config.json" ] && command -v jq >/dev/null 2>&1; then
377
- ACTIVE_PROJECT=$(jq -r '.activeProject // "default"' ".specweave/config.json" 2>/dev/null || echo "default")
378
- if [ -n "$ACTIVE_PROJECT" ] && [ "$ACTIVE_PROJECT" != "null" ]; then
379
- PROJECT_ID="$ACTIVE_PROJECT"
380
- fi
381
- fi
382
-
383
- # Find sync script
384
- SYNC_SCRIPT=""
385
- if [ -f "$PROJECT_ROOT/plugins/specweave/lib/hooks/sync-living-docs.js" ]; then
386
- SYNC_SCRIPT="$PROJECT_ROOT/plugins/specweave/lib/hooks/sync-living-docs.js"
387
- elif [ -f "$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/sync-living-docs.js" ]; then
388
- SYNC_SCRIPT="$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/sync-living-docs.js"
389
- elif [ -f "$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/sync-living-docs.js" ]; then
390
- SYNC_SCRIPT="$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/sync-living-docs.js"
391
- elif [ -n "${CLAUDE_PLUGIN_ROOT}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/lib/hooks/sync-living-docs.js" ]; then
392
- SYNC_SCRIPT="${CLAUDE_PLUGIN_ROOT}/lib/hooks/sync-living-docs.js"
393
- fi
394
-
395
- if [ -n "$SYNC_SCRIPT" ]; then
396
- if [ -n "$FEATURE_ID" ]; then
397
- if (cd "$PROJECT_ROOT" && FEATURE_ID="$FEATURE_ID" PROJECT_ID="$PROJECT_ID" node "$SYNC_SCRIPT" "$CURRENT_INCREMENT") >> "$DEBUG_LOG" 2>&1; then
398
- echo "[$(date)] ✅ Living docs synced" >> "$DEBUG_LOG" 2>/dev/null || true
399
- ANY_SUCCESS=true
400
- else
401
- echo "[$(date)] âš ī¸ Living docs sync failed (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
402
- fi
403
- else
404
- if (cd "$PROJECT_ROOT" && PROJECT_ID="$PROJECT_ID" node "$SYNC_SCRIPT" "$CURRENT_INCREMENT") >> "$DEBUG_LOG" 2>&1; then
405
- echo "[$(date)] ✅ Living docs synced" >> "$DEBUG_LOG" 2>/dev/null || true
406
- ANY_SUCCESS=true
407
- else
408
- echo "[$(date)] âš ī¸ Living docs sync failed (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
409
- fi
410
- fi
411
- fi
359
+ echo "[$(date)] 🚀 Running consolidated sync" >> "$DEBUG_LOG" 2>/dev/null || true
360
+
361
+ # Find consolidated sync script
362
+ CONSOLIDATED_SCRIPT=""
363
+ if [ -f "$PROJECT_ROOT/plugins/specweave/lib/hooks/consolidated-sync.js" ]; then
364
+ CONSOLIDATED_SCRIPT="$PROJECT_ROOT/plugins/specweave/lib/hooks/consolidated-sync.js"
365
+ elif [ -f "$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/consolidated-sync.js" ]; then
366
+ CONSOLIDATED_SCRIPT="$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/consolidated-sync.js"
367
+ elif [ -f "$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/consolidated-sync.js" ]; then
368
+ CONSOLIDATED_SCRIPT="$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/consolidated-sync.js"
369
+ elif [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/lib/hooks/consolidated-sync.js" ]; then
370
+ CONSOLIDATED_SCRIPT="${CLAUDE_PLUGIN_ROOT}/lib/hooks/consolidated-sync.js"
412
371
  fi
413
372
 
414
- # ============================================================================
415
- # 3. UPDATE AC STATUS
416
- # ============================================================================
417
- echo "[$(date)] ✓ Updating AC status" >> "$DEBUG_LOG" 2>/dev/null || true
418
-
419
- UPDATE_AC_SCRIPT=""
420
- if [ -f "$PROJECT_ROOT/plugins/specweave/lib/hooks/update-ac-status.js" ]; then
421
- UPDATE_AC_SCRIPT="$PROJECT_ROOT/plugins/specweave/lib/hooks/update-ac-status.js"
422
- elif [ -f "$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/update-ac-status.js" ]; then
423
- UPDATE_AC_SCRIPT="$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/update-ac-status.js"
424
- elif [ -f "$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/update-ac-status.js" ]; then
425
- UPDATE_AC_SCRIPT="$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/update-ac-status.js"
426
- elif [ -n "${CLAUDE_PLUGIN_ROOT}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/lib/hooks/update-ac-status.js" ]; then
427
- UPDATE_AC_SCRIPT="${CLAUDE_PLUGIN_ROOT}/lib/hooks/update-ac-status.js"
428
- fi
429
-
430
- if [ -n "$UPDATE_AC_SCRIPT" ]; then
431
- if (cd "$PROJECT_ROOT" && node "$UPDATE_AC_SCRIPT" "$CURRENT_INCREMENT") >> "$DEBUG_LOG" 2>&1; then
432
- echo "[$(date)] ✅ AC status updated" >> "$DEBUG_LOG" 2>/dev/null || true
373
+ if [ -n "$CONSOLIDATED_SCRIPT" ]; then
374
+ # Run consolidated sync (single Node.js process handles ALL operations)
375
+ if (cd "$PROJECT_ROOT" && node "$CONSOLIDATED_SCRIPT" "$CURRENT_INCREMENT") >> "$DEBUG_LOG" 2>&1; then
376
+ echo "[$(date)] ✅ Consolidated sync completed" >> "$DEBUG_LOG" 2>/dev/null || true
433
377
  ANY_SUCCESS=true
434
378
  else
435
- echo "[$(date)] âš ī¸ AC status update failed (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
436
- fi
437
- fi
438
-
439
- # ============================================================================
440
- # 4. TRANSLATE LIVING DOCS (if needed)
441
- # ============================================================================
442
- echo "[$(date)] 🌐 Checking translation needs" >> "$DEBUG_LOG" 2>/dev/null || true
443
-
444
- TRANSLATE_SCRIPT=""
445
- if [ -f "$PROJECT_ROOT/plugins/specweave/lib/hooks/translate-living-docs.js" ]; then
446
- TRANSLATE_SCRIPT="$PROJECT_ROOT/plugins/specweave/lib/hooks/translate-living-docs.js"
447
- elif [ -f "$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/translate-living-docs.js" ]; then
448
- TRANSLATE_SCRIPT="$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/translate-living-docs.js"
449
- elif [ -f "$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/translate-living-docs.js" ]; then
450
- TRANSLATE_SCRIPT="$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/translate-living-docs.js"
451
- elif [ -n "${CLAUDE_PLUGIN_ROOT}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/lib/hooks/translate-living-docs.js" ]; then
452
- TRANSLATE_SCRIPT="${CLAUDE_PLUGIN_ROOT}/lib/hooks/translate-living-docs.js"
453
- fi
454
-
455
- if [ -n "$TRANSLATE_SCRIPT" ]; then
456
- if (cd "$PROJECT_ROOT" && node "$TRANSLATE_SCRIPT" "$CURRENT_INCREMENT") >> "$DEBUG_LOG" 2>&1; then
457
- echo "[$(date)] ✅ Translation checked" >> "$DEBUG_LOG" 2>/dev/null || true
458
- ANY_SUCCESS=true
459
- fi
460
- fi
461
-
462
- # ============================================================================
463
- # 5. SELF-REFLECTION (only if all tasks complete)
464
- # ============================================================================
465
- if [ "$ALL_COMPLETED" = "true" ]; then
466
- echo "[$(date)] 🤔 Preparing reflection" >> "$DEBUG_LOG" 2>/dev/null || true
467
-
468
- LATEST_TASK=$(grep "^## T-[0-9]" ".specweave/increments/$CURRENT_INCREMENT/tasks.md" 2>/dev/null | tail -1 | awk '{print $2}' | sed 's/://')
469
-
470
- if [ -n "$LATEST_TASK" ]; then
471
- REFLECTION_SCRIPT=""
472
- if [ -f "$PROJECT_ROOT/plugins/specweave/lib/hooks/prepare-reflection-context.js" ]; then
473
- REFLECTION_SCRIPT="$PROJECT_ROOT/plugins/specweave/lib/hooks/prepare-reflection-context.js"
474
- elif [ -f "$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/prepare-reflection-context.js" ]; then
475
- REFLECTION_SCRIPT="$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/prepare-reflection-context.js"
476
- elif [ -f "$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/prepare-reflection-context.js" ]; then
477
- REFLECTION_SCRIPT="$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/prepare-reflection-context.js"
478
- elif [ -n "${CLAUDE_PLUGIN_ROOT}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/lib/hooks/prepare-reflection-context.js" ]; then
479
- REFLECTION_SCRIPT="${CLAUDE_PLUGIN_ROOT}/lib/hooks/prepare-reflection-context.js"
480
- fi
481
-
482
- if [ -n "$REFLECTION_SCRIPT" ]; then
483
- if (cd "$PROJECT_ROOT" && node "$REFLECTION_SCRIPT" "$CURRENT_INCREMENT" "$LATEST_TASK") >> "$DEBUG_LOG" 2>&1; then
484
- echo "[$(date)] ✅ Reflection prepared" >> "$DEBUG_LOG" 2>/dev/null || true
485
- ANY_SUCCESS=true
486
- fi
487
- fi
379
+ echo "[$(date)] âš ī¸ Consolidated sync failed (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
488
380
  fi
381
+ else
382
+ echo "[$(date)] âš ī¸ consolidated-sync.js not found, skipping sync" >> "$DEBUG_LOG" 2>/dev/null || true
489
383
  fi
490
384
 
491
385
  done # End of ACTIVE_INCREMENTS loop
@@ -0,0 +1,179 @@
1
+ #!/bin/bash
2
+
3
+ ###############################################################################
4
+ # SpecWeave Post-User-Story-Complete Hook
5
+ #
6
+ # CRITICAL ARCHITECTURE:
7
+ # - Fires when user story marked complete in spec.md (AC checkbox checked)
8
+ # - Updates external PM tool (GitHub Issue/Jira Story/ADO User Story)
9
+ # - Moves GitHub card to "Done" / Closes Jira story / Completes ADO story
10
+ #
11
+ # Trigger Points:
12
+ # 1. After user manually checks AC checkbox in spec.md
13
+ # 2. After bidirectional sync updates AC status
14
+ # 3. After increment completion syncs to spec
15
+ #
16
+ # What It Does:
17
+ # - Detects which user story was completed (all AC checkboxes checked)
18
+ # - Finds corresponding external item (GitHub Issue/Jira Story/ADO User Story)
19
+ # - Updates item status to "Done" / "Closed"
20
+ # - Adds completion comment with timestamp
21
+ #
22
+ # Usage:
23
+ # post-user-story-complete.sh <spec-id> <user-story-id>
24
+ #
25
+ # Example:
26
+ # post-user-story-complete.sh spec-001 US-001
27
+ #
28
+ ###############################################################################
29
+
30
+ set -euo pipefail
31
+
32
+ # Arguments
33
+ SPEC_ID="${1:-}"
34
+ USER_STORY_ID="${2:-}"
35
+
36
+ # Validate arguments
37
+ if [[ -z "$SPEC_ID" || -z "$USER_STORY_ID" ]]; then
38
+ echo "❌ Error: Spec ID and User Story ID required"
39
+ echo "Usage: post-user-story-complete.sh <spec-id> <user-story-id>"
40
+ exit 1
41
+ fi
42
+
43
+ echo ""
44
+ echo "🎉 Post-User-Story-Complete Hook"
45
+ echo " Spec: $SPEC_ID"
46
+ echo " User Story: $USER_STORY_ID"
47
+
48
+ # Find spec file
49
+ SPEC_FILE=""
50
+ if [[ -f ".specweave/docs/internal/specs/$SPEC_ID.md" ]]; then
51
+ SPEC_FILE=".specweave/docs/internal/specs/$SPEC_ID.md"
52
+ elif [[ -f ".specweave/docs/internal/projects/default/specs/$SPEC_ID.md" ]]; then
53
+ SPEC_FILE=".specweave/docs/internal/projects/default/specs/$SPEC_ID.md"
54
+ else
55
+ echo "❌ Error: Spec file not found for $SPEC_ID"
56
+ exit 1
57
+ fi
58
+
59
+ # Load config to check if auto-sync is enabled
60
+ CONFIG_FILE=".specweave/config.json"
61
+ if [[ ! -f "$CONFIG_FILE" ]]; then
62
+ echo " â„šī¸ No config file found, skipping auto-sync"
63
+ exit 0
64
+ fi
65
+
66
+ # Check if auto-sync is enabled
67
+ AUTO_SYNC=$(jq -r '.hooks.post_user_story_complete.auto_sync // true' "$CONFIG_FILE")
68
+
69
+ if [[ "$AUTO_SYNC" != "true" ]]; then
70
+ echo " â„šī¸ Auto-sync disabled in config, skipping"
71
+ exit 0
72
+ fi
73
+
74
+ # Parse spec frontmatter to detect external links
75
+ # Check if GitHub link exists
76
+ GITHUB_LINK=$(grep -A 10 "^externalLinks:" "$SPEC_FILE" | grep -A 5 "github:" | grep "projectId:" | sed 's/.*projectId: *//; s/ *$//' || echo "")
77
+
78
+ # Check if Jira link exists
79
+ JIRA_LINK=$(grep -A 10 "^externalLinks:" "$SPEC_FILE" | grep -A 5 "jira:" | grep "epicKey:" | sed 's/.*epicKey: *//; s/ *$//' || echo "")
80
+
81
+ # Check if ADO link exists
82
+ ADO_LINK=$(grep -A 10 "^externalLinks:" "$SPEC_FILE" | grep -A 5 "ado:" | grep "featureId:" | sed 's/.*featureId: *//; s/ *$//' || echo "")
83
+
84
+ # Determine which provider to sync
85
+ PROVIDER=""
86
+ if [[ -n "$GITHUB_LINK" ]]; then
87
+ PROVIDER="github"
88
+ EXTERNAL_ID="$GITHUB_LINK"
89
+ elif [[ -n "$JIRA_LINK" ]]; then
90
+ PROVIDER="jira"
91
+ EXTERNAL_ID="$JIRA_LINK"
92
+ elif [[ -n "$ADO_LINK" ]]; then
93
+ PROVIDER="ado"
94
+ EXTERNAL_ID="$ADO_LINK"
95
+ fi
96
+
97
+ # No external link found - skip sync
98
+ if [[ -z "$PROVIDER" ]]; then
99
+ echo " â„šī¸ Spec not linked to external tool, skipping sync"
100
+ exit 0
101
+ fi
102
+
103
+ echo " 🔗 Detected external link: $PROVIDER"
104
+
105
+ # Update external tool based on provider
106
+ case "$PROVIDER" in
107
+ github)
108
+ echo " 🔄 Updating GitHub Issue for $USER_STORY_ID..."
109
+
110
+ # Check if GitHub CLI is available
111
+ if ! command -v gh &> /dev/null; then
112
+ echo " âš ī¸ GitHub CLI (gh) not found, skipping sync"
113
+ exit 0
114
+ fi
115
+
116
+ # Find GitHub Issue for this user story
117
+ # Search for issue with title pattern "[USER_STORY_ID]"
118
+ REPO=$(git remote get-url origin | sed -E 's/.*github\.com[:/]([^/]+\/[^/]+)(\.git)?$/\1/')
119
+
120
+ # Search for issue
121
+ ISSUE_NUMBER=$(gh issue list --repo "$REPO" --search "\"[$USER_STORY_ID]\" in:title" --json number --jq '.[0].number' 2>/dev/null || echo "")
122
+
123
+ if [[ -z "$ISSUE_NUMBER" ]]; then
124
+ echo " âš ī¸ GitHub Issue not found for $USER_STORY_ID"
125
+ exit 0
126
+ fi
127
+
128
+ echo " 📝 Found GitHub Issue #$ISSUE_NUMBER"
129
+
130
+ # Close issue
131
+ gh issue close "$ISSUE_NUMBER" --repo "$REPO" --comment "✅ User story completed
132
+
133
+ 🤖 Auto-closed by SpecWeave hook
134
+ Completed at: $(date -u +%Y-%m-%dT%H:%M:%SZ)" 2>/dev/null || {
135
+ echo " âš ī¸ Failed to close issue"
136
+ exit 0
137
+ }
138
+
139
+ echo " ✅ GitHub Issue #$ISSUE_NUMBER closed"
140
+ ;;
141
+
142
+ jira)
143
+ echo " 🔄 Updating Jira Story for $USER_STORY_ID..."
144
+
145
+ # Check if Jira config exists
146
+ if [[ -z "${JIRA_DOMAIN:-}" ]]; then
147
+ echo " âš ī¸ Jira not configured (.env), skipping sync"
148
+ exit 0
149
+ fi
150
+
151
+ # TODO: Find Jira Story by title pattern
152
+ # TODO: Transition story to "Done" status
153
+ echo " ✅ Jira story transition queued (implementation pending)"
154
+ ;;
155
+
156
+ ado)
157
+ echo " 🔄 Updating ADO User Story for $USER_STORY_ID..."
158
+
159
+ # Check if ADO config exists
160
+ if [[ -z "${ADO_ORGANIZATION:-}" ]]; then
161
+ echo " âš ī¸ ADO not configured (.env), skipping sync"
162
+ exit 0
163
+ fi
164
+
165
+ # TODO: Find ADO User Story by title pattern
166
+ # TODO: Update state to "Closed"
167
+ echo " ✅ ADO user story update queued (implementation pending)"
168
+ ;;
169
+
170
+ *)
171
+ echo " âš ī¸ Unknown provider: $PROVIDER"
172
+ exit 0
173
+ ;;
174
+ esac
175
+
176
+ echo " ✅ Post-user-story-complete hook complete"
177
+ echo ""
178
+
179
+ exit 0
@@ -0,0 +1,179 @@
1
+ #!/bin/bash
2
+
3
+ ###############################################################################
4
+ # SpecWeave Post-User-Story-Complete Hook
5
+ #
6
+ # CRITICAL ARCHITECTURE:
7
+ # - Fires when user story marked complete in spec.md (AC checkbox checked)
8
+ # - Updates external PM tool (GitHub Issue/Jira Story/ADO User Story)
9
+ # - Moves GitHub card to "Done" / Closes Jira story / Completes ADO story
10
+ #
11
+ # Trigger Points:
12
+ # 1. After user manually checks AC checkbox in spec.md
13
+ # 2. After bidirectional sync updates AC status
14
+ # 3. After increment completion syncs to spec
15
+ #
16
+ # What It Does:
17
+ # - Detects which user story was completed (all AC checkboxes checked)
18
+ # - Finds corresponding external item (GitHub Issue/Jira Story/ADO User Story)
19
+ # - Updates item status to "Done" / "Closed"
20
+ # - Adds completion comment with timestamp
21
+ #
22
+ # Usage:
23
+ # post-user-story-complete.sh <spec-id> <user-story-id>
24
+ #
25
+ # Example:
26
+ # post-user-story-complete.sh spec-001 US-001
27
+ #
28
+ ###############################################################################
29
+
30
+ set -euo pipefail
31
+
32
+ # Arguments
33
+ SPEC_ID="${1:-}"
34
+ USER_STORY_ID="${2:-}"
35
+
36
+ # Validate arguments
37
+ if [[ -z "$SPEC_ID" || -z "$USER_STORY_ID" ]]; then
38
+ echo "❌ Error: Spec ID and User Story ID required"
39
+ echo "Usage: post-user-story-complete.sh <spec-id> <user-story-id>"
40
+ exit 1
41
+ fi
42
+
43
+ echo ""
44
+ echo "🎉 Post-User-Story-Complete Hook"
45
+ echo " Spec: $SPEC_ID"
46
+ echo " User Story: $USER_STORY_ID"
47
+
48
+ # Find spec file
49
+ SPEC_FILE=""
50
+ if [[ -f ".specweave/docs/internal/specs/$SPEC_ID.md" ]]; then
51
+ SPEC_FILE=".specweave/docs/internal/specs/$SPEC_ID.md"
52
+ elif [[ -f ".specweave/docs/internal/projects/default/specs/$SPEC_ID.md" ]]; then
53
+ SPEC_FILE=".specweave/docs/internal/projects/default/specs/$SPEC_ID.md"
54
+ else
55
+ echo "❌ Error: Spec file not found for $SPEC_ID"
56
+ exit 1
57
+ fi
58
+
59
+ # Load config to check if auto-sync is enabled
60
+ CONFIG_FILE=".specweave/config.json"
61
+ if [[ ! -f "$CONFIG_FILE" ]]; then
62
+ echo " â„šī¸ No config file found, skipping auto-sync"
63
+ exit 0
64
+ fi
65
+
66
+ # Check if auto-sync is enabled
67
+ AUTO_SYNC=$(jq -r '.hooks.post_user_story_complete.auto_sync // true' "$CONFIG_FILE")
68
+
69
+ if [[ "$AUTO_SYNC" != "true" ]]; then
70
+ echo " â„šī¸ Auto-sync disabled in config, skipping"
71
+ exit 0
72
+ fi
73
+
74
+ # Parse spec frontmatter to detect external links
75
+ # Check if GitHub link exists
76
+ GITHUB_LINK=$(grep -A 10 "^externalLinks:" "$SPEC_FILE" | grep -A 5 "github:" | grep "projectId:" | sed 's/.*projectId: *//; s/ *$//' || echo "")
77
+
78
+ # Check if Jira link exists
79
+ JIRA_LINK=$(grep -A 10 "^externalLinks:" "$SPEC_FILE" | grep -A 5 "jira:" | grep "epicKey:" | sed 's/.*epicKey: *//; s/ *$//' || echo "")
80
+
81
+ # Check if ADO link exists
82
+ ADO_LINK=$(grep -A 10 "^externalLinks:" "$SPEC_FILE" | grep -A 5 "ado:" | grep "featureId:" | sed 's/.*featureId: *//; s/ *$//' || echo "")
83
+
84
+ # Determine which provider to sync
85
+ PROVIDER=""
86
+ if [[ -n "$GITHUB_LINK" ]]; then
87
+ PROVIDER="github"
88
+ EXTERNAL_ID="$GITHUB_LINK"
89
+ elif [[ -n "$JIRA_LINK" ]]; then
90
+ PROVIDER="jira"
91
+ EXTERNAL_ID="$JIRA_LINK"
92
+ elif [[ -n "$ADO_LINK" ]]; then
93
+ PROVIDER="ado"
94
+ EXTERNAL_ID="$ADO_LINK"
95
+ fi
96
+
97
+ # No external link found - skip sync
98
+ if [[ -z "$PROVIDER" ]]; then
99
+ echo " â„šī¸ Spec not linked to external tool, skipping sync"
100
+ exit 0
101
+ fi
102
+
103
+ echo " 🔗 Detected external link: $PROVIDER"
104
+
105
+ # Update external tool based on provider
106
+ case "$PROVIDER" in
107
+ github)
108
+ echo " 🔄 Updating GitHub Issue for $USER_STORY_ID..."
109
+
110
+ # Check if GitHub CLI is available
111
+ if ! command -v gh &> /dev/null; then
112
+ echo " âš ī¸ GitHub CLI (gh) not found, skipping sync"
113
+ exit 0
114
+ fi
115
+
116
+ # Find GitHub Issue for this user story
117
+ # Search for issue with title pattern "[USER_STORY_ID]"
118
+ REPO=$(git remote get-url origin | sed -E 's/.*github\.com[:/]([^/]+\/[^/]+)(\.git)?$/\1/')
119
+
120
+ # Search for issue
121
+ ISSUE_NUMBER=$(gh issue list --repo "$REPO" --search "\"[$USER_STORY_ID]\" in:title" --json number --jq '.[0].number' 2>/dev/null || echo "")
122
+
123
+ if [[ -z "$ISSUE_NUMBER" ]]; then
124
+ echo " âš ī¸ GitHub Issue not found for $USER_STORY_ID"
125
+ exit 0
126
+ fi
127
+
128
+ echo " 📝 Found GitHub Issue #$ISSUE_NUMBER"
129
+
130
+ # Close issue
131
+ gh issue close "$ISSUE_NUMBER" --repo "$REPO" --comment "✅ User story completed
132
+
133
+ 🤖 Auto-closed by SpecWeave hook
134
+ Completed at: $(date -u +%Y-%m-%dT%H:%M:%SZ)" 2>/dev/null || {
135
+ echo " âš ī¸ Failed to close issue"
136
+ exit 0
137
+ }
138
+
139
+ echo " ✅ GitHub Issue #$ISSUE_NUMBER closed"
140
+ ;;
141
+
142
+ jira)
143
+ echo " 🔄 Updating Jira Story for $USER_STORY_ID..."
144
+
145
+ # Check if Jira config exists
146
+ if [[ -z "${JIRA_DOMAIN:-}" ]]; then
147
+ echo " âš ī¸ Jira not configured (.env), skipping sync"
148
+ exit 0
149
+ fi
150
+
151
+ # TODO: Find Jira Story by title pattern
152
+ # TODO: Transition story to "Done" status
153
+ echo " ✅ Jira story transition queued (implementation pending)"
154
+ ;;
155
+
156
+ ado)
157
+ echo " 🔄 Updating ADO User Story for $USER_STORY_ID..."
158
+
159
+ # Check if ADO config exists
160
+ if [[ -z "${ADO_ORGANIZATION:-}" ]]; then
161
+ echo " âš ī¸ ADO not configured (.env), skipping sync"
162
+ exit 0
163
+ fi
164
+
165
+ # TODO: Find ADO User Story by title pattern
166
+ # TODO: Update state to "Closed"
167
+ echo " ✅ ADO user story update queued (implementation pending)"
168
+ ;;
169
+
170
+ *)
171
+ echo " âš ī¸ Unknown provider: $PROVIDER"
172
+ exit 0
173
+ ;;
174
+ esac
175
+
176
+ echo " ✅ Post-user-story-complete hook complete"
177
+ echo ""
178
+
179
+ exit 0