specweave 0.28.11 → 0.28.14
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/dist/src/cli/commands/archive.d.ts +0 -1
- package/dist/src/cli/commands/archive.d.ts.map +1 -1
- package/dist/src/cli/commands/archive.js +1 -4
- package/dist/src/cli/commands/archive.js.map +1 -1
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +29 -18
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/helpers/init/external-import.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/external-import.js +83 -10
- package/dist/src/cli/helpers/init/external-import.js.map +1 -1
- package/dist/src/cli/helpers/init/index.d.ts +1 -0
- package/dist/src/cli/helpers/init/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/index.js +2 -0
- package/dist/src/cli/helpers/init/index.js.map +1 -1
- package/dist/src/cli/helpers/init/language-selection.d.ts +40 -0
- package/dist/src/cli/helpers/init/language-selection.d.ts.map +1 -0
- package/dist/src/cli/helpers/init/language-selection.js +281 -0
- package/dist/src/cli/helpers/init/language-selection.js.map +1 -0
- package/dist/src/cli/helpers/init/repository-setup.d.ts +2 -0
- package/dist/src/cli/helpers/init/repository-setup.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/repository-setup.js +156 -12
- package/dist/src/cli/helpers/init/repository-setup.js.map +1 -1
- package/dist/src/cli/helpers/init/translation-config.d.ts +10 -2
- package/dist/src/cli/helpers/init/translation-config.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/translation-config.js +302 -81
- package/dist/src/cli/helpers/init/translation-config.js.map +1 -1
- package/dist/src/core/config/types.d.ts +30 -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/feature-deleter/validator.d.ts +1 -0
- package/dist/src/core/feature-deleter/validator.d.ts.map +1 -1
- package/dist/src/core/feature-deleter/validator.js +8 -10
- package/dist/src/core/feature-deleter/validator.js.map +1 -1
- package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
- package/dist/src/core/increment/increment-archiver.js +12 -5
- package/dist/src/core/increment/increment-archiver.js.map +1 -1
- package/dist/src/core/living-docs/feature-archiver.d.ts +25 -3
- package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -1
- package/dist/src/core/living-docs/feature-archiver.js +131 -129
- package/dist/src/core/living-docs/feature-archiver.js.map +1 -1
- package/dist/src/core/living-docs/feature-consistency-validator.d.ts +23 -22
- package/dist/src/core/living-docs/feature-consistency-validator.d.ts.map +1 -1
- package/dist/src/core/living-docs/feature-consistency-validator.js +68 -150
- package/dist/src/core/living-docs/feature-consistency-validator.js.map +1 -1
- package/dist/src/core/living-docs/feature-id-manager.d.ts +5 -1
- package/dist/src/core/living-docs/feature-id-manager.d.ts.map +1 -1
- package/dist/src/core/living-docs/feature-id-manager.js +43 -23
- package/dist/src/core/living-docs/feature-id-manager.js.map +1 -1
- package/dist/src/core/living-docs/hierarchy-mapper.d.ts +21 -12
- package/dist/src/core/living-docs/hierarchy-mapper.d.ts.map +1 -1
- package/dist/src/core/living-docs/hierarchy-mapper.js +89 -70
- package/dist/src/core/living-docs/hierarchy-mapper.js.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.d.ts +10 -11
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +24 -56
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/repo-structure/repo-bulk-discovery.d.ts +1 -1
- package/dist/src/core/repo-structure/repo-bulk-discovery.d.ts.map +1 -1
- package/dist/src/core/repo-structure/repo-bulk-discovery.js +168 -126
- package/dist/src/core/repo-structure/repo-bulk-discovery.js.map +1 -1
- package/dist/src/core/spec-detector.js +2 -2
- package/dist/src/core/spec-detector.js.map +1 -1
- package/dist/src/importers/duplicate-detector.d.ts +6 -0
- package/dist/src/importers/duplicate-detector.d.ts.map +1 -1
- package/dist/src/importers/duplicate-detector.js +8 -2
- package/dist/src/importers/duplicate-detector.js.map +1 -1
- package/dist/src/importers/external-importer.d.ts +6 -0
- package/dist/src/importers/external-importer.d.ts.map +1 -1
- package/dist/src/importers/import-coordinator.d.ts +38 -2
- package/dist/src/importers/import-coordinator.d.ts.map +1 -1
- package/dist/src/importers/import-coordinator.js +142 -5
- package/dist/src/importers/import-coordinator.js.map +1 -1
- package/dist/src/importers/item-converter.d.ts +39 -1
- package/dist/src/importers/item-converter.d.ts.map +1 -1
- package/dist/src/importers/item-converter.js +193 -24
- package/dist/src/importers/item-converter.js.map +1 -1
- package/dist/src/living-docs/fs-id-allocator.d.ts +8 -2
- package/dist/src/living-docs/fs-id-allocator.d.ts.map +1 -1
- package/dist/src/living-docs/fs-id-allocator.js +18 -10
- package/dist/src/living-docs/fs-id-allocator.js.map +1 -1
- package/dist/src/sync/sync-coordinator.d.ts +5 -0
- package/dist/src/sync/sync-coordinator.d.ts.map +1 -1
- package/dist/src/sync/sync-coordinator.js +104 -6
- package/dist/src/sync/sync-coordinator.js.map +1 -1
- package/dist/src/utils/project-detection.d.ts +13 -10
- package/dist/src/utils/project-detection.d.ts.map +1 -1
- package/dist/src/utils/project-detection.js +26 -11
- package/dist/src/utils/project-detection.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/agents/pm/AGENT.md +41 -4
- package/plugins/specweave/agents/test-aware-planner/AGENT.md +54 -0
- package/plugins/specweave/commands/specweave-increment.md +30 -0
- package/plugins/specweave/commands/specweave-save.md +838 -0
- package/plugins/specweave/hooks/lib/update-status-line.sh +9 -1
- package/plugins/specweave/hooks/post-increment-completion.sh +4 -3
- package/plugins/specweave/hooks/post-metadata-change.sh +18 -4
- package/plugins/specweave/skills/increment-planner/SKILL.md +252 -2
- package/plugins/specweave/skills/spec-generator/SKILL.md +163 -0
- package/plugins/specweave/skills/umbrella-repo-detector/SKILL.md +79 -12
- package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +6 -0
- package/plugins/specweave-release/commands/specweave-release-npm.md +14 -22
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +9 -0
|
@@ -58,9 +58,17 @@ fi
|
|
|
58
58
|
# ============================================================================
|
|
59
59
|
# TTL CHECK (10 seconds - balanced for UX vs performance)
|
|
60
60
|
# ============================================================================
|
|
61
|
+
# TTL check (skip if --force flag provided or SPECWEAVE_FORCE_STATUS_UPDATE=1)
|
|
62
|
+
# ============================================================================
|
|
61
63
|
TTL_SECONDS=10
|
|
64
|
+
FORCE_UPDATE=0
|
|
65
|
+
|
|
66
|
+
# Check for --force flag
|
|
67
|
+
if [[ "${1:-}" == "--force" ]] || [[ "${SPECWEAVE_FORCE_STATUS_UPDATE:-0}" == "1" ]]; then
|
|
68
|
+
FORCE_UPDATE=1
|
|
69
|
+
fi
|
|
62
70
|
|
|
63
|
-
if [[ -f "$CACHE_FILE" ]]; then
|
|
71
|
+
if [[ "$FORCE_UPDATE" -eq 0 ]] && [[ -f "$CACHE_FILE" ]]; then
|
|
64
72
|
if [[ "$(uname)" == "Darwin" ]]; then
|
|
65
73
|
CACHE_AGE=$(( $(date +%s) - $(stat -f %m "$CACHE_FILE" 2>/dev/null || echo 0) ))
|
|
66
74
|
else
|
|
@@ -21,8 +21,8 @@ if [ -z "$INCREMENT_ID" ]; then
|
|
|
21
21
|
exit 0
|
|
22
22
|
fi
|
|
23
23
|
|
|
24
|
-
# Get project root
|
|
25
|
-
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")
|
|
24
|
+
# Get project root (3 levels up from plugins/specweave/hooks/)
|
|
25
|
+
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
|
26
26
|
INCREMENT_DIR="$PROJECT_ROOT/.specweave/increments/$INCREMENT_ID"
|
|
27
27
|
|
|
28
28
|
# ============================================================================
|
|
@@ -135,6 +135,7 @@ if [ -f "$SPEC_FILE" ]; then
|
|
|
135
135
|
echo "🔄 Syncing spec.md status to 'completed'..."
|
|
136
136
|
|
|
137
137
|
# Read current status from spec.md frontmatter
|
|
138
|
+
# Use heredoc to avoid quote escaping issues in awk
|
|
138
139
|
SPEC_STATUS=$(awk '
|
|
139
140
|
BEGIN { in_frontmatter=0 }
|
|
140
141
|
/^---$/ {
|
|
@@ -146,7 +147,7 @@ if [ -f "$SPEC_FILE" ]; then
|
|
|
146
147
|
}
|
|
147
148
|
in_frontmatter == 1 && /^status:/ {
|
|
148
149
|
gsub(/^status:[ \t]*/, "");
|
|
149
|
-
gsub(/["'
|
|
150
|
+
gsub(/["'"'"']/, "");
|
|
150
151
|
print;
|
|
151
152
|
exit
|
|
152
153
|
}
|
|
@@ -170,6 +170,20 @@ CURRENT_STATUS=$(jq -r '.status // "unknown"' "$METADATA_PATH" 2>/dev/null)
|
|
|
170
170
|
|
|
171
171
|
echo "[$(date)] post-metadata-change: Current status: $CURRENT_STATUS" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
172
172
|
|
|
173
|
+
# ============================================================================
|
|
174
|
+
# CRITICAL FIX (v0.28.12): Remove guard BEFORE calling sub-hooks
|
|
175
|
+
# ============================================================================
|
|
176
|
+
# PROBLEM: Sub-hooks (post-increment-completion.sh) check for recursion guard
|
|
177
|
+
# and exit immediately if it exists. But the guard was created HERE (line 77),
|
|
178
|
+
# so sub-hooks NEVER ran - causing status line to never update!
|
|
179
|
+
#
|
|
180
|
+
# SOLUTION: Temporarily remove the guard before calling sub-hooks.
|
|
181
|
+
# The guard's purpose is to prevent THIS hook from being called recursively
|
|
182
|
+
# (if sub-hooks modify metadata.json). Sub-hooks have their OWN guards.
|
|
183
|
+
#
|
|
184
|
+
# See: Root cause analysis 2025-11-25 - status line never updates after /done
|
|
185
|
+
rm -f "$RECURSION_GUARD_FILE" 2>/dev/null || true
|
|
186
|
+
|
|
173
187
|
# Dispatch to appropriate lifecycle hook based on status
|
|
174
188
|
case "$CURRENT_STATUS" in
|
|
175
189
|
completed)
|
|
@@ -186,9 +200,9 @@ case "$CURRENT_STATUS" in
|
|
|
186
200
|
}
|
|
187
201
|
else
|
|
188
202
|
echo "[$(date)] post-metadata-change: post-increment-completion.sh not found or not executable" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
189
|
-
# Fallback: Update status line directly
|
|
190
|
-
bash "$HOOK_DIR/lib/update-status-line.sh" 2>/dev/null || true
|
|
191
203
|
fi
|
|
204
|
+
# ALWAYS update status line after completion (force bypass TTL cache)
|
|
205
|
+
bash "$HOOK_DIR/lib/update-status-line.sh" --force 2>/dev/null || true
|
|
192
206
|
;;
|
|
193
207
|
|
|
194
208
|
paused|resumed|abandoned)
|
|
@@ -205,9 +219,9 @@ case "$CURRENT_STATUS" in
|
|
|
205
219
|
}
|
|
206
220
|
else
|
|
207
221
|
echo "[$(date)] post-metadata-change: post-increment-status-change.sh not found" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
208
|
-
# Fallback: Update status line directly
|
|
209
|
-
bash "$HOOK_DIR/lib/update-status-line.sh" 2>/dev/null || true
|
|
210
222
|
fi
|
|
223
|
+
# ALWAYS update status line after status change (force bypass TTL cache)
|
|
224
|
+
bash "$HOOK_DIR/lib/update-status-line.sh" --force 2>/dev/null || true
|
|
211
225
|
;;
|
|
212
226
|
|
|
213
227
|
active|planning|in-progress)
|
|
@@ -130,9 +130,45 @@ Every increment MUST have `metadata.json` or:
|
|
|
130
130
|
|
|
131
131
|
## Workflow (Safe, Self-Contained)
|
|
132
132
|
|
|
133
|
-
### STEP 0:
|
|
133
|
+
### STEP 0: Detect Multi-Project Mode (MANDATORY FIRST!)
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
**⚠️ CRITICAL: Before creating ANY user stories, detect if this is a multi-project (umbrella) setup!**
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# 1. Check config.json for umbrella mode
|
|
139
|
+
UMBRELLA_ENABLED=$(cat .specweave/config.json 2>/dev/null | jq -r '.umbrella.enabled // false')
|
|
140
|
+
|
|
141
|
+
# 2. Check for childRepos
|
|
142
|
+
CHILD_REPOS=$(cat .specweave/config.json 2>/dev/null | jq -r '.umbrella.childRepos[]?.id // empty' | tr '\n' ',')
|
|
143
|
+
|
|
144
|
+
# 3. Check for project folders in specs/
|
|
145
|
+
PROJECT_FOLDERS=$(ls -1 .specweave/docs/internal/specs/ 2>/dev/null | grep -v "^_" | head -5)
|
|
146
|
+
|
|
147
|
+
echo "Multi-project mode: $UMBRELLA_ENABLED"
|
|
148
|
+
echo "Child repos: $CHILD_REPOS"
|
|
149
|
+
echo "Project folders: $PROJECT_FOLDERS"
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**If multi-project detected (`umbrella.enabled: true` OR multiple project folders exist):**
|
|
153
|
+
- ✅ **MUST** generate project-scoped user stories: `US-FE-001`, `US-BE-001`, `US-SHARED-001`
|
|
154
|
+
- ✅ **MUST** use project-scoped AC-IDs: `AC-FE-US1-01`, `AC-BE-US1-01`
|
|
155
|
+
- ✅ **MUST** group user stories by project in spec.md
|
|
156
|
+
- ✅ **MUST** infer project from repo name if available (e.g., `sw-app-fe` → FE, `sw-app-be` → BE)
|
|
157
|
+
|
|
158
|
+
**Project Prefix Detection from Repo Names:**
|
|
159
|
+
```
|
|
160
|
+
sw-thumbnail-ab-fe → prefix: FE (frontend)
|
|
161
|
+
sw-thumbnail-ab-be → prefix: BE (backend)
|
|
162
|
+
sw-thumbnail-ab-shared → prefix: SHARED (shared library)
|
|
163
|
+
my-app-mobile → prefix: MOBILE (mobile app)
|
|
164
|
+
infra-terraform → prefix: INFRA (infrastructure)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Store this for use in STEP 4 (spec.md generation)!**
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
### STEP 0A: Read Config Values (MANDATORY)
|
|
136
172
|
|
|
137
173
|
```bash
|
|
138
174
|
# Read testMode (default: "TDD")
|
|
@@ -178,6 +214,10 @@ mkdir -p .specweave/increments/0021-feature-name
|
|
|
178
214
|
|
|
179
215
|
Create `.specweave/increments/0021-feature-name/spec.md`:
|
|
180
216
|
|
|
217
|
+
**⚠️ IMPORTANT: Use the correct template based on STEP 0 detection!**
|
|
218
|
+
|
|
219
|
+
#### 4A: Single-Project Template (umbrella.enabled: false)
|
|
220
|
+
|
|
181
221
|
```markdown
|
|
182
222
|
---
|
|
183
223
|
increment: 0021-feature-name
|
|
@@ -231,6 +271,110 @@ coverage_target: <VALUE FROM config.testing.defaultCoverageTarget OR 95>
|
|
|
231
271
|
[Other features or systems this depends on]
|
|
232
272
|
```
|
|
233
273
|
|
|
274
|
+
#### 4B: Multi-Project Template (umbrella.enabled: true) - USE THIS!
|
|
275
|
+
|
|
276
|
+
```markdown
|
|
277
|
+
---
|
|
278
|
+
increment: 0021-feature-name
|
|
279
|
+
title: "Feature Name"
|
|
280
|
+
type: feature
|
|
281
|
+
priority: P1
|
|
282
|
+
status: planned
|
|
283
|
+
created: 2025-11-24
|
|
284
|
+
structure: user-stories
|
|
285
|
+
test_mode: <VALUE FROM config.testing.defaultTestMode OR 'TDD'>
|
|
286
|
+
coverage_target: <VALUE FROM config.testing.defaultCoverageTarget OR 95>
|
|
287
|
+
multi_project: true
|
|
288
|
+
projects:
|
|
289
|
+
- id: sw-app-fe
|
|
290
|
+
prefix: FE
|
|
291
|
+
- id: sw-app-be
|
|
292
|
+
prefix: BE
|
|
293
|
+
- id: sw-app-shared
|
|
294
|
+
prefix: SHARED
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
# Feature: [Title]
|
|
298
|
+
|
|
299
|
+
## Overview
|
|
300
|
+
|
|
301
|
+
[High-level description - WHAT this feature does and WHY it's needed]
|
|
302
|
+
|
|
303
|
+
## User Stories by Project
|
|
304
|
+
|
|
305
|
+
### Frontend ([repo-name-fe])
|
|
306
|
+
|
|
307
|
+
#### US-FE-001: [Story Title] (P1)
|
|
308
|
+
**Related Repo**: [repo-name-fe]
|
|
309
|
+
**As a** [user type]
|
|
310
|
+
**I want** [goal]
|
|
311
|
+
**So that** [benefit]
|
|
312
|
+
|
|
313
|
+
**Acceptance Criteria**:
|
|
314
|
+
- [ ] **AC-FE-US1-01**: [Specific, testable criterion]
|
|
315
|
+
- [ ] **AC-FE-US1-02**: [Another criterion]
|
|
316
|
+
|
|
317
|
+
#### US-FE-002: [Story Title] (P2)
|
|
318
|
+
[Repeat structure with FE prefix]
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
### Backend ([repo-name-be])
|
|
323
|
+
|
|
324
|
+
#### US-BE-001: [Story Title] (P1)
|
|
325
|
+
**Related Repo**: [repo-name-be]
|
|
326
|
+
**As a** [system/frontend application]
|
|
327
|
+
**I want** [API endpoint/service goal]
|
|
328
|
+
**So that** [benefit]
|
|
329
|
+
|
|
330
|
+
**Acceptance Criteria**:
|
|
331
|
+
- [ ] **AC-BE-US1-01**: [API endpoint specification]
|
|
332
|
+
- [ ] **AC-BE-US1-02**: [Data validation rule]
|
|
333
|
+
|
|
334
|
+
#### US-BE-002: [Story Title] (P2)
|
|
335
|
+
[Repeat structure with BE prefix]
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
### Shared Library ([repo-name-shared])
|
|
340
|
+
|
|
341
|
+
#### US-SHARED-001: [Story Title] (P1)
|
|
342
|
+
**Related Repo**: [repo-name-shared]
|
|
343
|
+
**As a** developer in FE or BE repos
|
|
344
|
+
**I want** [shared types/utilities/validators]
|
|
345
|
+
**So that** [consistency across projects]
|
|
346
|
+
|
|
347
|
+
**Acceptance Criteria**:
|
|
348
|
+
- [ ] **AC-SHARED-US1-01**: [Type definition]
|
|
349
|
+
- [ ] **AC-SHARED-US1-02**: [Validator/utility function]
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## Functional Requirements
|
|
354
|
+
|
|
355
|
+
### FR-001: [Requirement]
|
|
356
|
+
[Detailed description]
|
|
357
|
+
|
|
358
|
+
## Success Criteria
|
|
359
|
+
|
|
360
|
+
[Measurable outcomes - metrics, KPIs]
|
|
361
|
+
|
|
362
|
+
## Out of Scope
|
|
363
|
+
|
|
364
|
+
[What this explicitly does NOT include]
|
|
365
|
+
|
|
366
|
+
## Dependencies
|
|
367
|
+
|
|
368
|
+
[Other features or systems this depends on]
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
**Key Rules for Multi-Project spec.md:**
|
|
372
|
+
1. **User stories MUST be grouped by project** (Frontend, Backend, Shared, etc.)
|
|
373
|
+
2. **User story IDs MUST have project prefix**: `US-FE-001`, `US-BE-001`, `US-SHARED-001`
|
|
374
|
+
3. **AC-IDs MUST have project prefix**: `AC-FE-US1-01`, `AC-BE-US1-01`
|
|
375
|
+
4. **Each user story MUST have `Related Repo` field**
|
|
376
|
+
5. **Frontmatter MUST include `multi_project: true` and `projects` list**
|
|
377
|
+
|
|
234
378
|
### STEP 5: Create plan.md Template
|
|
235
379
|
|
|
236
380
|
Create `.specweave/increments/0021-feature-name/plan.md`:
|
|
@@ -292,6 +436,10 @@ Create `.specweave/increments/0021-feature-name/plan.md`:
|
|
|
292
436
|
|
|
293
437
|
Create `.specweave/increments/0021-feature-name/tasks.md`:
|
|
294
438
|
|
|
439
|
+
**⚠️ IMPORTANT: Use the correct template based on STEP 0 detection!**
|
|
440
|
+
|
|
441
|
+
#### 6A: Single-Project Template
|
|
442
|
+
|
|
295
443
|
```markdown
|
|
296
444
|
# Tasks: [Feature Title]
|
|
297
445
|
|
|
@@ -343,6 +491,108 @@ Create `.specweave/increments/0021-feature-name/tasks.md`:
|
|
|
343
491
|
- [ ] [T051] Verify all acceptance criteria
|
|
344
492
|
```
|
|
345
493
|
|
|
494
|
+
#### 6B: Multi-Project Template (umbrella.enabled: true) - USE THIS!
|
|
495
|
+
|
|
496
|
+
```markdown
|
|
497
|
+
# Tasks: [Feature Title]
|
|
498
|
+
|
|
499
|
+
## Task Notation
|
|
500
|
+
|
|
501
|
+
- `[T###]`: Task ID
|
|
502
|
+
- `[P]`: Parallelizable
|
|
503
|
+
- `[ ]`: Not started
|
|
504
|
+
- `[x]`: Completed
|
|
505
|
+
- Model hints: ⚡ haiku, 🧠 sonnet, 💎 opus
|
|
506
|
+
|
|
507
|
+
## Phase 1: Foundation & Setup
|
|
508
|
+
|
|
509
|
+
### T-001: Initialize Shared Library (sw-app-shared)
|
|
510
|
+
**User Story**: US-SHARED-001
|
|
511
|
+
**Satisfies ACs**: AC-SHARED-US1-01, AC-SHARED-US1-02
|
|
512
|
+
**Status**: [ ] Not Started
|
|
513
|
+
|
|
514
|
+
**Description**: Set up shared TypeScript types and validators
|
|
515
|
+
|
|
516
|
+
**Implementation**:
|
|
517
|
+
- Create shared types package
|
|
518
|
+
- Export common interfaces and types
|
|
519
|
+
- Add validation schemas
|
|
520
|
+
|
|
521
|
+
**Test Plan**:
|
|
522
|
+
- **File**: `sw-app-shared/tests/types.test.ts`
|
|
523
|
+
- **Tests**:
|
|
524
|
+
- **TC-001**: Type exports compile correctly
|
|
525
|
+
|
|
526
|
+
---
|
|
527
|
+
|
|
528
|
+
## Phase 2: Backend Implementation (sw-app-be)
|
|
529
|
+
|
|
530
|
+
### T-002: Database Schema & Models
|
|
531
|
+
**User Story**: US-BE-001
|
|
532
|
+
**Satisfies ACs**: AC-BE-US1-01, AC-BE-US1-02
|
|
533
|
+
**Status**: [ ] Not Started
|
|
534
|
+
|
|
535
|
+
**Description**: Create database schema for backend service
|
|
536
|
+
|
|
537
|
+
**Implementation**:
|
|
538
|
+
- Define Prisma/TypeORM models
|
|
539
|
+
- Run migrations
|
|
540
|
+
- Seed initial data
|
|
541
|
+
|
|
542
|
+
**Test Plan**:
|
|
543
|
+
- **File**: `sw-app-be/tests/models.test.ts`
|
|
544
|
+
- **Tests**:
|
|
545
|
+
- **TC-002**: Models create correctly
|
|
546
|
+
- **TC-003**: Relationships work
|
|
547
|
+
|
|
548
|
+
### T-003: API Endpoints
|
|
549
|
+
**User Story**: US-BE-001, US-BE-002
|
|
550
|
+
**Satisfies ACs**: AC-BE-US1-01, AC-BE-US2-01
|
|
551
|
+
**Status**: [ ] Not Started
|
|
552
|
+
|
|
553
|
+
**Description**: Implement REST API endpoints
|
|
554
|
+
|
|
555
|
+
---
|
|
556
|
+
|
|
557
|
+
## Phase 3: Frontend Implementation (sw-app-fe)
|
|
558
|
+
|
|
559
|
+
### T-004: UI Components
|
|
560
|
+
**User Story**: US-FE-001
|
|
561
|
+
**Satisfies ACs**: AC-FE-US1-01, AC-FE-US1-02
|
|
562
|
+
**Status**: [ ] Not Started
|
|
563
|
+
|
|
564
|
+
**Description**: Build frontend components
|
|
565
|
+
|
|
566
|
+
**Implementation**:
|
|
567
|
+
- Create upload component
|
|
568
|
+
- Add comparison view
|
|
569
|
+
- Wire up to backend API
|
|
570
|
+
|
|
571
|
+
**Test Plan**:
|
|
572
|
+
- **File**: `sw-app-fe/tests/components.test.tsx`
|
|
573
|
+
- **Tests**:
|
|
574
|
+
- **TC-004**: Component renders correctly
|
|
575
|
+
- **TC-005**: Upload triggers validation
|
|
576
|
+
|
|
577
|
+
---
|
|
578
|
+
|
|
579
|
+
## Phase 4: Integration & Testing
|
|
580
|
+
|
|
581
|
+
### T-005: End-to-End Tests
|
|
582
|
+
**User Story**: US-FE-001, US-BE-001
|
|
583
|
+
**Satisfies ACs**: (all FE and BE ACs)
|
|
584
|
+
**Status**: [ ] Not Started
|
|
585
|
+
|
|
586
|
+
**Description**: E2E tests across all projects
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
**Key Rules for Multi-Project tasks.md:**
|
|
590
|
+
1. **Tasks MUST reference project-scoped user stories**: `US-FE-001`, `US-BE-001`
|
|
591
|
+
2. **Tasks MUST reference project-scoped ACs**: `AC-FE-US1-01`, `AC-BE-US1-01`
|
|
592
|
+
3. **Group tasks by project/phase** (Shared first, then BE, then FE)
|
|
593
|
+
4. **Test file paths MUST include project folder**: `sw-app-be/tests/`, `sw-app-fe/tests/`
|
|
594
|
+
5. **Dependencies between projects should be explicit**
|
|
595
|
+
|
|
346
596
|
### STEP 7: Create metadata.json (MANDATORY)
|
|
347
597
|
|
|
348
598
|
**IMPORTANT**: Read `testMode` and `coverageTarget` from `.specweave/config.json`:
|
|
@@ -46,6 +46,12 @@ description: Generates comprehensive specifications (spec.md, plan.md, tasks.md
|
|
|
46
46
|
### Target Audience
|
|
47
47
|
|
|
48
48
|
## User Stories & Acceptance Criteria
|
|
49
|
+
|
|
50
|
+
<!--
|
|
51
|
+
⚠️ MULTI-PROJECT MODE: If umbrella.enabled=true in config.json,
|
|
52
|
+
user stories MUST be project-scoped! See section below.
|
|
53
|
+
-->
|
|
54
|
+
|
|
49
55
|
### US-001: [Title]
|
|
50
56
|
**As a** [user type]
|
|
51
57
|
**I want** [goal]
|
|
@@ -348,15 +354,172 @@ spec_generator:
|
|
|
348
354
|
|
|
349
355
|
---
|
|
350
356
|
|
|
357
|
+
## 🔀 Multi-Project User Story Generation (v0.29.0+)
|
|
358
|
+
|
|
359
|
+
**CRITICAL**: When umbrella/multi-project mode is detected, user stories MUST be generated per-project!
|
|
360
|
+
|
|
361
|
+
### Detection (MANDATORY FIRST STEP)
|
|
362
|
+
|
|
363
|
+
**Before generating spec.md, ALWAYS check for multi-project mode:**
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
# 1. Check config.json for umbrella mode
|
|
367
|
+
cat .specweave/config.json | jq '.umbrella.enabled'
|
|
368
|
+
|
|
369
|
+
# 2. Check for childRepos configuration
|
|
370
|
+
cat .specweave/config.json | jq '.umbrella.childRepos[]'
|
|
371
|
+
|
|
372
|
+
# 3. Check for project folders in specs/
|
|
373
|
+
ls -la .specweave/docs/internal/specs/
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
**If ANY of these conditions are TRUE → Multi-project mode ACTIVE:**
|
|
377
|
+
- `umbrella.enabled: true` in config.json
|
|
378
|
+
- `umbrella.childRepos` has entries
|
|
379
|
+
- Multiple project folders exist in `specs/` (e.g., `sw-app-fe/`, `sw-app-be/`, `sw-app-shared/`)
|
|
380
|
+
- User prompt mentions: "3 repos", "frontend repo", "backend API", "shared library"
|
|
381
|
+
|
|
382
|
+
### Project-Scoped User Story Format (MANDATORY in Multi-Project Mode)
|
|
383
|
+
|
|
384
|
+
**❌ WRONG (Single-Project Format - DO NOT USE in multi-project!):**
|
|
385
|
+
```markdown
|
|
386
|
+
## User Stories
|
|
387
|
+
|
|
388
|
+
### US-001: Thumbnail Upload
|
|
389
|
+
As a content creator, I want to upload thumbnails...
|
|
390
|
+
|
|
391
|
+
### US-002: CTR Prediction API
|
|
392
|
+
As a system, I want to predict click-through rates...
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
**✅ CORRECT (Multi-Project Format - ALWAYS USE when umbrella detected!):**
|
|
396
|
+
```markdown
|
|
397
|
+
## User Stories by Project
|
|
398
|
+
|
|
399
|
+
### Frontend (sw-thumbnail-ab-fe)
|
|
400
|
+
|
|
401
|
+
#### US-FE-001: Thumbnail Upload & Comparison (P1)
|
|
402
|
+
**Related Repo**: sw-thumbnail-ab-fe
|
|
403
|
+
**As a** content creator
|
|
404
|
+
**I want** to upload multiple thumbnail variants and compare them side-by-side
|
|
405
|
+
**So that** I can visually evaluate my options before testing
|
|
406
|
+
|
|
407
|
+
**Acceptance Criteria**:
|
|
408
|
+
- [ ] **AC-FE-US1-01**: User can drag-and-drop up to 5 thumbnail images (JPG, PNG, WebP)
|
|
409
|
+
- [ ] **AC-FE-US1-02**: Images are validated for YouTube specs (1280x720 min, <2MB)
|
|
410
|
+
- [ ] **AC-FE-US1-03**: Side-by-side comparison view displays all variants
|
|
411
|
+
|
|
412
|
+
---
|
|
413
|
+
|
|
414
|
+
### Backend (sw-thumbnail-ab-be)
|
|
415
|
+
|
|
416
|
+
#### US-BE-001: Thumbnail Analysis API (P1)
|
|
417
|
+
**Related Repo**: sw-thumbnail-ab-be
|
|
418
|
+
**As a** frontend application
|
|
419
|
+
**I want** to call POST /predict-ctr endpoint
|
|
420
|
+
**So that** I can get AI-powered click-through rate predictions
|
|
421
|
+
|
|
422
|
+
**Acceptance Criteria**:
|
|
423
|
+
- [ ] **AC-BE-US1-01**: POST /predict-ctr endpoint accepts thumbnail image
|
|
424
|
+
- [ ] **AC-BE-US1-02**: ML model analyzes: face detection, text readability, color psychology
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
### Shared Library (sw-thumbnail-ab-shared)
|
|
429
|
+
|
|
430
|
+
#### US-SHARED-001: Common Types & Validators (P1)
|
|
431
|
+
**Related Repo**: sw-thumbnail-ab-shared
|
|
432
|
+
**As a** developer in FE or BE repos
|
|
433
|
+
**I want** shared TypeScript types and validators
|
|
434
|
+
**So that** API contracts are consistent across projects
|
|
435
|
+
|
|
436
|
+
**Acceptance Criteria**:
|
|
437
|
+
- [ ] **AC-SHARED-US1-01**: ThumbnailMetadata type exported
|
|
438
|
+
- [ ] **AC-SHARED-US1-02**: Validation schemas for image specs
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### Project Classification Rules
|
|
442
|
+
|
|
443
|
+
When analyzing user descriptions, classify each user story by keywords:
|
|
444
|
+
|
|
445
|
+
| Keywords | Project | Prefix |
|
|
446
|
+
|----------|---------|--------|
|
|
447
|
+
| UI, component, page, form, view, drag-drop, theme, builder, menu display | Frontend | FE |
|
|
448
|
+
| API, endpoint, CRUD, webhook, analytics, database, service, ML model | Backend | BE |
|
|
449
|
+
| types, schemas, validators, utilities, localization, common | Shared | SHARED |
|
|
450
|
+
| iOS, Android, mobile app, push notification | Mobile | MOBILE |
|
|
451
|
+
| Terraform, K8s, Docker, CI/CD, deployment | Infrastructure | INFRA |
|
|
452
|
+
|
|
453
|
+
### AC-ID Format by Project
|
|
454
|
+
|
|
455
|
+
```
|
|
456
|
+
AC-{PROJECT}-US{story}-{number}
|
|
457
|
+
|
|
458
|
+
Examples:
|
|
459
|
+
- AC-FE-US1-01 (Frontend, User Story 1, AC #1)
|
|
460
|
+
- AC-BE-US1-01 (Backend, User Story 1, AC #1)
|
|
461
|
+
- AC-SHARED-US1-01 (Shared, User Story 1, AC #1)
|
|
462
|
+
- AC-MOBILE-US1-01 (Mobile, User Story 1, AC #1)
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### tasks.md Must Reference Project-Scoped User Stories
|
|
466
|
+
|
|
467
|
+
```markdown
|
|
468
|
+
### T-001: Create Thumbnail Upload Component
|
|
469
|
+
**User Story**: US-FE-001 ← MUST reference project-scoped ID!
|
|
470
|
+
**Satisfies ACs**: AC-FE-US1-01, AC-FE-US1-02
|
|
471
|
+
**Status**: [ ] Not Started
|
|
472
|
+
|
|
473
|
+
### T-004: Database Schema & Migrations
|
|
474
|
+
**User Story**: US-BE-001, US-BE-002 ← Backend stories only!
|
|
475
|
+
**Satisfies ACs**: AC-BE-US1-01, AC-BE-US2-01
|
|
476
|
+
**Status**: [ ] Not Started
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
### Workflow Summary
|
|
480
|
+
|
|
481
|
+
```
|
|
482
|
+
1. DETECT multi-project mode (check config.json, folder structure)
|
|
483
|
+
↓
|
|
484
|
+
2. If multi-project → Group user stories by project (FE/BE/SHARED/MOBILE/INFRA)
|
|
485
|
+
↓
|
|
486
|
+
3. Generate prefixed user stories: US-FE-001, US-BE-001, US-SHARED-001
|
|
487
|
+
↓
|
|
488
|
+
4. Generate prefixed ACs: AC-FE-US1-01, AC-BE-US1-01
|
|
489
|
+
↓
|
|
490
|
+
5. Generate tasks referencing correct project user stories
|
|
491
|
+
↓
|
|
492
|
+
6. Each project folder gets its own filtered spec
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### Why This Matters
|
|
496
|
+
|
|
497
|
+
Without project-scoped stories:
|
|
498
|
+
- ❌ All issues created in ONE repo (wrong!)
|
|
499
|
+
- ❌ No clarity which team owns what
|
|
500
|
+
- ❌ Tasks reference wrong user stories
|
|
501
|
+
- ❌ GitHub sync broken across repos
|
|
502
|
+
|
|
503
|
+
With project-scoped stories:
|
|
504
|
+
- ✅ Each repo gets only its user stories
|
|
505
|
+
- ✅ Clear ownership per team/repo
|
|
506
|
+
- ✅ GitHub issues in correct repo
|
|
507
|
+
- ✅ Clean separation of concerns
|
|
508
|
+
|
|
509
|
+
---
|
|
510
|
+
|
|
351
511
|
## Related Skills
|
|
352
512
|
|
|
353
513
|
- **Planning workflow**: Guides increment planning (uses Spec Generator internally)
|
|
354
514
|
- **Context loading**: Loads relevant context for specification generation
|
|
355
515
|
- **Quality validation**: Validates generated specifications for completeness
|
|
516
|
+
- **multi-project-spec-mapper**: Splits specs into project-specific files
|
|
517
|
+
- **umbrella-repo-detector**: Detects multi-repo architecture
|
|
356
518
|
|
|
357
519
|
---
|
|
358
520
|
|
|
359
521
|
## Version History
|
|
360
522
|
|
|
523
|
+
- **v2.0.0** (0.29.0): Added multi-project user story generation support
|
|
361
524
|
- **v1.0.0** (0.8.0): Initial release with flexible template system
|
|
362
525
|
- Based on: Flexible Spec Generator (V2) - context-aware, non-rigid templates
|
|
@@ -122,6 +122,32 @@ umbrella-project/ # Optional parent repo
|
|
|
122
122
|
└── ... # sync → my-app-shared GitHub issues
|
|
123
123
|
```
|
|
124
124
|
|
|
125
|
+
## Project ID Strategy
|
|
126
|
+
|
|
127
|
+
**CRITICAL**: The `id` field MUST match your canonical source name - no arbitrary abbreviations!
|
|
128
|
+
|
|
129
|
+
| Scenario | ID Source | Example |
|
|
130
|
+
|----------|-----------|---------|
|
|
131
|
+
| **1:1 Repo Mapping** | Exact repo name | `sw-qr-menu-fe` |
|
|
132
|
+
| **JIRA Project** | Project key (lowercase) | `WEBAPP` → `webapp` |
|
|
133
|
+
| **ADO Project** | Project name (kebab-case) | `Frontend Team` → `frontend-team` |
|
|
134
|
+
| **Area Path** | Last segment (kebab-case) | `Product\Web` → `web` |
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
✅ CORRECT: id matches repo name
|
|
138
|
+
id: "sw-qr-menu-fe"
|
|
139
|
+
path: "./sw-qr-menu-fe"
|
|
140
|
+
githubUrl: "https://github.com/user/sw-qr-menu-fe"
|
|
141
|
+
|
|
142
|
+
❌ WRONG: arbitrary abbreviation
|
|
143
|
+
id: "fe" ← What if you have 2 frontend repos?
|
|
144
|
+
path: "./sw-qr-menu-fe"
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Note**: The `prefix` (for user stories like `US-FE-001`) can be short even if `id` is long:
|
|
148
|
+
- `id: "sw-qr-menu-fe"` (full repo name)
|
|
149
|
+
- `prefix: "FE"` (short, for user story IDs)
|
|
150
|
+
|
|
125
151
|
## Config Example
|
|
126
152
|
|
|
127
153
|
**Parent umbrella config** (`.specweave/config.json`):
|
|
@@ -131,33 +157,51 @@ umbrella-project/ # Optional parent repo
|
|
|
131
157
|
"enabled": true,
|
|
132
158
|
"childRepos": [
|
|
133
159
|
{
|
|
134
|
-
"id": "fe",
|
|
135
|
-
"path": "./
|
|
160
|
+
"id": "sw-qr-menu-fe",
|
|
161
|
+
"path": "./sw-qr-menu-fe",
|
|
136
162
|
"prefix": "FE",
|
|
137
|
-
"githubUrl": "https://github.com/myorg/
|
|
163
|
+
"githubUrl": "https://github.com/myorg/sw-qr-menu-fe"
|
|
138
164
|
},
|
|
139
165
|
{
|
|
140
|
-
"id": "be",
|
|
141
|
-
"path": "./
|
|
166
|
+
"id": "sw-qr-menu-be",
|
|
167
|
+
"path": "./sw-qr-menu-be",
|
|
142
168
|
"prefix": "BE",
|
|
143
|
-
"githubUrl": "https://github.com/myorg/
|
|
169
|
+
"githubUrl": "https://github.com/myorg/sw-qr-menu-be"
|
|
144
170
|
},
|
|
145
171
|
{
|
|
146
|
-
"id": "shared",
|
|
147
|
-
"path": "./
|
|
172
|
+
"id": "sw-qr-menu-shared",
|
|
173
|
+
"path": "./sw-qr-menu-shared",
|
|
148
174
|
"prefix": "SHARED",
|
|
149
|
-
"githubUrl": "https://github.com/myorg/
|
|
175
|
+
"githubUrl": "https://github.com/myorg/sw-qr-menu-shared"
|
|
176
|
+
}
|
|
177
|
+
]
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**JIRA-based project** (when JIRA is source of truth):
|
|
183
|
+
```json
|
|
184
|
+
{
|
|
185
|
+
"umbrella": {
|
|
186
|
+
"enabled": true,
|
|
187
|
+
"childRepos": [
|
|
188
|
+
{
|
|
189
|
+
"id": "webapp",
|
|
190
|
+
"path": "./frontend",
|
|
191
|
+
"prefix": "WEBAPP",
|
|
192
|
+
"jiraProject": "WEBAPP",
|
|
193
|
+
"githubUrl": "https://github.com/myorg/frontend"
|
|
150
194
|
}
|
|
151
195
|
]
|
|
152
196
|
}
|
|
153
197
|
}
|
|
154
198
|
```
|
|
155
199
|
|
|
156
|
-
**Child repo config** (`
|
|
200
|
+
**Child repo config** (`sw-qr-menu-fe/.specweave/config.json`):
|
|
157
201
|
```json
|
|
158
202
|
{
|
|
159
203
|
"project": {
|
|
160
|
-
"name": "
|
|
204
|
+
"name": "QR Menu Frontend",
|
|
161
205
|
"prefix": "FE"
|
|
162
206
|
},
|
|
163
207
|
"sync": {
|
|
@@ -167,7 +211,7 @@ umbrella-project/ # Optional parent repo
|
|
|
167
211
|
"provider": "github",
|
|
168
212
|
"config": {
|
|
169
213
|
"owner": "myorg",
|
|
170
|
-
"repo": "
|
|
214
|
+
"repo": "sw-qr-menu-fe"
|
|
171
215
|
}
|
|
172
216
|
}
|
|
173
217
|
}
|
|
@@ -211,9 +255,32 @@ Which would you like to do?
|
|
|
211
255
|
| iOS, Android, mobile, push notification | Mobile | MOBILE |
|
|
212
256
|
| Terraform, K8s, Docker, CI/CD | Infrastructure | INFRA |
|
|
213
257
|
|
|
258
|
+
## Saving Changes Across Repos
|
|
259
|
+
|
|
260
|
+
Use `/specweave:save` to commit and push changes across all repos at once:
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
# Save all repos with same commit message
|
|
264
|
+
/specweave:save "feat: Add user authentication"
|
|
265
|
+
|
|
266
|
+
# Preview what would happen
|
|
267
|
+
/specweave:save --dry-run
|
|
268
|
+
|
|
269
|
+
# Save specific repos only
|
|
270
|
+
/specweave:save "fix: Bug fixes" --repos frontend,backend
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**Features:**
|
|
274
|
+
- Auto-detects repos with changes
|
|
275
|
+
- Sets up remotes if missing (prompts for URL or uses umbrella config)
|
|
276
|
+
- Commits with same message to all repos
|
|
277
|
+
- Pushes to origin
|
|
278
|
+
- Skips repos with no changes
|
|
279
|
+
|
|
214
280
|
## Important Notes
|
|
215
281
|
|
|
216
282
|
1. **Each repo is independent** - Own `.specweave/`, own increments, own external tool sync
|
|
217
283
|
2. **Parent repo is optional** - Can have umbrella config or just independent repos
|
|
218
284
|
3. **User stories MUST have project prefix** - Never generate generic `US-001` in multi-repo mode
|
|
219
285
|
4. **Cross-project stories get special handling** - Tagged and linked across repos
|
|
286
|
+
5. **Use `/specweave:save`** - Single command to save changes across all repos
|