specweave 1.0.39 → 1.0.41
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 +18 -18
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +16 -0
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/project/project-service.d.ts.map +1 -1
- package/dist/src/core/project/project-service.js +5 -6
- package/dist/src/core/project/project-service.js.map +1 -1
- package/dist/src/hooks/processor.d.ts +5 -2
- package/dist/src/hooks/processor.d.ts.map +1 -1
- package/dist/src/hooks/processor.js +17 -6
- package/dist/src/hooks/processor.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/commands/save.md +28 -0
- package/plugins/specweave/hooks/hooks.json +0 -32
- package/plugins/specweave/hooks/lib/common-setup.sh +0 -18
- package/plugins/specweave/hooks/v2/guards/completion-guard.sh +7 -69
- package/plugins/specweave/hooks/v2/guards/increment-duplicate-guard.sh +7 -142
- package/plugins/specweave/hooks/v2/guards/metadata-json-guard.sh +8 -92
- package/plugins/specweave/hooks/v2/guards/spec-validation-guard.sh +7 -168
- package/plugins/specweave/hooks/v2/handlers/github-sync-handler.sh +12 -1
- package/plugins/specweave/hooks/v2/queue/processor.sh +21 -7
- package/plugins/specweave/hooks/v2/guards/metadata-json-guard.test.sh +0 -302
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"processor.js","sourceRoot":"","sources":["../../../src/hooks/processor.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"processor.js","sourceRoot":"","sources":["../../../src/hooks/processor.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specweave",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.41",
|
|
4
4
|
"description": "Spec-driven development framework for Claude Code. AI-native workflow with living documentation, intelligent agents, and multilingual support (9 languages). Enterprise-grade traceability with permanent specs and temporary increments.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -897,6 +897,34 @@ Summary:
|
|
|
897
897
|
Saved: 1/1 repository
|
|
898
898
|
```
|
|
899
899
|
|
|
900
|
+
### No Remote Configured (Single Repo or Parent Project)
|
|
901
|
+
|
|
902
|
+
If operating in single-repo mode and no git remote is configured, prompt the user with the **EXACT project name** in the question:
|
|
903
|
+
|
|
904
|
+
```markdown
|
|
905
|
+
⚠️ No remote repository configured for 'sw-content-repurposer' (parent project).
|
|
906
|
+
|
|
907
|
+
How would you like to proceed?
|
|
908
|
+
1. 📝 Enter URL manually - I'll provide the GitHub/GitLab URL for this repository
|
|
909
|
+
2. ⏭️ Skip push (commit only) - Just commit locally, I'll set up remote later
|
|
910
|
+
3. ❌ Cancel - Don't commit or push anything right now
|
|
911
|
+
```
|
|
912
|
+
|
|
913
|
+
**IMPORTANT**: Always include the project/repository name in the dialog so the user knows WHICH repository is missing the remote. For umbrella setups, this helps distinguish between:
|
|
914
|
+
- Parent project (the umbrella root directory)
|
|
915
|
+
- Child repositories (cloned into `repositories/` folder)
|
|
916
|
+
|
|
917
|
+
**Check for pending clone jobs**: If `umbrella.childRepos` is empty but a clone job is running (check `/sw:jobs`), inform the user:
|
|
918
|
+
|
|
919
|
+
```markdown
|
|
920
|
+
ℹ️ Repository cloning is in progress (job: a84e4fe5).
|
|
921
|
+
|
|
922
|
+
The child repositories are being cloned in the background. Options:
|
|
923
|
+
1. ⏳ Wait for cloning to complete (run `/sw:jobs` to check status)
|
|
924
|
+
2. 💾 Save parent project only (commit .specweave/ changes)
|
|
925
|
+
3. ❌ Cancel and retry later
|
|
926
|
+
```
|
|
927
|
+
|
|
900
928
|
## Flags and Options
|
|
901
929
|
|
|
902
930
|
| Flag | Description |
|
|
@@ -20,38 +20,6 @@
|
|
|
20
20
|
]
|
|
21
21
|
}
|
|
22
22
|
],
|
|
23
|
-
"PreToolUse": [
|
|
24
|
-
{
|
|
25
|
-
"matcher": "Write",
|
|
26
|
-
"matcher_content": "\\.specweave/increments/\\d{3,4}E?-[^/]+/spec\\.md",
|
|
27
|
-
"hooks": [
|
|
28
|
-
{
|
|
29
|
-
"type": "command",
|
|
30
|
-
"command": "bash -c 'W=\"${CLAUDE_PLUGIN_ROOT}/hooks/universal/fail-fast-wrapper.sh\"; S=\"${CLAUDE_PLUGIN_ROOT}/hooks/v2/guards/metadata-json-guard.sh\"; [[ -x \"$W\" ]] && exec \"$W\" \"$S\" || (cat >/dev/null && printf \"{\\\"decision\\\":\\\"allow\\\"}\")'"
|
|
31
|
-
}
|
|
32
|
-
]
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
"matcher": "Write",
|
|
36
|
-
"matcher_content": "\\.specweave/increments/\\d{3,4}E?-[^/]+/",
|
|
37
|
-
"hooks": [
|
|
38
|
-
{
|
|
39
|
-
"type": "command",
|
|
40
|
-
"command": "bash -c 'W=\"${CLAUDE_PLUGIN_ROOT}/hooks/universal/fail-fast-wrapper.sh\"; S=\"${CLAUDE_PLUGIN_ROOT}/hooks/v2/guards/increment-duplicate-guard.sh\"; [[ -x \"$W\" ]] && exec \"$W\" \"$S\" || (cat >/dev/null && printf \"{\\\"decision\\\":\\\"allow\\\"}\")'"
|
|
41
|
-
}
|
|
42
|
-
]
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
"matcher": "Write",
|
|
46
|
-
"matcher_content": "\\.specweave/(increments/\\d{3,4}E?-[^/]+/spec\\.md|docs/internal/specs/)",
|
|
47
|
-
"hooks": [
|
|
48
|
-
{
|
|
49
|
-
"type": "command",
|
|
50
|
-
"command": "bash -c 'W=\"${CLAUDE_PLUGIN_ROOT}/hooks/universal/fail-fast-wrapper.sh\"; S=\"${CLAUDE_PLUGIN_ROOT}/hooks/v2/guards/spec-validation-guard.sh\"; [[ -x \"$W\" ]] && exec \"$W\" \"$S\" || (cat >/dev/null && printf \"{\\\"decision\\\":\\\"allow\\\"}\")'"
|
|
51
|
-
}
|
|
52
|
-
]
|
|
53
|
-
}
|
|
54
|
-
],
|
|
55
23
|
"PostToolUse": [
|
|
56
24
|
{
|
|
57
25
|
"matcher": "Edit|Write",
|
|
@@ -77,24 +77,6 @@ guard_allow() {
|
|
|
77
77
|
exit 0
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
# Block the tool call with reason (DEPRECATED v1.0.37 - use guard_warn instead)
|
|
81
|
-
# NOTE: Blocking is discouraged. Use guard_warn for most cases.
|
|
82
|
-
guard_block() {
|
|
83
|
-
local reason="$1"
|
|
84
|
-
reason=$(echo "$reason" | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g')
|
|
85
|
-
printf '{"decision":"block","reason":"%s"}\n' "$reason"
|
|
86
|
-
exit 2
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
# Warn but ALLOW the tool call (v1.0.37+)
|
|
90
|
-
# This is the PREFERRED approach - never block operations, always allow with warnings.
|
|
91
|
-
guard_warn() {
|
|
92
|
-
local message="$1"
|
|
93
|
-
message=$(echo "$message" | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g')
|
|
94
|
-
printf '{"decision":"allow","message":"%s"}\n' "$message"
|
|
95
|
-
exit 0
|
|
96
|
-
}
|
|
97
|
-
|
|
98
80
|
# ============================================================================
|
|
99
81
|
# SIMPLE LOGGING (optional, writes to .specweave/logs/hooks.log)
|
|
100
82
|
# ============================================================================
|
|
@@ -1,76 +1,14 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# completion-guard.sh -
|
|
2
|
+
# completion-guard.sh - DISABLED (v1.0.38)
|
|
3
3
|
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
4
|
+
# This guard was converted to WARNING-only in v1.0.37, and now completely
|
|
5
|
+
# disabled in v1.0.38 per user feedback: "you MUST NEVER block such operations"
|
|
6
6
|
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
# Business logic and validation should be in scripts/agents, not hard blocks.
|
|
7
|
+
# Completion workflow should be handled by agents/scripts with proper business logic,
|
|
8
|
+
# not by hooks that can interfere with file operations.
|
|
10
9
|
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
# IMPORTANT: This is a safety guard. Exit 0 allows (with warning if needed).
|
|
14
|
-
# All exit paths MUST output JSON for proper Claude Code handling.
|
|
15
|
-
set +e
|
|
16
|
-
|
|
17
|
-
[[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]] && echo '{"decision":"allow"}' && exit 0
|
|
18
|
-
|
|
19
|
-
# Read stdin for tool input
|
|
20
|
-
INPUT=$(cat 2>/dev/null || echo '{}')
|
|
21
|
-
|
|
22
|
-
# Check if this is editing metadata.json with status: completed
|
|
23
|
-
# Pattern: file_path contains metadata.json AND (new_string OR content) contains "status"..."completed"
|
|
24
|
-
|
|
25
|
-
# Extract file_path
|
|
26
|
-
# Claude Code passes tool input in .tool_input.file_path format
|
|
27
|
-
if command -v jq &> /dev/null; then
|
|
28
|
-
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .file_path // empty' 2>/dev/null)
|
|
29
|
-
else
|
|
30
|
-
FILE_PATH=$(echo "$INPUT" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)".*/\1/')
|
|
31
|
-
fi
|
|
10
|
+
# This guard now does NOTHING - just allows all operations.
|
|
32
11
|
|
|
33
|
-
|
|
34
|
-
if [[ "$FILE_PATH" != *metadata.json ]]; then
|
|
35
|
-
echo '{"decision":"allow"}'
|
|
36
|
-
exit 0 # Allow
|
|
37
|
-
fi
|
|
38
|
-
|
|
39
|
-
# Extract the content being written (new_string for Edit, content for Write)
|
|
40
|
-
# Claude Code passes tool input in .tool_input format
|
|
41
|
-
if command -v jq &> /dev/null; then
|
|
42
|
-
NEW_CONTENT=$(echo "$INPUT" | jq -r '.tool_input.new_string // .tool_input.content // .new_string // .content // empty' 2>/dev/null)
|
|
43
|
-
else
|
|
44
|
-
NEW_CONTENT=$(echo "$INPUT" | grep -o '"new_string"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1)
|
|
45
|
-
if [[ -z "$NEW_CONTENT" ]]; then
|
|
46
|
-
NEW_CONTENT=$(echo "$INPUT" | grep -o '"content"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1)
|
|
47
|
-
fi
|
|
48
|
-
fi
|
|
49
|
-
|
|
50
|
-
# Check if trying to set status to "completed" directly
|
|
51
|
-
# This is a simple pattern match - if the edit/write contains status...completed
|
|
52
|
-
if echo "$NEW_CONTENT" | grep -q '"status"[[:space:]]*:[[:space:]]*"completed"'; then
|
|
53
|
-
# Read current status from file to check if coming from ready_for_review
|
|
54
|
-
if [[ -f "$FILE_PATH" ]]; then
|
|
55
|
-
CURRENT_STATUS=$(grep -o '"status"[[:space:]]*:[[:space:]]*"[^"]*"' "$FILE_PATH" | head -1 | sed 's/.*"\([^"]*\)".*/\1/')
|
|
56
|
-
|
|
57
|
-
if [[ "$CURRENT_STATUS" == "ready_for_review" ]]; then
|
|
58
|
-
# This is a valid transition - allow
|
|
59
|
-
echo '{"decision":"allow"}'
|
|
60
|
-
exit 0
|
|
61
|
-
fi
|
|
62
|
-
fi
|
|
63
|
-
|
|
64
|
-
# WARN - trying to set completed without going through ready_for_review (v1.0.37)
|
|
65
|
-
cat << 'WARN_EOF'
|
|
66
|
-
{
|
|
67
|
-
"decision": "allow",
|
|
68
|
-
"message": "⚠️ WARNING: Direct status change to \"completed\" detected!\n\n🚨 RECOMMENDED WORKFLOW:\n1. All tasks completed → status auto-transitions to \"ready_for_review\"\n2. Run /sw:done <increment-id> with explicit user confirmation\n3. Only then does status become \"completed\"\n\nWHY THIS MATTERS:\n• Ensures all ACs are checked in spec.md before closure\n• Requires explicit user approval\n• Maintains audit trail (approvedAt timestamp)\n\n💡 If implementing closure logic, use:\n MetadataManager.updateStatus(incrementId, IncrementStatus.COMPLETED)\n\nOperation ALLOWED - proceeding with status change."
|
|
69
|
-
}
|
|
70
|
-
WARN_EOF
|
|
71
|
-
exit 0 # ALLOW with warning (v1.0.37)
|
|
72
|
-
fi
|
|
73
|
-
|
|
74
|
-
# Allow other edits to metadata.json
|
|
12
|
+
set +e
|
|
75
13
|
echo '{"decision":"allow"}'
|
|
76
14
|
exit 0
|
|
@@ -1,149 +1,14 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# increment-duplicate-guard.sh -
|
|
2
|
+
# increment-duplicate-guard.sh - DISABLED (v1.0.38)
|
|
3
3
|
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
4
|
+
# This guard was converted to WARNING-only in v1.0.37, and now completely
|
|
5
|
+
# disabled in v1.0.38 per user feedback: "you MUST NEVER block such operations"
|
|
6
6
|
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
# Business logic and validation should be in scripts/agents, not hard blocks.
|
|
7
|
+
# Duplicate detection should be handled by agents/scripts with proper business logic,
|
|
8
|
+
# not by hooks that can interfere with file operations.
|
|
10
9
|
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
# Exit 0 = allow (with JSON warning message if duplicate detected)
|
|
14
|
-
set +e
|
|
15
|
-
|
|
16
|
-
[[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]] && echo '{"decision":"allow"}' && exit 0
|
|
17
|
-
|
|
18
|
-
# Read stdin for tool input
|
|
19
|
-
INPUT=$(cat 2>/dev/null || echo '{}')
|
|
20
|
-
|
|
21
|
-
# Extract file_path from the tool call
|
|
22
|
-
# Claude Code passes tool input in .tool_input.file_path format
|
|
23
|
-
if command -v jq &> /dev/null; then
|
|
24
|
-
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .file_path // empty' 2>/dev/null)
|
|
25
|
-
else
|
|
26
|
-
FILE_PATH=$(echo "$INPUT" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)".*/\1/')
|
|
27
|
-
fi
|
|
28
|
-
|
|
29
|
-
# Only care about .specweave/increments/ paths
|
|
30
|
-
if [[ "$FILE_PATH" != *.specweave/increments/* ]]; then
|
|
31
|
-
echo '{"decision":"allow"}'
|
|
32
|
-
exit 0 # Not an increment file - allow
|
|
33
|
-
fi
|
|
34
|
-
|
|
35
|
-
# CRITICAL FIX (v1.0.37): ALWAYS allow metadata.json writes!
|
|
36
|
-
# metadata.json is the FIRST file created for any increment - it MUST succeed.
|
|
37
|
-
# Duplicate detection only makes sense for the INCREMENT FOLDER, not individual files.
|
|
38
|
-
# Once the folder exists, any file writes within it should be allowed.
|
|
39
|
-
if [[ "$FILE_PATH" == *metadata.json ]]; then
|
|
40
|
-
echo '{"decision":"allow","message":"metadata.json write allowed (increment creation)"}'
|
|
41
|
-
exit 0
|
|
42
|
-
fi
|
|
43
|
-
|
|
44
|
-
# Extract the increment folder name from the path
|
|
45
|
-
# Pattern: .specweave/increments/XXXX-name/file.md or .specweave/increments/XXXX-name/subfolder/file
|
|
46
|
-
# We need to extract "XXXX-name" part
|
|
47
|
-
|
|
48
|
-
# Remove the .specweave/increments/ prefix
|
|
49
|
-
AFTER_INCREMENTS=${FILE_PATH#*.specweave/increments/}
|
|
50
|
-
|
|
51
|
-
# Get the first path component (the increment folder)
|
|
52
|
-
INCREMENT_FOLDER=$(echo "$AFTER_INCREMENTS" | cut -d'/' -f1)
|
|
53
|
-
|
|
54
|
-
# Skip special folders
|
|
55
|
-
if [[ "$INCREMENT_FOLDER" == "_archive" ]] || [[ "$INCREMENT_FOLDER" == "_abandoned" ]] || [[ "$INCREMENT_FOLDER" == "_paused" ]] || [[ "$INCREMENT_FOLDER" == "README.md" ]]; then
|
|
56
|
-
echo '{"decision":"allow"}'
|
|
57
|
-
exit 0
|
|
58
|
-
fi
|
|
59
|
-
|
|
60
|
-
# Extract the increment number from folder name (handles both 0121-name and 0121E-name)
|
|
61
|
-
INCREMENT_NUM=$(echo "$INCREMENT_FOLDER" | grep -oE '^[0-9]{3,4}' | head -1)
|
|
62
|
-
|
|
63
|
-
if [[ -z "$INCREMENT_NUM" ]]; then
|
|
64
|
-
echo '{"decision":"allow"}'
|
|
65
|
-
exit 0 # Not a standard increment folder pattern - allow
|
|
66
|
-
fi
|
|
67
|
-
|
|
68
|
-
# Normalize to 4 digits (strip leading zeros to avoid octal interpretation)
|
|
69
|
-
INCREMENT_NUM=$(printf "%04d" "$((10#$INCREMENT_NUM))")
|
|
70
|
-
|
|
71
|
-
# Find the increments root directory
|
|
72
|
-
INCREMENTS_DIR=$(echo "$FILE_PATH" | grep -o '.*/\.specweave/increments' | head -1)
|
|
10
|
+
# This guard now does NOTHING - just allows all operations.
|
|
73
11
|
|
|
74
|
-
|
|
75
|
-
# Increments directory doesn't exist yet - first increment, allow creation
|
|
76
|
-
echo '{"decision":"allow"}'
|
|
77
|
-
exit 0
|
|
78
|
-
fi
|
|
79
|
-
|
|
80
|
-
# Scan ALL directories for existing increment with the same number
|
|
81
|
-
DIRS_TO_CHECK=(
|
|
82
|
-
"$INCREMENTS_DIR"
|
|
83
|
-
"$INCREMENTS_DIR/_archive"
|
|
84
|
-
"$INCREMENTS_DIR/_abandoned"
|
|
85
|
-
"$INCREMENTS_DIR/_paused"
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
FOUND_DUPLICATES=()
|
|
89
|
-
|
|
90
|
-
for DIR in "${DIRS_TO_CHECK[@]}"; do
|
|
91
|
-
if [[ ! -d "$DIR" ]]; then
|
|
92
|
-
continue
|
|
93
|
-
fi
|
|
94
|
-
|
|
95
|
-
# Find all folders matching this increment number (including E suffix variants)
|
|
96
|
-
while IFS= read -r -d '' EXISTING_FOLDER; do
|
|
97
|
-
EXISTING_NAME=$(basename "$EXISTING_FOLDER")
|
|
98
|
-
|
|
99
|
-
# Extract number from existing folder
|
|
100
|
-
EXISTING_NUM=$(echo "$EXISTING_NAME" | grep -oE '^[0-9]{3,4}' | head -1)
|
|
101
|
-
|
|
102
|
-
if [[ -z "$EXISTING_NUM" ]]; then
|
|
103
|
-
continue
|
|
104
|
-
fi
|
|
105
|
-
|
|
106
|
-
EXISTING_NUM=$(printf "%04d" "$((10#$EXISTING_NUM))")
|
|
107
|
-
|
|
108
|
-
# Check if same base number (0121 matches 0121, 0121E, etc.)
|
|
109
|
-
if [[ "$EXISTING_NUM" == "$INCREMENT_NUM" ]]; then
|
|
110
|
-
# Skip if it's the exact same folder we're creating
|
|
111
|
-
if [[ "$EXISTING_NAME" == "$INCREMENT_FOLDER" ]]; then
|
|
112
|
-
continue
|
|
113
|
-
fi
|
|
114
|
-
|
|
115
|
-
# Found a duplicate!
|
|
116
|
-
FOUND_DUPLICATES+=("$EXISTING_NAME (in $(basename "$DIR"))")
|
|
117
|
-
fi
|
|
118
|
-
done < <(find "$DIR" -maxdepth 1 -type d -name "${INCREMENT_NUM}*" -print0 2>/dev/null)
|
|
119
|
-
done
|
|
120
|
-
|
|
121
|
-
# If duplicates found, WARN but ALLOW the operation (v1.0.37+: no blocking!)
|
|
122
|
-
if [[ ${#FOUND_DUPLICATES[@]} -gt 0 ]]; then
|
|
123
|
-
# Format duplicates for JSON
|
|
124
|
-
DUP_LIST=""
|
|
125
|
-
for DUP in "${FOUND_DUPLICATES[@]}"; do
|
|
126
|
-
DUP_LIST="${DUP_LIST}\\n - ${DUP}"
|
|
127
|
-
done
|
|
128
|
-
|
|
129
|
-
# Calculate the next available number using gap-filling strategy
|
|
130
|
-
EXISTING_NUMS=$(find "$INCREMENTS_DIR" "$INCREMENTS_DIR/_archive" "$INCREMENTS_DIR/_abandoned" "$INCREMENTS_DIR/_paused" -maxdepth 1 -type d -name "[0-9]*-*" 2>/dev/null | xargs -I {} basename {} | grep -oE '^[0-9]{3,4}' | sort -n | uniq)
|
|
131
|
-
NEXT_NUM=1
|
|
132
|
-
while echo "$EXISTING_NUMS" | grep -q "^$(printf "%04d" $NEXT_NUM)$\|^$(printf "%03d" $NEXT_NUM)$"; do
|
|
133
|
-
NEXT_NUM=$((NEXT_NUM + 1))
|
|
134
|
-
done
|
|
135
|
-
NEXT_NUM_PADDED=$(printf "%04d" $NEXT_NUM)
|
|
136
|
-
|
|
137
|
-
# Extract the name part from the attempted folder
|
|
138
|
-
FOLDER_NAME_PART=$(echo "$INCREMENT_FOLDER" | sed 's/^[0-9]\{3,4\}E\?-//')
|
|
139
|
-
SUGGESTED_FOLDER="${NEXT_NUM_PADDED}-${FOLDER_NAME_PART}"
|
|
140
|
-
|
|
141
|
-
# v1.0.37: ALLOW with WARNING instead of blocking
|
|
142
|
-
# User can still proceed - the warning provides guidance
|
|
143
|
-
printf '{"decision":"allow","message":"⚠️ DUPLICATE INCREMENT ID DETECTED\\n\\n✅ SUGGESTED: %s\\n⚠️ CURRENT: %s\\n\\nNumber %s already exists:%s\\n\\n💡 RECOMMENDATION: Consider using .specweave/increments/%s/ instead.\\n\\nOperation ALLOWED - proceeding with current path."}\n' "$SUGGESTED_FOLDER" "$INCREMENT_FOLDER" "$INCREMENT_NUM" "$DUP_LIST" "$SUGGESTED_FOLDER"
|
|
144
|
-
exit 0 # ALLOW with warning (v1.0.37: no blocking!)
|
|
145
|
-
fi
|
|
146
|
-
|
|
147
|
-
# No duplicates - allow
|
|
12
|
+
set +e
|
|
148
13
|
echo '{"decision":"allow"}'
|
|
149
14
|
exit 0
|
|
@@ -1,98 +1,14 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
# metadata-json-guard.sh - DISABLED (v1.0.38)
|
|
2
3
|
#
|
|
3
|
-
#
|
|
4
|
+
# This guard was converted to WARNING-only in v1.0.37, and now completely
|
|
5
|
+
# disabled in v1.0.38 per user feedback: "you MUST NEVER block such operations"
|
|
4
6
|
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
+
# Metadata validation should be handled by agents/scripts with proper business logic,
|
|
8
|
+
# not by hooks that can interfere with file operations.
|
|
7
9
|
#
|
|
8
|
-
#
|
|
9
|
-
# metadata.json may be forgotten, causing:
|
|
10
|
-
# - Status tracking broken
|
|
11
|
-
# - WIP limits don't work
|
|
12
|
-
# - External sync fails (GitHub/Jira/ADO)
|
|
13
|
-
# - All increment commands fail
|
|
14
|
-
#
|
|
15
|
-
# v1.0.37+: CRITICAL CHANGE - Now WARNS instead of BLOCKING!
|
|
16
|
-
# User feedback: "you MUST NEVER block such operations... do at least warning"
|
|
17
|
-
# Business logic and validation should be in scripts/agents, not hard blocks.
|
|
18
|
-
#
|
|
19
|
-
# SOLUTION: WARN if spec.md is created without metadata.json, but ALLOW the operation.
|
|
20
|
-
# The warning prompts Claude to create metadata.json immediately after.
|
|
21
|
-
#
|
|
22
|
-
# Activation:
|
|
23
|
-
# - tool_name: Write
|
|
24
|
-
# - file_path matches: .specweave/increments/*/spec.md
|
|
25
|
-
#
|
|
26
|
-
# Returns exit 0 (allow) with warning message if metadata.json missing
|
|
27
|
-
#
|
|
28
|
-
# Bypass: Set SPECWEAVE_FORCE_METADATA=1 to skip validation
|
|
29
|
-
#
|
|
30
|
-
# v0.34.0 - Initial implementation based on user project bug analysis
|
|
31
|
-
# v1.0.37 - Changed from BLOCK to WARN (allow with warning message)
|
|
32
|
-
|
|
33
|
-
set +e # CRITICAL: Never use set -e in hooks (causes cascading failures)
|
|
34
|
-
|
|
35
|
-
# Check for force bypass
|
|
36
|
-
if [ "$SPECWEAVE_FORCE_METADATA" = "1" ]; then
|
|
37
|
-
echo '{"decision": "allow", "message": "metadata.json guard bypassed (SPECWEAVE_FORCE_METADATA=1)"}'
|
|
38
|
-
exit 0
|
|
39
|
-
fi
|
|
40
|
-
|
|
41
|
-
# Disable hooks bypass
|
|
42
|
-
if [ "$SPECWEAVE_DISABLE_HOOKS" = "1" ]; then
|
|
43
|
-
echo '{"decision": "allow"}'
|
|
44
|
-
exit 0
|
|
45
|
-
fi
|
|
46
|
-
|
|
47
|
-
# Read tool input from stdin (safe handling)
|
|
48
|
-
INPUT=$(cat 2>/dev/null || echo '{}')
|
|
49
|
-
|
|
50
|
-
# Check jq availability - allow if not present
|
|
51
|
-
if ! command -v jq >/dev/null 2>&1; then
|
|
52
|
-
echo '{"decision": "allow"}'
|
|
53
|
-
exit 0
|
|
54
|
-
fi
|
|
55
|
-
|
|
56
|
-
# Extract tool name - with jq fallback
|
|
57
|
-
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // .tool_input.tool_name // ""' 2>/dev/null || echo "")
|
|
58
|
-
|
|
59
|
-
# Only validate Write tool calls
|
|
60
|
-
if [ "$TOOL_NAME" != "Write" ]; then
|
|
61
|
-
echo '{"decision": "allow"}'
|
|
62
|
-
exit 0
|
|
63
|
-
fi
|
|
64
|
-
|
|
65
|
-
# Extract file path - handle both formats
|
|
66
|
-
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .file_path // ""' 2>/dev/null || echo "")
|
|
67
|
-
|
|
68
|
-
# Only validate spec.md files in increments folder
|
|
69
|
-
# Match: 3-4 digits, optional E suffix, kebab-case name, spec.md
|
|
70
|
-
if [[ ! "$FILE_PATH" =~ \.specweave/increments/([0-9]{3,4}E?-[^/]+)/spec\.md$ ]]; then
|
|
71
|
-
echo '{"decision": "allow"}'
|
|
72
|
-
exit 0
|
|
73
|
-
fi
|
|
74
|
-
|
|
75
|
-
# Extract increment folder path
|
|
76
|
-
INCREMENT_DIR=$(dirname "$FILE_PATH")
|
|
77
|
-
INCREMENT_ID="${BASH_REMATCH[1]}"
|
|
78
|
-
|
|
79
|
-
# Check if metadata.json exists in the same increment folder
|
|
80
|
-
METADATA_PATH="${INCREMENT_DIR}/metadata.json"
|
|
81
|
-
|
|
82
|
-
if [ -f "$METADATA_PATH" ]; then
|
|
83
|
-
# metadata.json exists, allow spec.md creation
|
|
84
|
-
echo '{"decision": "allow"}'
|
|
85
|
-
exit 0
|
|
86
|
-
fi
|
|
87
|
-
|
|
88
|
-
# metadata.json doesn't exist - WARN but ALLOW spec.md creation (v1.0.37)
|
|
89
|
-
NOW=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
90
|
-
|
|
91
|
-
cat << WARN_EOF
|
|
92
|
-
{
|
|
93
|
-
"decision": "allow",
|
|
94
|
-
"message": "⚠️ WARNING: metadata.json MISSING - Creating spec.md without it!\n\n🚨 IMMEDIATE ACTION REQUIRED:\nCreate metadata.json NOW for this increment to work properly.\n\nWithout metadata.json:\n - ❌ Status tracking broken\n - ❌ WIP limits don't work\n - ❌ External sync fails (GitHub/Jira/ADO)\n - ❌ All increment commands fail\n\n📋 CREATE metadata.json:\n Write({\n file_path: \"${METADATA_PATH}\",\n content: {\n \"id\": \"${INCREMENT_ID}\",\n \"status\": \"planned\",\n \"type\": \"feature\",\n \"priority\": \"P1\",\n \"created\": \"${NOW}\",\n \"lastActivity\": \"${NOW}\",\n \"testMode\": \"TDD\",\n \"coverageTarget\": 95,\n \"feature_id\": null,\n \"epic_id\": null,\n \"externalLinks\": {}\n }\n })\n\nOperation ALLOWED - proceeding with spec.md write."
|
|
95
|
-
}
|
|
96
|
-
WARN_EOF
|
|
10
|
+
# This guard now does NOTHING - just allows all operations.
|
|
97
11
|
|
|
12
|
+
set +e
|
|
13
|
+
echo '{"decision":"allow"}'
|
|
98
14
|
exit 0
|