specweave 0.33.4 → 0.33.5
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 +20 -12
- package/dist/src/cli/commands/jobs.js +19 -2
- package/dist/src/cli/commands/jobs.js.map +1 -1
- package/dist/src/cli/commands/living-docs.js +1 -1
- package/dist/src/cli/commands/living-docs.js.map +1 -1
- package/dist/src/cli/helpers/init/external-import-grouping.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/external-import-grouping.js +11 -7
- package/dist/src/cli/helpers/init/external-import-grouping.js.map +1 -1
- package/dist/src/cli/workers/clone-worker.js +22 -5
- package/dist/src/cli/workers/clone-worker.js.map +1 -1
- package/dist/src/core/background/job-dependency.d.ts.map +1 -1
- package/dist/src/core/background/job-dependency.js +1 -0
- package/dist/src/core/background/job-dependency.js.map +1 -1
- package/dist/src/core/background/job-launcher.js +2 -2
- package/dist/src/core/background/job-launcher.js.map +1 -1
- package/dist/src/core/background/job-manager.d.ts +8 -0
- package/dist/src/core/background/job-manager.d.ts.map +1 -1
- package/dist/src/core/background/job-manager.js +19 -1
- package/dist/src/core/background/job-manager.js.map +1 -1
- package/dist/src/core/background/types.d.ts +9 -1
- package/dist/src/core/background/types.d.ts.map +1 -1
- package/dist/src/core/background/types.js +8 -1
- package/dist/src/core/background/types.js.map +1 -1
- package/dist/src/importers/external-importer.d.ts +26 -5
- package/dist/src/importers/external-importer.d.ts.map +1 -1
- package/dist/src/importers/item-converter.d.ts.map +1 -1
- package/dist/src/importers/item-converter.js +18 -1
- package/dist/src/importers/item-converter.js.map +1 -1
- package/dist/src/importers/jira-importer.d.ts.map +1 -1
- package/dist/src/importers/jira-importer.js +15 -1
- package/dist/src/importers/jira-importer.js.map +1 -1
- package/dist/src/living-docs/smart-doc-organizer.js +1 -1
- package/dist/src/living-docs/smart-doc-organizer.js.map +1 -1
- package/dist/src/utils/docs-preview/config-generator.d.ts.map +1 -1
- package/dist/src/utils/docs-preview/config-generator.js +4 -0
- package/dist/src/utils/docs-preview/config-generator.js.map +1 -1
- package/dist/src/utils/notification-constants.d.ts +8 -6
- package/dist/src/utils/notification-constants.d.ts.map +1 -1
- package/dist/src/utils/notification-constants.js +8 -6
- package/dist/src/utils/notification-constants.js.map +1 -1
- package/dist/src/utils/notification-manager.d.ts +24 -0
- package/dist/src/utils/notification-manager.d.ts.map +1 -1
- package/dist/src/utils/notification-manager.js +29 -0
- package/dist/src/utils/notification-manager.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/commands/specweave-judge-llm.md +296 -0
- package/plugins/specweave/commands/specweave-organize-docs.md +2 -2
- package/plugins/specweave/hooks/hooks.json +10 -0
- package/plugins/specweave/hooks/v2/guards/metadata-json-guard.sh +87 -0
- package/plugins/specweave/hooks/v2/guards/metadata-json-guard.test.sh +302 -0
- package/plugins/specweave/hooks/v2/guards/per-us-project-validator.sh +72 -18
- package/plugins/specweave/hooks/v2/guards/per-us-project-validator.test.sh +406 -0
- package/plugins/specweave/scripts/session-watchdog.sh +10 -4
- package/plugins/specweave/skills/increment-planner/SKILL.md +1 -1
- package/plugins/specweave-docs/commands/build.md +4 -4
- package/plugins/specweave-docs/commands/generate.md +1 -1
- package/plugins/specweave-docs/commands/health.md +1 -1
- package/plugins/specweave-docs/commands/init.md +1 -1
- package/plugins/specweave-docs/commands/organize.md +2 -2
- package/plugins/specweave-docs/commands/validate.md +1 -1
- package/plugins/specweave-docs/commands/view.md +391 -0
- package/plugins/specweave-docs/skills/preview/SKILL.md +56 -17
- package/src/templates/AGENTS.md.template +24 -28
- package/src/templates/CLAUDE.md.template +12 -8
- package/plugins/specweave/commands/specweave-judge.md +0 -276
- package/plugins/specweave-docs/commands/preview.md +0 -274
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Comprehensive test suite for per-us-project-validator.sh
|
|
3
|
+
# Tests that each User Story in spec.md has **Project**: (and **Board**: for 2-level)
|
|
4
|
+
#
|
|
5
|
+
# Usage: bash per-us-project-validator.test.sh
|
|
6
|
+
#
|
|
7
|
+
# v0.34.0 - Initial test suite with all US formats
|
|
8
|
+
|
|
9
|
+
set -e
|
|
10
|
+
|
|
11
|
+
GUARD="$(dirname "$0")/per-us-project-validator.sh"
|
|
12
|
+
TEST_DIR=$(mktemp -d)
|
|
13
|
+
PASS=0
|
|
14
|
+
FAIL=0
|
|
15
|
+
TOTAL=0
|
|
16
|
+
|
|
17
|
+
# Colors for output
|
|
18
|
+
RED='\033[0;31m'
|
|
19
|
+
GREEN='\033[0;32m'
|
|
20
|
+
YELLOW='\033[1;33m'
|
|
21
|
+
NC='\033[0m' # No Color
|
|
22
|
+
|
|
23
|
+
cleanup() {
|
|
24
|
+
rm -rf "$TEST_DIR"
|
|
25
|
+
}
|
|
26
|
+
trap cleanup EXIT
|
|
27
|
+
|
|
28
|
+
# Test helper: should block
|
|
29
|
+
test_should_block() {
|
|
30
|
+
local name="$1"
|
|
31
|
+
local spec_content="$2"
|
|
32
|
+
TOTAL=$((TOTAL + 1))
|
|
33
|
+
|
|
34
|
+
local file_path="$TEST_DIR/.specweave/increments/0001-test/spec.md"
|
|
35
|
+
mkdir -p "$(dirname "$file_path")"
|
|
36
|
+
|
|
37
|
+
# Build JSON input for the guard
|
|
38
|
+
# Use printf + jq -Rs to properly escape newlines in the content
|
|
39
|
+
local json_input
|
|
40
|
+
json_input=$(printf '%s' "$spec_content" | jq -Rs \
|
|
41
|
+
--arg tool_name "Write" \
|
|
42
|
+
--arg file_path "$file_path" \
|
|
43
|
+
'{tool_name: $tool_name, tool_input: {file_path: $file_path, content: .}}')
|
|
44
|
+
|
|
45
|
+
result=$(echo "$json_input" | bash "$GUARD" 2>&1; echo "EXIT:$?")
|
|
46
|
+
exit_code=$(echo "$result" | grep -o 'EXIT:[0-9]*' | cut -d: -f2)
|
|
47
|
+
|
|
48
|
+
if [[ "$exit_code" == "0" ]] && echo "$result" | grep -q '"decision".*"block"'; then
|
|
49
|
+
echo -e "${GREEN}✓ BLOCKED${NC}: $name"
|
|
50
|
+
PASS=$((PASS + 1))
|
|
51
|
+
else
|
|
52
|
+
echo -e "${RED}✗ NOT BLOCKED${NC}: $name"
|
|
53
|
+
echo " Exit code: $exit_code"
|
|
54
|
+
echo " Result: $(echo "$result" | head -3)"
|
|
55
|
+
FAIL=$((FAIL + 1))
|
|
56
|
+
fi
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
# Test helper: should allow
|
|
60
|
+
test_should_allow() {
|
|
61
|
+
local name="$1"
|
|
62
|
+
local spec_content="$2"
|
|
63
|
+
TOTAL=$((TOTAL + 1))
|
|
64
|
+
|
|
65
|
+
local file_path="$TEST_DIR/.specweave/increments/0001-test/spec.md"
|
|
66
|
+
mkdir -p "$(dirname "$file_path")"
|
|
67
|
+
|
|
68
|
+
# Build JSON input for the guard
|
|
69
|
+
# Use printf + jq -Rs to properly escape newlines in the content
|
|
70
|
+
local json_input
|
|
71
|
+
json_input=$(printf '%s' "$spec_content" | jq -Rs \
|
|
72
|
+
--arg tool_name "Write" \
|
|
73
|
+
--arg file_path "$file_path" \
|
|
74
|
+
'{tool_name: $tool_name, tool_input: {file_path: $file_path, content: .}}')
|
|
75
|
+
|
|
76
|
+
result=$(echo "$json_input" | bash "$GUARD" 2>&1; echo "EXIT:$?")
|
|
77
|
+
exit_code=$(echo "$result" | grep -o 'EXIT:[0-9]*' | cut -d: -f2)
|
|
78
|
+
|
|
79
|
+
if [[ "$exit_code" == "0" ]] && echo "$result" | grep -q '"decision".*"allow"'; then
|
|
80
|
+
echo -e "${GREEN}✓ ALLOWED${NC}: $name"
|
|
81
|
+
PASS=$((PASS + 1))
|
|
82
|
+
else
|
|
83
|
+
echo -e "${RED}✗ WRONGLY BLOCKED${NC}: $name"
|
|
84
|
+
echo " Exit code: $exit_code"
|
|
85
|
+
echo " Result: $(echo "$result" | head -5)"
|
|
86
|
+
FAIL=$((FAIL + 1))
|
|
87
|
+
fi
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
echo "========================================"
|
|
91
|
+
echo " PER-US PROJECT VALIDATOR - COMPREHENSIVE TESTS"
|
|
92
|
+
echo "========================================"
|
|
93
|
+
echo ""
|
|
94
|
+
echo "Test directory: $TEST_DIR"
|
|
95
|
+
echo ""
|
|
96
|
+
|
|
97
|
+
echo -e "${YELLOW}=== SIMPLE US FORMAT (### US-001:) ===${NC}"
|
|
98
|
+
|
|
99
|
+
test_should_allow "Simple US with Project field" '---
|
|
100
|
+
increment: 0001-test
|
|
101
|
+
project: my-app
|
|
102
|
+
---
|
|
103
|
+
# Feature
|
|
104
|
+
|
|
105
|
+
### US-001: Login Form
|
|
106
|
+
**Project**: frontend-app
|
|
107
|
+
|
|
108
|
+
**As a** user
|
|
109
|
+
**I want** to log in
|
|
110
|
+
**So that** I can access the app
|
|
111
|
+
|
|
112
|
+
**Acceptance Criteria**:
|
|
113
|
+
- [ ] **AC-US1-01**: Form exists
|
|
114
|
+
'
|
|
115
|
+
|
|
116
|
+
test_should_block "Simple US WITHOUT Project field" '---
|
|
117
|
+
increment: 0001-test
|
|
118
|
+
project: my-app
|
|
119
|
+
---
|
|
120
|
+
# Feature
|
|
121
|
+
|
|
122
|
+
### US-001: Login Form
|
|
123
|
+
|
|
124
|
+
**As a** user
|
|
125
|
+
**I want** to log in
|
|
126
|
+
**So that** I can access the app
|
|
127
|
+
'
|
|
128
|
+
|
|
129
|
+
echo ""
|
|
130
|
+
echo -e "${YELLOW}=== MULTI-PROJECT US FORMAT (#### US-FE-001:) ===${NC}"
|
|
131
|
+
|
|
132
|
+
test_should_allow "Multi-project US-FE-001 with Project field" '---
|
|
133
|
+
increment: 0001-test
|
|
134
|
+
project: my-app
|
|
135
|
+
multi_project: true
|
|
136
|
+
---
|
|
137
|
+
# Feature
|
|
138
|
+
|
|
139
|
+
#### US-FE-001: Login Form UI
|
|
140
|
+
**Project**: frontend-app
|
|
141
|
+
|
|
142
|
+
**As a** user
|
|
143
|
+
**I want** to see a login form
|
|
144
|
+
|
|
145
|
+
#### US-BE-001: Auth API
|
|
146
|
+
**Project**: backend-api
|
|
147
|
+
|
|
148
|
+
**As a** frontend
|
|
149
|
+
**I want** auth endpoints
|
|
150
|
+
'
|
|
151
|
+
|
|
152
|
+
test_should_block "Multi-project US-FE-001 WITHOUT Project field" '---
|
|
153
|
+
increment: 0001-test
|
|
154
|
+
project: my-app
|
|
155
|
+
multi_project: true
|
|
156
|
+
---
|
|
157
|
+
# Feature
|
|
158
|
+
|
|
159
|
+
#### US-FE-001: Login Form UI
|
|
160
|
+
|
|
161
|
+
**As a** user
|
|
162
|
+
**I want** to see a login form
|
|
163
|
+
'
|
|
164
|
+
|
|
165
|
+
echo ""
|
|
166
|
+
echo -e "${YELLOW}=== MIXED FORMAT (### with prefixes) ===${NC}"
|
|
167
|
+
|
|
168
|
+
test_should_allow "Mixed: ### US-FE-001 with Project" '---
|
|
169
|
+
increment: 0001-test
|
|
170
|
+
project: my-app
|
|
171
|
+
---
|
|
172
|
+
# Feature
|
|
173
|
+
|
|
174
|
+
### US-FE-001: Frontend Story
|
|
175
|
+
**Project**: frontend
|
|
176
|
+
|
|
177
|
+
### US-BE-001: Backend Story
|
|
178
|
+
**Project**: backend
|
|
179
|
+
'
|
|
180
|
+
|
|
181
|
+
test_should_block "Mixed: ### US-FE-001 without Project" '---
|
|
182
|
+
increment: 0001-test
|
|
183
|
+
project: my-app
|
|
184
|
+
---
|
|
185
|
+
# Feature
|
|
186
|
+
|
|
187
|
+
### US-FE-001: Frontend Story
|
|
188
|
+
|
|
189
|
+
### US-BE-001: Backend Story
|
|
190
|
+
**Project**: backend
|
|
191
|
+
'
|
|
192
|
+
|
|
193
|
+
echo ""
|
|
194
|
+
echo -e "${YELLOW}=== SHARED PROJECT PREFIX ===${NC}"
|
|
195
|
+
|
|
196
|
+
test_should_allow "US-SHARED-001 with Project" '---
|
|
197
|
+
increment: 0001-test
|
|
198
|
+
project: my-app
|
|
199
|
+
---
|
|
200
|
+
# Feature
|
|
201
|
+
|
|
202
|
+
#### US-SHARED-001: Shared Types
|
|
203
|
+
**Project**: shared-lib
|
|
204
|
+
|
|
205
|
+
**As a** developer
|
|
206
|
+
**I want** shared types
|
|
207
|
+
'
|
|
208
|
+
|
|
209
|
+
test_should_block "US-SHARED-001 without Project" '---
|
|
210
|
+
increment: 0001-test
|
|
211
|
+
project: my-app
|
|
212
|
+
---
|
|
213
|
+
# Feature
|
|
214
|
+
|
|
215
|
+
#### US-SHARED-001: Shared Types
|
|
216
|
+
|
|
217
|
+
**As a** developer
|
|
218
|
+
**I want** shared types
|
|
219
|
+
'
|
|
220
|
+
|
|
221
|
+
echo ""
|
|
222
|
+
echo -e "${YELLOW}=== MULTIPLE PROJECTS (1:1 VIOLATION - COMMA SEPARATED) ===${NC}"
|
|
223
|
+
|
|
224
|
+
test_should_block "Multiple projects (comma separated) - FORBIDDEN" '---
|
|
225
|
+
increment: 0001-test
|
|
226
|
+
project: my-app
|
|
227
|
+
---
|
|
228
|
+
# Feature
|
|
229
|
+
|
|
230
|
+
### US-001: Cross-cutting Story
|
|
231
|
+
**Project**: frontend-app, backend-api
|
|
232
|
+
|
|
233
|
+
**As a** user
|
|
234
|
+
**I want** everything
|
|
235
|
+
'
|
|
236
|
+
|
|
237
|
+
test_should_block "Multiple projects with spaces" '---
|
|
238
|
+
increment: 0001-test
|
|
239
|
+
project: my-app
|
|
240
|
+
---
|
|
241
|
+
# Feature
|
|
242
|
+
|
|
243
|
+
### US-001: Cross-cutting Story
|
|
244
|
+
**Project**: frontend-app,backend-api,shared
|
|
245
|
+
|
|
246
|
+
**As a** user
|
|
247
|
+
**I want** everything
|
|
248
|
+
'
|
|
249
|
+
|
|
250
|
+
echo ""
|
|
251
|
+
echo -e "${YELLOW}=== NO USER STORIES (should allow) ===${NC}"
|
|
252
|
+
|
|
253
|
+
test_should_allow "Spec without any User Stories" '---
|
|
254
|
+
increment: 0001-test
|
|
255
|
+
project: my-app
|
|
256
|
+
---
|
|
257
|
+
# Feature Overview
|
|
258
|
+
|
|
259
|
+
This is just an overview document.
|
|
260
|
+
|
|
261
|
+
## Goals
|
|
262
|
+
|
|
263
|
+
- Goal 1
|
|
264
|
+
- Goal 2
|
|
265
|
+
'
|
|
266
|
+
|
|
267
|
+
test_should_allow "Tasks-only spec (no US headings)" '---
|
|
268
|
+
increment: 0001-test
|
|
269
|
+
project: my-app
|
|
270
|
+
---
|
|
271
|
+
# Implementation Tasks
|
|
272
|
+
|
|
273
|
+
## T-001: Setup
|
|
274
|
+
|
|
275
|
+
Do setup stuff.
|
|
276
|
+
'
|
|
277
|
+
|
|
278
|
+
echo ""
|
|
279
|
+
echo -e "${YELLOW}=== ALL USER STORIES HAVE PROJECT ===${NC}"
|
|
280
|
+
|
|
281
|
+
test_should_allow "Multiple US, all with Project" '---
|
|
282
|
+
increment: 0001-test
|
|
283
|
+
project: my-app
|
|
284
|
+
---
|
|
285
|
+
# Feature
|
|
286
|
+
|
|
287
|
+
### US-001: First Story
|
|
288
|
+
**Project**: app-a
|
|
289
|
+
|
|
290
|
+
### US-002: Second Story
|
|
291
|
+
**Project**: app-b
|
|
292
|
+
|
|
293
|
+
### US-003: Third Story
|
|
294
|
+
**Project**: app-c
|
|
295
|
+
'
|
|
296
|
+
|
|
297
|
+
test_should_block "Multiple US, one missing Project" '---
|
|
298
|
+
increment: 0001-test
|
|
299
|
+
project: my-app
|
|
300
|
+
---
|
|
301
|
+
# Feature
|
|
302
|
+
|
|
303
|
+
### US-001: First Story
|
|
304
|
+
**Project**: app-a
|
|
305
|
+
|
|
306
|
+
### US-002: Second Story
|
|
307
|
+
|
|
308
|
+
### US-003: Third Story
|
|
309
|
+
**Project**: app-c
|
|
310
|
+
'
|
|
311
|
+
|
|
312
|
+
echo ""
|
|
313
|
+
echo -e "${YELLOW}=== NON-WRITE TOOLS ===${NC}"
|
|
314
|
+
|
|
315
|
+
# Test with Edit tool (should allow - no full content)
|
|
316
|
+
TOTAL=$((TOTAL + 1))
|
|
317
|
+
json_input=$(jq -n \
|
|
318
|
+
--arg tool_name "Edit" \
|
|
319
|
+
--arg file_path "$TEST_DIR/.specweave/increments/0001-test/spec.md" \
|
|
320
|
+
'{tool_name: $tool_name, tool_input: {file_path: $file_path}}')
|
|
321
|
+
|
|
322
|
+
result=$(echo "$json_input" | bash "$GUARD" 2>&1; echo "EXIT:$?")
|
|
323
|
+
exit_code=$(echo "$result" | grep -o 'EXIT:[0-9]*' | cut -d: -f2)
|
|
324
|
+
if [[ "$exit_code" == "0" ]]; then
|
|
325
|
+
echo -e "${GREEN}✓ ALLOWED${NC}: Edit tool (no full content validation)"
|
|
326
|
+
PASS=$((PASS + 1))
|
|
327
|
+
else
|
|
328
|
+
echo -e "${RED}✗ FAILED${NC}: Edit tool should be allowed"
|
|
329
|
+
FAIL=$((FAIL + 1))
|
|
330
|
+
fi
|
|
331
|
+
|
|
332
|
+
echo ""
|
|
333
|
+
echo -e "${YELLOW}=== BYPASS MODES ===${NC}"
|
|
334
|
+
|
|
335
|
+
# Test SPECWEAVE_FORCE_PROJECT bypass
|
|
336
|
+
TOTAL=$((TOTAL + 1))
|
|
337
|
+
spec_content='---
|
|
338
|
+
increment: 0001-test
|
|
339
|
+
---
|
|
340
|
+
### US-001: No Project
|
|
341
|
+
**As a** user
|
|
342
|
+
**I want** something
|
|
343
|
+
'
|
|
344
|
+
json_input=$(jq -n \
|
|
345
|
+
--arg tool_name "Write" \
|
|
346
|
+
--arg file_path "$TEST_DIR/.specweave/increments/0001-test/spec.md" \
|
|
347
|
+
--arg content "$spec_content" \
|
|
348
|
+
'{tool_name: $tool_name, tool_input: {file_path: $file_path, content: $content}}')
|
|
349
|
+
|
|
350
|
+
result=$(SPECWEAVE_FORCE_PROJECT=1 bash -c "echo '$json_input' | bash '$GUARD'" 2>&1; echo "EXIT:$?")
|
|
351
|
+
exit_code=$(echo "$result" | grep -o 'EXIT:[0-9]*' | cut -d: -f2)
|
|
352
|
+
if [[ "$exit_code" == "0" ]] && echo "$result" | grep -q "bypassed"; then
|
|
353
|
+
echo -e "${GREEN}✓ ALLOWED (bypass)${NC}: SPECWEAVE_FORCE_PROJECT=1"
|
|
354
|
+
PASS=$((PASS + 1))
|
|
355
|
+
else
|
|
356
|
+
echo -e "${RED}✗ BYPASS FAILED${NC}: SPECWEAVE_FORCE_PROJECT=1"
|
|
357
|
+
FAIL=$((FAIL + 1))
|
|
358
|
+
fi
|
|
359
|
+
|
|
360
|
+
# Test SPECWEAVE_LEGACY_SPEC bypass
|
|
361
|
+
TOTAL=$((TOTAL + 1))
|
|
362
|
+
result=$(SPECWEAVE_LEGACY_SPEC=1 bash -c "echo '$json_input' | bash '$GUARD'" 2>&1; echo "EXIT:$?")
|
|
363
|
+
exit_code=$(echo "$result" | grep -o 'EXIT:[0-9]*' | cut -d: -f2)
|
|
364
|
+
if [[ "$exit_code" == "0" ]] && echo "$result" | grep -q "legacy"; then
|
|
365
|
+
echo -e "${GREEN}✓ ALLOWED (bypass)${NC}: SPECWEAVE_LEGACY_SPEC=1"
|
|
366
|
+
PASS=$((PASS + 1))
|
|
367
|
+
else
|
|
368
|
+
echo -e "${RED}✗ BYPASS FAILED${NC}: SPECWEAVE_LEGACY_SPEC=1"
|
|
369
|
+
FAIL=$((FAIL + 1))
|
|
370
|
+
fi
|
|
371
|
+
|
|
372
|
+
echo ""
|
|
373
|
+
echo -e "${YELLOW}=== FILES OUTSIDE INCREMENTS ===${NC}"
|
|
374
|
+
|
|
375
|
+
# Test file outside increments folder
|
|
376
|
+
TOTAL=$((TOTAL + 1))
|
|
377
|
+
json_input=$(jq -n \
|
|
378
|
+
--arg tool_name "Write" \
|
|
379
|
+
--arg file_path "$TEST_DIR/other/spec.md" \
|
|
380
|
+
--arg content "no project" \
|
|
381
|
+
'{tool_name: $tool_name, tool_input: {file_path: $file_path, content: $content}}')
|
|
382
|
+
|
|
383
|
+
result=$(echo "$json_input" | bash "$GUARD" 2>&1; echo "EXIT:$?")
|
|
384
|
+
exit_code=$(echo "$result" | grep -o 'EXIT:[0-9]*' | cut -d: -f2)
|
|
385
|
+
if [[ "$exit_code" == "0" ]] && echo "$result" | grep -q '"decision".*"allow"'; then
|
|
386
|
+
echo -e "${GREEN}✓ ALLOWED${NC}: spec.md outside increments folder"
|
|
387
|
+
PASS=$((PASS + 1))
|
|
388
|
+
else
|
|
389
|
+
echo -e "${RED}✗ FAILED${NC}: Files outside increments should be allowed"
|
|
390
|
+
FAIL=$((FAIL + 1))
|
|
391
|
+
fi
|
|
392
|
+
|
|
393
|
+
echo ""
|
|
394
|
+
echo "========================================"
|
|
395
|
+
echo " RESULTS"
|
|
396
|
+
echo "========================================"
|
|
397
|
+
echo -e "Total: $TOTAL"
|
|
398
|
+
echo -e "${GREEN}Passed: $PASS${NC}"
|
|
399
|
+
if [[ $FAIL -gt 0 ]]; then
|
|
400
|
+
echo -e "${RED}Failed: $FAIL${NC}"
|
|
401
|
+
exit 1
|
|
402
|
+
else
|
|
403
|
+
echo -e "Failed: 0"
|
|
404
|
+
echo ""
|
|
405
|
+
echo -e "${GREEN}ALL TESTS PASSED!${NC}"
|
|
406
|
+
fi
|
|
@@ -77,15 +77,21 @@ send_notification() {
|
|
|
77
77
|
return
|
|
78
78
|
fi
|
|
79
79
|
|
|
80
|
-
# macOS notification
|
|
80
|
+
# macOS notification - use "Submarine" for warnings (not alarming like "Basso")
|
|
81
|
+
# Per CLAUDE.md section 11: Basso = ONLY critical errors requiring IMMEDIATE action
|
|
82
|
+
# Zombie detection is recoverable - user can run cleanup script when convenient
|
|
81
83
|
if command -v osascript &> /dev/null; then
|
|
82
|
-
osascript -e "display notification \"$message\" with title \"$title\" sound name \"
|
|
84
|
+
osascript -e "display notification \"$message\" with title \"$title\" sound name \"Submarine\""
|
|
83
85
|
fi
|
|
84
86
|
|
|
85
|
-
# Linux notification (if available)
|
|
87
|
+
# Linux notification (if available) - use "normal" urgency (not "critical")
|
|
88
|
+
# Critical urgency can bypass Do Not Disturb, which is too aggressive
|
|
86
89
|
if command -v notify-send &> /dev/null; then
|
|
87
|
-
notify-send "$title" "$message" --urgency=
|
|
90
|
+
notify-send "$title" "$message" --urgency=normal
|
|
88
91
|
fi
|
|
92
|
+
|
|
93
|
+
# Windows: notifications sent via PowerShell toast don't have urgency levels
|
|
94
|
+
# They're always non-alarming by design
|
|
89
95
|
}
|
|
90
96
|
|
|
91
97
|
get_file_age_seconds() {
|
|
@@ -243,7 +243,7 @@ For each US you will generate:
|
|
|
243
243
|
|
|
244
244
|
❌ FORBIDDEN: Skipping this step and generating spec.md directly
|
|
245
245
|
❌ FORBIDDEN: Inventing project names not in the API output
|
|
246
|
-
❌ FORBIDDEN: Using folder names as project (e.g., "
|
|
246
|
+
❌ FORBIDDEN: Using folder names as project (e.g., "my-project-folder")
|
|
247
247
|
❌ FORBIDDEN: Using {{PROJECT_ID}} or {{BOARD_ID}} placeholders
|
|
248
248
|
❌ FORBIDDEN: Creating spec.md for 2-level without board: field
|
|
249
249
|
❌ FORBIDDEN: Generating spec.md without running context API first
|
|
@@ -52,7 +52,7 @@ if [ ! -d ".specweave/cache/docs-site/node_modules" ]; then
|
|
|
52
52
|
fi
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
-
If not set up, follow the same setup steps as `/specweave-docs:
|
|
55
|
+
If not set up, follow the same setup steps as `/specweave-docs:view` (Step 3 in view.md).
|
|
56
56
|
|
|
57
57
|
### Step 3: Run Build
|
|
58
58
|
|
|
@@ -131,8 +131,8 @@ git commit -m "docs: update documentation site"
|
|
|
131
131
|
|
|
132
132
|
### Build fails with broken links
|
|
133
133
|
```bash
|
|
134
|
-
#
|
|
135
|
-
/specweave-docs:
|
|
134
|
+
# View docs first to find errors
|
|
135
|
+
/specweave-docs:view
|
|
136
136
|
# Fix broken links, then build
|
|
137
137
|
/specweave-docs:build
|
|
138
138
|
```
|
|
@@ -155,6 +155,6 @@ rm -rf .specweave/cache/docs-site
|
|
|
155
155
|
|
|
156
156
|
## See Also
|
|
157
157
|
|
|
158
|
-
- `/specweave-docs:
|
|
158
|
+
- `/specweave-docs:view` - View docs locally with hot reload
|
|
159
159
|
- `/specweave-docs:organize` - Organize large folders with themed indexes
|
|
160
160
|
- `/specweave-docs:health` - Documentation health report
|
|
@@ -408,7 +408,7 @@ cat ./docs/api/index.md ./docs/specs/index.md > ./docs/complete-reference.md
|
|
|
408
408
|
## Related Commands
|
|
409
409
|
|
|
410
410
|
- `/specweave-docs:init` - Initialize Docusaurus documentation site
|
|
411
|
-
- `/specweave-docs:
|
|
411
|
+
- `/specweave-docs:view` - View generated documentation
|
|
412
412
|
- `/specweave-docs:build` - Build static site from generated docs
|
|
413
413
|
|
|
414
414
|
## Requirements
|
|
@@ -264,5 +264,5 @@ jobs:
|
|
|
264
264
|
## See Also
|
|
265
265
|
|
|
266
266
|
- `/specweave-docs:organize` - Organize large folders with themed indexes
|
|
267
|
-
- `/specweave-docs:
|
|
267
|
+
- `/specweave-docs:view` - View documentation with Docusaurus
|
|
268
268
|
- `/specweave-docs:generate` - Generate docs from code
|
|
@@ -309,7 +309,7 @@ themeConfig: {
|
|
|
309
309
|
## Related Commands
|
|
310
310
|
|
|
311
311
|
- `/specweave-docs:generate` - Generate docs from code/specs
|
|
312
|
-
- `/specweave-docs:
|
|
312
|
+
- `/specweave-docs:view` - Launch documentation server
|
|
313
313
|
- `/specweave-docs:build` - Build static documentation site
|
|
314
314
|
|
|
315
315
|
## Requirements
|
|
@@ -161,7 +161,7 @@ Generated 9 index files:
|
|
|
161
161
|
After running this command, use:
|
|
162
162
|
|
|
163
163
|
```bash
|
|
164
|
-
/specweave-docs:
|
|
164
|
+
/specweave-docs:view
|
|
165
165
|
```
|
|
166
166
|
|
|
167
167
|
The generated indexes will appear in the sidebar:
|
|
@@ -179,6 +179,6 @@ The generated indexes will appear in the sidebar:
|
|
|
179
179
|
|
|
180
180
|
## See Also
|
|
181
181
|
|
|
182
|
-
- `/specweave-docs:
|
|
182
|
+
- `/specweave-docs:view` - View documentation with Docusaurus
|
|
183
183
|
- `/specweave-docs:build` - Build static documentation site
|
|
184
184
|
- `/specweave-docs:health` - Documentation health report
|
|
@@ -245,6 +245,6 @@ onBrokenMarkdownLinks: 'warn',
|
|
|
245
245
|
|
|
246
246
|
## See Also
|
|
247
247
|
|
|
248
|
-
- `/specweave-docs:
|
|
248
|
+
- `/specweave-docs:view` - View docs (runs validation first)
|
|
249
249
|
- `/specweave-docs:build` - Build docs (runs validation first)
|
|
250
250
|
- `/specweave-docs:health` - Full documentation health report
|