specweave 0.28.11 → 0.28.13

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.
Files changed (38) hide show
  1. package/dist/src/cli/commands/init.d.ts.map +1 -1
  2. package/dist/src/cli/commands/init.js +29 -18
  3. package/dist/src/cli/commands/init.js.map +1 -1
  4. package/dist/src/cli/helpers/init/index.d.ts +1 -0
  5. package/dist/src/cli/helpers/init/index.d.ts.map +1 -1
  6. package/dist/src/cli/helpers/init/index.js +2 -0
  7. package/dist/src/cli/helpers/init/index.js.map +1 -1
  8. package/dist/src/cli/helpers/init/language-selection.d.ts +40 -0
  9. package/dist/src/cli/helpers/init/language-selection.d.ts.map +1 -0
  10. package/dist/src/cli/helpers/init/language-selection.js +281 -0
  11. package/dist/src/cli/helpers/init/language-selection.js.map +1 -0
  12. package/dist/src/cli/helpers/init/repository-setup.d.ts +2 -0
  13. package/dist/src/cli/helpers/init/repository-setup.d.ts.map +1 -1
  14. package/dist/src/cli/helpers/init/repository-setup.js +156 -12
  15. package/dist/src/cli/helpers/init/repository-setup.js.map +1 -1
  16. package/dist/src/cli/helpers/init/translation-config.d.ts +10 -2
  17. package/dist/src/cli/helpers/init/translation-config.d.ts.map +1 -1
  18. package/dist/src/cli/helpers/init/translation-config.js +302 -81
  19. package/dist/src/cli/helpers/init/translation-config.js.map +1 -1
  20. package/dist/src/core/config/types.d.ts +30 -2
  21. package/dist/src/core/config/types.d.ts.map +1 -1
  22. package/dist/src/core/config/types.js.map +1 -1
  23. package/dist/src/sync/sync-coordinator.d.ts +5 -0
  24. package/dist/src/sync/sync-coordinator.d.ts.map +1 -1
  25. package/dist/src/sync/sync-coordinator.js +104 -6
  26. package/dist/src/sync/sync-coordinator.js.map +1 -1
  27. package/package.json +1 -1
  28. package/plugins/specweave/agents/pm/AGENT.md +41 -4
  29. package/plugins/specweave/agents/test-aware-planner/AGENT.md +54 -0
  30. package/plugins/specweave/commands/specweave-increment.md +30 -0
  31. package/plugins/specweave/commands/specweave-save.md +838 -0
  32. package/plugins/specweave/hooks/lib/update-status-line.sh +9 -1
  33. package/plugins/specweave/hooks/post-increment-completion.sh +4 -3
  34. package/plugins/specweave/hooks/post-metadata-change.sh +18 -4
  35. package/plugins/specweave/skills/increment-planner/SKILL.md +252 -2
  36. package/plugins/specweave/skills/spec-generator/SKILL.md +163 -0
  37. package/plugins/specweave/skills/umbrella-repo-detector/SKILL.md +79 -12
  38. package/plugins/specweave-release/commands/specweave-release-npm.md +14 -22
@@ -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]}")/../../../.." && pwd)"
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: Read Config Values (MANDATORY)
133
+ ### STEP 0: Detect Multi-Project Mode (MANDATORY FIRST!)
134
134
 
135
- **Read testing configuration from `.specweave/config.json`**:
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": "./my-app-fe",
160
+ "id": "sw-qr-menu-fe",
161
+ "path": "./sw-qr-menu-fe",
136
162
  "prefix": "FE",
137
- "githubUrl": "https://github.com/myorg/my-app-fe"
163
+ "githubUrl": "https://github.com/myorg/sw-qr-menu-fe"
138
164
  },
139
165
  {
140
- "id": "be",
141
- "path": "./my-app-be",
166
+ "id": "sw-qr-menu-be",
167
+ "path": "./sw-qr-menu-be",
142
168
  "prefix": "BE",
143
- "githubUrl": "https://github.com/myorg/my-app-be"
169
+ "githubUrl": "https://github.com/myorg/sw-qr-menu-be"
144
170
  },
145
171
  {
146
- "id": "shared",
147
- "path": "./my-app-shared",
172
+ "id": "sw-qr-menu-shared",
173
+ "path": "./sw-qr-menu-shared",
148
174
  "prefix": "SHARED",
149
- "githubUrl": "https://github.com/myorg/my-app-shared"
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** (`my-app-fe/.specweave/config.json`):
200
+ **Child repo config** (`sw-qr-menu-fe/.specweave/config.json`):
157
201
  ```json
158
202
  {
159
203
  "project": {
160
- "name": "My App Frontend",
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": "my-app-fe"
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