specweave 0.28.9 → 0.28.11

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 (37) hide show
  1. package/dist/src/cli/commands/init.d.ts.map +1 -1
  2. package/dist/src/cli/commands/init.js +17 -1
  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/translation-config.d.ts +53 -0
  9. package/dist/src/cli/helpers/init/translation-config.d.ts.map +1 -0
  10. package/dist/src/cli/helpers/init/translation-config.js +216 -0
  11. package/dist/src/cli/helpers/init/translation-config.js.map +1 -0
  12. package/dist/src/cli/helpers/init/types.d.ts +33 -0
  13. package/dist/src/cli/helpers/init/types.d.ts.map +1 -1
  14. package/dist/src/core/config/types.d.ts +115 -0
  15. package/dist/src/core/config/types.d.ts.map +1 -1
  16. package/dist/src/core/config/types.js.map +1 -1
  17. package/dist/src/core/repo-structure/repo-id-generator.d.ts +24 -95
  18. package/dist/src/core/repo-structure/repo-id-generator.d.ts.map +1 -1
  19. package/dist/src/core/repo-structure/repo-id-generator.js +31 -223
  20. package/dist/src/core/repo-structure/repo-id-generator.js.map +1 -1
  21. package/dist/src/core/repo-structure/repo-structure-manager.d.ts.map +1 -1
  22. package/dist/src/core/repo-structure/repo-structure-manager.js +12 -46
  23. package/dist/src/core/repo-structure/repo-structure-manager.js.map +1 -1
  24. package/dist/src/utils/multi-repo-detector.d.ts +85 -0
  25. package/dist/src/utils/multi-repo-detector.d.ts.map +1 -0
  26. package/dist/src/utils/multi-repo-detector.js +264 -0
  27. package/dist/src/utils/multi-repo-detector.js.map +1 -0
  28. package/package.json +1 -1
  29. package/plugins/specweave/agents/pm/AGENT.md +141 -0
  30. package/plugins/specweave/hooks/hooks.json +12 -0
  31. package/plugins/specweave/hooks/post-increment-planning.sh +95 -51
  32. package/plugins/specweave/hooks/pre-task-completion-edit.sh +355 -0
  33. package/plugins/specweave/lib/hooks/sync-living-docs.js +43 -0
  34. package/plugins/specweave/skills/umbrella-repo-detector/SKILL.md +219 -0
  35. package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +18 -0
  36. package/plugins/specweave-infrastructure/skills/hetzner-provisioner/README.md +1 -1
  37. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +27 -0
@@ -0,0 +1,355 @@
1
+ #!/bin/bash
2
+ #
3
+ # pre-task-completion-edit.sh (v1.0.0)
4
+ #
5
+ # QUALITY GATE: Validates AC completion BEFORE allowing task status change to completed
6
+ #
7
+ # Triggered by: PreToolUse:Edit on .specweave/increments/*/tasks.md
8
+ #
9
+ # WORKFLOW:
10
+ # =========
11
+ # 1. Edit tool called on tasks.md
12
+ # 2. This hook fires (PreToolUse - BEFORE the edit executes)
13
+ # 3. Detect if edit is marking a task as completed ([ ] → [x])
14
+ # 4. Extract task's "Satisfies ACs" (e.g., AC-US1-01, AC-US1-02)
15
+ # 5. Verify those ACs are checked [x] in spec.md
16
+ # 6. If ACs verified → Allow edit (continue: true)
17
+ # 7. If ACs NOT verified → BLOCK edit (continue: false)
18
+ #
19
+ # ENFORCEMENT:
20
+ # ============
21
+ # Tasks CANNOT be marked complete unless their linked ACs are verified.
22
+ # This is the ONLY enforcement point - cannot be bypassed.
23
+ #
24
+ # See: ADR-0xxx (AC Verification Quality Gate)
25
+
26
+ set +e # CRITICAL: Never crash Claude Code
27
+
28
+ # ============================================================================
29
+ # EMERGENCY KILL SWITCH
30
+ # ============================================================================
31
+ if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
32
+ cat <<EOF
33
+ {"continue": true}
34
+ EOF
35
+ exit 0
36
+ fi
37
+
38
+ # ============================================================================
39
+ # RECURSION PREVENTION (v0.26.0 pattern)
40
+ # ============================================================================
41
+ find_project_root() {
42
+ local dir="$PWD"
43
+ while [[ "$dir" != "/" ]]; do
44
+ if [[ -d "$dir/.specweave" ]]; then
45
+ echo "$dir"
46
+ return 0
47
+ fi
48
+ dir=$(dirname "$dir")
49
+ done
50
+ echo "$PWD"
51
+ }
52
+
53
+ PROJECT_ROOT=$(find_project_root)
54
+
55
+ if [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
56
+ cat <<EOF
57
+ {"continue": true}
58
+ EOF
59
+ exit 0
60
+ fi
61
+
62
+ RECURSION_GUARD_FILE="$PROJECT_ROOT/.specweave/state/.hook-recursion-guard"
63
+ if [[ -f "$RECURSION_GUARD_FILE" ]]; then
64
+ cat <<EOF
65
+ {"continue": true}
66
+ EOF
67
+ exit 0
68
+ fi
69
+
70
+ # ============================================================================
71
+ # SETUP
72
+ # ============================================================================
73
+ LOGS_DIR="$PROJECT_ROOT/.specweave/logs"
74
+ DEBUG_LOG="$LOGS_DIR/hooks-debug.log"
75
+ mkdir -p "$LOGS_DIR" 2>/dev/null || true
76
+
77
+ echo "[$(date)] pre-task-completion-edit: Hook triggered" >> "$DEBUG_LOG" 2>/dev/null || true
78
+
79
+ # ============================================================================
80
+ # CAPTURE INPUT (PreToolUse receives tool_input JSON)
81
+ # ============================================================================
82
+ STDIN_DATA=$(cat)
83
+
84
+ # Log the input for debugging
85
+ echo "[$(date)] pre-task-completion-edit: Input: $STDIN_DATA" >> "$DEBUG_LOG" 2>/dev/null || true
86
+
87
+ # ============================================================================
88
+ # EXTRACT EDIT DETAILS
89
+ # ============================================================================
90
+ # PreToolUse:Edit receives: { "tool_input": { "file_path": "...", "old_string": "...", "new_string": "..." } }
91
+
92
+ FILE_PATH=""
93
+ OLD_STRING=""
94
+ NEW_STRING=""
95
+
96
+ if command -v jq &>/dev/null; then
97
+ FILE_PATH=$(echo "$STDIN_DATA" | jq -r '.tool_input.file_path // empty' 2>/dev/null || echo "")
98
+ OLD_STRING=$(echo "$STDIN_DATA" | jq -r '.tool_input.old_string // empty' 2>/dev/null || echo "")
99
+ NEW_STRING=$(echo "$STDIN_DATA" | jq -r '.tool_input.new_string // empty' 2>/dev/null || echo "")
100
+ else
101
+ # Fallback: basic regex extraction
102
+ FILE_PATH=$(echo "$STDIN_DATA" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)".*/\1/' || echo "")
103
+ fi
104
+
105
+ echo "[$(date)] pre-task-completion-edit: file_path=$FILE_PATH" >> "$DEBUG_LOG" 2>/dev/null || true
106
+
107
+ # ============================================================================
108
+ # EARLY EXIT: Only process tasks.md in active increments
109
+ # ============================================================================
110
+ if [[ "$FILE_PATH" != *"/tasks.md" ]]; then
111
+ echo "[$(date)] pre-task-completion-edit: Not tasks.md, skipping" >> "$DEBUG_LOG" 2>/dev/null || true
112
+ cat <<EOF
113
+ {"continue": true}
114
+ EOF
115
+ exit 0
116
+ fi
117
+
118
+ if [[ "$FILE_PATH" != *"/.specweave/increments/"* ]] && [[ "$FILE_PATH" != *".specweave/increments/"* ]]; then
119
+ echo "[$(date)] pre-task-completion-edit: Not in increments/, skipping" >> "$DEBUG_LOG" 2>/dev/null || true
120
+ cat <<EOF
121
+ {"continue": true}
122
+ EOF
123
+ exit 0
124
+ fi
125
+
126
+ if [[ "$FILE_PATH" == *"/_archive/"* ]]; then
127
+ echo "[$(date)] pre-task-completion-edit: Archived increment, skipping" >> "$DEBUG_LOG" 2>/dev/null || true
128
+ cat <<EOF
129
+ {"continue": true}
130
+ EOF
131
+ exit 0
132
+ fi
133
+
134
+ # ============================================================================
135
+ # DETECT TASK COMPLETION PATTERN
136
+ # ============================================================================
137
+ # Check if edit is changing status from pending to completed:
138
+ # old_string: "**Status**: [ ] pending" or "**Status**: [ ]"
139
+ # new_string: "**Status**: [x] completed" or "**Status**: [x]"
140
+
141
+ IS_COMPLETION=false
142
+
143
+ # Pattern 1: Full status line change
144
+ if [[ "$OLD_STRING" == *"**Status**:"*"[ ]"* ]] && [[ "$NEW_STRING" == *"**Status**:"*"[x]"* ]]; then
145
+ IS_COMPLETION=true
146
+ fi
147
+
148
+ # Pattern 2: Just checkbox change (some formats)
149
+ if [[ "$OLD_STRING" == *"[ ] pending"* ]] && [[ "$NEW_STRING" == *"[x] completed"* ]]; then
150
+ IS_COMPLETION=true
151
+ fi
152
+
153
+ # Pattern 3: Minimal checkbox change
154
+ if [[ "$OLD_STRING" == "[ ]"* ]] && [[ "$NEW_STRING" == "[x]"* ]]; then
155
+ IS_COMPLETION=true
156
+ fi
157
+
158
+ if [[ "$IS_COMPLETION" != "true" ]]; then
159
+ echo "[$(date)] pre-task-completion-edit: Not a completion edit, allowing" >> "$DEBUG_LOG" 2>/dev/null || true
160
+ cat <<EOF
161
+ {"continue": true}
162
+ EOF
163
+ exit 0
164
+ fi
165
+
166
+ echo "[$(date)] pre-task-completion-edit: COMPLETION DETECTED - Validating ACs" >> "$DEBUG_LOG" 2>/dev/null || true
167
+
168
+ # ============================================================================
169
+ # EXTRACT INCREMENT AND TASK INFO
170
+ # ============================================================================
171
+ # Parse increment name from file path
172
+ # Pattern: .specweave/increments/XXXX-name/tasks.md
173
+ INCREMENT_NAME=$(echo "$FILE_PATH" | grep -o '[0-9]\{4\}-[a-zA-Z0-9_-]*' | tail -1 || echo "")
174
+ INCREMENT_DIR="$PROJECT_ROOT/.specweave/increments/$INCREMENT_NAME"
175
+ TASKS_FILE="$INCREMENT_DIR/tasks.md"
176
+ SPEC_FILE="$INCREMENT_DIR/spec.md"
177
+
178
+ echo "[$(date)] pre-task-completion-edit: INCREMENT=$INCREMENT_NAME" >> "$DEBUG_LOG" 2>/dev/null || true
179
+
180
+ if [[ -z "$INCREMENT_NAME" ]] || [[ ! -f "$TASKS_FILE" ]]; then
181
+ echo "[$(date)] pre-task-completion-edit: Cannot find increment, allowing (safety)" >> "$DEBUG_LOG" 2>/dev/null || true
182
+ cat <<EOF
183
+ {"continue": true}
184
+ EOF
185
+ exit 0
186
+ fi
187
+
188
+ if [[ ! -f "$SPEC_FILE" ]]; then
189
+ echo "[$(date)] pre-task-completion-edit: No spec.md found, allowing (no ACs to verify)" >> "$DEBUG_LOG" 2>/dev/null || true
190
+ cat <<EOF
191
+ {"continue": true}
192
+ EOF
193
+ exit 0
194
+ fi
195
+
196
+ # ============================================================================
197
+ # FIND TASK BEING COMPLETED
198
+ # ============================================================================
199
+ # We need to find which task is being completed by matching the old_string context
200
+ # Look for the task section that contains this status line
201
+
202
+ # Extract task context from old_string (task header should be nearby)
203
+ # First, read tasks.md and find the task that contains this status line
204
+
205
+ TASK_ID=""
206
+ SATISFIES_ACS=""
207
+
208
+ # Read tasks.md and find the task context
209
+ TASKS_CONTENT=$(cat "$TASKS_FILE" 2>/dev/null || echo "")
210
+
211
+ # Find the task ID that precedes the old_string status
212
+ # Tasks follow pattern:
213
+ # ### T-XXX: Title
214
+ # **User Story**: US-XXX
215
+ # **Satisfies ACs**: AC-XXX-YY, AC-XXX-ZZ
216
+ # **Status**: [ ] pending
217
+
218
+ # Strategy: Search for task header, then check if its status matches old_string
219
+ CURRENT_TASK_ID=""
220
+ CURRENT_ACS=""
221
+ IN_TASK=false
222
+
223
+ while IFS= read -r line; do
224
+ # Detect task header
225
+ if [[ "$line" =~ ^###[[:space:]]+(T-[0-9]+): ]]; then
226
+ CURRENT_TASK_ID="${BASH_REMATCH[1]}"
227
+ CURRENT_ACS=""
228
+ IN_TASK=true
229
+ fi
230
+
231
+ # Capture Satisfies ACs
232
+ if [[ "$IN_TASK" == "true" ]] && [[ "$line" == *"**Satisfies ACs**:"* ]]; then
233
+ # Extract AC IDs (comma-separated)
234
+ CURRENT_ACS=$(echo "$line" | sed 's/.*\*\*Satisfies ACs\*\*:[[:space:]]*//' | tr -d '\r')
235
+ fi
236
+
237
+ # Check if this task's status matches what we're editing
238
+ if [[ "$IN_TASK" == "true" ]] && [[ "$line" == *"**Status**:"*"[ ]"* ]]; then
239
+ # This task is pending - check if the old_string matches
240
+ # Compare by checking if old_string is a substring of status line
241
+ if [[ "$OLD_STRING" == *"[ ]"* ]]; then
242
+ TASK_ID="$CURRENT_TASK_ID"
243
+ SATISFIES_ACS="$CURRENT_ACS"
244
+ # Don't break - continue to find the EXACT task
245
+ fi
246
+ fi
247
+
248
+ # Task boundary
249
+ if [[ "$line" == "---" ]]; then
250
+ IN_TASK=false
251
+ fi
252
+ done <<< "$TASKS_CONTENT"
253
+
254
+ echo "[$(date)] pre-task-completion-edit: TASK_ID=$TASK_ID, SATISFIES_ACS=$SATISFIES_ACS" >> "$DEBUG_LOG" 2>/dev/null || true
255
+
256
+ if [[ -z "$TASK_ID" ]]; then
257
+ echo "[$(date)] pre-task-completion-edit: Could not identify task, allowing (safety)" >> "$DEBUG_LOG" 2>/dev/null || true
258
+ cat <<EOF
259
+ {"continue": true, "systemMessage": "Warning: Could not identify which task is being completed. AC verification skipped."}
260
+ EOF
261
+ exit 0
262
+ fi
263
+
264
+ if [[ -z "$SATISFIES_ACS" ]]; then
265
+ echo "[$(date)] pre-task-completion-edit: Task has no ACs, allowing" >> "$DEBUG_LOG" 2>/dev/null || true
266
+ cat <<EOF
267
+ {"continue": true, "systemMessage": "Task $TASK_ID has no Acceptance Criteria linked. Consider adding 'Satisfies ACs' field."}
268
+ EOF
269
+ exit 0
270
+ fi
271
+
272
+ # ============================================================================
273
+ # VERIFY ACs IN spec.md
274
+ # ============================================================================
275
+ # Check that each AC in SATISFIES_ACS is marked [x] (checked) in spec.md
276
+ # AC format in spec.md:
277
+ # - [x] **AC-US1-01**: Description...
278
+ # - [ ] **AC-US1-02**: Description...
279
+
280
+ SPEC_CONTENT=$(cat "$SPEC_FILE" 2>/dev/null || echo "")
281
+ FAILED_ACS=""
282
+ PASSED_ACS=""
283
+
284
+ # Parse comma-separated ACs
285
+ IFS=',' read -ra AC_ARRAY <<< "$SATISFIES_ACS"
286
+
287
+ for ac_raw in "${AC_ARRAY[@]}"; do
288
+ # Trim whitespace
289
+ AC_ID=$(echo "$ac_raw" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
290
+
291
+ if [[ -z "$AC_ID" ]]; then
292
+ continue
293
+ fi
294
+
295
+ echo "[$(date)] pre-task-completion-edit: Checking AC: $AC_ID" >> "$DEBUG_LOG" 2>/dev/null || true
296
+
297
+ # Check if AC is checked [x] in spec.md
298
+ # Look for: - [x] **AC-US1-01** (with optional bold around ID)
299
+ if echo "$SPEC_CONTENT" | grep -qE "^\s*-\s*\[x\]\s*\*\*${AC_ID}\*\*"; then
300
+ PASSED_ACS="$PASSED_ACS $AC_ID"
301
+ echo "[$(date)] pre-task-completion-edit: $AC_ID is VERIFIED (checked in spec.md)" >> "$DEBUG_LOG" 2>/dev/null || true
302
+ elif echo "$SPEC_CONTENT" | grep -qE "^\s*-\s*\[ \]\s*\*\*${AC_ID}\*\*"; then
303
+ FAILED_ACS="$FAILED_ACS $AC_ID"
304
+ echo "[$(date)] pre-task-completion-edit: $AC_ID is NOT verified (unchecked in spec.md)" >> "$DEBUG_LOG" 2>/dev/null || true
305
+ else
306
+ # AC not found in spec.md - warn but allow
307
+ echo "[$(date)] pre-task-completion-edit: $AC_ID not found in spec.md (warning)" >> "$DEBUG_LOG" 2>/dev/null || true
308
+ fi
309
+ done
310
+
311
+ # ============================================================================
312
+ # DECISION: ALLOW OR BLOCK
313
+ # ============================================================================
314
+ FAILED_ACS=$(echo "$FAILED_ACS" | sed 's/^[[:space:]]*//')
315
+
316
+ if [[ -n "$FAILED_ACS" ]]; then
317
+ # BLOCK the completion - ACs not verified
318
+ echo "[$(date)] pre-task-completion-edit: BLOCKING - Unverified ACs: $FAILED_ACS" >> "$DEBUG_LOG" 2>/dev/null || true
319
+
320
+ # Escape for JSON
321
+ FAILED_ACS_ESCAPED=$(echo "$FAILED_ACS" | sed 's/"/\\"/g')
322
+
323
+ cat <<EOF
324
+ {
325
+ "continue": false,
326
+ "systemMessage": "BLOCKED: Task $TASK_ID cannot be marked complete.
327
+
328
+ Unverified Acceptance Criteria: $FAILED_ACS_ESCAPED
329
+
330
+ These ACs are NOT checked [x] in spec.md:
331
+ $FAILED_ACS_ESCAPED
332
+
333
+ ACTION REQUIRED:
334
+ 1. Verify each AC is actually satisfied by the implementation
335
+ 2. Check the AC in spec.md: Edit the line from [ ] to [x]
336
+ 3. Then retry marking this task as completed
337
+
338
+ This quality gate ensures tasks are only completed when their ACs are verified."
339
+ }
340
+ EOF
341
+ exit 0
342
+ fi
343
+
344
+ # All ACs verified - allow completion
345
+ echo "[$(date)] pre-task-completion-edit: ALLOWING - All ACs verified" >> "$DEBUG_LOG" 2>/dev/null || true
346
+
347
+ PASSED_ACS=$(echo "$PASSED_ACS" | sed 's/^[[:space:]]*//')
348
+ cat <<EOF
349
+ {
350
+ "continue": true,
351
+ "systemMessage": "AC Verification Passed for $TASK_ID. Verified ACs:$PASSED_ACS"
352
+ }
353
+ EOF
354
+
355
+ exit 0
@@ -70,6 +70,49 @@ async function syncLivingDocs(incrementId) {
70
70
  }
71
71
  console.log(`\u{1F4C4} Changed/created ${changedDocs.length} file(s)`);
72
72
 
73
+ // ========================================================================
74
+ // TRANSLATION TRIGGER (v0.29.0+ - Multi-Language Support)
75
+ // ========================================================================
76
+ // After living docs sync, check if translation is needed.
77
+ // User MUST opt-in during init (cost warning shown).
78
+ // Translation only happens if:
79
+ // - config.language != 'en'
80
+ // - config.translation.enabled == true
81
+ // - config.translation.scope.livingDocs == true
82
+ const targetLang = config.language || 'en';
83
+ const translationEnabled = config.translation?.enabled ?? false;
84
+ const translateLivingDocs = config.translation?.scope?.livingDocs ?? false;
85
+
86
+ if (targetLang !== 'en' && translationEnabled && translateLivingDocs && changedDocs.length > 0) {
87
+ console.log(`\n\u{1F30D} Translating ${changedDocs.length} updated file(s) to ${targetLang}...`);
88
+
89
+ try {
90
+ // Try to load translate-file module
91
+ const { translateFile } = await import('./translate-file.js');
92
+
93
+ for (const docPath of changedDocs) {
94
+ try {
95
+ await translateFile({
96
+ filePath: docPath,
97
+ targetLang,
98
+ preview: false,
99
+ verbose: false,
100
+ });
101
+ console.log(` \u2705 ${path.basename(docPath)}`);
102
+ } catch (err) {
103
+ console.warn(` \u26A0\uFE0F Failed to translate ${path.basename(docPath)}: ${err.message}`);
104
+ }
105
+ }
106
+ console.log(`\u2705 Living docs translation complete`);
107
+ } catch (importErr) {
108
+ // translate-file.js may not be compiled yet
109
+ console.log(` \u2139\uFE0F Translation module not available (run 'npm run build')`);
110
+ console.log(` \u{1F4A1} Tip: Run /specweave:translate to translate manually`);
111
+ }
112
+ } else if (targetLang !== 'en' && !translationEnabled) {
113
+ console.log(` \u2139\uFE0F Translation disabled (use /specweave:translate manually)`);
114
+ }
115
+
73
116
  // ========================================================================
74
117
  // CHECK PERMISSION: canUpdateExternalItems (v0.24.0 - Three-Permission Architecture)
75
118
  // ========================================================================
@@ -0,0 +1,219 @@
1
+ ---
2
+ name: umbrella-repo-detector
3
+ description: Detects multi-repo architecture from user prompts and guides setup. Activates for: multiple repos, 3 repos, frontend repo, backend repo, shared library repo, monorepo services, microservices, separate repos, FE/BE/Shared, multi-repo architecture, independent repos.
4
+ ---
5
+
6
+ # Umbrella Multi-Repo Architecture Detector
7
+
8
+ ## When This Skill Activates
9
+
10
+ Activates when user describes:
11
+ - Multiple repos: "3 repos", "frontend repo", "backend repo", "shared library"
12
+ - Architecture patterns: "monorepo with services", "microservices", "multi-repo"
13
+ - Explicit splits: "FE/BE/Shared", "frontend/backend/common"
14
+ - GitHub URLs for multiple repositories
15
+
16
+ ## My Role
17
+
18
+ When I detect a multi-repo architecture in the user's prompt:
19
+
20
+ 1. **Acknowledge the architecture** with detected repos
21
+ 2. **Explain project-scoped user stories** (US-FE-*, US-BE-*, US-SHARED-*)
22
+ 3. **Guide the init flow** for proper setup
23
+ 4. **Route to PM agent** with multi-repo context
24
+
25
+ ## Detection Patterns
26
+
27
+ | Pattern | Example | Detected As |
28
+ |---------|---------|-------------|
29
+ | Repo count | "3 repos", "multiple repos" | Multi-repo intent |
30
+ | Frontend repo | "Frontend repo", "UI repo", "web app" | Type: frontend, Prefix: FE |
31
+ | Backend repo | "Backend API repo", "server", "API" | Type: backend, Prefix: BE |
32
+ | Shared repo | "Shared library", "common types" | Type: shared, Prefix: SHARED |
33
+ | Mobile repo | "Mobile app", "iOS/Android" | Type: mobile, Prefix: MOBILE |
34
+ | Infra repo | "Infrastructure", "Terraform" | Type: infrastructure, Prefix: INFRA |
35
+
36
+ ## Project-Scoped User Stories
37
+
38
+ When user describes multi-repo, user stories MUST be prefixed:
39
+
40
+ ```markdown
41
+ ## Instead of (generic):
42
+ US-001: User Registration
43
+ US-002: Registration API
44
+ US-003: Validation Schema
45
+
46
+ ## Generate (project-scoped):
47
+ US-FE-001: User Registration Form
48
+ - Related repo: frontend
49
+ - Keywords: form, UI, validation display
50
+
51
+ US-BE-001: Registration API Endpoint
52
+ - Related repo: backend
53
+ - Keywords: API, endpoint, database
54
+
55
+ US-SHARED-001: Registration Validation Schema
56
+ - Related repo: shared
57
+ - Keywords: validator, schema, types
58
+ ```
59
+
60
+ ## Cross-Cutting User Stories
61
+
62
+ For features that span multiple repos, use cross-project tagging:
63
+
64
+ ```markdown
65
+ US-AUTH-001: OAuth Integration
66
+ - Tags: ["cross-project", "frontend", "backend"]
67
+ - Creates linked issues in: FE repo, BE repo
68
+ - Child stories:
69
+ - US-FE-002: OAuth Login Button (frontend)
70
+ - US-BE-002: OAuth Token Validation (backend)
71
+ ```
72
+
73
+ ## Setup Flow Guidance
74
+
75
+ When multi-repo detected, guide user through options:
76
+
77
+ ### Option 1: Clone from GitHub (Recommended)
78
+ ```
79
+ You have existing repos? Let's clone them:
80
+ 1. Provide GitHub URLs (comma-separated or one per line)
81
+ 2. Each repo gets its own .specweave/ configuration
82
+ 3. Each repo syncs to its own GitHub issues
83
+ ```
84
+
85
+ ### Option 2: Create New Repos
86
+ ```
87
+ Creating fresh repos:
88
+ 1. I'll create repos on GitHub for you
89
+ 2. Each gets initialized with .specweave/
90
+ 3. External tool sync configured per repo
91
+ ```
92
+
93
+ ### Option 3: Initialize Local Folders
94
+ ```
95
+ Have local folders already?
96
+ 1. Point me to each folder
97
+ 2. I'll initialize .specweave/ in each
98
+ 3. Configure external tools per repo
99
+ ```
100
+
101
+ ## Umbrella Repo Structure
102
+
103
+ ```
104
+ umbrella-project/ # Optional parent repo
105
+ ├── .specweave/
106
+ │ ├── config.json # umbrella config with childRepos[]
107
+ │ └── docs/ # High-level PRD, roadmap only
108
+
109
+ ├── my-app-fe/ # Frontend repo (cloned/created)
110
+ │ └── .specweave/
111
+ │ ├── config.json # sync → my-app-fe GitHub issues
112
+ │ └── increments/
113
+ │ └── 0001-feature/
114
+ │ └── spec.md # Only US-FE-* stories
115
+
116
+ ├── my-app-be/ # Backend repo (cloned/created)
117
+ │ └── .specweave/
118
+ │ └── ... # sync → my-app-be GitHub issues
119
+
120
+ └── my-app-shared/ # Shared repo (cloned/created)
121
+ └── .specweave/
122
+ └── ... # sync → my-app-shared GitHub issues
123
+ ```
124
+
125
+ ## Config Example
126
+
127
+ **Parent umbrella config** (`.specweave/config.json`):
128
+ ```json
129
+ {
130
+ "umbrella": {
131
+ "enabled": true,
132
+ "childRepos": [
133
+ {
134
+ "id": "fe",
135
+ "path": "./my-app-fe",
136
+ "prefix": "FE",
137
+ "githubUrl": "https://github.com/myorg/my-app-fe"
138
+ },
139
+ {
140
+ "id": "be",
141
+ "path": "./my-app-be",
142
+ "prefix": "BE",
143
+ "githubUrl": "https://github.com/myorg/my-app-be"
144
+ },
145
+ {
146
+ "id": "shared",
147
+ "path": "./my-app-shared",
148
+ "prefix": "SHARED",
149
+ "githubUrl": "https://github.com/myorg/my-app-shared"
150
+ }
151
+ ]
152
+ }
153
+ }
154
+ ```
155
+
156
+ **Child repo config** (`my-app-fe/.specweave/config.json`):
157
+ ```json
158
+ {
159
+ "project": {
160
+ "name": "My App Frontend",
161
+ "prefix": "FE"
162
+ },
163
+ "sync": {
164
+ "activeProfile": "github",
165
+ "profiles": {
166
+ "github": {
167
+ "provider": "github",
168
+ "config": {
169
+ "owner": "myorg",
170
+ "repo": "my-app-fe"
171
+ }
172
+ }
173
+ }
174
+ }
175
+ }
176
+ ```
177
+
178
+ ## Response Template
179
+
180
+ When I detect multi-repo intent, respond:
181
+
182
+ ```
183
+ I detected a **multi-repo architecture** in your description:
184
+
185
+ **Detected Repos:**
186
+ - Frontend (prefix: FE) - [matched keywords]
187
+ - Backend (prefix: BE) - [matched keywords]
188
+ - Shared (prefix: SHARED) - [matched keywords]
189
+
190
+ **User Story Format:**
191
+ User stories will be project-scoped:
192
+ - `US-FE-001`: Frontend stories
193
+ - `US-BE-001`: Backend stories
194
+ - `US-SHARED-001`: Shared library stories
195
+
196
+ **Setup Options:**
197
+ 1. **Clone from GitHub** - Provide URLs, I'll clone and initialize each
198
+ 2. **Create new repos** - I'll create on GitHub and initialize
199
+ 3. **Initialize local folders** - Point to existing folders
200
+
201
+ Which would you like to do?
202
+ ```
203
+
204
+ ## Keywords for Story Routing
205
+
206
+ | Keywords | Routes To | Prefix |
207
+ |----------|-----------|--------|
208
+ | UI, component, page, form, view, theme, drag-drop, builder | Frontend | FE |
209
+ | API, endpoint, CRUD, webhook, notification, analytics | Backend | BE |
210
+ | schema, validator, types, utilities, localization | Shared | SHARED |
211
+ | iOS, Android, mobile, push notification | Mobile | MOBILE |
212
+ | Terraform, K8s, Docker, CI/CD | Infrastructure | INFRA |
213
+
214
+ ## Important Notes
215
+
216
+ 1. **Each repo is independent** - Own `.specweave/`, own increments, own external tool sync
217
+ 2. **Parent repo is optional** - Can have umbrella config or just independent repos
218
+ 3. **User stories MUST have project prefix** - Never generate generic `US-001` in multi-repo mode
219
+ 4. **Cross-project stories get special handling** - Tagged and linked across repos
@@ -1114,3 +1114,21 @@
1114
1114
  [Tue Nov 25 02:03:38 EST 2025] [GitHub] ⚠️ sync-spec-content CLI not found at /Users/antonabyzov/Projects/github/specweave/plugins/specweave-github/hooks/dist/src/cli/commands/sync-spec-content.js, skipping sync
1115
1115
  [Tue Nov 25 02:03:39 EST 2025] [GitHub] 🔗 GitHub sync hook fired
1116
1116
  [Tue Nov 25 02:03:39 EST 2025] [GitHub] ⚠️ sync-spec-content CLI not found at /Users/antonabyzov/Projects/github/specweave/plugins/specweave-github/hooks/dist/src/cli/commands/sync-spec-content.js, skipping sync
1117
+ [Tue Nov 25 03:33:47 EST 2025] [GitHub] 🔗 GitHub sync hook fired
1118
+ [Tue Nov 25 03:33:47 EST 2025] [GitHub] ⚠️ sync-spec-content CLI not found at /Users/antonabyzov/Projects/github/specweave/plugins/specweave-github/hooks/dist/src/cli/commands/sync-spec-content.js, skipping sync
1119
+ [Tue Nov 25 03:33:47 EST 2025] [GitHub] 🔗 GitHub sync hook fired
1120
+ [Tue Nov 25 03:33:47 EST 2025] [GitHub] ⚠️ sync-spec-content CLI not found at /Users/antonabyzov/Projects/github/specweave/plugins/specweave-github/hooks/dist/src/cli/commands/sync-spec-content.js, skipping sync
1121
+ [Tue Nov 25 03:33:47 EST 2025] [GitHub] 🔗 GitHub sync hook fired
1122
+ [Tue Nov 25 03:33:47 EST 2025] [GitHub] ⚠️ sync-spec-content CLI not found at /Users/antonabyzov/Projects/github/specweave/plugins/specweave-github/hooks/dist/src/cli/commands/sync-spec-content.js, skipping sync
1123
+ [Tue Nov 25 03:36:17 EST 2025] [GitHub] 🔗 GitHub sync hook fired
1124
+ [Tue Nov 25 03:36:17 EST 2025] [GitHub] ⚠️ sync-spec-content CLI not found at /Users/antonabyzov/Projects/github/specweave/plugins/specweave-github/hooks/dist/src/cli/commands/sync-spec-content.js, skipping sync
1125
+ [Tue Nov 25 03:36:17 EST 2025] [GitHub] 🔗 GitHub sync hook fired
1126
+ [Tue Nov 25 03:36:17 EST 2025] [GitHub] ⚠️ sync-spec-content CLI not found at /Users/antonabyzov/Projects/github/specweave/plugins/specweave-github/hooks/dist/src/cli/commands/sync-spec-content.js, skipping sync
1127
+ [Tue Nov 25 03:36:18 EST 2025] [GitHub] 🔗 GitHub sync hook fired
1128
+ [Tue Nov 25 03:36:18 EST 2025] [GitHub] ⚠️ sync-spec-content CLI not found at /Users/antonabyzov/Projects/github/specweave/plugins/specweave-github/hooks/dist/src/cli/commands/sync-spec-content.js, skipping sync
1129
+ [Tue Nov 25 04:01:54 EST 2025] [GitHub] 🔗 GitHub sync hook fired
1130
+ [Tue Nov 25 04:01:54 EST 2025] [GitHub] ⚠️ sync-spec-content CLI not found at /Users/antonabyzov/Projects/github/specweave/plugins/specweave-github/hooks/dist/src/cli/commands/sync-spec-content.js, skipping sync
1131
+ [Tue Nov 25 04:01:54 EST 2025] [GitHub] 🔗 GitHub sync hook fired
1132
+ [Tue Nov 25 04:01:54 EST 2025] [GitHub] ⚠️ sync-spec-content CLI not found at /Users/antonabyzov/Projects/github/specweave/plugins/specweave-github/hooks/dist/src/cli/commands/sync-spec-content.js, skipping sync
1133
+ [Tue Nov 25 04:01:54 EST 2025] [GitHub] 🔗 GitHub sync hook fired
1134
+ [Tue Nov 25 04:01:54 EST 2025] [GitHub] ⚠️ sync-spec-content CLI not found at /Users/antonabyzov/Projects/github/specweave/plugins/specweave-github/hooks/dist/src/cli/commands/sync-spec-content.js, skipping sync
@@ -1,6 +1,6 @@
1
1
  **Name:** hetzner-provisioner
2
2
  **Type:** Infrastructure / DevOps
3
- **Model:** Claude Sonnet 4 (balanced for IaC generation)
3
+ **Model:** Claude Sonnet 4.5 (balanced for IaC generation)
4
4
  **Status:** Planned
5
5
 
6
6
  ---