specweave 1.0.44 → 1.0.46
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
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
<!-- SW:META template="claude" version="1.0.
|
|
1
|
+
<!-- SW:META template="claude" version="1.0.44" sections="header,start,autodetect,metarule,rules,workflow,structure,taskformat,secrets,syncing,mapping,testing,limits,troubleshooting,principles,linking,docs" -->
|
|
2
2
|
|
|
3
|
-
<!-- SW:SECTION:header version="1.0.
|
|
3
|
+
<!-- SW:SECTION:header version="1.0.44" -->
|
|
4
4
|
**Framework**: SpecWeave | **Truth**: `spec.md` + `tasks.md`
|
|
5
5
|
<!-- SW:END:header -->
|
|
6
6
|
|
|
7
|
-
<!-- SW:SECTION:start version="1.0.
|
|
7
|
+
<!-- SW:SECTION:start version="1.0.44" -->
|
|
8
8
|
## Getting Started
|
|
9
9
|
|
|
10
10
|
**Initial increment**: `0001-project-setup` (auto-created by `specweave init`)
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
2. **Customize**: Edit spec.md and use for setup tasks
|
|
15
15
|
<!-- SW:END:start -->
|
|
16
16
|
|
|
17
|
-
<!-- SW:SECTION:autodetect version="1.0.
|
|
17
|
+
<!-- SW:SECTION:autodetect version="1.0.44" -->
|
|
18
18
|
## Auto-Detection
|
|
19
19
|
|
|
20
20
|
SpecWeave auto-detects product descriptions and routes to `/sw:increment`:
|
|
@@ -24,7 +24,7 @@ SpecWeave auto-detects product descriptions and routes to `/sw:increment`:
|
|
|
24
24
|
**Opt-out phrases**: "Just brainstorm first" | "Don't plan yet" | "Quick discussion" | "Let's explore ideas"
|
|
25
25
|
<!-- SW:END:autodetect -->
|
|
26
26
|
|
|
27
|
-
<!-- SW:SECTION:metarule version="1.0.
|
|
27
|
+
<!-- SW:SECTION:metarule version="1.0.44" -->
|
|
28
28
|
## Meta-Rule: Think-Before-Act
|
|
29
29
|
|
|
30
30
|
**Satisfy dependencies BEFORE dependent operations.**
|
|
@@ -35,7 +35,7 @@ SpecWeave auto-detects product descriptions and routes to `/sw:increment`:
|
|
|
35
35
|
```
|
|
36
36
|
<!-- SW:END:metarule -->
|
|
37
37
|
|
|
38
|
-
<!-- SW:SECTION:rules version="1.0.
|
|
38
|
+
<!-- SW:SECTION:rules version="1.0.44" -->
|
|
39
39
|
## Rules
|
|
40
40
|
|
|
41
41
|
1. **Files** → `.specweave/increments/####-name/` (spec.md, plan.md, tasks.md at root; reports/, scripts/, logs/ subfolders)
|
|
@@ -45,7 +45,7 @@ SpecWeave auto-detects product descriptions and routes to `/sw:increment`:
|
|
|
45
45
|
5. **Root clean**: NEVER create .md/reports/scripts in project root → use increment folders
|
|
46
46
|
<!-- SW:END:rules -->
|
|
47
47
|
|
|
48
|
-
<!-- SW:SECTION:workflow version="1.0.
|
|
48
|
+
<!-- SW:SECTION:workflow version="1.0.44" -->
|
|
49
49
|
## Workflow
|
|
50
50
|
|
|
51
51
|
`/sw:increment "X"` → `/sw:do` → `/sw:progress` → `/sw:done 0001`
|
|
@@ -62,7 +62,7 @@ SpecWeave auto-detects product descriptions and routes to `/sw:increment`:
|
|
|
62
62
|
**Natural language**: "Let's build X" → `/sw:increment` | "What's status?" → `/sw:progress` | "We're done" → `/sw:done`
|
|
63
63
|
<!-- SW:END:workflow -->
|
|
64
64
|
|
|
65
|
-
<!-- SW:SECTION:structure version="1.0.
|
|
65
|
+
<!-- SW:SECTION:structure version="1.0.44" -->
|
|
66
66
|
## Structure
|
|
67
67
|
|
|
68
68
|
```
|
|
@@ -84,7 +84,7 @@ SpecWeave auto-detects product descriptions and routes to `/sw:increment`:
|
|
|
84
84
|
**Path syntax**: `//path` = absolute | `/path` = relative to settings file | `**` = recursive | `additionalDirectories` = explicit working dirs
|
|
85
85
|
<!-- SW:END:structure -->
|
|
86
86
|
|
|
87
|
-
<!-- SW:SECTION:taskformat version="1.0.
|
|
87
|
+
<!-- SW:SECTION:taskformat version="1.0.44" -->
|
|
88
88
|
## Task Format
|
|
89
89
|
|
|
90
90
|
```markdown
|
|
@@ -94,7 +94,7 @@ SpecWeave auto-detects product descriptions and routes to `/sw:increment`:
|
|
|
94
94
|
```
|
|
95
95
|
<!-- SW:END:taskformat -->
|
|
96
96
|
|
|
97
|
-
<!-- SW:SECTION:secrets version="1.0.
|
|
97
|
+
<!-- SW:SECTION:secrets version="1.0.44" -->
|
|
98
98
|
## Secrets Check
|
|
99
99
|
|
|
100
100
|
**BEFORE CLI tools**: Check existing config first!
|
|
@@ -105,7 +105,7 @@ gh auth status
|
|
|
105
105
|
```
|
|
106
106
|
<!-- SW:END:secrets -->
|
|
107
107
|
|
|
108
|
-
<!-- SW:SECTION:syncing version="1.0.
|
|
108
|
+
<!-- SW:SECTION:syncing version="1.0.44" -->
|
|
109
109
|
## External Sync (GitHub/JIRA/ADO)
|
|
110
110
|
|
|
111
111
|
**After increment creation**: Run `/sw-github:sync {id}` to create issues!
|
|
@@ -124,7 +124,7 @@ Living docs sync ≠ External sync. They are separate:
|
|
|
124
124
|
**Verify tokens**: `grep GITHUB_TOKEN .env` | `gh auth status`
|
|
125
125
|
<!-- SW:END:syncing -->
|
|
126
126
|
|
|
127
|
-
<!-- SW:SECTION:mapping version="1.0.
|
|
127
|
+
<!-- SW:SECTION:mapping version="1.0.44" -->
|
|
128
128
|
## GitHub Mapping
|
|
129
129
|
|
|
130
130
|
| SpecWeave | GitHub |
|
|
@@ -134,7 +134,7 @@ Living docs sync ≠ External sync. They are separate:
|
|
|
134
134
|
| Task T-XXX | Checkbox |
|
|
135
135
|
<!-- SW:END:mapping -->
|
|
136
136
|
|
|
137
|
-
<!-- SW:SECTION:testing version="1.0.
|
|
137
|
+
<!-- SW:SECTION:testing version="1.0.44" -->
|
|
138
138
|
## Testing
|
|
139
139
|
|
|
140
140
|
BDD in tasks.md | Unit >80% | `.test.ts` (Vitest)
|
|
@@ -146,13 +146,13 @@ vi.mock('fs', () => ({ readFile: vi.fn() }));
|
|
|
146
146
|
```
|
|
147
147
|
<!-- SW:END:testing -->
|
|
148
148
|
|
|
149
|
-
<!-- SW:SECTION:limits version="1.0.
|
|
149
|
+
<!-- SW:SECTION:limits version="1.0.44" -->
|
|
150
150
|
## Limits
|
|
151
151
|
|
|
152
152
|
**Max 1500 lines/file** — extract before adding
|
|
153
153
|
<!-- SW:END:limits -->
|
|
154
154
|
|
|
155
|
-
<!-- SW:SECTION:troubleshooting version="1.0.
|
|
155
|
+
<!-- SW:SECTION:troubleshooting version="1.0.44" -->
|
|
156
156
|
## Troubleshooting
|
|
157
157
|
|
|
158
158
|
| Issue | Fix |
|
|
@@ -170,7 +170,7 @@ vi.mock('fs', () => ({ readFile: vi.fn() }));
|
|
|
170
170
|
| Path patterns not working | `//path` = absolute, `/path` = relative to settings file, `additionalDirectories` for explicit working dirs |
|
|
171
171
|
<!-- SW:END:troubleshooting -->
|
|
172
172
|
|
|
173
|
-
<!-- SW:SECTION:principles version="1.0.
|
|
173
|
+
<!-- SW:SECTION:principles version="1.0.44" -->
|
|
174
174
|
## Principles
|
|
175
175
|
|
|
176
176
|
1. **Spec-first**: `/sw:increment` before coding
|
|
@@ -180,7 +180,7 @@ vi.mock('fs', () => ({ readFile: vi.fn() }));
|
|
|
180
180
|
5. **Clean**: All files in increment folders
|
|
181
181
|
<!-- SW:END:principles -->
|
|
182
182
|
|
|
183
|
-
<!-- SW:SECTION:linking version="1.0.
|
|
183
|
+
<!-- SW:SECTION:linking version="1.0.44" -->
|
|
184
184
|
## Bidirectional Linking
|
|
185
185
|
|
|
186
186
|
Tasks ↔ User Stories auto-linked via AC-IDs: `AC-US1-01` → `US-001`
|
|
@@ -188,7 +188,7 @@ Tasks ↔ User Stories auto-linked via AC-IDs: `AC-US1-01` → `US-001`
|
|
|
188
188
|
Task format: `**AC**: AC-US1-01, AC-US1-02` (CRITICAL for linking)
|
|
189
189
|
<!-- SW:END:linking -->
|
|
190
190
|
|
|
191
|
-
<!-- SW:SECTION:docs version="1.0.
|
|
191
|
+
<!-- SW:SECTION:docs version="1.0.44" -->
|
|
192
192
|
## Docs
|
|
193
193
|
|
|
194
194
|
[spec-weave.com](https://spec-weave.com) | `.specweave/docs/internal/`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specweave",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.46",
|
|
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",
|
|
@@ -1,24 +1,38 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# github-sync-handler.sh - Sync increment to GitHub (create issues for User Stories)
|
|
2
|
+
# github-sync-handler.sh - Sync increment to GitHub (create/update issues for User Stories)
|
|
3
3
|
# Called async by processor, non-blocking, error-tolerant
|
|
4
4
|
#
|
|
5
5
|
# Argument formats supported:
|
|
6
6
|
# 1. (event_type, increment_id) - from lifecycle/spec.updated events
|
|
7
|
-
# 2. (
|
|
7
|
+
# 2. (event_type, INC_ID:US_ID) - from user-story.completed/reopened events (v1.0.45+)
|
|
8
|
+
# 3. (increment_id) - from metadata.changed events (legacy)
|
|
9
|
+
#
|
|
10
|
+
# CRITICAL FIX (v1.0.45): Added user-story.completed/reopened support
|
|
11
|
+
# Root cause: GitHub issues were created but NEVER UPDATED when User Stories completed!
|
|
8
12
|
#
|
|
9
13
|
# IMPORTANT: Never crash Claude, always exit 0
|
|
10
14
|
set +e
|
|
11
15
|
|
|
12
16
|
[[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]] && exit 0
|
|
13
17
|
|
|
14
|
-
#
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
INC_ID="
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
# Parse arguments - support multiple formats
|
|
19
|
+
EVENT_TYPE="${1:-}"
|
|
20
|
+
EVENT_DATA="${2:-}"
|
|
21
|
+
INC_ID=""
|
|
22
|
+
US_ID=""
|
|
23
|
+
|
|
24
|
+
if [[ "$EVENT_TYPE" == user-story.* ]]; then
|
|
25
|
+
# user-story.completed/reopened: $2 = INC_ID:US_ID
|
|
26
|
+
INC_ID="${EVENT_DATA%%:*}"
|
|
27
|
+
US_ID="${EVENT_DATA##*:}"
|
|
28
|
+
elif [[ "$EVENT_TYPE" == increment.* ]] || [[ "$EVENT_TYPE" == spec.* ]] || [[ "$EVENT_TYPE" == metadata.* ]]; then
|
|
29
|
+
# Lifecycle events: $2 = increment_id
|
|
30
|
+
INC_ID="$EVENT_DATA"
|
|
31
|
+
else
|
|
32
|
+
# Legacy format: $1 = increment_id directly
|
|
33
|
+
INC_ID="$EVENT_TYPE"
|
|
21
34
|
fi
|
|
35
|
+
|
|
22
36
|
[[ -z "$INC_ID" ]] && exit 0
|
|
23
37
|
|
|
24
38
|
# Find project root
|
|
@@ -35,12 +49,24 @@ CONFIG_FILE="$PROJECT_ROOT/.specweave/config.json"
|
|
|
35
49
|
GITHUB_ENABLED=$(grep -o '"enabled"[[:space:]]*:[[:space:]]*true' "$CONFIG_FILE" | head -1)
|
|
36
50
|
[[ -z "$GITHUB_ENABLED" ]] && exit 0
|
|
37
51
|
|
|
38
|
-
# Throttle:
|
|
39
|
-
|
|
52
|
+
# Throttle configuration:
|
|
53
|
+
# - Full sync (increment lifecycle): 5 minutes (creates all issues)
|
|
54
|
+
# - US completion sync: 60 seconds (more targeted, less aggressive)
|
|
40
55
|
THROTTLE_LOG="$PROJECT_ROOT/.specweave/logs/throttle.log"
|
|
41
|
-
THROTTLE_WINDOW=300 # 5 minutes
|
|
42
56
|
mkdir -p "$(dirname "$THROTTLE_LOG")" 2>/dev/null
|
|
43
57
|
|
|
58
|
+
if [[ -n "$US_ID" ]]; then
|
|
59
|
+
# Per-US throttle (60 seconds) - more frequent for targeted updates
|
|
60
|
+
THROTTLE_FILE="$PROJECT_ROOT/.specweave/state/.github-sync-$INC_ID-$US_ID"
|
|
61
|
+
THROTTLE_WINDOW=60
|
|
62
|
+
SYNC_TYPE="US:$US_ID"
|
|
63
|
+
else
|
|
64
|
+
# Per-increment throttle (5 minutes) - less frequent for full sync
|
|
65
|
+
THROTTLE_FILE="$PROJECT_ROOT/.specweave/state/.github-sync-$INC_ID"
|
|
66
|
+
THROTTLE_WINDOW=300
|
|
67
|
+
SYNC_TYPE="increment"
|
|
68
|
+
fi
|
|
69
|
+
|
|
44
70
|
if [[ -f "$THROTTLE_FILE" ]]; then
|
|
45
71
|
if [[ "$(uname)" == "Darwin" ]]; then
|
|
46
72
|
AGE=$(($(date +%s) - $(stat -f %m "$THROTTLE_FILE" 2>/dev/null || echo 0)))
|
|
@@ -49,12 +75,12 @@ if [[ -f "$THROTTLE_FILE" ]]; then
|
|
|
49
75
|
fi
|
|
50
76
|
if [[ $AGE -lt $THROTTLE_WINDOW ]]; then
|
|
51
77
|
REMAINING=$((THROTTLE_WINDOW - AGE))
|
|
52
|
-
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [github-sync] THROTTLED $INC_ID (wait ${REMAINING}s
|
|
78
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [github-sync] THROTTLED $INC_ID ($SYNC_TYPE, wait ${REMAINING}s)" >> "$THROTTLE_LOG" 2>/dev/null
|
|
53
79
|
exit 0
|
|
54
80
|
fi
|
|
55
81
|
fi
|
|
56
82
|
touch "$THROTTLE_FILE"
|
|
57
|
-
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [github-sync] EXECUTING $INC_ID" >> "$THROTTLE_LOG" 2>/dev/null
|
|
83
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [github-sync] EXECUTING $INC_ID ($SYNC_TYPE) event=$EVENT_TYPE" >> "$THROTTLE_LOG" 2>/dev/null
|
|
58
84
|
|
|
59
85
|
# Cross-platform timeout wrapper
|
|
60
86
|
run_with_timeout() {
|
|
@@ -90,6 +116,16 @@ FEATURE_ID=""
|
|
|
90
116
|
[[ -z "$FEATURE_ID" ]] && exit 0
|
|
91
117
|
|
|
92
118
|
# Run sync (timeout 60s)
|
|
119
|
+
# The github-feature-sync-cli.js script will:
|
|
120
|
+
# 1. Find all User Stories in the feature
|
|
121
|
+
# 2. For each US, call updateUserStoryIssue() which:
|
|
122
|
+
# - Updates issue body with latest content
|
|
123
|
+
# - Calculates completion via CompletionCalculator (verifies [x] checkboxes)
|
|
124
|
+
# - CLOSES the issue if ALL ACs and tasks are verified complete
|
|
125
|
+
# - Updates status labels (status:complete, status:active, status:not_started)
|
|
93
126
|
cd "$PROJECT_ROOT" || exit 0
|
|
94
|
-
|
|
127
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [github-sync] Running: node $SYNC_SCRIPT $FEATURE_ID" >> "$THROTTLE_LOG" 2>/dev/null
|
|
128
|
+
GITHUB_TOKEN="$GITHUB_TOKEN" run_with_timeout 60 node "$SYNC_SCRIPT" "$FEATURE_ID" >> "$THROTTLE_LOG" 2>&1
|
|
129
|
+
SYNC_EXIT=$?
|
|
130
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [github-sync] COMPLETED $INC_ID ($SYNC_TYPE) exit=$SYNC_EXIT" >> "$THROTTLE_LOG" 2>/dev/null
|
|
95
131
|
exit 0
|
|
@@ -6,11 +6,15 @@
|
|
|
6
6
|
#
|
|
7
7
|
# Event routing (EDA v2):
|
|
8
8
|
# - increment.created/done/archived/reopened -> living-specs-handler + status-line-handler + project-bridge-handler + github-sync-handler
|
|
9
|
-
# - user-story.completed/reopened -> status-line-handler + project-bridge-handler
|
|
9
|
+
# - user-story.completed/reopened -> status-line-handler + project-bridge-handler + github-sync-handler (v1.0.45+: CRITICAL FIX)
|
|
10
10
|
# - spec.updated -> living-docs-handler + ac-validation-handler + github-sync-handler (creates GitHub issues for User Stories)
|
|
11
11
|
# - task.updated -> living-docs-handler + ac-validation-handler (legacy)
|
|
12
12
|
# - metadata.changed -> github-sync-handler
|
|
13
13
|
#
|
|
14
|
+
# CRITICAL FIX (v1.0.45): user-story.completed now triggers github-sync-handler!
|
|
15
|
+
# Root cause: GitHub issues were CREATED but NEVER UPDATED when User Stories completed.
|
|
16
|
+
# Result: Issues stayed OPEN forever even after all tasks/ACs were marked complete.
|
|
17
|
+
#
|
|
14
18
|
# The project-bridge-handler connects increment events to project-level EDA,
|
|
15
19
|
# enabling automatic sync to GitHub, ADO, and JIRA via ProjectService.
|
|
16
20
|
#
|
|
@@ -167,11 +171,15 @@ process_event() {
|
|
|
167
171
|
run_handler "$HANDLER_DIR/github-sync-handler.sh" "$EVENT_TYPE" "$EVENT_DATA"
|
|
168
172
|
;;
|
|
169
173
|
|
|
170
|
-
# User story events -> status-line-handler + project-bridge-handler
|
|
174
|
+
# User story events -> status-line-handler + project-bridge-handler + github-sync-handler
|
|
175
|
+
# CRITICAL FIX (v1.0.45): Added github-sync-handler to update GitHub issues when US completes
|
|
176
|
+
# Root cause: user-story.completed was NOT triggering GitHub sync → issues stayed open!
|
|
171
177
|
user-story.completed|user-story.reopened)
|
|
172
178
|
run_handler "$HANDLER_DIR/status-line-handler.sh" "$EVENT_TYPE" "$EVENT_DATA"
|
|
173
179
|
# Bridge to project-level EDA (may trigger issue updates)
|
|
174
180
|
run_handler "$HANDLER_DIR/project-bridge-handler.sh" "$EVENT_TYPE" "$EVENT_DATA"
|
|
181
|
+
# Sync to GitHub (updates User Story issue status when US completes/reopens)
|
|
182
|
+
run_handler "$HANDLER_DIR/github-sync-handler.sh" "$EVENT_TYPE" "$EVENT_DATA"
|
|
175
183
|
;;
|
|
176
184
|
|
|
177
185
|
# Spec updated -> sync to living docs + validate ACs + sync to GitHub
|