specweave 0.23.10 → 0.23.14
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-plugin/marketplace.json +7 -7
- package/CLAUDE.md +384 -1449
- package/dist/src/cli/commands/cleanup-cache.d.ts +14 -0
- package/dist/src/cli/commands/cleanup-cache.d.ts.map +1 -0
- package/dist/src/cli/commands/cleanup-cache.js +63 -0
- package/dist/src/cli/commands/cleanup-cache.js.map +1 -0
- package/dist/src/cli/commands/init.js +40 -0
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/helpers/async-project-loader.d.ts +148 -0
- package/dist/src/cli/helpers/async-project-loader.d.ts.map +1 -0
- package/dist/src/cli/helpers/async-project-loader.js +351 -0
- package/dist/src/cli/helpers/async-project-loader.js.map +1 -0
- package/dist/src/cli/helpers/cancelation-handler.d.ts +123 -0
- package/dist/src/cli/helpers/cancelation-handler.d.ts.map +1 -0
- package/dist/src/cli/helpers/cancelation-handler.js +187 -0
- package/dist/src/cli/helpers/cancelation-handler.js.map +1 -0
- package/dist/src/cli/helpers/import-strategy-prompter.d.ts +43 -0
- package/dist/src/cli/helpers/import-strategy-prompter.d.ts.map +1 -0
- package/dist/src/cli/helpers/import-strategy-prompter.js +136 -0
- package/dist/src/cli/helpers/import-strategy-prompter.js.map +1 -0
- package/dist/src/cli/helpers/issue-tracker/ado.d.ts +5 -2
- package/dist/src/cli/helpers/issue-tracker/ado.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/ado.js +90 -40
- package/dist/src/cli/helpers/issue-tracker/ado.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/jira.d.ts +2 -1
- package/dist/src/cli/helpers/issue-tracker/jira.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/jira.js +120 -35
- package/dist/src/cli/helpers/issue-tracker/jira.js.map +1 -1
- package/dist/src/cli/helpers/progress-tracker.d.ts +121 -0
- package/dist/src/cli/helpers/progress-tracker.d.ts.map +1 -0
- package/dist/src/cli/helpers/progress-tracker.js +202 -0
- package/dist/src/cli/helpers/progress-tracker.js.map +1 -0
- package/dist/src/cli/helpers/project-count-fetcher.d.ts +69 -0
- package/dist/src/cli/helpers/project-count-fetcher.d.ts.map +1 -0
- package/dist/src/cli/helpers/project-count-fetcher.js +173 -0
- package/dist/src/cli/helpers/project-count-fetcher.js.map +1 -0
- package/dist/src/config/types.d.ts +14 -14
- package/dist/src/core/cache/cache-manager.d.ts +119 -0
- package/dist/src/core/cache/cache-manager.d.ts.map +1 -0
- package/dist/src/core/cache/cache-manager.js +304 -0
- package/dist/src/core/cache/cache-manager.js.map +1 -0
- package/dist/src/core/cache/rate-limit-checker.d.ts +92 -0
- package/dist/src/core/cache/rate-limit-checker.d.ts.map +1 -0
- package/dist/src/core/cache/rate-limit-checker.js +160 -0
- package/dist/src/core/cache/rate-limit-checker.js.map +1 -0
- package/dist/src/core/progress/cancelation-handler.d.ts +79 -0
- package/dist/src/core/progress/cancelation-handler.d.ts.map +1 -0
- package/dist/src/core/progress/cancelation-handler.js +111 -0
- package/dist/src/core/progress/cancelation-handler.js.map +1 -0
- package/dist/src/core/progress/error-logger.d.ts +58 -0
- package/dist/src/core/progress/error-logger.d.ts.map +1 -0
- package/dist/src/core/progress/error-logger.js +99 -0
- package/dist/src/core/progress/error-logger.js.map +1 -0
- package/dist/src/core/progress/import-state.d.ts +71 -0
- package/dist/src/core/progress/import-state.d.ts.map +1 -0
- package/dist/src/core/progress/import-state.js +96 -0
- package/dist/src/core/progress/import-state.js.map +1 -0
- package/dist/src/core/progress/progress-tracker.d.ts +139 -0
- package/dist/src/core/progress/progress-tracker.d.ts.map +1 -0
- package/dist/src/core/progress/progress-tracker.js +223 -0
- package/dist/src/core/progress/progress-tracker.js.map +1 -0
- package/dist/src/init/architecture/types.d.ts +6 -6
- package/dist/src/integrations/ado/ado-client.d.ts +25 -0
- package/dist/src/integrations/ado/ado-client.d.ts.map +1 -1
- package/dist/src/integrations/ado/ado-client.js +67 -0
- package/dist/src/integrations/ado/ado-client.js.map +1 -1
- package/dist/src/integrations/ado/ado-dependency-loader.d.ts +99 -0
- package/dist/src/integrations/ado/ado-dependency-loader.d.ts.map +1 -0
- package/dist/src/integrations/ado/ado-dependency-loader.js +207 -0
- package/dist/src/integrations/ado/ado-dependency-loader.js.map +1 -0
- package/dist/src/integrations/jira/jira-client.d.ts +32 -0
- package/dist/src/integrations/jira/jira-client.d.ts.map +1 -1
- package/dist/src/integrations/jira/jira-client.js +81 -0
- package/dist/src/integrations/jira/jira-client.js.map +1 -1
- package/dist/src/integrations/jira/jira-dependency-loader.d.ts +101 -0
- package/dist/src/integrations/jira/jira-dependency-loader.d.ts.map +1 -0
- package/dist/src/integrations/jira/jira-dependency-loader.js +200 -0
- package/dist/src/integrations/jira/jira-dependency-loader.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/.claude-plugin/plugin.json +20 -0
- package/plugins/specweave/agents/architect/AGENT.md +100 -602
- package/plugins/specweave/agents/pm/AGENT.md +96 -597
- package/plugins/specweave/agents/pm/AGENT.md.bak +1893 -0
- package/plugins/specweave/agents/pm/AGENT.md.bak2 +1754 -0
- package/plugins/specweave/commands/check-hooks.md +257 -0
- package/plugins/specweave/hooks/docs-changed.sh +9 -1
- package/plugins/specweave/hooks/docs-changed.sh.backup +79 -0
- package/plugins/specweave/hooks/human-input-required.sh +9 -1
- package/plugins/specweave/hooks/human-input-required.sh.backup +75 -0
- package/plugins/specweave/hooks/post-edit-spec.sh +202 -31
- package/plugins/specweave/hooks/post-first-increment.sh.backup +61 -0
- package/plugins/specweave/hooks/post-increment-change.sh +6 -1
- package/plugins/specweave/hooks/post-increment-change.sh.backup +98 -0
- package/plugins/specweave/hooks/post-increment-completion.sh +6 -1
- package/plugins/specweave/hooks/post-increment-completion.sh.backup +231 -0
- package/plugins/specweave/hooks/post-increment-planning.sh +6 -1
- package/plugins/specweave/hooks/post-increment-planning.sh.backup +1048 -0
- package/plugins/specweave/hooks/post-increment-status-change.sh +6 -1
- package/plugins/specweave/hooks/post-increment-status-change.sh.backup +147 -0
- package/plugins/specweave/hooks/post-metadata-change.sh +7 -1
- package/plugins/specweave/hooks/post-spec-update.sh.backup +158 -0
- package/plugins/specweave/hooks/post-task-completion.sh +225 -228
- package/plugins/specweave/hooks/post-user-story-complete.sh.backup +179 -0
- package/plugins/specweave/hooks/post-write-spec.sh +207 -31
- package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +83 -0
- package/plugins/specweave/hooks/pre-edit-spec.sh +151 -0
- package/plugins/specweave/hooks/pre-implementation.sh +9 -1
- package/plugins/specweave/hooks/pre-implementation.sh.backup +67 -0
- package/plugins/specweave/hooks/pre-task-completion.sh +14 -8
- package/plugins/specweave/hooks/pre-task-completion.sh.backup +194 -0
- package/plugins/specweave/hooks/pre-tool-use.sh +9 -1
- package/plugins/specweave/hooks/pre-tool-use.sh.backup +133 -0
- package/plugins/specweave/hooks/pre-write-spec.sh +151 -0
- package/plugins/specweave/hooks/test-pretooluse-env.sh +72 -0
- package/plugins/specweave/hooks/user-prompt-submit.sh.backup +386 -0
- package/plugins/specweave/skills/compliance-architecture/SKILL.md +374 -0
- package/plugins/specweave/skills/external-sync-wizard/SKILL.md +610 -0
- package/plugins/specweave/skills/pm-closure-validation/SKILL.md +541 -0
- package/plugins/specweave/skills/roadmap-planner/SKILL.md +473 -0
- package/plugins/specweave-ado/commands/refresh-cache.js +25 -0
- package/plugins/specweave-ado/commands/refresh-cache.ts +40 -0
- package/plugins/specweave-ado/hooks/post-living-docs-update.sh +9 -2
- package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +353 -0
- package/plugins/specweave-ado/hooks/post-task-completion.sh +10 -2
- package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-github/hooks/post-task-completion.sh +10 -2
- package/plugins/specweave-github/hooks/post-task-completion.sh.backup +258 -0
- package/plugins/specweave-jira/commands/refresh-cache.js +25 -0
- package/plugins/specweave-jira/commands/refresh-cache.ts +40 -0
- package/plugins/specweave-jira/hooks/post-task-completion.sh +10 -2
- package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-kafka-streams/commands/topology.md +437 -0
- package/plugins/specweave-n8n/commands/workflow-template.md +262 -0
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +252 -6465
- package/plugins/specweave-release/hooks/post-task-completion.sh.backup +110 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# Pre-Edit Hook: Capture File Path BEFORE Edit Executes (Tier 2)
|
|
4
|
+
#
|
|
5
|
+
# Purpose: Detect which file will be edited BEFORE the Edit tool runs
|
|
6
|
+
# Strategy: PreToolUse has better access to tool arguments than PostToolUse
|
|
7
|
+
#
|
|
8
|
+
# TIER 2 COORDINATION:
|
|
9
|
+
# 1. Extract file_path from TOOL_USE_ARGS (more reliable in PreToolUse)
|
|
10
|
+
# 2. If it's spec.md/tasks.md in increments folder, signal PostToolUse hook
|
|
11
|
+
# 3. Write file path to .pending-status-update for PostToolUse to consume
|
|
12
|
+
#
|
|
13
|
+
# This eliminates the need for mtime-based fallback detection (Tier 1)
|
|
14
|
+
# and reduces false positives to near zero.
|
|
15
|
+
#
|
|
16
|
+
# Architecture:
|
|
17
|
+
# PreToolUse:Edit → pre-edit-spec.sh (this file)
|
|
18
|
+
# ↓ writes to
|
|
19
|
+
# .specweave/state/.pending-status-update
|
|
20
|
+
# ↓ read by
|
|
21
|
+
# PostToolUse:Edit → post-edit-spec.sh
|
|
22
|
+
#
|
|
23
|
+
# Version: v0.24.3 (EMERGENCY FIXES)
|
|
24
|
+
# Date: 2025-11-22
|
|
25
|
+
|
|
26
|
+
# EMERGENCY FIX: Remove set -e - it causes Claude Code crashes!
|
|
27
|
+
set +e
|
|
28
|
+
|
|
29
|
+
# EMERGENCY KILL SWITCH: Disable all hooks if env variable set
|
|
30
|
+
if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
|
|
31
|
+
exit 0
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# Find project root
|
|
35
|
+
find_project_root() {
|
|
36
|
+
local dir="$PWD"
|
|
37
|
+
while [[ "$dir" != "/" ]]; do
|
|
38
|
+
if [[ -d "$dir/.specweave" ]]; then
|
|
39
|
+
echo "$dir"
|
|
40
|
+
return 0
|
|
41
|
+
fi
|
|
42
|
+
dir=$(dirname "$dir")
|
|
43
|
+
done
|
|
44
|
+
echo "$PWD"
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
PROJECT_ROOT=$(find_project_root)
|
|
48
|
+
STATE_DIR="$PROJECT_ROOT/.specweave/state"
|
|
49
|
+
LOGS_DIR="$PROJECT_ROOT/.specweave/logs"
|
|
50
|
+
DEBUG_LOG="$LOGS_DIR/hooks-debug.log"
|
|
51
|
+
PENDING_FILE="$STATE_DIR/.pending-status-update"
|
|
52
|
+
METRICS_FILE="$STATE_DIR/hook-metrics.jsonl"
|
|
53
|
+
|
|
54
|
+
# Ensure directories exist
|
|
55
|
+
mkdir -p "$STATE_DIR" "$LOGS_DIR" 2>/dev/null || true
|
|
56
|
+
|
|
57
|
+
# ============================================================================
|
|
58
|
+
# TIER 2: Extract File Path from Tool Arguments
|
|
59
|
+
# ============================================================================
|
|
60
|
+
# PreToolUse should have access to tool arguments BEFORE execution
|
|
61
|
+
# Try multiple methods to extract file_path
|
|
62
|
+
|
|
63
|
+
FILE_PATH=""
|
|
64
|
+
|
|
65
|
+
# Method 1: TOOL_USE_ARGS environment variable (primary for PreToolUse)
|
|
66
|
+
if [[ -n "${TOOL_USE_ARGS:-}" ]]; then
|
|
67
|
+
# Try to parse JSON with jq if available
|
|
68
|
+
if command -v jq &> /dev/null; then
|
|
69
|
+
FILE_PATH=$(echo "$TOOL_USE_ARGS" | jq -r '.file_path // empty' 2>/dev/null || echo "")
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# Fallback: Regex extraction if jq not available or failed
|
|
73
|
+
if [[ -z "$FILE_PATH" ]]; then
|
|
74
|
+
FILE_PATH=$(echo "$TOOL_USE_ARGS" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)".*/\1/' || echo "")
|
|
75
|
+
fi
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
# Method 2: TOOL_USE_CONTENT (fallback)
|
|
79
|
+
if [[ -z "$FILE_PATH" ]] && [[ -n "${TOOL_USE_CONTENT:-}" ]]; then
|
|
80
|
+
FILE_PATH="$TOOL_USE_CONTENT"
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
# Method 3: Parse from stdin (last resort - experimental)
|
|
84
|
+
if [[ -z "$FILE_PATH" ]] && [[ ! -t 0 ]]; then
|
|
85
|
+
# Read stdin and try to extract file_path
|
|
86
|
+
STDIN_DATA=$(cat 2>/dev/null || echo "")
|
|
87
|
+
if [[ -n "$STDIN_DATA" ]] && command -v jq &> /dev/null; then
|
|
88
|
+
FILE_PATH=$(echo "$STDIN_DATA" | jq -r '.file_path // empty' 2>/dev/null || echo "")
|
|
89
|
+
fi
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
# ============================================================================
|
|
93
|
+
# TIER 2: Signal Detection and Validation
|
|
94
|
+
# ============================================================================
|
|
95
|
+
|
|
96
|
+
# Log what we detected (for debugging PreToolUse effectiveness)
|
|
97
|
+
if [[ -n "$FILE_PATH" ]]; then
|
|
98
|
+
echo "[$(date)] pre-edit-spec: Detected file_path: $FILE_PATH" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
99
|
+
else
|
|
100
|
+
echo "[$(date)] pre-edit-spec: No file_path detected (will fall back to Tier 1)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
101
|
+
exit 0 # Let PostToolUse handle it with mtime fallback
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
# Check if this is a spec.md or tasks.md file in increments folder
|
|
105
|
+
IS_SPEC_FILE=false
|
|
106
|
+
if [[ "$FILE_PATH" == *"/spec.md" ]] || [[ "$FILE_PATH" == *"/tasks.md" ]]; then
|
|
107
|
+
if [[ "$FILE_PATH" == *"/.specweave/increments/"* ]]; then
|
|
108
|
+
# Exclude archived increments
|
|
109
|
+
if [[ "$FILE_PATH" != *"/_archive/"* ]]; then
|
|
110
|
+
IS_SPEC_FILE=true
|
|
111
|
+
fi
|
|
112
|
+
fi
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
# If not a spec/tasks file, exit silently (no signal to PostToolUse)
|
|
116
|
+
if [[ "$IS_SPEC_FILE" != "true" ]]; then
|
|
117
|
+
echo "[$(date)] pre-edit-spec: Not a spec/tasks file - no signal" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
118
|
+
exit 0
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
# ============================================================================
|
|
122
|
+
# TIER 2: Write Signal for PostToolUse Hook
|
|
123
|
+
# ============================================================================
|
|
124
|
+
|
|
125
|
+
# Write file path to pending file for PostToolUse to consume
|
|
126
|
+
echo "$FILE_PATH" > "$PENDING_FILE" 2>/dev/null || true
|
|
127
|
+
|
|
128
|
+
echo "[$(date)] pre-edit-spec: Signaled PostToolUse for: $FILE_PATH" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
129
|
+
|
|
130
|
+
# ============================================================================
|
|
131
|
+
# TIER 2: Metrics Collection
|
|
132
|
+
# ============================================================================
|
|
133
|
+
|
|
134
|
+
# Record metrics (JSONL format - one JSON object per line)
|
|
135
|
+
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
136
|
+
METRIC_ENTRY="{\"timestamp\":\"$TIMESTAMP\",\"hook\":\"pre-edit-spec\",\"event\":\"file_detected\",\"file_path\":\"$FILE_PATH\",\"method\":\"TOOL_USE_ARGS\"}"
|
|
137
|
+
|
|
138
|
+
# Append to metrics file (JSONL)
|
|
139
|
+
echo "$METRIC_ENTRY" >> "$METRICS_FILE" 2>/dev/null || true
|
|
140
|
+
|
|
141
|
+
# Log rotation for metrics (keep last 1000 entries)
|
|
142
|
+
if [[ -f "$METRICS_FILE" ]]; then
|
|
143
|
+
LINE_COUNT=$(wc -l < "$METRICS_FILE" 2>/dev/null || echo 0)
|
|
144
|
+
if (( LINE_COUNT > 1000 )); then
|
|
145
|
+
tail -1000 "$METRICS_FILE" > "$METRICS_FILE.tmp" 2>/dev/null || true
|
|
146
|
+
mv "$METRICS_FILE.tmp" "$METRICS_FILE" 2>/dev/null || true
|
|
147
|
+
fi
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
# ALWAYS exit 0 - NEVER let hook errors crash Claude Code
|
|
151
|
+
exit 0
|
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
# Runs before starting implementation of a task
|
|
5
5
|
# Checks regression risk for brownfield projects
|
|
6
6
|
|
|
7
|
-
set
|
|
7
|
+
set +e # EMERGENCY FIX: Prevents Claude Code crashes
|
|
8
|
+
|
|
9
|
+
# EMERGENCY KILL SWITCH
|
|
10
|
+
if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
|
|
11
|
+
exit 0
|
|
12
|
+
fi
|
|
8
13
|
|
|
9
14
|
# Find project root by searching upward for .specweave/ directory
|
|
10
15
|
# Works regardless of where hook is installed (source or .claude/hooks/)
|
|
@@ -65,3 +70,6 @@ echo "[$(date)] Pre-implementation check complete" >> "$LOGS_DIR/hooks.log"
|
|
|
65
70
|
|
|
66
71
|
echo ""
|
|
67
72
|
echo -e "${GREEN}✅ Pre-implementation check complete${NC}"
|
|
73
|
+
|
|
74
|
+
# ALWAYS exit 0 - NEVER let hook errors crash Claude Code
|
|
75
|
+
exit 0
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# SpecWeave Pre-Implementation Hook
|
|
4
|
+
# Runs before starting implementation of a task
|
|
5
|
+
# Checks regression risk for brownfield projects
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
# Find project root by searching upward for .specweave/ directory
|
|
10
|
+
# Works regardless of where hook is installed (source or .claude/hooks/)
|
|
11
|
+
find_project_root() {
|
|
12
|
+
local dir="$1"
|
|
13
|
+
while [ "$dir" != "/" ]; do
|
|
14
|
+
if [ -d "$dir/.specweave" ]; then
|
|
15
|
+
echo "$dir"
|
|
16
|
+
return 0
|
|
17
|
+
fi
|
|
18
|
+
dir="$(dirname "$dir")"
|
|
19
|
+
done
|
|
20
|
+
# Fallback: try current directory
|
|
21
|
+
if [ -d "$(pwd)/.specweave" ]; then
|
|
22
|
+
pwd
|
|
23
|
+
else
|
|
24
|
+
echo "$(pwd)"
|
|
25
|
+
fi
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
|
|
29
|
+
cd "$PROJECT_ROOT"
|
|
30
|
+
|
|
31
|
+
# Colors
|
|
32
|
+
YELLOW='\033[1;33m'
|
|
33
|
+
BLUE='\033[0;34m'
|
|
34
|
+
GREEN='\033[0;32m'
|
|
35
|
+
NC='\033[0m'
|
|
36
|
+
|
|
37
|
+
echo -e "${BLUE}🔍 Pre-Implementation Check${NC}"
|
|
38
|
+
|
|
39
|
+
# Check if this is a brownfield project (has existing code)
|
|
40
|
+
if [ -d "src" ] || [ -d "app" ] || [ -d "lib" ]; then
|
|
41
|
+
echo -e "${YELLOW}⚠️ Brownfield project detected${NC}"
|
|
42
|
+
echo ""
|
|
43
|
+
echo "Recommendations:"
|
|
44
|
+
echo " 1. Create baseline tests before changes"
|
|
45
|
+
echo " 2. Check for existing tests that may break"
|
|
46
|
+
echo " 3. Review impact on existing features"
|
|
47
|
+
echo ""
|
|
48
|
+
|
|
49
|
+
# Check if baseline tests exist
|
|
50
|
+
if [ -d ".specweave/tests/baseline" ]; then
|
|
51
|
+
echo -e "${GREEN}✅ Baseline tests exist${NC}"
|
|
52
|
+
else
|
|
53
|
+
echo -e "${YELLOW}⚠️ No baseline tests found${NC}"
|
|
54
|
+
echo " Consider creating baseline tests first"
|
|
55
|
+
echo " This captures current state before changes"
|
|
56
|
+
fi
|
|
57
|
+
else
|
|
58
|
+
echo -e "${GREEN}✅ Greenfield project - no regression risk${NC}"
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# Log to hooks log
|
|
62
|
+
LOGS_DIR=".specweave/logs"
|
|
63
|
+
mkdir -p "$LOGS_DIR"
|
|
64
|
+
echo "[$(date)] Pre-implementation check complete" >> "$LOGS_DIR/hooks.log"
|
|
65
|
+
|
|
66
|
+
echo ""
|
|
67
|
+
echo -e "${GREEN}✅ Pre-implementation check complete${NC}"
|
|
@@ -20,7 +20,12 @@
|
|
|
20
20
|
# This is the ONLY way to mark tasks complete in SpecWeave.
|
|
21
21
|
# Manual edits to tasks.md are detected and flagged by pre-commit hooks.
|
|
22
22
|
|
|
23
|
-
set
|
|
23
|
+
set +e # EMERGENCY FIX: Prevents Claude Code crashes
|
|
24
|
+
|
|
25
|
+
# EMERGENCY KILL SWITCH
|
|
26
|
+
if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
|
|
27
|
+
exit 0
|
|
28
|
+
fi
|
|
24
29
|
|
|
25
30
|
# Find project root
|
|
26
31
|
find_project_root() {
|
|
@@ -92,15 +97,14 @@ fi
|
|
|
92
97
|
# DETECT CURRENT INCREMENT
|
|
93
98
|
# ============================================================================
|
|
94
99
|
|
|
95
|
-
CURRENT_INCREMENT=$(ls -
|
|
100
|
+
CURRENT_INCREMENT=$(ls -td .specweave/increments/*/ 2>/dev/null | xargs -n1 basename | grep -v "_backlog" | grep -v "_archive" | grep -v "_working" | head -1)
|
|
96
101
|
|
|
97
102
|
if [ -z "$CURRENT_INCREMENT" ]; then
|
|
98
|
-
echo "[$(date)]
|
|
103
|
+
echo "[$(date)] ℹ️ No active increment found, skipping validation" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
99
104
|
rm -f "$STDIN_DATA"
|
|
100
105
|
cat <<EOF
|
|
101
106
|
{
|
|
102
|
-
"continue": true
|
|
103
|
-
"systemMessage": "⚠️ Warning: No active increment found. Task completion validation skipped."
|
|
107
|
+
"continue": true
|
|
104
108
|
}
|
|
105
109
|
EOF
|
|
106
110
|
exit 0
|
|
@@ -109,12 +113,11 @@ fi
|
|
|
109
113
|
TASKS_MD=".specweave/increments/$CURRENT_INCREMENT/tasks.md"
|
|
110
114
|
|
|
111
115
|
if [ ! -f "$TASKS_MD" ]; then
|
|
112
|
-
echo "[$(date)]
|
|
116
|
+
echo "[$(date)] ℹ️ tasks.md not found for $CURRENT_INCREMENT (increment may be in planning stage)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
113
117
|
rm -f "$STDIN_DATA"
|
|
114
118
|
cat <<EOF
|
|
115
119
|
{
|
|
116
|
-
"continue": true
|
|
117
|
-
"systemMessage": "⚠️ Warning: tasks.md not found. Task completion validation skipped."
|
|
120
|
+
"continue": true
|
|
118
121
|
}
|
|
119
122
|
EOF
|
|
120
123
|
exit 0
|
|
@@ -194,3 +197,6 @@ Fix the failing tests and try again. Run tests manually: npm test"
|
|
|
194
197
|
}
|
|
195
198
|
EOF
|
|
196
199
|
fi
|
|
200
|
+
|
|
201
|
+
# ALWAYS exit 0 - NEVER let hook errors crash Claude Code
|
|
202
|
+
exit 0
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# SpecWeave Pre-Task-Completion Hook
|
|
4
|
+
# CRITICAL QUALITY GATE: Validates AC tests before allowing task completion
|
|
5
|
+
#
|
|
6
|
+
# Runs automatically BEFORE any task is marked complete via TodoWrite
|
|
7
|
+
#
|
|
8
|
+
# WORKFLOW:
|
|
9
|
+
# =========
|
|
10
|
+
# 1. TodoWrite called with status="completed"
|
|
11
|
+
# 2. This hook fires (pre-completion validation)
|
|
12
|
+
# 3. Extract task ID from TodoWrite input
|
|
13
|
+
# 4. Find task in tasks.md
|
|
14
|
+
# 5. Run AC test validator
|
|
15
|
+
# 6. If tests PASS → Allow completion (continue: true)
|
|
16
|
+
# 7. If tests FAIL → Block completion (continue: false, show error)
|
|
17
|
+
#
|
|
18
|
+
# ENFORCEMENT:
|
|
19
|
+
# ============
|
|
20
|
+
# This is the ONLY way to mark tasks complete in SpecWeave.
|
|
21
|
+
# Manual edits to tasks.md are detected and flagged by pre-commit hooks.
|
|
22
|
+
|
|
23
|
+
set -e
|
|
24
|
+
|
|
25
|
+
# Find project root
|
|
26
|
+
find_project_root() {
|
|
27
|
+
local dir="$1"
|
|
28
|
+
while [ "$dir" != "/" ]; do
|
|
29
|
+
if [ -d "$dir/.specweave" ]; then
|
|
30
|
+
echo "$dir"
|
|
31
|
+
return 0
|
|
32
|
+
fi
|
|
33
|
+
dir="$(dirname "$dir")"
|
|
34
|
+
done
|
|
35
|
+
pwd
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
|
|
39
|
+
cd "$PROJECT_ROOT" 2>/dev/null || true
|
|
40
|
+
|
|
41
|
+
# ============================================================================
|
|
42
|
+
# CONFIGURATION
|
|
43
|
+
# ============================================================================
|
|
44
|
+
|
|
45
|
+
LOGS_DIR=".specweave/logs"
|
|
46
|
+
DEBUG_LOG="$LOGS_DIR/hooks-debug.log"
|
|
47
|
+
|
|
48
|
+
mkdir -p "$LOGS_DIR" 2>/dev/null || true
|
|
49
|
+
|
|
50
|
+
echo "[$(date)] 🔒 Pre-task-completion hook fired" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
51
|
+
|
|
52
|
+
# ============================================================================
|
|
53
|
+
# CAPTURE INPUT
|
|
54
|
+
# ============================================================================
|
|
55
|
+
|
|
56
|
+
STDIN_DATA=$(mktemp)
|
|
57
|
+
cat > "$STDIN_DATA"
|
|
58
|
+
|
|
59
|
+
echo "[$(date)] Input JSON:" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
60
|
+
cat "$STDIN_DATA" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
61
|
+
|
|
62
|
+
# ============================================================================
|
|
63
|
+
# CHECK FOR TASK COMPLETION
|
|
64
|
+
# ============================================================================
|
|
65
|
+
|
|
66
|
+
# Only validate if a task is being marked complete
|
|
67
|
+
COMPLETING_TASK=false
|
|
68
|
+
|
|
69
|
+
if command -v jq >/dev/null 2>&1; then
|
|
70
|
+
# Check if any task is transitioning to "completed" status
|
|
71
|
+
COMPLETED_COUNT=$(jq -r '.tool_input.todos // [] | map(select(.status == "completed")) | length' "$STDIN_DATA" 2>/dev/null || echo "0")
|
|
72
|
+
|
|
73
|
+
if [ "$COMPLETED_COUNT" != "0" ]; then
|
|
74
|
+
COMPLETING_TASK=true
|
|
75
|
+
echo "[$(date)] ✓ Detected task completion (${COMPLETED_COUNT} tasks)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
76
|
+
fi
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# If no tasks being completed, allow without validation
|
|
80
|
+
if [ "$COMPLETING_TASK" = "false" ]; then
|
|
81
|
+
echo "[$(date)] ⏭️ No tasks being completed, skipping validation" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
82
|
+
rm -f "$STDIN_DATA"
|
|
83
|
+
cat <<EOF
|
|
84
|
+
{
|
|
85
|
+
"continue": true
|
|
86
|
+
}
|
|
87
|
+
EOF
|
|
88
|
+
exit 0
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
# ============================================================================
|
|
92
|
+
# DETECT CURRENT INCREMENT
|
|
93
|
+
# ============================================================================
|
|
94
|
+
|
|
95
|
+
CURRENT_INCREMENT=$(ls -td .specweave/increments/*/ 2>/dev/null | xargs -n1 basename | grep -v "_backlog" | grep -v "_archive" | grep -v "_working" | head -1)
|
|
96
|
+
|
|
97
|
+
if [ -z "$CURRENT_INCREMENT" ]; then
|
|
98
|
+
echo "[$(date)] ℹ️ No active increment found, skipping validation" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
99
|
+
rm -f "$STDIN_DATA"
|
|
100
|
+
cat <<EOF
|
|
101
|
+
{
|
|
102
|
+
"continue": true
|
|
103
|
+
}
|
|
104
|
+
EOF
|
|
105
|
+
exit 0
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
TASKS_MD=".specweave/increments/$CURRENT_INCREMENT/tasks.md"
|
|
109
|
+
|
|
110
|
+
if [ ! -f "$TASKS_MD" ]; then
|
|
111
|
+
echo "[$(date)] ℹ️ tasks.md not found for $CURRENT_INCREMENT (increment may be in planning stage)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
112
|
+
rm -f "$STDIN_DATA"
|
|
113
|
+
cat <<EOF
|
|
114
|
+
{
|
|
115
|
+
"continue": true
|
|
116
|
+
}
|
|
117
|
+
EOF
|
|
118
|
+
exit 0
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
# ============================================================================
|
|
122
|
+
# RUN AC TEST VALIDATION
|
|
123
|
+
# ============================================================================
|
|
124
|
+
|
|
125
|
+
echo "[$(date)] 🧪 Running AC test validation for $CURRENT_INCREMENT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
126
|
+
|
|
127
|
+
# Determine which validation script to use
|
|
128
|
+
VALIDATOR_SCRIPT=""
|
|
129
|
+
if [ -f "$PROJECT_ROOT/dist/src/core/ac-test-validator-cli.js" ]; then
|
|
130
|
+
VALIDATOR_SCRIPT="$PROJECT_ROOT/dist/src/core/ac-test-validator-cli.js"
|
|
131
|
+
elif [ -f "$PROJECT_ROOT/node_modules/specweave/dist/src/core/ac-test-validator-cli.js" ]; then
|
|
132
|
+
VALIDATOR_SCRIPT="$PROJECT_ROOT/node_modules/specweave/dist/src/core/ac-test-validator-cli.js"
|
|
133
|
+
elif [ -n "${CLAUDE_PLUGIN_ROOT}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/dist/src/core/ac-test-validator-cli.js" ]; then
|
|
134
|
+
VALIDATOR_SCRIPT="${CLAUDE_PLUGIN_ROOT}/dist/src/core/ac-test-validator-cli.js"
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
if [ -z "$VALIDATOR_SCRIPT" ] || ! command -v node &> /dev/null; then
|
|
138
|
+
echo "[$(date)] ⚠️ AC test validator not found or Node.js missing" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
139
|
+
rm -f "$STDIN_DATA"
|
|
140
|
+
cat <<EOF
|
|
141
|
+
{
|
|
142
|
+
"continue": true,
|
|
143
|
+
"systemMessage": "⚠️ Warning: AC test validator not available. Task completion validation skipped. Install Node.js and rebuild SpecWeave to enable validation."
|
|
144
|
+
}
|
|
145
|
+
EOF
|
|
146
|
+
exit 0
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
# Run validator (captures exit code)
|
|
150
|
+
VALIDATION_OUTPUT=$(mktemp)
|
|
151
|
+
VALIDATION_EXIT_CODE=0
|
|
152
|
+
|
|
153
|
+
(cd "$PROJECT_ROOT" && node "$VALIDATOR_SCRIPT" "$CURRENT_INCREMENT") > "$VALIDATION_OUTPUT" 2>&1 || VALIDATION_EXIT_CODE=$?
|
|
154
|
+
|
|
155
|
+
echo "[$(date)] Validator exit code: $VALIDATION_EXIT_CODE" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
156
|
+
cat "$VALIDATION_OUTPUT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
157
|
+
|
|
158
|
+
rm -f "$STDIN_DATA"
|
|
159
|
+
|
|
160
|
+
# ============================================================================
|
|
161
|
+
# DECISION LOGIC
|
|
162
|
+
# ============================================================================
|
|
163
|
+
|
|
164
|
+
if [ "$VALIDATION_EXIT_CODE" = "0" ]; then
|
|
165
|
+
# Validation passed - allow completion
|
|
166
|
+
echo "[$(date)] ✅ AC test validation passed" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
167
|
+
|
|
168
|
+
VALIDATION_SUMMARY=$(cat "$VALIDATION_OUTPUT" | tail -5 | tr '\n' ' ')
|
|
169
|
+
|
|
170
|
+
rm -f "$VALIDATION_OUTPUT"
|
|
171
|
+
|
|
172
|
+
cat <<EOF
|
|
173
|
+
{
|
|
174
|
+
"continue": true,
|
|
175
|
+
"systemMessage": "✅ AC Test Validation Passed: All acceptance criteria have passing tests. Task completion allowed. ${VALIDATION_SUMMARY}"
|
|
176
|
+
}
|
|
177
|
+
EOF
|
|
178
|
+
else
|
|
179
|
+
# Validation failed - block completion
|
|
180
|
+
echo "[$(date)] ❌ AC test validation failed" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
181
|
+
|
|
182
|
+
VALIDATION_ERROR=$(cat "$VALIDATION_OUTPUT" | grep -A 10 "VALIDATION FAILED" | tr '\n' ' ' | cut -c 1-300)
|
|
183
|
+
|
|
184
|
+
rm -f "$VALIDATION_OUTPUT"
|
|
185
|
+
|
|
186
|
+
cat <<EOF
|
|
187
|
+
{
|
|
188
|
+
"continue": false,
|
|
189
|
+
"systemMessage": "❌ AC TEST VALIDATION FAILED: Cannot mark task as complete until all acceptance criteria have passing tests. ${VALIDATION_ERROR}
|
|
190
|
+
|
|
191
|
+
Fix the failing tests and try again. Run tests manually: npm test"
|
|
192
|
+
}
|
|
193
|
+
EOF
|
|
194
|
+
fi
|
|
@@ -13,7 +13,12 @@
|
|
|
13
13
|
# - We filter for AskUserQuestion specifically to play sound
|
|
14
14
|
# - Non-blocking and fast (<10ms overhead)
|
|
15
15
|
|
|
16
|
-
set
|
|
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
|
|
17
22
|
|
|
18
23
|
# ============================================================================
|
|
19
24
|
# CONFIGURATION
|
|
@@ -131,3 +136,6 @@ else
|
|
|
131
136
|
}
|
|
132
137
|
EOF
|
|
133
138
|
fi
|
|
139
|
+
|
|
140
|
+
# ALWAYS exit 0 - NEVER let hook errors crash Claude Code
|
|
141
|
+
exit 0
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# SpecWeave Pre-Tool-Use Hook
|
|
4
|
+
# Runs BEFORE Claude calls any tool (PreToolUse event)
|
|
5
|
+
#
|
|
6
|
+
# PURPOSE: Detect when Claude asks questions via AskUserQuestion
|
|
7
|
+
# - Plays sound IMMEDIATELY when question is about to be asked
|
|
8
|
+
# - Complements post-task-completion hook (which only fires after TodoWrite)
|
|
9
|
+
# - Ensures user is always notified when Claude needs input
|
|
10
|
+
#
|
|
11
|
+
# SCOPE:
|
|
12
|
+
# - This hook fires for ALL tool calls (Read, Edit, Write, AskUserQuestion, etc.)
|
|
13
|
+
# - We filter for AskUserQuestion specifically to play sound
|
|
14
|
+
# - Non-blocking and fast (<10ms overhead)
|
|
15
|
+
|
|
16
|
+
set -e
|
|
17
|
+
|
|
18
|
+
# ============================================================================
|
|
19
|
+
# CONFIGURATION
|
|
20
|
+
# ============================================================================
|
|
21
|
+
|
|
22
|
+
# Find project root
|
|
23
|
+
find_project_root() {
|
|
24
|
+
local dir="$1"
|
|
25
|
+
while [ "$dir" != "/" ]; do
|
|
26
|
+
if [ -d "$dir/.specweave" ]; then
|
|
27
|
+
echo "$dir"
|
|
28
|
+
return 0
|
|
29
|
+
fi
|
|
30
|
+
dir="$(dirname "$dir")"
|
|
31
|
+
done
|
|
32
|
+
# Fallback
|
|
33
|
+
if [ -d "$(pwd)/.specweave" ]; then
|
|
34
|
+
pwd
|
|
35
|
+
else
|
|
36
|
+
echo "$(pwd)"
|
|
37
|
+
fi
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
|
|
41
|
+
cd "$PROJECT_ROOT" 2>/dev/null || true
|
|
42
|
+
|
|
43
|
+
LOGS_DIR=".specweave/logs"
|
|
44
|
+
DEBUG_LOG="$LOGS_DIR/hooks-debug.log"
|
|
45
|
+
|
|
46
|
+
mkdir -p "$LOGS_DIR" 2>/dev/null || true
|
|
47
|
+
|
|
48
|
+
# ============================================================================
|
|
49
|
+
# CAPTURE INPUT (Tool Call Details)
|
|
50
|
+
# ============================================================================
|
|
51
|
+
|
|
52
|
+
STDIN_DATA=$(mktemp)
|
|
53
|
+
cat > "$STDIN_DATA"
|
|
54
|
+
|
|
55
|
+
# Log the tool call for debugging
|
|
56
|
+
echo "[$(date)] 🔧 PreToolUse hook fired" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
57
|
+
echo "[$(date)] Tool call JSON:" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
58
|
+
cat "$STDIN_DATA" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
59
|
+
echo "" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
60
|
+
|
|
61
|
+
# ============================================================================
|
|
62
|
+
# DETECT AskUserQuestion TOOL
|
|
63
|
+
# ============================================================================
|
|
64
|
+
|
|
65
|
+
TOOL_NAME=""
|
|
66
|
+
|
|
67
|
+
if command -v jq >/dev/null 2>&1; then
|
|
68
|
+
# Use jq if available (most reliable)
|
|
69
|
+
TOOL_NAME=$(jq -r '.tool_name // empty' "$STDIN_DATA" 2>/dev/null)
|
|
70
|
+
else
|
|
71
|
+
# Fallback: grep-based detection
|
|
72
|
+
if grep -q '"tool_name"' "$STDIN_DATA" 2>/dev/null; then
|
|
73
|
+
TOOL_NAME=$(grep -o '"tool_name":"[^"]*"' "$STDIN_DATA" | cut -d'"' -f4)
|
|
74
|
+
fi
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
echo "[$(date)] Tool name: $TOOL_NAME" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
78
|
+
|
|
79
|
+
# ============================================================================
|
|
80
|
+
# PLAY SOUND IF AskUserQuestion
|
|
81
|
+
# ============================================================================
|
|
82
|
+
|
|
83
|
+
play_sound() {
|
|
84
|
+
case "$(uname -s)" in
|
|
85
|
+
Darwin)
|
|
86
|
+
# macOS: Use afplay with a distinctive sound for questions
|
|
87
|
+
afplay /System/Library/Sounds/Tink.aiff 2>/dev/null || true
|
|
88
|
+
;;
|
|
89
|
+
Linux)
|
|
90
|
+
# Linux: Use paplay or aplay
|
|
91
|
+
paplay /usr/share/sounds/freedesktop/stereo/dialog-question.oga 2>/dev/null || \
|
|
92
|
+
paplay /usr/share/sounds/freedesktop/stereo/message-new-instant.oga 2>/dev/null || \
|
|
93
|
+
aplay /usr/share/sounds/alsa/Front_Center.wav 2>/dev/null || true
|
|
94
|
+
;;
|
|
95
|
+
MINGW*|MSYS*|CYGWIN*)
|
|
96
|
+
# Windows: Use PowerShell
|
|
97
|
+
powershell -c "(New-Object Media.SoundPlayer 'C:\Windows\Media\Windows Notify.wav').PlaySync();" 2>/dev/null || true
|
|
98
|
+
;;
|
|
99
|
+
esac
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if [ "$TOOL_NAME" = "AskUserQuestion" ]; then
|
|
103
|
+
echo "[$(date)] 🔔 QUESTION DETECTED! Playing notification sound" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
104
|
+
play_sound
|
|
105
|
+
|
|
106
|
+
# Log this event
|
|
107
|
+
echo "[$(date)] Claude is asking for user input via AskUserQuestion" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
# ============================================================================
|
|
111
|
+
# CLEANUP
|
|
112
|
+
# ============================================================================
|
|
113
|
+
|
|
114
|
+
rm -f "$STDIN_DATA"
|
|
115
|
+
|
|
116
|
+
# ============================================================================
|
|
117
|
+
# OUTPUT TO CLAUDE (Always continue)
|
|
118
|
+
# ============================================================================
|
|
119
|
+
|
|
120
|
+
if [ "$TOOL_NAME" = "AskUserQuestion" ]; then
|
|
121
|
+
cat <<EOF
|
|
122
|
+
{
|
|
123
|
+
"continue": true,
|
|
124
|
+
"systemMessage": "🔔 Sound played - user notified of question request"
|
|
125
|
+
}
|
|
126
|
+
EOF
|
|
127
|
+
else
|
|
128
|
+
cat <<EOF
|
|
129
|
+
{
|
|
130
|
+
"continue": true
|
|
131
|
+
}
|
|
132
|
+
EOF
|
|
133
|
+
fi
|