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,447 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# post-tool-use.sh - Single dispatcher for ALL PostToolUse events
|
|
3
|
-
#
|
|
4
|
-
# v1.0.148+: NEW ARCHITECTURE - No background processor
|
|
5
|
-
#
|
|
6
|
-
# CRITICAL DESIGN PRINCIPLE:
|
|
7
|
-
# - Tool operations ALWAYS succeed (Edit/Write never blocked by hooks)
|
|
8
|
-
# - All hook errors become visible warnings to user
|
|
9
|
-
# - Logs captured for debugging
|
|
10
|
-
# - Background processes for heavy work
|
|
11
|
-
#
|
|
12
|
-
# Architecture (v1.0.148 - Simplified):
|
|
13
|
-
# - Detectors run asynchronously (don't block tool results)
|
|
14
|
-
# - CRITICAL events (increment.done/reopened) sync IMMEDIATELY
|
|
15
|
-
# - Other events queued to pending.jsonl for stop-sync.sh (session end)
|
|
16
|
-
# - NO background processor daemon
|
|
17
|
-
#
|
|
18
|
-
# Event flow:
|
|
19
|
-
# 1. metadata.json change -> lifecycle-detector -> increment.* events
|
|
20
|
-
# - IF done/reopened: IMMEDIATE sync via project-bridge-handler
|
|
21
|
-
# - ELSE: queued for stop-sync.sh
|
|
22
|
-
# 2. tasks.md/spec.md change -> queued for stop-sync.sh (batched at session end)
|
|
23
|
-
#
|
|
24
|
-
# Goal: Never crash Claude, always exit 0, warn on errors
|
|
25
|
-
|
|
26
|
-
set +e # CRITICAL: Never exit on error
|
|
27
|
-
|
|
28
|
-
[[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]] && exit 0
|
|
29
|
-
|
|
30
|
-
# ============================================================================
|
|
31
|
-
# CONSTANTS
|
|
32
|
-
# ============================================================================
|
|
33
|
-
|
|
34
|
-
HOOK_NAME="post-tool-use"
|
|
35
|
-
HOOK_VERSION="1.0.148"
|
|
36
|
-
|
|
37
|
-
# ============================================================================
|
|
38
|
-
# PROJECT ROOT DETECTION
|
|
39
|
-
# ============================================================================
|
|
40
|
-
|
|
41
|
-
PROJECT_ROOT="$PWD"
|
|
42
|
-
while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
|
|
43
|
-
PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
|
|
44
|
-
done
|
|
45
|
-
[[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
|
|
46
|
-
|
|
47
|
-
STATE_DIR="$PROJECT_ROOT/.specweave/state"
|
|
48
|
-
|
|
49
|
-
# ============================================================================
|
|
50
|
-
# LOGGING INFRASTRUCTURE
|
|
51
|
-
# ============================================================================
|
|
52
|
-
|
|
53
|
-
LOGS_DIR="$PROJECT_ROOT/.specweave/logs"
|
|
54
|
-
DEBUG_LOG="$LOGS_DIR/post-tool-use.log"
|
|
55
|
-
WARNING_LOG="$LOGS_DIR/hook-warnings.log"
|
|
56
|
-
mkdir -p "$LOGS_DIR" 2>/dev/null || true
|
|
57
|
-
|
|
58
|
-
log_debug() {
|
|
59
|
-
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$HOOK_NAME] $*" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
log_warning() {
|
|
63
|
-
local message="$1"
|
|
64
|
-
local details="${2:-}"
|
|
65
|
-
|
|
66
|
-
# Always log to file
|
|
67
|
-
{
|
|
68
|
-
echo "[$(date '+%Y-%m-%d %H:%M:%S')] WARNING [$HOOK_NAME]: $message"
|
|
69
|
-
[[ -n "$details" ]] && echo " Details: $details"
|
|
70
|
-
} >> "$WARNING_LOG" 2>/dev/null || true
|
|
71
|
-
|
|
72
|
-
# Show to user so they know something went wrong
|
|
73
|
-
echo ""
|
|
74
|
-
echo " [Hook Warning] $HOOK_NAME: $message"
|
|
75
|
-
[[ -n "$details" ]] && echo " $details"
|
|
76
|
-
echo " (Tool operation succeeded - hook issue only)"
|
|
77
|
-
echo ""
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
# ============================================================================
|
|
81
|
-
# SAFE EXECUTION HELPERS
|
|
82
|
-
# ============================================================================
|
|
83
|
-
|
|
84
|
-
# Run a hook script safely in background (never blocks, logs errors)
|
|
85
|
-
safe_run_background() {
|
|
86
|
-
local script="$1"
|
|
87
|
-
local context="$2"
|
|
88
|
-
shift 2
|
|
89
|
-
|
|
90
|
-
if [[ ! -f "$script" ]]; then
|
|
91
|
-
log_debug "Script not found (skipping): $script"
|
|
92
|
-
return 0
|
|
93
|
-
fi
|
|
94
|
-
|
|
95
|
-
if [[ ! -x "$script" ]] && [[ ! "$script" == *.sh ]]; then
|
|
96
|
-
log_debug "Script not executable (skipping): $script"
|
|
97
|
-
return 0
|
|
98
|
-
fi
|
|
99
|
-
|
|
100
|
-
# Run in background, capture errors to log
|
|
101
|
-
(
|
|
102
|
-
set +e
|
|
103
|
-
local output
|
|
104
|
-
local exit_code
|
|
105
|
-
|
|
106
|
-
output=$(bash "$script" "$@" 2>&1)
|
|
107
|
-
exit_code=$?
|
|
108
|
-
|
|
109
|
-
if [[ $exit_code -ne 0 ]]; then
|
|
110
|
-
echo "[$(date '+%Y-%m-%d %H:%M:%S')] BACKGROUND ERROR [$context]: exit $exit_code" >> "$WARNING_LOG" 2>/dev/null || true
|
|
111
|
-
echo " Output: $output" >> "$WARNING_LOG" 2>/dev/null || true
|
|
112
|
-
fi
|
|
113
|
-
) &
|
|
114
|
-
|
|
115
|
-
return 0
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
# Run a hook script safely in foreground (for sync guards)
|
|
119
|
-
safe_run_sync() {
|
|
120
|
-
local script="$1"
|
|
121
|
-
local context="$2"
|
|
122
|
-
local input="$3"
|
|
123
|
-
|
|
124
|
-
if [[ ! -f "$script" ]]; then
|
|
125
|
-
log_debug "Script not found (skipping): $script"
|
|
126
|
-
return 0
|
|
127
|
-
fi
|
|
128
|
-
|
|
129
|
-
local output
|
|
130
|
-
local exit_code
|
|
131
|
-
|
|
132
|
-
# Run with timeout protection (5 second max)
|
|
133
|
-
if command -v gtimeout >/dev/null 2>&1; then
|
|
134
|
-
output=$(echo "$input" | gtimeout --kill-after=2 5 bash "$script" 2>&1)
|
|
135
|
-
exit_code=$?
|
|
136
|
-
elif command -v timeout >/dev/null 2>&1; then
|
|
137
|
-
output=$(echo "$input" | timeout --kill-after=2 5 bash "$script" 2>&1)
|
|
138
|
-
exit_code=$?
|
|
139
|
-
else
|
|
140
|
-
output=$(echo "$input" | bash "$script" 2>&1)
|
|
141
|
-
exit_code=$?
|
|
142
|
-
fi
|
|
143
|
-
|
|
144
|
-
# Log errors but don't fail
|
|
145
|
-
if [[ $exit_code -ne 0 ]]; then
|
|
146
|
-
if [[ $exit_code -eq 124 ]] || [[ $exit_code -eq 137 ]]; then
|
|
147
|
-
log_warning "Hook timed out: $context" "Script: $script"
|
|
148
|
-
else
|
|
149
|
-
log_debug "Hook exited with code $exit_code: $context"
|
|
150
|
-
fi
|
|
151
|
-
fi
|
|
152
|
-
|
|
153
|
-
# Output any non-error output (for status messages, etc.)
|
|
154
|
-
if [[ -n "$output" ]] && [[ "$output" != *"ERROR"* ]] && [[ "$output" != *"error"* ]]; then
|
|
155
|
-
echo "$output"
|
|
156
|
-
fi
|
|
157
|
-
|
|
158
|
-
return 0 # Always succeed
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
# ============================================================================
|
|
162
|
-
# TASK COMPLETION SOUND (plays when task marked [x])
|
|
163
|
-
# ============================================================================
|
|
164
|
-
|
|
165
|
-
play_task_completion_sound() {
|
|
166
|
-
local tasks_file="$1"
|
|
167
|
-
local state_file="$STATE_DIR/.last-task-completion"
|
|
168
|
-
local session_file="$STATE_DIR/auto-mode.json"
|
|
169
|
-
|
|
170
|
-
# DISABLED: Sound notifications are disabled by default
|
|
171
|
-
# To re-enable, set SPECWEAVE_SOUND_ENABLED=1 in environment
|
|
172
|
-
if [[ "${SPECWEAVE_SOUND_ENABLED:-0}" != "1" ]]; then
|
|
173
|
-
log_debug "Sound disabled (set SPECWEAVE_SOUND_ENABLED=1 to enable)"
|
|
174
|
-
return 0
|
|
175
|
-
fi
|
|
176
|
-
|
|
177
|
-
# CRITICAL: Skip sound if auto mode is active
|
|
178
|
-
# Auto mode has its own completion sound via Stop hook (plays once at END)
|
|
179
|
-
if [[ -f "$session_file" ]]; then
|
|
180
|
-
local auto_status=$(jq -r '.status // "unknown"' "$session_file" 2>/dev/null || echo "unknown")
|
|
181
|
-
if [[ "$auto_status" == "active" ]] || [[ "$auto_status" == "running" ]]; then
|
|
182
|
-
log_debug "Auto mode active - skipping task completion sound (Stop hook will handle it)"
|
|
183
|
-
return 0
|
|
184
|
-
fi
|
|
185
|
-
fi
|
|
186
|
-
|
|
187
|
-
# Extract current completion count
|
|
188
|
-
local current_count=$(grep -c '\*\*Status\*\*:.*\[x\]' "$tasks_file" 2>/dev/null || echo "0")
|
|
189
|
-
|
|
190
|
-
# Read previous count
|
|
191
|
-
local previous_count="0"
|
|
192
|
-
if [[ -f "$state_file" ]]; then
|
|
193
|
-
previous_count=$(cat "$state_file" 2>/dev/null || echo "0")
|
|
194
|
-
fi
|
|
195
|
-
|
|
196
|
-
# If count increased, a task was just completed
|
|
197
|
-
if [[ "$current_count" -gt "$previous_count" ]]; then
|
|
198
|
-
# Save new count
|
|
199
|
-
echo "$current_count" > "$state_file" 2>/dev/null
|
|
200
|
-
|
|
201
|
-
# Play completion sound (background, never blocks)
|
|
202
|
-
(
|
|
203
|
-
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
204
|
-
# macOS - use Glass.aiff for pleasant completion sound
|
|
205
|
-
afplay /System/Library/Sounds/Glass.aiff 2>/dev/null &
|
|
206
|
-
elif command -v paplay >/dev/null 2>&1; then
|
|
207
|
-
# Linux with PulseAudio
|
|
208
|
-
paplay /usr/share/sounds/freedesktop/stereo/complete.oga 2>/dev/null &
|
|
209
|
-
elif command -v aplay >/dev/null 2>&1; then
|
|
210
|
-
# Linux with ALSA
|
|
211
|
-
aplay /usr/share/sounds/alsa/Front_Center.wav 2>/dev/null &
|
|
212
|
-
fi
|
|
213
|
-
) &
|
|
214
|
-
|
|
215
|
-
log_debug "Task completion sound played (count: $previous_count → $current_count)"
|
|
216
|
-
fi
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
# ============================================================================
|
|
220
|
-
# INPUT PARSING (with safe fallbacks)
|
|
221
|
-
# ============================================================================
|
|
222
|
-
|
|
223
|
-
# Read stdin (tool result JSON) - with safe fallback and timeout
|
|
224
|
-
INPUT=""
|
|
225
|
-
if command -v gtimeout >/dev/null 2>&1; then
|
|
226
|
-
INPUT=$(gtimeout 1 cat 2>/dev/null || echo '{}')
|
|
227
|
-
elif command -v timeout >/dev/null 2>&1; then
|
|
228
|
-
INPUT=$(timeout 1 cat 2>/dev/null || echo '{}')
|
|
229
|
-
else
|
|
230
|
-
INPUT=$(cat 2>/dev/null || echo '{}')
|
|
231
|
-
fi
|
|
232
|
-
|
|
233
|
-
# Extract file path (fast grep, no jq required)
|
|
234
|
-
FILE_PATH=$(echo "$INPUT" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)".*/\1/')
|
|
235
|
-
[[ -z "$FILE_PATH" ]] && exit 0
|
|
236
|
-
|
|
237
|
-
# Extract increment ID from path
|
|
238
|
-
INC_ID=$(echo "$FILE_PATH" | grep -o '[0-9][0-9][0-9][0-9]-[^/]*' | head -1)
|
|
239
|
-
[[ -z "$INC_ID" ]] && exit 0
|
|
240
|
-
|
|
241
|
-
log_debug "Processing: $FILE_PATH (increment: $INC_ID)"
|
|
242
|
-
|
|
243
|
-
# ============================================================================
|
|
244
|
-
# SETUP PATHS
|
|
245
|
-
# ============================================================================
|
|
246
|
-
|
|
247
|
-
# Script is at: hooks/v2/dispatchers/post-tool-use.sh
|
|
248
|
-
# HOOK_DIR should be: hooks/v2 (one level up from dispatchers)
|
|
249
|
-
# PLUGIN_ROOT should be: plugin root (TWO levels up from hooks/v2)
|
|
250
|
-
HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
251
|
-
PLUGIN_ROOT="$(cd "$HOOK_DIR/../.." && pwd)"
|
|
252
|
-
DETECTOR_DIR="$HOOK_DIR/detectors"
|
|
253
|
-
SCRIPTS_DIR="$PLUGIN_ROOT/scripts"
|
|
254
|
-
|
|
255
|
-
# ============================================================================
|
|
256
|
-
# EDA DISPATCHER: Route to detectors based on file type
|
|
257
|
-
# All errors become warnings, never block the tool operation
|
|
258
|
-
# ============================================================================
|
|
259
|
-
|
|
260
|
-
case "$FILE_PATH" in
|
|
261
|
-
*/.specweave/increments/*/metadata.json)
|
|
262
|
-
log_debug "Metadata change detected"
|
|
263
|
-
|
|
264
|
-
# Metadata changed -> check for lifecycle transitions (background)
|
|
265
|
-
safe_run_background "$DETECTOR_DIR/lifecycle-detector.sh" "lifecycle-detector" "$INC_ID"
|
|
266
|
-
|
|
267
|
-
# Update dashboard cache (background)
|
|
268
|
-
safe_run_background "$SCRIPTS_DIR/update-dashboard-cache.sh" "dashboard-cache" "$INC_ID" "metadata"
|
|
269
|
-
|
|
270
|
-
# ========================================================================
|
|
271
|
-
# IMMEDIATE EXTERNAL SYNC for done/reopened (v1.0.148)
|
|
272
|
-
# ========================================================================
|
|
273
|
-
# Critical events sync IMMEDIATELY - user expects external tools updated
|
|
274
|
-
# Other events batched for session end (stop-sync.sh)
|
|
275
|
-
METADATA_FILE="$PROJECT_ROOT/.specweave/increments/$INC_ID/metadata.json"
|
|
276
|
-
if [[ -f "$METADATA_FILE" ]]; then
|
|
277
|
-
CURRENT_STATUS=$(grep -o '"status"[[:space:]]*:[[:space:]]*"[^"]*"' "$METADATA_FILE" | head -1 | sed 's/.*"\([^"]*\)".*/\1/')
|
|
278
|
-
|
|
279
|
-
if [[ "$CURRENT_STATUS" == "completed" ]] || [[ "$CURRENT_STATUS" == "done" ]] || [[ "$CURRENT_STATUS" == "reopened" ]]; then
|
|
280
|
-
log_debug "IMMEDIATE SYNC: Status is $CURRENT_STATUS - syncing to external tools"
|
|
281
|
-
|
|
282
|
-
# ====================================================================
|
|
283
|
-
# SYNC MODE CHECK (0618): queued vs immediate
|
|
284
|
-
# ====================================================================
|
|
285
|
-
SYNC_CONFIG_PATH="$PROJECT_ROOT/.specweave/config.json"
|
|
286
|
-
SYNC_MODE="queued"
|
|
287
|
-
if command -v jq >/dev/null 2>&1 && [[ -f "$SYNC_CONFIG_PATH" ]]; then
|
|
288
|
-
SYNC_MODE=$(jq -r '.sync.mode // "queued"' "$SYNC_CONFIG_PATH" 2>/dev/null || echo "queued")
|
|
289
|
-
fi
|
|
290
|
-
|
|
291
|
-
if [[ "$SYNC_MODE" == "queued" ]]; then
|
|
292
|
-
# Queue event to pending.jsonl instead of direct sync
|
|
293
|
-
QUEUE_DIR="$PROJECT_ROOT/.specweave/state/event-queue"
|
|
294
|
-
mkdir -p "$QUEUE_DIR" 2>/dev/null || true
|
|
295
|
-
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
296
|
-
echo "{\"incrementId\":\"$INC_ID\",\"eventType\":\"status.changed\",\"metadata\":{\"newStatus\":\"$CURRENT_STATUS\"},\"timestamp\":\"$TIMESTAMP\"}" >> "$QUEUE_DIR/pending.jsonl"
|
|
297
|
-
log_debug "QUEUED SYNC: Event queued for $INC_ID (status.changed -> $CURRENT_STATUS)"
|
|
298
|
-
else
|
|
299
|
-
# IMMEDIATE MODE (legacy): direct sync calls
|
|
300
|
-
|
|
301
|
-
# Map raw status to canonical event name (consistent with lifecycle-detector)
|
|
302
|
-
case "$CURRENT_STATUS" in
|
|
303
|
-
completed|done) BRIDGE_EVENT="increment.done" ;;
|
|
304
|
-
reopened) BRIDGE_EVENT="increment.reopened" ;;
|
|
305
|
-
*) BRIDGE_EVENT="increment.$CURRENT_STATUS" ;;
|
|
306
|
-
esac
|
|
307
|
-
|
|
308
|
-
BRIDGE_HANDLER="$HOOK_DIR/handlers/project-bridge-handler.sh"
|
|
309
|
-
if [[ -f "$BRIDGE_HANDLER" ]]; then
|
|
310
|
-
# Run synchronously but with timeout to not block too long
|
|
311
|
-
(
|
|
312
|
-
if command -v gtimeout >/dev/null 2>&1; then
|
|
313
|
-
gtimeout 15 bash "$BRIDGE_HANDLER" "$BRIDGE_EVENT" "$INC_ID" 2>/dev/null || true
|
|
314
|
-
elif command -v timeout >/dev/null 2>&1; then
|
|
315
|
-
timeout 15 bash "$BRIDGE_HANDLER" "$BRIDGE_EVENT" "$INC_ID" 2>/dev/null || true
|
|
316
|
-
else
|
|
317
|
-
bash "$BRIDGE_HANDLER" "$BRIDGE_EVENT" "$INC_ID" 2>/dev/null || true
|
|
318
|
-
fi
|
|
319
|
-
)
|
|
320
|
-
log_debug "IMMEDIATE SYNC completed for $INC_ID"
|
|
321
|
-
fi
|
|
322
|
-
|
|
323
|
-
# ========================================================================
|
|
324
|
-
# EXPLICIT CLOSURE (v1.0.257+): Close external issues on completion
|
|
325
|
-
# ========================================================================
|
|
326
|
-
# Only on completed/done - triggers provider-agnostic closure for ALL
|
|
327
|
-
# user stories, ensuring external issues are closed even if AC sync
|
|
328
|
-
# missed them. NOT called on reopened or on every AC change.
|
|
329
|
-
if [[ "$CURRENT_STATUS" == "completed" ]] || [[ "$CURRENT_STATUS" == "done" ]]; then
|
|
330
|
-
AC_CLOSE_DISPATCHER="${HOOK_DIR}/handlers/ac-sync-dispatcher.sh"
|
|
331
|
-
if [[ -f "$AC_CLOSE_DISPATCHER" ]]; then
|
|
332
|
-
log_debug "EXPLICIT CLOSURE: Triggering provider-agnostic closure for $INC_ID"
|
|
333
|
-
SPECWEAVE_CLOSE_ALL=1 safe_run_background "$AC_CLOSE_DISPATCHER" "ac-close" "$INC_ID"
|
|
334
|
-
fi
|
|
335
|
-
fi
|
|
336
|
-
fi
|
|
337
|
-
fi
|
|
338
|
-
fi
|
|
339
|
-
;;
|
|
340
|
-
|
|
341
|
-
*/.specweave/increments/*/tasks.md|*/.specweave/increments/*/spec.md)
|
|
342
|
-
log_debug "Tasks/spec change detected"
|
|
343
|
-
|
|
344
|
-
# ========================================================================
|
|
345
|
-
# TASK-AC SYNC (v0.35.2+): Sync task completion to spec.md ACs
|
|
346
|
-
# ========================================================================
|
|
347
|
-
# When tasks.md is edited, sync completed task ACs to spec.md
|
|
348
|
-
# Runs in BACKGROUND (non-blocking) — FILE_PATH passed as $1 argument
|
|
349
|
-
if [[ "$FILE_PATH" == *tasks.md ]]; then
|
|
350
|
-
SYNC_SCRIPT="$HOOK_DIR/guards/task-ac-sync-guard.sh"
|
|
351
|
-
if [[ -f "$SYNC_SCRIPT" ]]; then
|
|
352
|
-
log_debug "Running task-ac-sync guard (background)"
|
|
353
|
-
safe_run_background "$SYNC_SCRIPT" "task-ac-sync" "$FILE_PATH"
|
|
354
|
-
fi
|
|
355
|
-
|
|
356
|
-
# ========================================================================
|
|
357
|
-
# PROVIDER-AGNOSTIC AC SYNC (v1.0.255+): Sync progress to all providers
|
|
358
|
-
# ========================================================================
|
|
359
|
-
AC_SYNC_DISPATCHER="${HOOK_DIR}/handlers/ac-sync-dispatcher.sh"
|
|
360
|
-
if [[ -f "$AC_SYNC_DISPATCHER" ]]; then
|
|
361
|
-
safe_run_background "$AC_SYNC_DISPATCHER" "ac-sync" "$INC_ID"
|
|
362
|
-
fi
|
|
363
|
-
|
|
364
|
-
# ========================================================================
|
|
365
|
-
# TDD ENFORCEMENT (v1.0.160+): Enforce TDD discipline
|
|
366
|
-
# ========================================================================
|
|
367
|
-
# When tasks.md is edited in TDD mode, check for violations
|
|
368
|
-
# v1.0.160: In STRICT mode, runs synchronously and shows blocking warning
|
|
369
|
-
TDD_GUARD="$HOOK_DIR/guards/tdd-enforcement-guard.sh"
|
|
370
|
-
if [[ -f "$TDD_GUARD" ]]; then
|
|
371
|
-
# Check if strict TDD enforcement is enabled
|
|
372
|
-
TDD_STRICT=false
|
|
373
|
-
CONFIG_FILE="$PROJECT_ROOT/.specweave/config.json"
|
|
374
|
-
if [[ -f "$CONFIG_FILE" ]] && command -v jq >/dev/null 2>&1; then
|
|
375
|
-
TDD_ENFORCEMENT=$(jq -r '.testing.tddEnforcement // "warn"' "$CONFIG_FILE" 2>/dev/null)
|
|
376
|
-
[[ "$TDD_ENFORCEMENT" == "strict" ]] && TDD_STRICT=true
|
|
377
|
-
fi
|
|
378
|
-
|
|
379
|
-
if [[ "$TDD_STRICT" == "true" ]]; then
|
|
380
|
-
log_debug "Running TDD enforcement guard (STRICT - synchronous)"
|
|
381
|
-
# Run synchronously and capture output for strict mode
|
|
382
|
-
TDD_OUTPUT=$(bash "$TDD_GUARD" "$PROJECT_ROOT" "$FILE_PATH" "Edit" 2>&1)
|
|
383
|
-
TDD_EXIT=$?
|
|
384
|
-
if [[ $TDD_EXIT -ne 0 ]]; then
|
|
385
|
-
# Show blocking warning to user
|
|
386
|
-
echo ""
|
|
387
|
-
echo " ⚠️ TDD STRICT MODE VIOLATION DETECTED"
|
|
388
|
-
echo "$TDD_OUTPUT" | head -20
|
|
389
|
-
echo ""
|
|
390
|
-
log_debug "TDD violation detected (exit code: $TDD_EXIT)"
|
|
391
|
-
fi
|
|
392
|
-
else
|
|
393
|
-
log_debug "Running TDD enforcement guard (warn mode - background)"
|
|
394
|
-
safe_run_background "$TDD_GUARD" "tdd-enforcement" "$PROJECT_ROOT" "$FILE_PATH" "Edit"
|
|
395
|
-
fi
|
|
396
|
-
fi
|
|
397
|
-
|
|
398
|
-
# Play completion sound if task was marked complete (v1.0.77+)
|
|
399
|
-
play_task_completion_sound "$FILE_PATH"
|
|
400
|
-
fi
|
|
401
|
-
|
|
402
|
-
# ========================================================================
|
|
403
|
-
# UNIVERSAL AUTO-CREATE (v1.0.256+): Create items in ALL enabled providers
|
|
404
|
-
# ========================================================================
|
|
405
|
-
# When spec.md is created/updated AND has user stories, auto-create
|
|
406
|
-
# items in GitHub/JIRA/ADO if autoSync or auto_create is enabled.
|
|
407
|
-
if [[ "$FILE_PATH" == *spec.md ]]; then
|
|
408
|
-
UNIVERSAL_AUTO_CREATE="${HOOK_DIR}/handlers/universal-auto-create-dispatcher.sh"
|
|
409
|
-
if [[ -f "$UNIVERSAL_AUTO_CREATE" ]]; then
|
|
410
|
-
safe_run_background "$UNIVERSAL_AUTO_CREATE" "universal-auto-create" "$INC_ID"
|
|
411
|
-
fi
|
|
412
|
-
fi
|
|
413
|
-
|
|
414
|
-
# Tasks or spec changed -> check for US completion (background)
|
|
415
|
-
safe_run_background "$DETECTOR_DIR/us-completion-detector.sh" "us-completion-detector" "$INC_ID"
|
|
416
|
-
|
|
417
|
-
# Queue events for backward compatibility (background)
|
|
418
|
-
if [[ "$FILE_PATH" == *tasks.md ]]; then
|
|
419
|
-
safe_run_background "$HOOK_DIR/queue/enqueue.sh" "enqueue-task" "task.updated" "$INC_ID"
|
|
420
|
-
safe_run_background "$SCRIPTS_DIR/update-dashboard-cache.sh" "dashboard-cache" "$INC_ID" "tasks"
|
|
421
|
-
else
|
|
422
|
-
safe_run_background "$HOOK_DIR/queue/enqueue.sh" "enqueue-spec" "spec.updated" "$INC_ID"
|
|
423
|
-
safe_run_background "$SCRIPTS_DIR/update-dashboard-cache.sh" "dashboard-cache" "$INC_ID" "spec"
|
|
424
|
-
fi
|
|
425
|
-
;;
|
|
426
|
-
|
|
427
|
-
*/.specweave/increments/*/plan.md)
|
|
428
|
-
log_debug "Plan change detected"
|
|
429
|
-
# Queue plan update event (background)
|
|
430
|
-
safe_run_background "$HOOK_DIR/queue/enqueue.sh" "enqueue-plan" "plan.updated" "$INC_ID"
|
|
431
|
-
;;
|
|
432
|
-
|
|
433
|
-
*)
|
|
434
|
-
# Not a specweave increment file, ignore
|
|
435
|
-
exit 0
|
|
436
|
-
;;
|
|
437
|
-
esac
|
|
438
|
-
|
|
439
|
-
# ============================================================================
|
|
440
|
-
# NO BACKGROUND PROCESSOR (v1.0.148)
|
|
441
|
-
# ============================================================================
|
|
442
|
-
# Events are now batched and processed by stop-sync.sh at session end.
|
|
443
|
-
# Critical events (increment.done/reopened) sync immediately above.
|
|
444
|
-
# This eliminates the need for a background processor daemon.
|
|
445
|
-
|
|
446
|
-
log_debug "Dispatcher completed successfully"
|
|
447
|
-
exit 0
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# pre-tool-use.sh - Dispatcher for PreToolUse guards
|
|
3
|
-
#
|
|
4
|
-
# Routes to appropriate guards based on tool type:
|
|
5
|
-
# - Write: spec-template-enforcement-guard for spec.md
|
|
6
|
-
# - Edit: status-completion-guard for metadata.json protection
|
|
7
|
-
#
|
|
8
|
-
# Returns: {"decision":"allow"} or {"decision":"block","reason":"..."}
|
|
9
|
-
#
|
|
10
|
-
# @since 1.0.167
|
|
11
|
-
# @updated 1.0.196 - Added status-completion-guard for Edit operations
|
|
12
|
-
# @updated 1.0.352 - Added interview-enforcement-guard for agent-spawned spec.md writes
|
|
13
|
-
|
|
14
|
-
set +e # CRITICAL: Never exit on error - matches all other hook scripts
|
|
15
|
-
|
|
16
|
-
# Read input once and store
|
|
17
|
-
INPUT=$(cat)
|
|
18
|
-
|
|
19
|
-
# Skip if hooks disabled
|
|
20
|
-
[[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]] && echo '{"decision":"allow"}' && exit 0
|
|
21
|
-
|
|
22
|
-
# Detect project root via walk-up (cwd may not be root)
|
|
23
|
-
_DIR="$PWD"
|
|
24
|
-
_LIMIT=0
|
|
25
|
-
while [[ "$_DIR" != "/" ]] && [[ ! -f "$_DIR/.specweave/config.json" ]] && [[ $_LIMIT -lt 50 ]]; do
|
|
26
|
-
_DIR=$(dirname "$_DIR")
|
|
27
|
-
_LIMIT=$((_LIMIT + 1))
|
|
28
|
-
done
|
|
29
|
-
[[ ! -f "$_DIR/.specweave/config.json" ]] && echo '{"decision":"allow"}' && exit 0
|
|
30
|
-
|
|
31
|
-
# Fast file_path check: skip non-increment files before jq (< 5ms)
|
|
32
|
-
if ! echo "$INPUT" | grep -q '"file_path".*\.specweave/increments/'; then
|
|
33
|
-
echo '{"decision":"allow"}'
|
|
34
|
-
exit 0
|
|
35
|
-
fi
|
|
36
|
-
|
|
37
|
-
# Get plugin root for guard paths
|
|
38
|
-
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(dirname "$(dirname "$(dirname "$0")")")}"
|
|
39
|
-
GUARDS_DIR="$PLUGIN_ROOT/hooks/v2/guards"
|
|
40
|
-
|
|
41
|
-
# Extract tool info
|
|
42
|
-
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // .toolName // ""')
|
|
43
|
-
|
|
44
|
-
# ============================================================================
|
|
45
|
-
# Edit Tool Guards
|
|
46
|
-
# ============================================================================
|
|
47
|
-
|
|
48
|
-
if [[ "$TOOL_NAME" == "Edit" ]]; then
|
|
49
|
-
# Status Completion Guard - Prevents direct status changes to "completed"
|
|
50
|
-
# RULE: Use /sw:done or /sw:auto instead of direct metadata.json edits
|
|
51
|
-
STATUS_GUARD="$GUARDS_DIR/status-completion-guard.sh"
|
|
52
|
-
if [[ -x "$STATUS_GUARD" ]]; then
|
|
53
|
-
STATUS_RESULT=$(echo "$INPUT" | "$STATUS_GUARD" 2>/dev/null || echo '{"decision":"allow"}')
|
|
54
|
-
STATUS_DECISION=$(echo "$STATUS_RESULT" | jq -r '.decision // "allow"')
|
|
55
|
-
|
|
56
|
-
if [[ "$STATUS_DECISION" == "block" ]]; then
|
|
57
|
-
echo "$STATUS_RESULT"
|
|
58
|
-
exit 0
|
|
59
|
-
fi
|
|
60
|
-
fi
|
|
61
|
-
|
|
62
|
-
echo '{"decision":"allow"}'
|
|
63
|
-
exit 0
|
|
64
|
-
fi
|
|
65
|
-
|
|
66
|
-
# ============================================================================
|
|
67
|
-
# Write Tool Guards
|
|
68
|
-
# ============================================================================
|
|
69
|
-
|
|
70
|
-
if [[ "$TOOL_NAME" == "Write" ]]; then
|
|
71
|
-
# Spec Template Enforcement Guard
|
|
72
|
-
# Enforces template-first workflow for spec.md (skill usage)
|
|
73
|
-
SPEC_GUARD="$GUARDS_DIR/spec-template-enforcement-guard.sh"
|
|
74
|
-
if [[ -x "$SPEC_GUARD" ]]; then
|
|
75
|
-
SPEC_RESULT=$(echo "$INPUT" | "$SPEC_GUARD" 2>/dev/null || echo '{"decision":"allow"}')
|
|
76
|
-
SPEC_DECISION=$(echo "$SPEC_RESULT" | jq -r '.decision // "allow"')
|
|
77
|
-
|
|
78
|
-
if [[ "$SPEC_DECISION" == "block" ]]; then
|
|
79
|
-
echo "$SPEC_RESULT"
|
|
80
|
-
exit 0
|
|
81
|
-
fi
|
|
82
|
-
fi
|
|
83
|
-
|
|
84
|
-
# Interview Enforcement Guard
|
|
85
|
-
# Blocks spec.md writes until deep interview is complete (when strict mode enabled)
|
|
86
|
-
# Needed here because agent-spawned writes don't inherit skill-level hooks
|
|
87
|
-
INTERVIEW_GUARD="$GUARDS_DIR/interview-enforcement-guard.sh"
|
|
88
|
-
if [[ -x "$INTERVIEW_GUARD" ]]; then
|
|
89
|
-
INTERVIEW_RESULT=$(echo "$INPUT" | "$INTERVIEW_GUARD" 2>/dev/null || echo '{"decision":"allow"}')
|
|
90
|
-
INTERVIEW_DECISION=$(echo "$INTERVIEW_RESULT" | jq -r '.decision // "allow"')
|
|
91
|
-
|
|
92
|
-
if [[ "$INTERVIEW_DECISION" == "block" ]]; then
|
|
93
|
-
echo "$INTERVIEW_RESULT"
|
|
94
|
-
exit 0
|
|
95
|
-
fi
|
|
96
|
-
fi
|
|
97
|
-
|
|
98
|
-
echo '{"decision":"allow"}'
|
|
99
|
-
exit 0
|
|
100
|
-
fi
|
|
101
|
-
|
|
102
|
-
# Allow all other tools
|
|
103
|
-
echo '{"decision":"allow"}'
|
|
104
|
-
exit 0
|