specweave 1.0.550 → 1.0.552
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 +1 -1
- package/bin/specweave.js +23 -1
- package/dist/src/cli/commands/hook.d.ts +15 -0
- package/dist/src/cli/commands/hook.d.ts.map +1 -0
- package/dist/src/cli/commands/hook.js +61 -0
- package/dist/src/cli/commands/hook.js.map +1 -0
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +5 -0
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/refresh-plugins.d.ts.map +1 -1
- package/dist/src/cli/commands/refresh-plugins.js +11 -1
- package/dist/src/cli/commands/refresh-plugins.js.map +1 -1
- package/dist/src/cli/commands/sync-setup.d.ts.map +1 -1
- package/dist/src/cli/commands/sync-setup.js +7 -3
- package/dist/src/cli/commands/sync-setup.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.d.ts +9 -0
- package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.js +9 -3
- package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.js.map +1 -1
- package/dist/src/config/types.d.ts +2 -2
- package/dist/src/core/config/types.d.ts +18 -2
- package/dist/src/core/config/types.d.ts.map +1 -1
- package/dist/src/core/config/types.js.map +1 -1
- package/dist/src/core/hooks/handlers/hook-router.d.ts +19 -0
- package/dist/src/core/hooks/handlers/hook-router.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/hook-router.js +75 -0
- package/dist/src/core/hooks/handlers/hook-router.js.map +1 -0
- package/dist/src/core/hooks/handlers/index.d.ts +10 -0
- package/dist/src/core/hooks/handlers/index.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/index.js +9 -0
- package/dist/src/core/hooks/handlers/index.js.map +1 -0
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.d.ts +11 -0
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.js +73 -0
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.js.map +1 -0
- package/dist/src/core/hooks/handlers/post-tool-use.d.ts +11 -0
- package/dist/src/core/hooks/handlers/post-tool-use.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/post-tool-use.js +76 -0
- package/dist/src/core/hooks/handlers/post-tool-use.js.map +1 -0
- package/dist/src/core/hooks/handlers/pre-compact.d.ts +11 -0
- package/dist/src/core/hooks/handlers/pre-compact.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/pre-compact.js +77 -0
- package/dist/src/core/hooks/handlers/pre-compact.js.map +1 -0
- package/dist/src/core/hooks/handlers/pre-tool-use.d.ts +11 -0
- package/dist/src/core/hooks/handlers/pre-tool-use.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/pre-tool-use.js +318 -0
- package/dist/src/core/hooks/handlers/pre-tool-use.js.map +1 -0
- package/dist/src/core/hooks/handlers/session-start.d.ts +9 -0
- package/dist/src/core/hooks/handlers/session-start.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/session-start.js +111 -0
- package/dist/src/core/hooks/handlers/session-start.js.map +1 -0
- package/dist/src/core/hooks/handlers/stop-auto.d.ts +16 -0
- package/dist/src/core/hooks/handlers/stop-auto.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/stop-auto.js +122 -0
- package/dist/src/core/hooks/handlers/stop-auto.js.map +1 -0
- package/dist/src/core/hooks/handlers/stop-reflect.d.ts +14 -0
- package/dist/src/core/hooks/handlers/stop-reflect.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/stop-reflect.js +43 -0
- package/dist/src/core/hooks/handlers/stop-reflect.js.map +1 -0
- package/dist/src/core/hooks/handlers/stop-sync.d.ts +15 -0
- package/dist/src/core/hooks/handlers/stop-sync.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/stop-sync.js +68 -0
- package/dist/src/core/hooks/handlers/stop-sync.js.map +1 -0
- package/dist/src/core/hooks/handlers/types.d.ts +63 -0
- package/dist/src/core/hooks/handlers/types.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/types.js +27 -0
- package/dist/src/core/hooks/handlers/types.js.map +1 -0
- package/dist/src/core/hooks/handlers/user-prompt-submit.d.ts +14 -0
- package/dist/src/core/hooks/handlers/user-prompt-submit.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/user-prompt-submit.js +173 -0
- package/dist/src/core/hooks/handlers/user-prompt-submit.js.map +1 -0
- package/dist/src/core/hooks/handlers/utils.d.ts +25 -0
- package/dist/src/core/hooks/handlers/utils.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/utils.js +64 -0
- package/dist/src/core/hooks/handlers/utils.js.map +1 -0
- package/dist/src/core/increment/completion-validator.d.ts.map +1 -1
- package/dist/src/core/increment/completion-validator.js +32 -0
- package/dist/src/core/increment/completion-validator.js.map +1 -1
- package/dist/src/init/research/types.d.ts +1 -1
- package/dist/src/sync/sync-target-resolver.js.map +1 -1
- package/dist/src/utils/lock-manager.d.ts.map +1 -1
- package/dist/src/utils/lock-manager.js +5 -0
- package/dist/src/utils/lock-manager.js.map +1 -1
- package/dist/src/utils/plugin-copier.d.ts +10 -0
- package/dist/src/utils/plugin-copier.d.ts.map +1 -1
- package/dist/src/utils/plugin-copier.js +63 -35
- package/dist/src/utils/plugin-copier.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/agents/sw-closer.md +3 -2
- package/plugins/specweave/hooks/hooks.json +10 -10
- package/plugins/specweave/skills/code-reviewer/SKILL.md +180 -16
- package/plugins/specweave/skills/code-reviewer/agents/reviewer-comments.md +83 -0
- package/plugins/specweave/skills/code-reviewer/agents/reviewer-silent-failures.md +19 -0
- package/plugins/specweave/skills/code-reviewer/agents/reviewer-spec-compliance.md +19 -0
- package/plugins/specweave/skills/code-reviewer/agents/reviewer-tests.md +101 -0
- package/plugins/specweave/skills/code-reviewer/agents/reviewer-types.md +20 -0
- package/plugins/specweave/skills/done/SKILL.md +56 -21
- package/plugins/specweave/skills/grill/SKILL.md +1 -1
- package/plugins/specweave/skills/team-lead/agents/reviewer-logic.md +19 -0
- package/plugins/specweave/skills/team-lead/agents/reviewer-performance.md +20 -0
- package/plugins/specweave/skills/team-lead/agents/reviewer-security.md +20 -0
- package/src/templates/CLAUDE.md.template +7 -4
- package/plugins/specweave/hooks/README.md +0 -493
- package/plugins/specweave/hooks/_archive/stop-auto-v4-legacy.sh +0 -1319
- package/plugins/specweave/hooks/lib/common-setup.sh +0 -144
- package/plugins/specweave/hooks/lib/hook-errors.sh +0 -414
- package/plugins/specweave/hooks/lib/migrate-increment-work.sh +0 -245
- package/plugins/specweave/hooks/lib/resolve-package.sh +0 -146
- package/plugins/specweave/hooks/lib/scheduler-startup.sh +0 -135
- package/plugins/specweave/hooks/lib/score-increment.sh +0 -87
- package/plugins/specweave/hooks/lib/sync-spec-content.sh +0 -193
- package/plugins/specweave/hooks/lib/update-active-increment.sh +0 -95
- package/plugins/specweave/hooks/lib/update-status-line.sh +0 -233
- package/plugins/specweave/hooks/lib/validate-spec-status.sh +0 -171
- package/plugins/specweave/hooks/llm-judge-validator.sh +0 -219
- package/plugins/specweave/hooks/log-decision.sh +0 -168
- package/plugins/specweave/hooks/pre-compact.sh +0 -64
- package/plugins/specweave/hooks/startup-health-check.sh +0 -64
- package/plugins/specweave/hooks/stop-auto-v5.sh +0 -276
- package/plugins/specweave/hooks/stop-reflect.sh +0 -336
- package/plugins/specweave/hooks/stop-sync.sh +0 -283
- package/plugins/specweave/hooks/tests/test-auto-context-integration.sh +0 -126
- package/plugins/specweave/hooks/tests/test-stop-auto-enriched.sh +0 -128
- package/plugins/specweave/hooks/universal/dispatcher.mjs +0 -336
- package/plugins/specweave/hooks/universal/fail-fast-wrapper.sh +0 -325
- package/plugins/specweave/hooks/universal/hook-wrapper.cmd +0 -26
- package/plugins/specweave/hooks/universal/hook-wrapper.sh +0 -69
- package/plugins/specweave/hooks/universal/run-hook.sh +0 -20
- package/plugins/specweave/hooks/universal/session-start.cmd +0 -16
- package/plugins/specweave/hooks/universal/session-start.ps1 +0 -16
- package/plugins/specweave/hooks/user-prompt-submit.sh +0 -2550
- package/plugins/specweave/hooks/v2/detectors/lifecycle-detector.sh +0 -87
- package/plugins/specweave/hooks/v2/detectors/us-completion-detector.sh +0 -186
- package/plugins/specweave/hooks/v2/dispatchers/post-tool-use-analytics.sh +0 -83
- package/plugins/specweave/hooks/v2/dispatchers/post-tool-use.sh +0 -447
- package/plugins/specweave/hooks/v2/dispatchers/pre-tool-use.sh +0 -104
- package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +0 -270
- package/plugins/specweave/hooks/v2/guards/completion-guard.sh +0 -14
- package/plugins/specweave/hooks/v2/guards/increment-duplicate-guard.sh +0 -14
- package/plugins/specweave/hooks/v2/guards/increment-existence-guard.sh +0 -240
- package/plugins/specweave/hooks/v2/guards/interview-enforcement-guard.sh +0 -171
- package/plugins/specweave/hooks/v2/guards/metadata-json-guard.sh +0 -14
- package/plugins/specweave/hooks/v2/guards/skill-chain-enforcement-guard.sh +0 -222
- package/plugins/specweave/hooks/v2/guards/spec-template-enforcement-guard.sh +0 -21
- package/plugins/specweave/hooks/v2/guards/spec-validation-guard.sh +0 -14
- package/plugins/specweave/hooks/v2/guards/status-completion-guard.sh +0 -84
- package/plugins/specweave/hooks/v2/guards/task-ac-sync-guard.sh +0 -475
- package/plugins/specweave/hooks/v2/guards/tdd-enforcement-guard.sh +0 -268
- package/plugins/specweave/hooks/v2/handlers/ac-sync-dispatcher.sh +0 -332
- package/plugins/specweave/hooks/v2/handlers/ac-validation-handler.sh +0 -50
- package/plugins/specweave/hooks/v2/handlers/github-sync-handler.sh +0 -347
- package/plugins/specweave/hooks/v2/handlers/living-docs-handler.sh +0 -83
- package/plugins/specweave/hooks/v2/handlers/living-specs-handler.sh +0 -268
- package/plugins/specweave/hooks/v2/handlers/project-bridge-handler.sh +0 -104
- package/plugins/specweave/hooks/v2/handlers/status-line-handler.sh +0 -165
- package/plugins/specweave/hooks/v2/handlers/status-update.sh +0 -61
- package/plugins/specweave/hooks/v2/handlers/universal-auto-create-dispatcher.sh +0 -270
- package/plugins/specweave/hooks/v2/integrations/ado-post-living-docs-update.sh +0 -367
- package/plugins/specweave/hooks/v2/integrations/ado-post-task.sh +0 -179
- package/plugins/specweave/hooks/v2/integrations/github-auto-create-handler.sh +0 -553
- package/plugins/specweave/hooks/v2/integrations/github-post-task.sh +0 -345
- package/plugins/specweave/hooks/v2/integrations/jira-post-task.sh +0 -180
- package/plugins/specweave/hooks/v2/lib/check-provider-enabled.sh +0 -52
- package/plugins/specweave/hooks/v2/queue/enqueue.sh +0 -81
- package/plugins/specweave/hooks/v2/session-end.sh +0 -139
- package/plugins/specweave/hooks/validate-skill-activations.sh +0 -227
|
@@ -1,345 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# SpecWeave GitHub Sync Hook
|
|
4
|
-
# Runs after task completion to sync progress to GitHub Projects
|
|
5
|
-
#
|
|
6
|
-
# ARCHITECTURE (v0.19.0+): IMMUTABLE DESCRIPTIONS + PROGRESS COMMENTS
|
|
7
|
-
# - User Story files (.specweave/docs/internal/specs/) ↔ GitHub Issues
|
|
8
|
-
# - Issue descriptions created once (IMMUTABLE snapshot)
|
|
9
|
-
# - All updates via progress comments (audit trail)
|
|
10
|
-
#
|
|
11
|
-
# This hook is part of the specweave-github plugin and handles:
|
|
12
|
-
# - Finding which spec user stories the current work belongs to
|
|
13
|
-
# - Syncing progress via GitHub comments (NOT editing issue body)
|
|
14
|
-
# - Creating audit trail of all changes over time
|
|
15
|
-
# - Notifying stakeholders via GitHub notifications
|
|
16
|
-
#
|
|
17
|
-
# Dependencies:
|
|
18
|
-
# - Node.js and TypeScript CLI (dist/cli/commands/sync-spec-content.js)
|
|
19
|
-
# - GitHub CLI (gh) must be installed and authenticated
|
|
20
|
-
# - ProgressCommentBuilder (lib/progress-comment-builder.ts)
|
|
21
|
-
|
|
22
|
-
set +e # EMERGENCY FIX: Prevents Claude Code crashes
|
|
23
|
-
|
|
24
|
-
# EMERGENCY KILL SWITCH
|
|
25
|
-
if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
|
|
26
|
-
exit 0
|
|
27
|
-
fi
|
|
28
|
-
|
|
29
|
-
# ============================================================================
|
|
30
|
-
# PROJECT ROOT DETECTION (MUST BE FIRST - before any mkdir!)
|
|
31
|
-
# ============================================================================
|
|
32
|
-
|
|
33
|
-
# Find project root by searching upward for .specweave/ directory
|
|
34
|
-
find_project_root() {
|
|
35
|
-
local dir="$1"
|
|
36
|
-
while [ "$dir" != "/" ]; do
|
|
37
|
-
if [ -f "$dir/.specweave/config.json" ]; then
|
|
38
|
-
echo "$dir"
|
|
39
|
-
return 0
|
|
40
|
-
fi
|
|
41
|
-
dir="$(dirname "$dir")"
|
|
42
|
-
done
|
|
43
|
-
return 1 # NOT FOUND - return error, do NOT fallback to pwd
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
PROJECT_ROOT="$(find_project_root "$(pwd)")"
|
|
47
|
-
if [[ -z "$PROJECT_ROOT" ]]; then
|
|
48
|
-
# NOT a SpecWeave project - exit silently (no .specweave pollution!)
|
|
49
|
-
exit 0
|
|
50
|
-
fi
|
|
51
|
-
cd "$PROJECT_ROOT" 2>/dev/null || exit 0
|
|
52
|
-
|
|
53
|
-
# ============================================================================
|
|
54
|
-
# CIRCUIT BREAKER & FILE LOCKING
|
|
55
|
-
# ============================================================================
|
|
56
|
-
|
|
57
|
-
# CIRCUIT BREAKER: Auto-disable after consecutive failures
|
|
58
|
-
CIRCUIT_BREAKER_FILE="$PROJECT_ROOT/.specweave/state/.hook-circuit-breaker-github"
|
|
59
|
-
CIRCUIT_BREAKER_THRESHOLD=3
|
|
60
|
-
|
|
61
|
-
mkdir -p "$PROJECT_ROOT/.specweave/state" 2>/dev/null || true
|
|
62
|
-
|
|
63
|
-
if [[ -f "$CIRCUIT_BREAKER_FILE" ]]; then
|
|
64
|
-
FAILURE_COUNT=$(cat "$CIRCUIT_BREAKER_FILE" 2>/dev/null || echo 0)
|
|
65
|
-
if (( FAILURE_COUNT >= CIRCUIT_BREAKER_THRESHOLD )); then
|
|
66
|
-
# Circuit breaker is OPEN - hooks are disabled
|
|
67
|
-
exit 0
|
|
68
|
-
fi
|
|
69
|
-
fi
|
|
70
|
-
|
|
71
|
-
# FILE LOCK: Only allow 1 GitHub sync hook at a time
|
|
72
|
-
LOCK_FILE="$PROJECT_ROOT/.specweave/state/.hook-github-sync.lock"
|
|
73
|
-
LOCK_TIMEOUT=15 # seconds (GitHub sync can take longer)
|
|
74
|
-
|
|
75
|
-
LOCK_ACQUIRED=false
|
|
76
|
-
for i in {1..15}; do
|
|
77
|
-
if mkdir "$LOCK_FILE" 2>/dev/null; then
|
|
78
|
-
LOCK_ACQUIRED=true
|
|
79
|
-
trap 'rmdir "$LOCK_FILE" 2>/dev/null || true' EXIT
|
|
80
|
-
break
|
|
81
|
-
fi
|
|
82
|
-
|
|
83
|
-
# Check for stale lock (POSIX-portable: works on macOS and Linux)
|
|
84
|
-
if [[ -d "$LOCK_FILE" ]]; then
|
|
85
|
-
# Use find -mmin which works on both macOS and Linux
|
|
86
|
-
LOCK_TIMEOUT_MIN=$(( (LOCK_TIMEOUT + 59) / 60 )) # Convert seconds to minutes (ceil)
|
|
87
|
-
[[ $LOCK_TIMEOUT_MIN -lt 1 ]] && LOCK_TIMEOUT_MIN=1
|
|
88
|
-
STALE=$(find "$LOCK_FILE" -maxdepth 0 -mmin +${LOCK_TIMEOUT_MIN} 2>/dev/null)
|
|
89
|
-
if [[ -n "$STALE" ]]; then
|
|
90
|
-
rmdir "$LOCK_FILE" 2>/dev/null || true
|
|
91
|
-
continue
|
|
92
|
-
fi
|
|
93
|
-
fi
|
|
94
|
-
|
|
95
|
-
sleep 0.2
|
|
96
|
-
done
|
|
97
|
-
|
|
98
|
-
if [[ "$LOCK_ACQUIRED" == "false" ]]; then
|
|
99
|
-
# Another instance is running, skip
|
|
100
|
-
exit 0
|
|
101
|
-
fi
|
|
102
|
-
|
|
103
|
-
# NOTE: PROJECT_ROOT already detected at top of script (before any mkdir)
|
|
104
|
-
|
|
105
|
-
# ============================================================================
|
|
106
|
-
# CONFIGURATION
|
|
107
|
-
# ============================================================================
|
|
108
|
-
|
|
109
|
-
LOGS_DIR=".specweave/logs"
|
|
110
|
-
DEBUG_LOG="$LOGS_DIR/hooks-debug.log"
|
|
111
|
-
|
|
112
|
-
mkdir -p "$LOGS_DIR" 2>/dev/null || true
|
|
113
|
-
|
|
114
|
-
# ============================================================================
|
|
115
|
-
# PRECONDITIONS CHECK
|
|
116
|
-
# ============================================================================
|
|
117
|
-
|
|
118
|
-
echo "[$(date)] [GitHub] 🔗 GitHub sync hook fired" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
119
|
-
|
|
120
|
-
# Check if Node.js is available
|
|
121
|
-
if ! command -v node &> /dev/null; then
|
|
122
|
-
echo "[$(date)] [GitHub] ⚠️ Node.js not found, skipping GitHub sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
123
|
-
cat <<EOF
|
|
124
|
-
{
|
|
125
|
-
"continue": true
|
|
126
|
-
}
|
|
127
|
-
EOF
|
|
128
|
-
exit 0
|
|
129
|
-
fi
|
|
130
|
-
|
|
131
|
-
# Find sync-spec-content CLI — check multiple locations
|
|
132
|
-
SYNC_CLI=""
|
|
133
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
134
|
-
# Derive package root: hooks/ → specweave-github/ → plugins/ → package root (3 levels up)
|
|
135
|
-
_PKG_ROOT="$(cd "$SCRIPT_DIR/../../.." 2>/dev/null && pwd)"
|
|
136
|
-
# Source resolve-package.sh for dynamic specweave path resolution
|
|
137
|
-
RESOLVE_LIB="$SCRIPT_DIR/../../specweave/hooks/lib/resolve-package.sh"
|
|
138
|
-
if [[ -f "$RESOLVE_LIB" ]]; then
|
|
139
|
-
source "$RESOLVE_LIB"
|
|
140
|
-
fi
|
|
141
|
-
# 0. SPECWEAVE_PKG (set by hook infrastructure)
|
|
142
|
-
[[ -n "${SPECWEAVE_PKG:-}" ]] && [[ -f "${SPECWEAVE_PKG}/dist/src/cli/commands/sync-spec-content.js" ]] && SYNC_CLI="${SPECWEAVE_PKG}/dist/src/cli/commands/sync-spec-content.js"
|
|
143
|
-
# 1. Package root (derived from script location)
|
|
144
|
-
[[ -z "$SYNC_CLI" ]] && [[ -f "${_PKG_ROOT}/dist/src/cli/commands/sync-spec-content.js" ]] && SYNC_CLI="${_PKG_ROOT}/dist/src/cli/commands/sync-spec-content.js"
|
|
145
|
-
# 2. resolve-package.sh (dynamic resolution)
|
|
146
|
-
[[ -z "$SYNC_CLI" ]] && SYNC_CLI=$(find_specweave_script "dist/src/cli/commands/sync-spec-content.js" 2>/dev/null)
|
|
147
|
-
# 3. Legacy: PROJECT_ROOT/dist/
|
|
148
|
-
[[ -z "$SYNC_CLI" ]] && [[ -f "$PROJECT_ROOT/dist/src/cli/commands/sync-spec-content.js" ]] && SYNC_CLI="$PROJECT_ROOT/dist/src/cli/commands/sync-spec-content.js"
|
|
149
|
-
|
|
150
|
-
if [ -z "$SYNC_CLI" ]; then
|
|
151
|
-
echo "[$(date)] [GitHub] ⚠️ sync-spec-content CLI not found at any known path, skipping sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
152
|
-
cat <<EOF
|
|
153
|
-
{
|
|
154
|
-
"continue": true
|
|
155
|
-
}
|
|
156
|
-
EOF
|
|
157
|
-
exit 0
|
|
158
|
-
fi
|
|
159
|
-
echo "[$(date)] [GitHub] Using sync CLI: $SYNC_CLI" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
160
|
-
|
|
161
|
-
# Check for gh CLI
|
|
162
|
-
if ! command -v gh &> /dev/null; then
|
|
163
|
-
echo "[$(date)] [GitHub] ⚠️ GitHub CLI (gh) not found, skipping sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
164
|
-
cat <<EOF
|
|
165
|
-
{
|
|
166
|
-
"continue": true
|
|
167
|
-
}
|
|
168
|
-
EOF
|
|
169
|
-
exit 0
|
|
170
|
-
fi
|
|
171
|
-
|
|
172
|
-
# ============================================================================
|
|
173
|
-
# DETECT ALL SPECS (Multi-Spec Support)
|
|
174
|
-
# ============================================================================
|
|
175
|
-
|
|
176
|
-
# Strategy: Use multi-spec detector to find ALL specs referenced in current increment
|
|
177
|
-
|
|
178
|
-
# 1. Detect current increment (temporary context)
|
|
179
|
-
CURRENT_INCREMENT=$(ls -td .specweave/increments/*/ 2>/dev/null | xargs -n1 basename | grep -v "_backlog" | grep -v "_archive" | grep -v "_working" | head -1)
|
|
180
|
-
|
|
181
|
-
if [ -z "$CURRENT_INCREMENT" ]; then
|
|
182
|
-
echo "[$(date)] [GitHub] ℹ️ No active increment, checking for spec changes..." >> "$DEBUG_LOG" 2>/dev/null || true
|
|
183
|
-
# Fall through to sync all changed specs
|
|
184
|
-
fi
|
|
185
|
-
|
|
186
|
-
# 2. Use TypeScript CLI to detect all specs — check multiple locations
|
|
187
|
-
DETECT_CLI=""
|
|
188
|
-
[[ -n "${SPECWEAVE_PKG:-}" ]] && [[ -f "${SPECWEAVE_PKG}/dist/src/cli/commands/detect-specs.js" ]] && DETECT_CLI="${SPECWEAVE_PKG}/dist/src/cli/commands/detect-specs.js"
|
|
189
|
-
[[ -z "$DETECT_CLI" ]] && [[ -f "${_PKG_ROOT}/dist/src/cli/commands/detect-specs.js" ]] && DETECT_CLI="${_PKG_ROOT}/dist/src/cli/commands/detect-specs.js"
|
|
190
|
-
[[ -z "$DETECT_CLI" ]] && DETECT_CLI=$(find_specweave_script "dist/src/cli/commands/detect-specs.js" 2>/dev/null)
|
|
191
|
-
[[ -z "$DETECT_CLI" ]] && [[ -f "$PROJECT_ROOT/dist/src/cli/commands/detect-specs.js" ]] && DETECT_CLI="$PROJECT_ROOT/dist/src/cli/commands/detect-specs.js"
|
|
192
|
-
|
|
193
|
-
if [ -n "$DETECT_CLI" ] && [ -f "$DETECT_CLI" ]; then
|
|
194
|
-
echo "[$(date)] [GitHub] 🔍 Detecting all specs in increment $CURRENT_INCREMENT..." >> "$DEBUG_LOG" 2>/dev/null || true
|
|
195
|
-
|
|
196
|
-
# Call detect-specs CLI and capture JSON output
|
|
197
|
-
DETECTION_RESULT=$(node "$DETECT_CLI" 2>> "$DEBUG_LOG" || echo "{}")
|
|
198
|
-
|
|
199
|
-
# Extract spec count
|
|
200
|
-
SPEC_COUNT=$(echo "$DETECTION_RESULT" | node -e "const fs=require('fs'); const data=JSON.parse(fs.readFileSync(0,'utf-8')); console.log(data.specs?.length || 0)")
|
|
201
|
-
|
|
202
|
-
echo "[$(date)] [GitHub] 📋 Detected $SPEC_COUNT spec(s)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
203
|
-
|
|
204
|
-
# Store detection result for later use
|
|
205
|
-
echo "$DETECTION_RESULT" > /tmp/specweave-detected-specs.json
|
|
206
|
-
else
|
|
207
|
-
echo "[$(date)] [GitHub] ⚠️ detect-specs CLI not found at any known path, falling back to git diff" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
208
|
-
SPEC_COUNT=0
|
|
209
|
-
fi
|
|
210
|
-
|
|
211
|
-
# ============================================================================
|
|
212
|
-
# SYNC ALL DETECTED SPECS TO GITHUB (Multi-Spec Support)
|
|
213
|
-
# ============================================================================
|
|
214
|
-
|
|
215
|
-
if [ -f /tmp/specweave-detected-specs.json ] && [ "$SPEC_COUNT" -gt 0 ]; then
|
|
216
|
-
# Multi-spec sync: Loop through all detected specs
|
|
217
|
-
echo "[$(date)] [GitHub] 🔄 Syncing $SPEC_COUNT spec(s) to GitHub..." >> "$DEBUG_LOG" 2>/dev/null || true
|
|
218
|
-
|
|
219
|
-
# Extract spec paths using Node.js
|
|
220
|
-
SPEC_PATHS=$(node -e "
|
|
221
|
-
const fs = require('fs');
|
|
222
|
-
const data = JSON.parse(fs.readFileSync('/tmp/specweave-detected-specs.json', 'utf-8'));
|
|
223
|
-
const syncable = data.specs.filter(s => s.syncEnabled && s.project !== '_parent');
|
|
224
|
-
syncable.forEach(s => console.log(s.path));
|
|
225
|
-
" 2>> "$DEBUG_LOG")
|
|
226
|
-
|
|
227
|
-
# Count syncable specs
|
|
228
|
-
SYNCABLE_COUNT=$(echo "$SPEC_PATHS" | grep -v '^$' | wc -l | tr -d ' ')
|
|
229
|
-
|
|
230
|
-
if [ "$SYNCABLE_COUNT" -gt 0 ]; then
|
|
231
|
-
echo "[$(date)] [GitHub] 📋 Syncing $SYNCABLE_COUNT syncable spec(s) (excluding _parent)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
232
|
-
|
|
233
|
-
# Sync each spec
|
|
234
|
-
echo "$SPEC_PATHS" | while read -r SPEC_FILE; do
|
|
235
|
-
if [ -n "$SPEC_FILE" ] && [ -f "$SPEC_FILE" ]; then
|
|
236
|
-
# Extract project and spec ID from path
|
|
237
|
-
SPEC_NAME=$(basename "$SPEC_FILE" .md)
|
|
238
|
-
PROJECT=$(basename "$(dirname "$SPEC_FILE")")
|
|
239
|
-
|
|
240
|
-
echo "[$(date)] [GitHub] 🔄 Syncing $PROJECT/$SPEC_NAME..." >> "$DEBUG_LOG" 2>/dev/null || true
|
|
241
|
-
|
|
242
|
-
(cd "$PROJECT_ROOT" && node "$SYNC_CLI" --spec "$SPEC_FILE" --provider github) 2>&1 | tee -a "$DEBUG_LOG" >/dev/null || {
|
|
243
|
-
echo "[$(date)] [GitHub] ⚠️ Spec sync failed for $PROJECT/$SPEC_NAME (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
echo "[$(date)] [GitHub] ✅ Synced $PROJECT/$SPEC_NAME" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
247
|
-
fi
|
|
248
|
-
done
|
|
249
|
-
|
|
250
|
-
echo "[$(date)] [GitHub] ✅ Multi-spec sync complete ($SYNCABLE_COUNT synced)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
251
|
-
else
|
|
252
|
-
echo "[$(date)] [GitHub] ℹ️ No syncable specs (all specs are _parent or syncEnabled=false)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
253
|
-
fi
|
|
254
|
-
|
|
255
|
-
# Cleanup temp file
|
|
256
|
-
rm -f /tmp/specweave-detected-specs.json 2>/dev/null || true
|
|
257
|
-
else
|
|
258
|
-
# Fallback: Sync all modified specs (check git diff)
|
|
259
|
-
echo "[$(date)] [GitHub] 🔄 Checking for modified specs..." >> "$DEBUG_LOG" 2>/dev/null || true
|
|
260
|
-
|
|
261
|
-
MODIFIED_SPECS=$(git diff --name-only HEAD .specweave/docs/internal/specs/**/*.md 2>/dev/null || echo "")
|
|
262
|
-
|
|
263
|
-
if [ -n "$MODIFIED_SPECS" ]; then
|
|
264
|
-
echo "[$(date)] [GitHub] 📝 Found modified specs:" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
265
|
-
echo "$MODIFIED_SPECS" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
266
|
-
|
|
267
|
-
# Sync each modified spec
|
|
268
|
-
echo "$MODIFIED_SPECS" | while read -r SPEC_FILE; do
|
|
269
|
-
if [ -n "$SPEC_FILE" ] && [ -f "$SPEC_FILE" ]; then
|
|
270
|
-
echo "[$(date)] [GitHub] 🔄 Syncing $SPEC_FILE..." >> "$DEBUG_LOG" 2>/dev/null || true
|
|
271
|
-
(cd "$PROJECT_ROOT" && node "$SYNC_CLI" --spec "$SPEC_FILE" --provider github) 2>&1 | tee -a "$DEBUG_LOG" >/dev/null || true
|
|
272
|
-
fi
|
|
273
|
-
done
|
|
274
|
-
|
|
275
|
-
echo "[$(date)] [GitHub] ✅ Batch spec sync complete" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
276
|
-
else
|
|
277
|
-
echo "[$(date)] [GitHub] ℹ️ No modified specs found, skipping sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
278
|
-
fi
|
|
279
|
-
fi
|
|
280
|
-
|
|
281
|
-
# ============================================================================
|
|
282
|
-
# EPIC GITHUB ISSUE SYNC (DEPRECATED v0.24.0+)
|
|
283
|
-
# ============================================================================
|
|
284
|
-
#
|
|
285
|
-
# ⚠️ DEPRECATED: SpecWeave now syncs ONLY at User Story level.
|
|
286
|
-
#
|
|
287
|
-
# Feature/Epic-level issues are no longer updated.
|
|
288
|
-
# Use /sw-github:sync instead to sync User Story issues.
|
|
289
|
-
#
|
|
290
|
-
# To re-enable (NOT recommended):
|
|
291
|
-
# export SPECWEAVE_ENABLE_EPIC_SYNC=true
|
|
292
|
-
#
|
|
293
|
-
# @see .specweave/increments/0047-us-task-linkage/reports/GITHUB-TITLE-FORMAT-FIX-PLAN.md
|
|
294
|
-
# ============================================================================
|
|
295
|
-
|
|
296
|
-
if [ "$SPECWEAVE_ENABLE_EPIC_SYNC" = "true" ]; then
|
|
297
|
-
echo "[$(date)] [GitHub] 🔄 Checking for Epic GitHub issue update (DEPRECATED)..." >> "$DEBUG_LOG" 2>/dev/null || true
|
|
298
|
-
|
|
299
|
-
# Find active increment ID
|
|
300
|
-
ACTIVE_INCREMENT=$(ls -t .specweave/increments/ | grep -v '^\.' | while read inc; do
|
|
301
|
-
if [ -f ".specweave/increments/$inc/metadata.json" ]; then
|
|
302
|
-
STATUS=$(grep -o '"status"[[:space:]]*:[[:space:]]*"[^"]*"' ".specweave/increments/$inc/metadata.json" 2>/dev/null | sed 's/.*"\([^"]*\)".*/\1/' || true)
|
|
303
|
-
if [ "$STATUS" = "active" ]; then
|
|
304
|
-
echo "$inc"
|
|
305
|
-
break
|
|
306
|
-
fi
|
|
307
|
-
fi
|
|
308
|
-
done | head -1)
|
|
309
|
-
|
|
310
|
-
if [ -n "$ACTIVE_INCREMENT" ]; then
|
|
311
|
-
echo "[$(date)] [GitHub] 🎯 Active increment: $ACTIVE_INCREMENT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
312
|
-
|
|
313
|
-
# Run Epic sync script (silently, errors logged to debug log)
|
|
314
|
-
if [ -f "$PROJECT_ROOT/scripts/update-epic-github-issue.sh" ]; then
|
|
315
|
-
echo "[$(date)] [GitHub] 🚀 Updating Epic GitHub issue (DEPRECATED)..." >> "$DEBUG_LOG" 2>/dev/null || true
|
|
316
|
-
"$PROJECT_ROOT/scripts/update-epic-github-issue.sh" "$ACTIVE_INCREMENT" >> "$DEBUG_LOG" 2>&1 || true
|
|
317
|
-
echo "[$(date)] [GitHub] ⚠️ Epic sync is deprecated. Use /sw-github:sync instead." >> "$DEBUG_LOG" 2>/dev/null || true
|
|
318
|
-
else
|
|
319
|
-
echo "[$(date)] [GitHub] ⚠️ Epic sync script not found, skipping" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
320
|
-
fi
|
|
321
|
-
else
|
|
322
|
-
echo "[$(date)] [GitHub] ℹ️ No active increment found, skipping Epic sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
323
|
-
fi
|
|
324
|
-
else
|
|
325
|
-
echo "[$(date)] [GitHub] ℹ️ Epic sync disabled (sync at User Story level only)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
326
|
-
fi
|
|
327
|
-
|
|
328
|
-
# ============================================================================
|
|
329
|
-
# CIRCUIT BREAKER UPDATE
|
|
330
|
-
# ============================================================================
|
|
331
|
-
# Reset circuit breaker on successful completion (all errors are caught above)
|
|
332
|
-
echo "0" > "$CIRCUIT_BREAKER_FILE" 2>/dev/null || true
|
|
333
|
-
|
|
334
|
-
# ============================================================================
|
|
335
|
-
# OUTPUT TO CLAUDE
|
|
336
|
-
# ============================================================================
|
|
337
|
-
|
|
338
|
-
cat <<EOF
|
|
339
|
-
{
|
|
340
|
-
"continue": true
|
|
341
|
-
}
|
|
342
|
-
EOF
|
|
343
|
-
|
|
344
|
-
# ALWAYS exit 0 - NEVER let hook errors crash Claude Code
|
|
345
|
-
exit 0
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# SpecWeave JIRA Sync Hook
|
|
4
|
-
# Runs after task completion to sync progress to JIRA Issues
|
|
5
|
-
#
|
|
6
|
-
# This hook is part of the specweave-jira plugin and handles:
|
|
7
|
-
# - Syncing task completion state to JIRA issues
|
|
8
|
-
# - Updating JIRA issue status based on increment progress
|
|
9
|
-
#
|
|
10
|
-
# Dependencies:
|
|
11
|
-
# - Node.js for running sync scripts
|
|
12
|
-
# - jq for JSON parsing
|
|
13
|
-
# - metadata.json must have .jira.issue field
|
|
14
|
-
# - JIRA API credentials in .env
|
|
15
|
-
|
|
16
|
-
set +e # EMERGENCY FIX: Prevents Claude Code crashes
|
|
17
|
-
|
|
18
|
-
# EMERGENCY KILL SWITCH
|
|
19
|
-
if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
|
|
20
|
-
exit 0
|
|
21
|
-
fi
|
|
22
|
-
|
|
23
|
-
# ============================================================================
|
|
24
|
-
# PROJECT ROOT DETECTION (CRITICAL - must NOT fallback to pwd!)
|
|
25
|
-
# ============================================================================
|
|
26
|
-
|
|
27
|
-
# Find project root by searching upward for .specweave/ directory
|
|
28
|
-
find_project_root() {
|
|
29
|
-
local dir="$1"
|
|
30
|
-
while [ "$dir" != "/" ]; do
|
|
31
|
-
if [ -f "$dir/.specweave/config.json" ]; then
|
|
32
|
-
echo "$dir"
|
|
33
|
-
return 0
|
|
34
|
-
fi
|
|
35
|
-
dir="$(dirname "$dir")"
|
|
36
|
-
done
|
|
37
|
-
return 1 # NOT FOUND - do NOT fallback to pwd (prevents .specweave pollution)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
PROJECT_ROOT="$(find_project_root "$(pwd)")"
|
|
41
|
-
if [[ -z "$PROJECT_ROOT" ]]; then
|
|
42
|
-
# NOT a SpecWeave project - exit silently without creating any files
|
|
43
|
-
exit 0
|
|
44
|
-
fi
|
|
45
|
-
cd "$PROJECT_ROOT" 2>/dev/null || exit 0
|
|
46
|
-
|
|
47
|
-
# ============================================================================
|
|
48
|
-
# CONFIGURATION
|
|
49
|
-
# ============================================================================
|
|
50
|
-
|
|
51
|
-
LOGS_DIR=".specweave/logs"
|
|
52
|
-
DEBUG_LOG="$LOGS_DIR/hooks-debug.log"
|
|
53
|
-
|
|
54
|
-
mkdir -p "$LOGS_DIR" 2>/dev/null || true
|
|
55
|
-
|
|
56
|
-
# ============================================================================
|
|
57
|
-
# PRECONDITIONS CHECK
|
|
58
|
-
# ============================================================================
|
|
59
|
-
|
|
60
|
-
echo "[$(date)] [JIRA] 🔗 JIRA sync hook fired" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
61
|
-
|
|
62
|
-
# Detect current increment
|
|
63
|
-
CURRENT_INCREMENT=$(ls -td .specweave/increments/*/ 2>/dev/null | xargs -n1 basename | grep -v "_backlog" | grep -v "_archive" | grep -v "_working" | head -1)
|
|
64
|
-
|
|
65
|
-
if [ -z "$CURRENT_INCREMENT" ]; then
|
|
66
|
-
echo "[$(date)] [JIRA] ℹ️ No active increment, skipping JIRA sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
67
|
-
cat <<EOF
|
|
68
|
-
{
|
|
69
|
-
"continue": true
|
|
70
|
-
}
|
|
71
|
-
EOF
|
|
72
|
-
exit 0
|
|
73
|
-
fi
|
|
74
|
-
|
|
75
|
-
# Check for metadata.json
|
|
76
|
-
METADATA_FILE=".specweave/increments/$CURRENT_INCREMENT/metadata.json"
|
|
77
|
-
|
|
78
|
-
if [ ! -f "$METADATA_FILE" ]; then
|
|
79
|
-
echo "[$(date)] [JIRA] ℹ️ No metadata.json for $CURRENT_INCREMENT, skipping JIRA sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
80
|
-
cat <<EOF
|
|
81
|
-
{
|
|
82
|
-
"continue": true
|
|
83
|
-
}
|
|
84
|
-
EOF
|
|
85
|
-
exit 0
|
|
86
|
-
fi
|
|
87
|
-
|
|
88
|
-
# Check for JIRA issue link
|
|
89
|
-
if ! command -v jq &> /dev/null; then
|
|
90
|
-
echo "[$(date)] [JIRA] ⚠️ jq not found, skipping JIRA sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
91
|
-
cat <<EOF
|
|
92
|
-
{
|
|
93
|
-
"continue": true
|
|
94
|
-
}
|
|
95
|
-
EOF
|
|
96
|
-
exit 0
|
|
97
|
-
fi
|
|
98
|
-
|
|
99
|
-
# Read JIRA issue key: canonical path first, then legacy fallbacks
|
|
100
|
-
JIRA_ISSUE=$(jq -r '.external_sync.jira.issueKey // .jira.issueKey // .jira.issue // empty' "$METADATA_FILE" 2>/dev/null)
|
|
101
|
-
|
|
102
|
-
if [ -z "$JIRA_ISSUE" ]; then
|
|
103
|
-
echo "[$(date)] [JIRA] ℹ️ No JIRA issue linked to $CURRENT_INCREMENT, skipping sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
104
|
-
cat <<EOF
|
|
105
|
-
{
|
|
106
|
-
"continue": true
|
|
107
|
-
}
|
|
108
|
-
EOF
|
|
109
|
-
exit 0
|
|
110
|
-
fi
|
|
111
|
-
|
|
112
|
-
# Check for Node.js
|
|
113
|
-
if ! command -v node &> /dev/null; then
|
|
114
|
-
echo "[$(date)] [JIRA] ⚠️ Node.js not found, skipping JIRA sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
115
|
-
cat <<EOF
|
|
116
|
-
{
|
|
117
|
-
"continue": true
|
|
118
|
-
}
|
|
119
|
-
EOF
|
|
120
|
-
exit 0
|
|
121
|
-
fi
|
|
122
|
-
|
|
123
|
-
# Check for JIRA sync script
|
|
124
|
-
if [ ! -f "dist/commands/jira-sync.js" ]; then
|
|
125
|
-
echo "[$(date)] [JIRA] ⚠️ jira-sync.js not found, skipping JIRA sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
126
|
-
cat <<EOF
|
|
127
|
-
{
|
|
128
|
-
"continue": true
|
|
129
|
-
}
|
|
130
|
-
EOF
|
|
131
|
-
exit 0
|
|
132
|
-
fi
|
|
133
|
-
|
|
134
|
-
# ============================================================================
|
|
135
|
-
# JIRA SYNC LOGIC
|
|
136
|
-
# ============================================================================
|
|
137
|
-
|
|
138
|
-
echo "[$(date)] [JIRA] 🔄 Syncing to JIRA issue $JIRA_ISSUE" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
139
|
-
|
|
140
|
-
# Run JIRA sync command (non-blocking)
|
|
141
|
-
node dist/commands/jira-sync.js "$CURRENT_INCREMENT" 2>&1 | tee -a "$DEBUG_LOG" >/dev/null || {
|
|
142
|
-
echo "[$(date)] [JIRA] ⚠️ Failed to sync to JIRA (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
echo "[$(date)] [JIRA] ✅ JIRA sync complete" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
146
|
-
|
|
147
|
-
# ============================================================================
|
|
148
|
-
# SPEC COMMIT SYNC (NEW!)
|
|
149
|
-
# ============================================================================
|
|
150
|
-
|
|
151
|
-
echo "[$(date)] [JIRA] 🔗 Checking for spec commit sync..." >> "$DEBUG_LOG" 2>/dev/null || true
|
|
152
|
-
|
|
153
|
-
# Call TypeScript CLI to sync commits
|
|
154
|
-
if command -v node &> /dev/null && [ -f "$PROJECT_ROOT/dist/cli/commands/sync-spec-commits.js" ]; then
|
|
155
|
-
echo "[$(date)] [JIRA] 🚀 Running spec commit sync..." >> "$DEBUG_LOG" 2>/dev/null || true
|
|
156
|
-
|
|
157
|
-
node "$PROJECT_ROOT/dist/cli/commands/sync-spec-commits.js" \
|
|
158
|
-
--increment "$PROJECT_ROOT/.specweave/increments/$CURRENT_INCREMENT" \
|
|
159
|
-
--provider jira \
|
|
160
|
-
2>&1 | tee -a "$DEBUG_LOG" >/dev/null || {
|
|
161
|
-
echo "[$(date)] [JIRA] ⚠️ Spec commit sync failed (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
echo "[$(date)] [JIRA] ✅ Spec commit sync complete" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
165
|
-
else
|
|
166
|
-
echo "[$(date)] [JIRA] ℹ️ Spec commit sync not available (node or script not found)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
167
|
-
fi
|
|
168
|
-
|
|
169
|
-
# ============================================================================
|
|
170
|
-
# OUTPUT TO CLAUDE
|
|
171
|
-
# ============================================================================
|
|
172
|
-
|
|
173
|
-
cat <<EOF
|
|
174
|
-
{
|
|
175
|
-
"continue": true
|
|
176
|
-
}
|
|
177
|
-
EOF
|
|
178
|
-
|
|
179
|
-
# ALWAYS exit 0 - NEVER let hook errors crash Claude Code
|
|
180
|
-
exit 0
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# check-provider-enabled.sh - Shared provider config detection for SpecWeave hooks
|
|
3
|
-
#
|
|
4
|
-
# Supports ALL 3 config formats:
|
|
5
|
-
# 1. PROFILES: sync.profiles.*.provider == "github" + canUpdateExternalItems
|
|
6
|
-
# 2. LEGACY DIRECT: sync.github.enabled == true
|
|
7
|
-
# 3. LEGACY PROVIDER: sync.provider == "github" + sync.enabled == true
|
|
8
|
-
#
|
|
9
|
-
# Usage:
|
|
10
|
-
# source "path/to/check-provider-enabled.sh"
|
|
11
|
-
# if check_provider_enabled "$CONFIG_PATH" "github"; then
|
|
12
|
-
# echo "GitHub enabled"
|
|
13
|
-
# fi
|
|
14
|
-
#
|
|
15
|
-
# Returns: 0 = enabled, 1 = disabled
|
|
16
|
-
# Reference: github-sync-handler.sh:72-107 (canonical implementation)
|
|
17
|
-
|
|
18
|
-
check_provider_enabled() {
|
|
19
|
-
local config_file="$1"
|
|
20
|
-
local provider="$2"
|
|
21
|
-
|
|
22
|
-
[[ ! -f "$config_file" ]] && return 1
|
|
23
|
-
|
|
24
|
-
# Method 1: PROFILES format (sync.profiles with provider field)
|
|
25
|
-
if grep -q '"profiles"[[:space:]]*:' "$config_file" 2>/dev/null; then
|
|
26
|
-
if grep -q "\"provider\"[[:space:]]*:[[:space:]]*\"$provider\"" "$config_file" 2>/dev/null; then
|
|
27
|
-
# Also check canUpdateExternalItems (required for sync)
|
|
28
|
-
if grep -q '"canUpdateExternalItems"[[:space:]]*:[[:space:]]*true' "$config_file" 2>/dev/null; then
|
|
29
|
-
return 0
|
|
30
|
-
fi
|
|
31
|
-
fi
|
|
32
|
-
fi
|
|
33
|
-
|
|
34
|
-
# Method 2: LEGACY DIRECT (sync.{provider}.enabled: true)
|
|
35
|
-
if grep -q "\"$provider\"[[:space:]]*:" "$config_file" 2>/dev/null; then
|
|
36
|
-
if grep -A5 "\"$provider\"[[:space:]]*:" "$config_file" 2>/dev/null | grep -q '"enabled"[[:space:]]*:[[:space:]]*true'; then
|
|
37
|
-
return 0
|
|
38
|
-
fi
|
|
39
|
-
fi
|
|
40
|
-
|
|
41
|
-
# Method 3: LEGACY PROVIDER (sync.provider: "provider" + sync.enabled: true)
|
|
42
|
-
# Only check if no profiles section (pure legacy config)
|
|
43
|
-
if ! grep -q '"profiles"[[:space:]]*:' "$config_file" 2>/dev/null; then
|
|
44
|
-
if grep -q "\"provider\"[[:space:]]*:[[:space:]]*\"$provider\"" "$config_file" 2>/dev/null; then
|
|
45
|
-
if grep -q '"sync"' "$config_file" && grep -A2 '"sync"' "$config_file" | grep -q '"enabled"[[:space:]]*:[[:space:]]*true'; then
|
|
46
|
-
return 0
|
|
47
|
-
fi
|
|
48
|
-
fi
|
|
49
|
-
fi
|
|
50
|
-
|
|
51
|
-
return 1
|
|
52
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# enqueue.sh - Add event to queue (v1.0.148 - simplified)
|
|
3
|
-
# Usage: enqueue.sh <event_type> <event_data>
|
|
4
|
-
#
|
|
5
|
-
# v1.0.148: Writes to pending.jsonl (processed by stop-sync.sh at session end)
|
|
6
|
-
# Events are coalesced (deduplicated) by type+data hash within 10 second window.
|
|
7
|
-
#
|
|
8
|
-
# IMPORTANT: This script must be fast (<5ms) and never crash
|
|
9
|
-
set +e
|
|
10
|
-
|
|
11
|
-
[[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]] && exit 0
|
|
12
|
-
|
|
13
|
-
EVENT_TYPE="${1:-unknown}"
|
|
14
|
-
EVENT_DATA="${2:-}"
|
|
15
|
-
|
|
16
|
-
# Find project root
|
|
17
|
-
PROJECT_ROOT="$PWD"
|
|
18
|
-
while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
|
|
19
|
-
PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
|
|
20
|
-
done
|
|
21
|
-
[[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
|
|
22
|
-
|
|
23
|
-
QUEUE_DIR="$PROJECT_ROOT/.specweave/state/event-queue"
|
|
24
|
-
PENDING_FILE="$QUEUE_DIR/pending.jsonl"
|
|
25
|
-
mkdir -p "$QUEUE_DIR" 2>/dev/null || exit 0
|
|
26
|
-
|
|
27
|
-
# ============================================================================
|
|
28
|
-
# DEDUPLICATION: Skip if same event within 10s window
|
|
29
|
-
# ============================================================================
|
|
30
|
-
|
|
31
|
-
# Cross-platform md5 (works on macOS, Linux, Windows Git Bash)
|
|
32
|
-
if command -v md5 >/dev/null 2>&1; then
|
|
33
|
-
HASH=$(echo "${EVENT_TYPE}:${EVENT_DATA}" | md5 | cut -c1-8)
|
|
34
|
-
elif command -v md5sum >/dev/null 2>&1; then
|
|
35
|
-
HASH=$(echo "${EVENT_TYPE}:${EVENT_DATA}" | md5sum | cut -c1-8)
|
|
36
|
-
else
|
|
37
|
-
# Fallback: simple hash from type and data
|
|
38
|
-
HASH=$(printf "%s" "${EVENT_TYPE}:${EVENT_DATA}" | cksum | cut -d' ' -f1)
|
|
39
|
-
fi
|
|
40
|
-
|
|
41
|
-
DEDUP_FILE="$QUEUE_DIR/.dedup-$HASH"
|
|
42
|
-
DEDUP_TTL=10 # 10 second deduplication window
|
|
43
|
-
|
|
44
|
-
# Coalescing check: skip if same event within TTL
|
|
45
|
-
if [[ -f "$DEDUP_FILE" ]]; then
|
|
46
|
-
if [[ "$(uname)" == "Darwin" ]]; then
|
|
47
|
-
AGE=$(($(date +%s) - $(stat -f %m "$DEDUP_FILE" 2>/dev/null || echo 0)))
|
|
48
|
-
else
|
|
49
|
-
AGE=$(($(date +%s) - $(stat -c %Y "$DEDUP_FILE" 2>/dev/null || echo 0)))
|
|
50
|
-
fi
|
|
51
|
-
[[ $AGE -lt $DEDUP_TTL ]] && exit 0
|
|
52
|
-
fi
|
|
53
|
-
touch "$DEDUP_FILE"
|
|
54
|
-
|
|
55
|
-
# ============================================================================
|
|
56
|
-
# ENQUEUE: Append to pending.jsonl (atomic via temp file)
|
|
57
|
-
# ============================================================================
|
|
58
|
-
|
|
59
|
-
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date +%Y-%m-%dT%H:%M:%SZ)
|
|
60
|
-
EVENT_JSON="{\"type\":\"$EVENT_TYPE\",\"data\":\"$EVENT_DATA\",\"ts\":\"$TIMESTAMP\",\"hash\":\"$HASH\"}"
|
|
61
|
-
|
|
62
|
-
# Atomic append: write to temp, then append and rename
|
|
63
|
-
# This prevents partial writes if process is killed
|
|
64
|
-
TMP_FILE="$QUEUE_DIR/.pending-$$.tmp"
|
|
65
|
-
{
|
|
66
|
-
[[ -f "$PENDING_FILE" ]] && cat "$PENDING_FILE"
|
|
67
|
-
echo "$EVENT_JSON"
|
|
68
|
-
} > "$TMP_FILE" 2>/dev/null
|
|
69
|
-
|
|
70
|
-
mv "$TMP_FILE" "$PENDING_FILE" 2>/dev/null || {
|
|
71
|
-
# Fallback: direct append (less safe but usually works)
|
|
72
|
-
echo "$EVENT_JSON" >> "$PENDING_FILE" 2>/dev/null
|
|
73
|
-
rm -f "$TMP_FILE" 2>/dev/null
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
# ============================================================================
|
|
77
|
-
# CLEANUP: Remove old dedup files (>1 minute) - non-blocking background
|
|
78
|
-
# ============================================================================
|
|
79
|
-
|
|
80
|
-
find "$QUEUE_DIR" -name ".dedup-*" -mmin +1 -delete 2>/dev/null &
|
|
81
|
-
exit 0
|