specweave 0.24.11 → 0.24.13
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/CLAUDE.md +158 -10
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts +28 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.js +47 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.js.map +1 -1
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +15 -7
- 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 +13 -1
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/types.d.ts +1 -1
- package/dist/src/cli/helpers/issue-tracker/types.d.ts.map +1 -1
- package/dist/src/core/config/types.d.ts +46 -12
- package/dist/src/core/config/types.d.ts.map +1 -1
- package/dist/src/core/config/types.js +0 -5
- package/dist/src/core/config/types.js.map +1 -1
- package/dist/src/core/repo-structure/repo-bulk-discovery.d.ts.map +1 -1
- package/dist/src/core/repo-structure/repo-bulk-discovery.js +20 -5
- package/dist/src/core/repo-structure/repo-bulk-discovery.js.map +1 -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 +29 -14
- package/dist/src/core/repo-structure/repo-structure-manager.js.map +1 -1
- package/dist/src/sync/format-preservation-sync.d.ts.map +1 -1
- package/dist/src/sync/format-preservation-sync.js +23 -5
- package/dist/src/sync/format-preservation-sync.js.map +1 -1
- package/dist/src/sync/frontmatter-updater.d.ts +57 -0
- package/dist/src/sync/frontmatter-updater.d.ts.map +1 -0
- package/dist/src/sync/frontmatter-updater.js +147 -0
- package/dist/src/sync/frontmatter-updater.js.map +1 -0
- package/dist/src/sync/sync-coordinator.d.ts +22 -1
- package/dist/src/sync/sync-coordinator.d.ts.map +1 -1
- package/dist/src/sync/sync-coordinator.js +268 -21
- package/dist/src/sync/sync-coordinator.js.map +1 -1
- package/dist/src/types/living-docs-us-file.d.ts +18 -0
- package/dist/src/types/living-docs-us-file.d.ts.map +1 -1
- package/dist/src/types/living-docs-us-file.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/.claude-plugin/plugin.json +17 -11
- package/plugins/specweave/agents/architect/AGENT.md +115 -45
- package/plugins/specweave/agents/test-aware-planner/AGENT.md +76 -6
- package/plugins/specweave/hooks/lib/update-status-line.sh +19 -0
- package/plugins/specweave/hooks/post-edit-write-consolidated.sh +335 -0
- package/plugins/specweave/hooks/post-metadata-change.sh +40 -6
- package/plugins/specweave/hooks/post-task-completion.sh +93 -9
- package/plugins/specweave/hooks/pre-edit-spec.sh +0 -11
- package/plugins/specweave/hooks/pre-edit-write-consolidated.sh +188 -0
- package/plugins/specweave/hooks/pre-task-completion.sh +11 -0
- package/plugins/specweave/hooks/pre-write-spec.sh +0 -11
- package/plugins/specweave/lib/hooks/consolidated-sync.js +61 -3
- package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +294 -0
- package/plugins/specweave-github/lib/github-client-v2.js +46 -0
- package/plugins/specweave-github/lib/github-client-v2.ts +65 -0
- package/plugins/specweave-release/commands/specweave-release-npm.md +130 -2
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +60 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# Pre-Edit/Write Consolidated Hook: Capture File Path BEFORE Edit/Write Executes
|
|
4
|
+
#
|
|
5
|
+
# Purpose: Unified hook for both Edit and Write tools
|
|
6
|
+
# Strategy: Detect file path, signal post-hook if it's a spec/tasks file
|
|
7
|
+
#
|
|
8
|
+
# CONSOLIDATION (v0.25.0):
|
|
9
|
+
# - Replaces pre-edit-spec.sh and pre-write-spec.sh (identical code)
|
|
10
|
+
# - Reduces hook overhead by 50% (2 pre-hooks → 1)
|
|
11
|
+
# - Single point of maintenance
|
|
12
|
+
#
|
|
13
|
+
# TIER 2 COORDINATION:
|
|
14
|
+
# 1. Extract file_path from TOOL_USE_ARGS (reliable in PreToolUse)
|
|
15
|
+
# 2. If it's spec.md/tasks.md in increments folder, signal PostToolUse hook
|
|
16
|
+
# 3. Write file path to .pending-status-update for PostToolUse to consume
|
|
17
|
+
#
|
|
18
|
+
# Architecture:
|
|
19
|
+
# PreToolUse:Edit/Write → pre-edit-write-consolidated.sh (this file)
|
|
20
|
+
# ↓ writes to
|
|
21
|
+
# .specweave/state/.pending-status-update
|
|
22
|
+
# ↓ read by
|
|
23
|
+
# PostToolUse:Edit/Write → post-edit-write-consolidated.sh
|
|
24
|
+
#
|
|
25
|
+
# Version: v0.25.0 (HOOK CONSOLIDATION)
|
|
26
|
+
# Date: 2025-11-23
|
|
27
|
+
#
|
|
28
|
+
# EMERGENCY FIXES (v0.24.3):
|
|
29
|
+
# - Kill switch: Set SPECWEAVE_DISABLE_HOOKS=1 to disable ALL hooks
|
|
30
|
+
# - Circuit breaker: Auto-disable after 3 consecutive failures
|
|
31
|
+
# - File locking: Prevent concurrent executions
|
|
32
|
+
# - Complete error isolation: Never let errors reach Claude Code
|
|
33
|
+
|
|
34
|
+
# EMERGENCY FIX: Remove set -e - it causes Claude Code crashes!
|
|
35
|
+
set +e
|
|
36
|
+
|
|
37
|
+
# Find project root (must be BEFORE recursion guard to get PROJECT_ROOT)
|
|
38
|
+
find_project_root() {
|
|
39
|
+
local dir="$PWD"
|
|
40
|
+
while [[ "$dir" != "/" ]]; do
|
|
41
|
+
if [[ -d "$dir/.specweave" ]]; then
|
|
42
|
+
echo "$dir"
|
|
43
|
+
return 0
|
|
44
|
+
fi
|
|
45
|
+
dir=$(dirname "$dir")
|
|
46
|
+
done
|
|
47
|
+
echo "$PWD"
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
PROJECT_ROOT=$(find_project_root)
|
|
51
|
+
STATE_DIR="$PROJECT_ROOT/.specweave/state"
|
|
52
|
+
LOGS_DIR="$PROJECT_ROOT/.specweave/logs"
|
|
53
|
+
DEBUG_LOG="$LOGS_DIR/hooks-debug.log"
|
|
54
|
+
PENDING_FILE="$STATE_DIR/.pending-status-update"
|
|
55
|
+
METRICS_FILE="$STATE_DIR/hook-metrics.jsonl"
|
|
56
|
+
|
|
57
|
+
# ============================================================================
|
|
58
|
+
# RECURSION PREVENTION (CRITICAL - v0.26.0 - FILE-BASED GUARD)
|
|
59
|
+
# ============================================================================
|
|
60
|
+
# NEW SOLUTION (v0.26.0): File-based recursion guard
|
|
61
|
+
# - Guard file exists = already inside hook chain
|
|
62
|
+
# - Works across ALL processes (not just current shell)
|
|
63
|
+
#
|
|
64
|
+
# See: ADR-0073 (Hook Recursion Prevention Strategy)
|
|
65
|
+
|
|
66
|
+
RECURSION_GUARD_FILE="$PROJECT_ROOT/.specweave/state/.hook-recursion-guard"
|
|
67
|
+
|
|
68
|
+
if [[ -f "$RECURSION_GUARD_FILE" ]]; then
|
|
69
|
+
# Silent exit - we're already inside a hook chain
|
|
70
|
+
exit 0
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
# EMERGENCY KILL SWITCH: Disable all hooks if env variable set
|
|
74
|
+
if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
|
|
75
|
+
exit 0
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
# Ensure directories exist
|
|
79
|
+
mkdir -p "$STATE_DIR" "$LOGS_DIR" 2>/dev/null || true
|
|
80
|
+
|
|
81
|
+
# ============================================================================
|
|
82
|
+
# TIER 2: Extract File Path from Tool Arguments
|
|
83
|
+
# ============================================================================
|
|
84
|
+
# PreToolUse should have access to tool arguments BEFORE execution
|
|
85
|
+
# Try multiple methods to extract file_path
|
|
86
|
+
|
|
87
|
+
FILE_PATH=""
|
|
88
|
+
|
|
89
|
+
# Method 1: TOOL_USE_ARGS environment variable (primary for PreToolUse)
|
|
90
|
+
if [[ -n "${TOOL_USE_ARGS:-}" ]]; then
|
|
91
|
+
# Try to parse JSON with jq if available
|
|
92
|
+
if command -v jq &> /dev/null; then
|
|
93
|
+
FILE_PATH=$(echo "$TOOL_USE_ARGS" | jq -r '.file_path // empty' 2>/dev/null || echo "")
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
# Fallback: Regex extraction if jq not available or failed
|
|
97
|
+
if [[ -z "$FILE_PATH" ]]; then
|
|
98
|
+
FILE_PATH=$(echo "$TOOL_USE_ARGS" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)".*/\1/' || echo "")
|
|
99
|
+
fi
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
# Method 2: TOOL_USE_CONTENT (fallback)
|
|
103
|
+
if [[ -z "$FILE_PATH" ]] && [[ -n "${TOOL_USE_CONTENT:-}" ]]; then
|
|
104
|
+
FILE_PATH="$TOOL_USE_CONTENT"
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
# Method 3: Parse from stdin (last resort - experimental)
|
|
108
|
+
if [[ -z "$FILE_PATH" ]] && [[ ! -t 0 ]]; then
|
|
109
|
+
# Read stdin and try to extract file_path
|
|
110
|
+
STDIN_DATA=$(cat 2>/dev/null || echo "")
|
|
111
|
+
if [[ -n "$STDIN_DATA" ]] && command -v jq &> /dev/null; then
|
|
112
|
+
FILE_PATH=$(echo "$STDIN_DATA" | jq -r '.file_path // empty' 2>/dev/null || echo "")
|
|
113
|
+
fi
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
# ============================================================================
|
|
117
|
+
# TIER 2: Signal Detection and Validation
|
|
118
|
+
# ============================================================================
|
|
119
|
+
|
|
120
|
+
# Log what we detected (for debugging PreToolUse effectiveness)
|
|
121
|
+
if [[ -n "$FILE_PATH" ]]; then
|
|
122
|
+
echo "[$(date)] pre-edit-write: Detected file_path: $FILE_PATH" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
123
|
+
else
|
|
124
|
+
echo "[$(date)] pre-edit-write: No file_path detected (will fall back to Tier 1)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
125
|
+
exit 0 # Let PostToolUse handle it with mtime fallback
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
# ============================================================================
|
|
129
|
+
# EARLY EXIT: Only process .specweave/ files (v0.24.4 Performance Fix)
|
|
130
|
+
# ============================================================================
|
|
131
|
+
# 90% of Edit/Write operations are on non-SpecWeave files (src/, tests/, node_modules/)
|
|
132
|
+
# Exit immediately for non-.specweave/ files to reduce hook overhead by 90%
|
|
133
|
+
|
|
134
|
+
# Handle both absolute and relative paths: /.specweave/ or .specweave/
|
|
135
|
+
if [[ "$FILE_PATH" != *"/.specweave/"* ]] && [[ "$FILE_PATH" != ".specweave/"* ]]; then
|
|
136
|
+
echo "[$(date)] pre-edit-write: Not a .specweave/ file, skipping (performance optimization)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
137
|
+
exit 0
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
# Check if this is a spec.md or tasks.md file in increments folder
|
|
141
|
+
IS_SPEC_FILE=false
|
|
142
|
+
if [[ "$FILE_PATH" == *"/spec.md" ]] || [[ "$FILE_PATH" == *"/tasks.md" ]]; then
|
|
143
|
+
# Handle both absolute (/.specweave/increments/) and relative (.specweave/increments/) paths
|
|
144
|
+
if [[ "$FILE_PATH" == *"/.specweave/increments/"* ]] || [[ "$FILE_PATH" == ".specweave/increments/"* ]]; then
|
|
145
|
+
# Exclude archived increments
|
|
146
|
+
if [[ "$FILE_PATH" != *"/_archive/"* ]]; then
|
|
147
|
+
IS_SPEC_FILE=true
|
|
148
|
+
fi
|
|
149
|
+
fi
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
# If not a spec/tasks file, exit silently (no signal to PostToolUse)
|
|
153
|
+
if [[ "$IS_SPEC_FILE" != "true" ]]; then
|
|
154
|
+
echo "[$(date)] pre-edit-write: Not a spec/tasks file - no signal" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
155
|
+
exit 0
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
# ============================================================================
|
|
159
|
+
# TIER 2: Write Signal for PostToolUse Hook
|
|
160
|
+
# ============================================================================
|
|
161
|
+
|
|
162
|
+
# Write file path to pending file for PostToolUse to consume
|
|
163
|
+
echo "$FILE_PATH" > "$PENDING_FILE" 2>/dev/null || true
|
|
164
|
+
|
|
165
|
+
echo "[$(date)] pre-edit-write: Signaled PostToolUse for: $FILE_PATH" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
166
|
+
|
|
167
|
+
# ============================================================================
|
|
168
|
+
# TIER 2: Metrics Collection
|
|
169
|
+
# ============================================================================
|
|
170
|
+
|
|
171
|
+
# Record metrics (JSONL format - one JSON object per line)
|
|
172
|
+
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
173
|
+
METRIC_ENTRY="{\"timestamp\":\"$TIMESTAMP\",\"hook\":\"pre-edit-write\",\"event\":\"file_detected\",\"file_path\":\"$FILE_PATH\",\"method\":\"TOOL_USE_ARGS\"}"
|
|
174
|
+
|
|
175
|
+
# Append to metrics file (JSONL)
|
|
176
|
+
echo "$METRIC_ENTRY" >> "$METRICS_FILE" 2>/dev/null || true
|
|
177
|
+
|
|
178
|
+
# Log rotation for metrics (keep last 1000 entries)
|
|
179
|
+
if [[ -f "$METRICS_FILE" ]]; then
|
|
180
|
+
LINE_COUNT=$(wc -l < "$METRICS_FILE" 2>/dev/null || echo 0)
|
|
181
|
+
if (( LINE_COUNT > 1000 )); then
|
|
182
|
+
tail -1000 "$METRICS_FILE" > "$METRICS_FILE.tmp" 2>/dev/null || true
|
|
183
|
+
mv "$METRICS_FILE.tmp" "$METRICS_FILE" 2>/dev/null || true
|
|
184
|
+
fi
|
|
185
|
+
fi
|
|
186
|
+
|
|
187
|
+
# ALWAYS exit 0 - NEVER let hook errors crash Claude Code
|
|
188
|
+
exit 0
|
|
@@ -22,6 +22,17 @@
|
|
|
22
22
|
|
|
23
23
|
set +e # EMERGENCY FIX: Prevents Claude Code crashes
|
|
24
24
|
|
|
25
|
+
# ============================================================================
|
|
26
|
+
# RECURSION PREVENTION (CRITICAL - v0.25.1)
|
|
27
|
+
# ============================================================================
|
|
28
|
+
# Skip if we're already inside a hook to prevent infinite recursion
|
|
29
|
+
if [[ "${SPECWEAVE_IN_HOOK:-0}" == "1" ]]; then
|
|
30
|
+
exit 0
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Mark that we're now inside a hook
|
|
34
|
+
export SPECWEAVE_IN_HOOK=1
|
|
35
|
+
|
|
25
36
|
# EMERGENCY KILL SWITCH
|
|
26
37
|
if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
|
|
27
38
|
exit 0
|
|
@@ -101,17 +101,6 @@ else
|
|
|
101
101
|
exit 0 # Let PostToolUse handle it with mtime fallback
|
|
102
102
|
fi
|
|
103
103
|
|
|
104
|
-
# ============================================================================
|
|
105
|
-
# EARLY EXIT: Only process .specweave/ files (v0.24.4 Performance Fix)
|
|
106
|
-
# ============================================================================
|
|
107
|
-
# 90% of Write operations are on non-SpecWeave files (src/, tests/, node_modules/)
|
|
108
|
-
# Exit immediately for non-.specweave/ files to reduce hook overhead by 90%
|
|
109
|
-
|
|
110
|
-
if [[ "$FILE_PATH" != *"/.specweave/"* ]]; then
|
|
111
|
-
echo "[$(date)] pre-write-spec: Not a .specweave/ file, skipping (performance optimization)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
112
|
-
exit 0
|
|
113
|
-
fi
|
|
114
|
-
|
|
115
104
|
# Check if this is a spec.md or tasks.md file in increments folder
|
|
116
105
|
IS_SPEC_FILE=false
|
|
117
106
|
if [[ "$FILE_PATH" == *"/spec.md" ]] || [[ "$FILE_PATH" == *"/tasks.md" ]]; then
|
|
@@ -42,6 +42,11 @@ import { translateLivingDocs } from './translate-living-docs.js';
|
|
|
42
42
|
// Import for AC status (uses ACStatusManager directly)
|
|
43
43
|
import { ACStatusManager } from '../vendor/core/increment/ac-status-manager.js';
|
|
44
44
|
|
|
45
|
+
// Import for GitHub sync (uses SyncCoordinator directly)
|
|
46
|
+
// NOTE: Import from project root dist (not relative path)
|
|
47
|
+
import { SyncCoordinator } from '../../../../dist/src/sync/sync-coordinator.js';
|
|
48
|
+
import { consoleLogger } from '../vendor/utils/logger.js';
|
|
49
|
+
|
|
45
50
|
// ============================================================================
|
|
46
51
|
// WRAPPER: UPDATE AC STATUS
|
|
47
52
|
// ============================================================================
|
|
@@ -87,6 +92,36 @@ async function updateACStatus(incrementId) {
|
|
|
87
92
|
}
|
|
88
93
|
}
|
|
89
94
|
|
|
95
|
+
// ============================================================================
|
|
96
|
+
// WRAPPER: GITHUB SYNC
|
|
97
|
+
// ============================================================================
|
|
98
|
+
async function syncGitHub(incrementId) {
|
|
99
|
+
try {
|
|
100
|
+
console.log(`\n🔗 [5/5] Syncing to GitHub...`);
|
|
101
|
+
|
|
102
|
+
const projectRoot = process.cwd();
|
|
103
|
+
|
|
104
|
+
const coordinator = new SyncCoordinator({
|
|
105
|
+
projectRoot,
|
|
106
|
+
incrementId,
|
|
107
|
+
logger: consoleLogger
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const result = await coordinator.syncIncrementCompletion();
|
|
111
|
+
|
|
112
|
+
if (result.success) {
|
|
113
|
+
console.log(`✅ GitHub sync completed (${result.userStoriesSynced} user stories synced)`);
|
|
114
|
+
} else {
|
|
115
|
+
console.warn(`⚠️ GitHub sync had errors (see logs)`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return { success: result.success, result };
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.error('❌ Error syncing to GitHub:', error.message);
|
|
121
|
+
return { success: false, error: error.message };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
90
125
|
// ============================================================================
|
|
91
126
|
// MAIN EXECUTION
|
|
92
127
|
// ============================================================================
|
|
@@ -100,7 +135,7 @@ async function runConsolidatedSync(incrementId) {
|
|
|
100
135
|
|
|
101
136
|
try {
|
|
102
137
|
// OPERATION 1: Update tasks.md (uses imported function)
|
|
103
|
-
console.log('\n🔄 [1/
|
|
138
|
+
console.log('\n🔄 [1/5] Updating tasks.md...');
|
|
104
139
|
try {
|
|
105
140
|
await updateTasksMd(incrementId);
|
|
106
141
|
results.updateTasks = { success: true };
|
|
@@ -110,7 +145,7 @@ async function runConsolidatedSync(incrementId) {
|
|
|
110
145
|
}
|
|
111
146
|
|
|
112
147
|
// OPERATION 2: Sync living docs (uses imported function)
|
|
113
|
-
console.log('\n📚 [2/
|
|
148
|
+
console.log('\n📚 [2/5] Syncing living docs...');
|
|
114
149
|
try {
|
|
115
150
|
await syncLivingDocs(incrementId);
|
|
116
151
|
results.syncDocs = { success: true };
|
|
@@ -128,7 +163,7 @@ async function runConsolidatedSync(incrementId) {
|
|
|
128
163
|
}
|
|
129
164
|
|
|
130
165
|
// OPERATION 4: Translate living docs (uses imported function)
|
|
131
|
-
console.log('\n🌐 [4/
|
|
166
|
+
console.log('\n🌐 [4/5] Checking translation needs...');
|
|
132
167
|
try {
|
|
133
168
|
await translateLivingDocs(incrementId);
|
|
134
169
|
results.translate = { success: true };
|
|
@@ -137,6 +172,29 @@ async function runConsolidatedSync(incrementId) {
|
|
|
137
172
|
results.translate = { success: false, error: error.message };
|
|
138
173
|
}
|
|
139
174
|
|
|
175
|
+
// OPERATION 5: Sync to GitHub (NEW in v0.24.0+)
|
|
176
|
+
// FIX (v0.26.0): Skip GitHub sync in post-task-completion hook!
|
|
177
|
+
// WHY: GitHub sync should ONLY run on increment COMPLETION, not task completion
|
|
178
|
+
// This prevents 27 duplicate comments on every TodoWrite (see root cause analysis)
|
|
179
|
+
//
|
|
180
|
+
// GitHub sync is now ONLY triggered by:
|
|
181
|
+
// - post-increment-completion.sh (when status → "completed")
|
|
182
|
+
// - Manual sync via /specweave-github:sync command
|
|
183
|
+
//
|
|
184
|
+
// See: .specweave/increments/0051-*/reports/GITHUB-COMMENT-RECURSION-ROOT-CAUSE-2025-11-24.md
|
|
185
|
+
if (process.env.SKIP_GITHUB_SYNC === 'true') {
|
|
186
|
+
console.log('\n⏭️ [5/5] GitHub sync SKIPPED (called from post-task-completion hook)');
|
|
187
|
+
console.log(' GitHub sync will run automatically on increment completion.');
|
|
188
|
+
results.syncGitHub = { success: true, skipped: true };
|
|
189
|
+
} else {
|
|
190
|
+
try {
|
|
191
|
+
results.syncGitHub = await syncGitHub(incrementId);
|
|
192
|
+
} catch (error) {
|
|
193
|
+
console.error('❌ Error syncing to GitHub:', error.message);
|
|
194
|
+
results.syncGitHub = { success: false, error: error.message };
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
140
198
|
const duration = Date.now() - startTime;
|
|
141
199
|
|
|
142
200
|
console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|