specweave 0.32.0 → 0.32.2
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 +176 -2
- package/README.md +22 -0
- package/bin/specweave.js +18 -1
- package/dist/src/cli/commands/cache.d.ts +17 -0
- package/dist/src/cli/commands/cache.d.ts.map +1 -0
- package/dist/src/cli/commands/cache.js +126 -0
- package/dist/src/cli/commands/cache.js.map +1 -0
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/plan/increment-detector.js +2 -2
- package/dist/src/cli/commands/plan/increment-detector.js.map +1 -1
- package/dist/src/cli/commands/sync-spec-commits.js +1 -1
- package/dist/src/cli/commands/sync-spec-commits.js.map +1 -1
- package/dist/src/cli/commands/sync-specs.js +2 -2
- package/dist/src/cli/commands/sync-specs.js.map +1 -1
- package/dist/src/cli/helpers/github/increment-profile-selector.js +1 -1
- package/dist/src/cli/helpers/github/increment-profile-selector.js.map +1 -1
- package/dist/src/cli/workers/living-docs-worker.js +66 -1
- package/dist/src/cli/workers/living-docs-worker.js.map +1 -1
- package/dist/src/config/types.d.ts +203 -1208
- package/dist/src/config/types.d.ts.map +1 -1
- package/dist/src/core/discrepancy/increment-generator.d.ts.map +1 -1
- package/dist/src/core/discrepancy/increment-generator.js +5 -2
- package/dist/src/core/discrepancy/increment-generator.js.map +1 -1
- package/dist/src/core/increment/duplicate-detector.js +2 -2
- package/dist/src/core/increment/duplicate-detector.js.map +1 -1
- package/dist/src/core/increment/increment-archiver.d.ts +24 -0
- package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
- package/dist/src/core/increment/increment-archiver.js +59 -2
- package/dist/src/core/increment/increment-archiver.js.map +1 -1
- package/dist/src/core/increment/increment-status.js +2 -2
- package/dist/src/core/increment/increment-status.js.map +1 -1
- package/dist/src/core/increment/increment-utils.d.ts +85 -0
- package/dist/src/core/increment/increment-utils.d.ts.map +1 -1
- package/dist/src/core/increment/increment-utils.js +102 -4
- package/dist/src/core/increment/increment-utils.js.map +1 -1
- package/dist/src/core/increment/metadata-validator.js +1 -1
- package/dist/src/core/increment/metadata-validator.js.map +1 -1
- package/dist/src/core/living-docs/feature-id-manager.js +1 -1
- package/dist/src/core/living-docs/feature-id-manager.js.map +1 -1
- package/dist/src/core/living-docs/hierarchy-mapper.js +3 -3
- package/dist/src/core/living-docs/hierarchy-mapper.js.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.d.ts +18 -0
- package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js +247 -0
- package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.d.ts +15 -0
- package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.js +138 -0
- package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.d.ts +24 -0
- package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.js +198 -0
- package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.d.ts +17 -0
- package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.js +241 -0
- package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts +28 -0
- package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/index.js +197 -0
- package/dist/src/core/living-docs/intelligent-analyzer/index.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts +18 -0
- package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js +154 -0
- package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.d.ts +42 -0
- package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.js +343 -0
- package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts +146 -0
- package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/types.js +7 -0
- package/dist/src/core/living-docs/intelligent-analyzer/types.js.map +1 -0
- package/dist/src/core/living-docs/living-docs-sync.d.ts +5 -0
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +36 -2
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/sync/spec-increment-mapper.js +3 -3
- package/dist/src/core/sync/spec-increment-mapper.js.map +1 -1
- package/dist/src/importers/item-converter.d.ts +25 -0
- package/dist/src/importers/item-converter.d.ts.map +1 -1
- package/dist/src/importers/item-converter.js +135 -5
- package/dist/src/importers/item-converter.js.map +1 -1
- package/dist/src/init/architecture/types.d.ts +33 -140
- package/dist/src/init/architecture/types.d.ts.map +1 -1
- package/dist/src/init/compliance/types.d.ts +30 -27
- package/dist/src/init/compliance/types.d.ts.map +1 -1
- package/dist/src/init/repo/types.d.ts +11 -34
- package/dist/src/init/repo/types.d.ts.map +1 -1
- package/dist/src/init/research/src/config/types.d.ts +15 -82
- package/dist/src/init/research/src/config/types.d.ts.map +1 -1
- package/dist/src/init/research/types.d.ts +38 -93
- package/dist/src/init/research/types.d.ts.map +1 -1
- package/dist/src/init/team/types.d.ts +4 -42
- package/dist/src/init/team/types.d.ts.map +1 -1
- package/dist/src/types/dashboard-cache.d.ts +181 -0
- package/dist/src/types/dashboard-cache.d.ts.map +1 -0
- package/dist/src/types/dashboard-cache.js +65 -0
- package/dist/src/types/dashboard-cache.js.map +1 -0
- package/dist/src/utils/docs-validator.d.ts +131 -0
- package/dist/src/utils/docs-validator.d.ts.map +1 -0
- package/dist/src/utils/docs-validator.js +529 -0
- package/dist/src/utils/docs-validator.js.map +1 -0
- package/dist/src/utils/feature-id-collision.js +1 -1
- package/dist/src/utils/feature-id-collision.js.map +1 -1
- package/dist/src/utils/html-to-mdx.d.ts +1 -0
- package/dist/src/utils/html-to-mdx.d.ts.map +1 -1
- package/dist/src/utils/html-to-mdx.js +43 -5
- package/dist/src/utils/html-to-mdx.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/agents/pm/AGENT.md +10 -7
- package/plugins/specweave/commands/specweave-archive-features.md +5 -7
- package/plugins/specweave/commands/specweave-archive.md +2 -1
- package/plugins/specweave/commands/specweave-do.md +35 -1
- package/plugins/specweave/commands/specweave-done.md +96 -0
- package/plugins/specweave/commands/specweave-import-external.md +45 -18
- package/plugins/specweave/commands/specweave-increment.md +331 -33
- package/plugins/specweave/commands/specweave-jobs.md +2 -2
- package/plugins/specweave/commands/specweave-progress.md +4 -4
- package/plugins/specweave/commands/specweave-restore-feature.md +5 -4
- package/plugins/specweave/commands/specweave-sync-docs.md +1 -1
- package/plugins/specweave/commands/specweave-sync-specs.md +216 -322
- package/plugins/specweave/commands/specweave-validate-features.md +13 -8
- package/plugins/specweave/hooks/docs-changed.sh.backup +79 -0
- package/plugins/specweave/hooks/hooks.json +33 -4
- package/plugins/specweave/hooks/human-input-required.sh.backup +75 -0
- package/plugins/specweave/hooks/lib/common-setup.sh +375 -0
- package/plugins/specweave/hooks/lib/crash-prevention.sh +336 -0
- package/plugins/specweave/hooks/post-first-increment.sh.backup +61 -0
- package/plugins/specweave/hooks/post-increment-change.sh.backup +98 -0
- package/plugins/specweave/hooks/post-increment-completion.sh.backup +231 -0
- package/plugins/specweave/hooks/post-increment-planning.sh.backup +1048 -0
- package/plugins/specweave/hooks/post-increment-status-change.sh.backup +147 -0
- package/plugins/specweave/hooks/post-spec-update.sh.backup +158 -0
- package/plugins/specweave/hooks/post-task-completion.sh +4 -23
- package/plugins/specweave/hooks/post-user-story-complete.sh.backup +179 -0
- package/plugins/specweave/hooks/pre-command-deduplication.sh +1 -6
- package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +83 -0
- package/plugins/specweave/hooks/pre-implementation.sh.backup +67 -0
- package/plugins/specweave/hooks/pre-task-completion.sh +8 -37
- package/plugins/specweave/hooks/pre-task-completion.sh.backup +194 -0
- package/plugins/specweave/hooks/pre-tool-use.sh +2 -11
- package/plugins/specweave/hooks/pre-tool-use.sh.backup +133 -0
- package/plugins/specweave/hooks/universal/dispatcher.mjs +135 -42
- package/plugins/specweave/hooks/universal/fail-fast-wrapper.sh +183 -0
- package/plugins/specweave/hooks/user-prompt-submit.sh +140 -38
- package/plugins/specweave/hooks/user-prompt-submit.sh.backup +386 -0
- package/plugins/specweave/hooks/v2/dispatchers/post-tool-use.sh +12 -0
- package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +89 -0
- package/plugins/specweave/hooks/v2/guards/bash-file-guard.sh +211 -0
- package/plugins/specweave/hooks/v2/guards/bash-file-guard.test.sh +163 -0
- package/plugins/specweave/hooks/v2/guards/completion-guard.sh +26 -28
- package/plugins/specweave/hooks/v2/guards/features-folder-guard.sh +50 -0
- package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js +2 -2
- package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js.map +1 -1
- package/plugins/specweave/scripts/README.md +166 -0
- package/plugins/specweave/scripts/cleanup-state.sh +142 -0
- package/plugins/specweave/scripts/force-kill.sh +142 -0
- package/plugins/specweave/scripts/jobs.js +171 -0
- package/plugins/specweave/scripts/progress.js +170 -0
- package/plugins/specweave/scripts/read-costs.sh +132 -0
- package/plugins/specweave/scripts/read-jobs.sh +324 -0
- package/plugins/specweave/scripts/read-progress.sh +185 -0
- package/plugins/specweave/scripts/read-status.sh +146 -0
- package/plugins/specweave/scripts/read-workflow.sh +173 -0
- package/plugins/specweave/scripts/rebuild-dashboard-cache.sh +327 -0
- package/plugins/specweave/scripts/session-watchdog.sh +192 -0
- package/plugins/specweave/scripts/status.js +154 -0
- package/plugins/specweave/scripts/update-dashboard-cache.sh +281 -0
- package/plugins/specweave/skills/increment-planner/SKILL.md +333 -24
- package/plugins/specweave/skills/increment-planner/templates/spec-multi-project.md +17 -9
- package/plugins/specweave/skills/increment-planner/templates/spec-single-project.md +6 -2
- package/plugins/specweave/skills/instant-status/SKILL.md +70 -0
- package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +353 -0
- package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-ado/lib/enhanced-ado-sync.js +170 -0
- package/plugins/specweave-docs/commands/build.md +32 -4
- package/plugins/specweave-docs/commands/preview.md +43 -1
- package/plugins/specweave-docs/commands/validate.md +250 -0
- package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +1262 -0
- package/plugins/specweave-github/hooks/post-task-completion.sh.backup +258 -0
- package/plugins/specweave-github/lib/enhanced-github-sync.js +220 -0
- package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-jira/lib/enhanced-jira-sync.js +134 -0
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +1254 -0
- package/plugins/specweave-release/hooks/post-task-completion.sh.backup +110 -0
- package/plugins/specweave/hooks/post-edit-spec.sh +0 -265
- package/plugins/specweave/hooks/post-write-spec.sh +0 -267
- package/plugins/specweave/hooks/pre-edit-spec.sh +0 -151
- package/plugins/specweave/hooks/pre-write-spec.sh +0 -151
|
@@ -1,151 +0,0 @@
|
|
|
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
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
#
|
|
3
|
-
# Pre-Write Hook: Capture File Path BEFORE Write Executes (Tier 2)
|
|
4
|
-
#
|
|
5
|
-
# Purpose: Detect which file will be written BEFORE the Write 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:Write → pre-write-spec.sh (this file)
|
|
18
|
-
# ↓ writes to
|
|
19
|
-
# .specweave/state/.pending-status-update
|
|
20
|
-
# ↓ read by
|
|
21
|
-
# PostToolUse:Write → post-write-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-write-spec: Detected file_path: $FILE_PATH" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
99
|
-
else
|
|
100
|
-
echo "[$(date)] pre-write-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-write-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-write-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-write-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
|