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.
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +3 -1
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.js +18 -2
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.js.map +1 -1
- package/dist/src/core/repo-structure/git-error-handler.d.ts +1 -1
- package/dist/src/core/repo-structure/git-error-handler.d.ts.map +1 -1
- package/dist/src/core/repo-structure/git-provider.d.ts +1 -1
- package/dist/src/core/repo-structure/git-provider.d.ts.map +1 -1
- package/dist/src/core/repo-structure/platform-registry.d.ts.map +1 -1
- package/dist/src/core/repo-structure/platform-registry.js +20 -9
- package/dist/src/core/repo-structure/platform-registry.js.map +1 -1
- package/dist/src/core/repo-structure/prompt-consolidator.d.ts +13 -1
- package/dist/src/core/repo-structure/prompt-consolidator.d.ts.map +1 -1
- package/dist/src/core/repo-structure/prompt-consolidator.js +38 -5
- package/dist/src/core/repo-structure/prompt-consolidator.js.map +1 -1
- package/dist/src/core/repo-structure/providers/azure-devops-provider.d.ts +64 -0
- package/dist/src/core/repo-structure/providers/azure-devops-provider.d.ts.map +1 -0
- package/dist/src/core/repo-structure/providers/azure-devops-provider.js +263 -0
- package/dist/src/core/repo-structure/providers/azure-devops-provider.js.map +1 -0
- package/dist/src/core/repo-structure/providers/bitbucket-provider.d.ts +12 -11
- package/dist/src/core/repo-structure/providers/bitbucket-provider.d.ts.map +1 -1
- package/dist/src/core/repo-structure/providers/bitbucket-provider.js +164 -30
- package/dist/src/core/repo-structure/providers/bitbucket-provider.js.map +1 -1
- package/dist/src/core/repo-structure/providers/gitlab-provider.d.ts +10 -9
- package/dist/src/core/repo-structure/providers/gitlab-provider.d.ts.map +1 -1
- package/dist/src/core/repo-structure/providers/gitlab-provider.js +182 -28
- package/dist/src/core/repo-structure/providers/gitlab-provider.js.map +1 -1
- package/dist/src/core/repo-structure/providers/index.d.ts +3 -1
- package/dist/src/core/repo-structure/providers/index.d.ts.map +1 -1
- package/dist/src/core/repo-structure/providers/index.js +10 -2
- package/dist/src/core/repo-structure/providers/index.js.map +1 -1
- package/dist/src/core/repo-structure/providers/local-provider.d.ts +61 -0
- package/dist/src/core/repo-structure/providers/local-provider.d.ts.map +1 -0
- package/dist/src/core/repo-structure/providers/local-provider.js +148 -0
- package/dist/src/core/repo-structure/providers/local-provider.js.map +1 -0
- package/dist/src/core/repo-structure/repo-structure-manager.d.ts +11 -1
- package/dist/src/core/repo-structure/repo-structure-manager.d.ts.map +1 -1
- package/dist/src/core/repo-structure/repo-structure-manager.js +268 -84
- package/dist/src/core/repo-structure/repo-structure-manager.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/agents/pm/AGENT.md.bak +1893 -0
- package/plugins/specweave/hooks/docs-changed.sh.backup +79 -0
- package/plugins/specweave/hooks/human-input-required.sh.backup +75 -0
- package/plugins/specweave/hooks/lib/migrate-increment-work.sh.bak +245 -0
- package/plugins/specweave/hooks/lib/sync-spec-content.sh.bak +149 -0
- package/plugins/specweave/hooks/lib/validate-spec-status.sh.bak +163 -0
- package/plugins/specweave/hooks/post-first-increment.sh.backup +61 -0
- package/plugins/specweave/hooks/post-first-increment.sh.bak +61 -0
- package/plugins/specweave/hooks/post-increment-change.sh.backup +98 -0
- package/plugins/specweave/hooks/post-increment-completion.sh.backup +231 -0
- package/plugins/specweave/hooks/post-increment-planning.sh.backup +1048 -0
- package/plugins/specweave/hooks/post-increment-status-change.sh.backup +147 -0
- package/plugins/specweave/hooks/post-spec-update.sh.backup +158 -0
- package/plugins/specweave/hooks/post-spec-update.sh.bak +158 -0
- package/plugins/specweave/hooks/post-task-completion.sh +69 -175
- package/plugins/specweave/hooks/post-user-story-complete.sh.backup +179 -0
- package/plugins/specweave/hooks/post-user-story-complete.sh.bak +179 -0
- package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +83 -0
- package/plugins/specweave/hooks/pre-command-deduplication.sh.bak +83 -0
- package/plugins/specweave/hooks/pre-implementation.sh.backup +67 -0
- package/plugins/specweave/hooks/pre-task-completion.sh.backup +194 -0
- package/plugins/specweave/hooks/pre-tool-use.sh.backup +133 -0
- package/plugins/specweave/hooks/user-prompt-submit.sh.backup +386 -0
- package/plugins/specweave/hooks/user-prompt-submit.sh.bak +386 -0
- package/plugins/specweave/lib/hooks/auto-transition.js.bak +50 -0
- package/plugins/specweave/lib/hooks/auto-transition.ts.bak +84 -0
- package/plugins/specweave/lib/hooks/consolidated-sync.js +183 -0
- package/plugins/specweave/lib/hooks/git-diff-analyzer.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/git-diff-analyzer.d.ts.bak +89 -0
- package/plugins/specweave/lib/hooks/git-diff-analyzer.js.bak +142 -0
- package/plugins/specweave/lib/hooks/git-diff-analyzer.ts.bak +269 -0
- package/plugins/specweave/lib/hooks/invoke-translator-skill.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/invoke-translator-skill.d.ts.bak +60 -0
- package/plugins/specweave/lib/hooks/invoke-translator-skill.js.bak +155 -0
- package/plugins/specweave/lib/hooks/invoke-translator-skill.ts.bak +264 -0
- package/plugins/specweave/lib/hooks/prepare-reflection-context.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/prepare-reflection-context.d.ts.bak +42 -0
- package/plugins/specweave/lib/hooks/prepare-reflection-context.js.bak +110 -0
- package/plugins/specweave/lib/hooks/prepare-reflection-context.ts.bak +178 -0
- package/plugins/specweave/lib/hooks/reflection-config-loader.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/reflection-config-loader.d.ts.bak +45 -0
- package/plugins/specweave/lib/hooks/reflection-config-loader.js.bak +92 -0
- package/plugins/specweave/lib/hooks/reflection-config-loader.ts.bak +156 -0
- package/plugins/specweave/lib/hooks/reflection-parser.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/reflection-parser.d.ts.bak +33 -0
- package/plugins/specweave/lib/hooks/reflection-parser.js.bak +301 -0
- package/plugins/specweave/lib/hooks/reflection-parser.ts.bak +484 -0
- package/plugins/specweave/lib/hooks/reflection-prompt-builder.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/reflection-prompt-builder.d.ts.bak +56 -0
- package/plugins/specweave/lib/hooks/reflection-prompt-builder.js.bak +182 -0
- package/plugins/specweave/lib/hooks/reflection-prompt-builder.ts.bak +306 -0
- package/plugins/specweave/lib/hooks/reflection-storage.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/reflection-storage.d.ts.bak +64 -0
- package/plugins/specweave/lib/hooks/reflection-storage.js.bak +231 -0
- package/plugins/specweave/lib/hooks/reflection-storage.ts.bak +369 -0
- package/plugins/specweave/lib/hooks/run-self-reflection.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/run-self-reflection.d.ts.bak +43 -0
- package/plugins/specweave/lib/hooks/run-self-reflection.js.bak +132 -0
- package/plugins/specweave/lib/hooks/run-self-reflection.ts.bak +258 -0
- package/plugins/specweave/lib/hooks/sync-cache.js.bak +294 -0
- package/plugins/specweave/lib/hooks/sync-living-docs.d.js.bak +1 -0
- package/plugins/specweave/lib/hooks/sync-living-docs.d.ts.bak +27 -0
- package/plugins/specweave/lib/hooks/sync-living-docs.js.bak +339 -0
- package/plugins/specweave/lib/hooks/sync-us-tasks.js.bak +476 -0
- package/plugins/specweave/lib/hooks/translate-file.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/translate-file.d.ts.bak +59 -0
- package/plugins/specweave/lib/hooks/translate-file.js.bak +289 -0
- package/plugins/specweave/lib/hooks/translate-file.ts.bak +428 -0
- package/plugins/specweave/lib/hooks/translate-living-docs.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/translate-living-docs.d.ts.bak +13 -0
- package/plugins/specweave/lib/hooks/translate-living-docs.js.bak +119 -0
- package/plugins/specweave/lib/hooks/translate-living-docs.ts.bak +224 -0
- package/plugins/specweave/lib/hooks/update-ac-status.js.bak +51 -0
- package/plugins/specweave/lib/hooks/update-ac-status.ts.bak +103 -0
- package/plugins/specweave/lib/hooks/update-tasks-md.d.js.bak +1 -0
- package/plugins/specweave/lib/hooks/update-tasks-md.d.ts.bak +29 -0
- package/plugins/specweave/lib/hooks/update-tasks-md.js.bak +296 -0
- package/plugins/specweave/lib/hooks/update-tasks-md.ts.bak +489 -0
- package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +353 -0
- package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-ado/lib/ado-multi-project-sync.js +1 -0
- package/plugins/specweave-ado/lib/enhanced-ado-sync.js +170 -0
- package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +424 -0
- package/plugins/specweave-github/hooks/post-task-completion.sh.backup +258 -0
- package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-jira/lib/enhanced-jira-sync.js +3 -3
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +540 -0
- 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:
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
-
#
|
|
350
|
+
# CONSOLIDATED SYNC (v0.24.4 - PERFORMANCE OPTIMIZATION)
|
|
335
351
|
# ============================================================================
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
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
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
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
|
-
|
|
416
|
-
|
|
417
|
-
|
|
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)] â ī¸
|
|
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
|