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
|
@@ -0,0 +1,838 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: specweave:save
|
|
3
|
+
description: Save and push changes across all repositories in an umbrella setup. Detects repos with changes, sets up remotes if missing, auto-generates or accepts user commit message, and pushes to origin. Works for single repos and multi-repo umbrella setups.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /specweave:save - Save Changes Across Repositories
|
|
7
|
+
|
|
8
|
+
Save and push changes across all repositories in your project. Works for both single repos and umbrella multi-repo setups.
|
|
9
|
+
|
|
10
|
+
## What This Command Does
|
|
11
|
+
|
|
12
|
+
1. **Detects repositories** - Finds all repos (umbrella childRepos or current repo)
|
|
13
|
+
2. **Checks for changes** - Identifies repos with uncommitted changes
|
|
14
|
+
3. **Sets up remotes** - Prompts for remote URL if missing
|
|
15
|
+
4. **Auto-generates or accepts commit message** - Smart message generation from changes
|
|
16
|
+
5. **Pushes to remote** - Pushes commits to origin
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Auto-generate commit message from changes (NEW!)
|
|
22
|
+
/specweave:save
|
|
23
|
+
|
|
24
|
+
# With explicit commit message
|
|
25
|
+
/specweave:save "feat: Add menu builder feature"
|
|
26
|
+
|
|
27
|
+
# Dry run (show what would happen, don't execute)
|
|
28
|
+
/specweave:save --dry-run
|
|
29
|
+
|
|
30
|
+
# Save specific repos only (umbrella mode)
|
|
31
|
+
/specweave:save "fix: Bug fixes" --repos frontend,backend
|
|
32
|
+
|
|
33
|
+
# Skip repos without remote (don't prompt)
|
|
34
|
+
/specweave:save "chore: Updates" --skip-no-remote
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Auto-Generated Commit Messages (IMPORTANT!)
|
|
38
|
+
|
|
39
|
+
When no commit message is provided, **automatically analyze git changes and generate a conventional commit message**.
|
|
40
|
+
|
|
41
|
+
### Step-by-Step Algorithm
|
|
42
|
+
|
|
43
|
+
#### 1. Get Git Changes
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Get file status
|
|
47
|
+
git status --porcelain
|
|
48
|
+
|
|
49
|
+
# Get diff stats for context
|
|
50
|
+
git diff --stat HEAD
|
|
51
|
+
|
|
52
|
+
# Check for active increment
|
|
53
|
+
ls .specweave/increments/*/metadata.json 2>/dev/null | head -1
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
#### 2. Categorize Files by Type
|
|
57
|
+
|
|
58
|
+
Parse `git status --porcelain` output. Status codes:
|
|
59
|
+
- `??` = untracked (new)
|
|
60
|
+
- ` M` or `M ` = modified
|
|
61
|
+
- ` D` or `D ` = deleted
|
|
62
|
+
- `R ` = renamed
|
|
63
|
+
- `A ` = added (staged)
|
|
64
|
+
|
|
65
|
+
**File Category Rules:**
|
|
66
|
+
|
|
67
|
+
| Pattern | Category | Commit Type |
|
|
68
|
+
|---------|----------|-------------|
|
|
69
|
+
| `*.md`, `docs/`, `README*`, `CHANGELOG*` | docs | `docs:` |
|
|
70
|
+
| `src/**/*.ts` (excluding `*.test.ts`) | source | `feat:` or `refactor:` |
|
|
71
|
+
| `*.test.ts`, `tests/`, `__tests__/`, `*.spec.ts` | tests | `test:` |
|
|
72
|
+
| `package.json`, `package-lock.json`, `*.config.*`, `tsconfig*` | config | `chore:` |
|
|
73
|
+
| `.github/`, `.gitlab-ci*`, `Jenkinsfile`, `.circleci/` | ci | `ci:` |
|
|
74
|
+
| `esbuild*`, `webpack*`, `dist/`, `build/` | build | `build:` |
|
|
75
|
+
| `.specweave/increments/*/` | increment | use increment name |
|
|
76
|
+
| `*.css`, `*.scss`, `*.less` | styles | `style:` |
|
|
77
|
+
| `scripts/`, `bin/` | scripts | `chore:` |
|
|
78
|
+
|
|
79
|
+
#### 3. Determine Primary Type
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
Count files per category:
|
|
83
|
+
docs: 5 files
|
|
84
|
+
source: 2 files
|
|
85
|
+
tests: 1 file
|
|
86
|
+
|
|
87
|
+
Primary = category with most files
|
|
88
|
+
If tie → prefer in order: feat > docs > test > chore
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
#### 4. Determine Action Verb
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
Count by status:
|
|
95
|
+
new (??, A): 3 files → "add"
|
|
96
|
+
modified (M): 5 files → "update"
|
|
97
|
+
deleted (D): 0 files → "remove"
|
|
98
|
+
renamed (R): 0 files → "rename"
|
|
99
|
+
|
|
100
|
+
Primary action = most common status
|
|
101
|
+
If new > modified → "add"
|
|
102
|
+
If deleted > others → "remove"
|
|
103
|
+
Else → "update"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### 5. Derive Scope from Common Path
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
Files:
|
|
110
|
+
docs-site/docs/guides/file1.md
|
|
111
|
+
docs-site/docs/overview/file2.md
|
|
112
|
+
docs-site/docs/intro.md
|
|
113
|
+
|
|
114
|
+
Common path = docs-site/docs/
|
|
115
|
+
Scope = "docs-site" (first significant directory)
|
|
116
|
+
|
|
117
|
+
Rules:
|
|
118
|
+
- If all files share a common directory → use as scope
|
|
119
|
+
- If files are in src/[subdir]/ → use subdir as scope
|
|
120
|
+
- If files are scattered → no scope (omit parentheses)
|
|
121
|
+
- Special scopes: cli, hooks, plugins, docs-site
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
#### 6. Check for Increment Context
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# Find active increment
|
|
128
|
+
ACTIVE=$(cat .specweave/increments/*/metadata.json 2>/dev/null | \
|
|
129
|
+
grep -l '"status": "active"' | head -1)
|
|
130
|
+
|
|
131
|
+
if [ -n "$ACTIVE" ]; then
|
|
132
|
+
INCREMENT_NAME=$(dirname "$ACTIVE" | xargs basename)
|
|
133
|
+
# Example: 0001-academy-restructure
|
|
134
|
+
fi
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**If increment is active AND increment files are in changes:**
|
|
138
|
+
- Include increment reference in message
|
|
139
|
+
- Use increment title/name for context
|
|
140
|
+
|
|
141
|
+
#### 7. Generate Message
|
|
142
|
+
|
|
143
|
+
**Format:** `type(scope): action description`
|
|
144
|
+
|
|
145
|
+
**Generation Rules:**
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
# Pattern 1: Pure docs changes
|
|
149
|
+
docs(docs-site): update learning journey documentation
|
|
150
|
+
|
|
151
|
+
# Pattern 2: New feature with tests
|
|
152
|
+
feat(auth): add user authentication service
|
|
153
|
+
|
|
154
|
+
# Pattern 3: Increment-related work
|
|
155
|
+
docs: add academy section (0001-academy-restructure)
|
|
156
|
+
|
|
157
|
+
# Pattern 4: Mixed changes
|
|
158
|
+
chore: update config and documentation
|
|
159
|
+
|
|
160
|
+
# Pattern 5: Single file change
|
|
161
|
+
refactor(cli): simplify init command logic
|
|
162
|
+
|
|
163
|
+
# Pattern 6: Dependency updates
|
|
164
|
+
chore(deps): update package dependencies
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Description Templates:**
|
|
168
|
+
|
|
169
|
+
| Action | File Count | Template |
|
|
170
|
+
|--------|------------|----------|
|
|
171
|
+
| add | 1 | `add [filename without ext]` |
|
|
172
|
+
| add | 2-5 | `add [primary thing] and [count-1] more` |
|
|
173
|
+
| add | >5 | `add [category] files` |
|
|
174
|
+
| update | 1 | `update [filename]` |
|
|
175
|
+
| update | 2-5 | `update [primary thing] and related files` |
|
|
176
|
+
| update | >5 | `update [scope/category]` |
|
|
177
|
+
| remove | any | `remove [thing(s)]` |
|
|
178
|
+
|
|
179
|
+
#### 8. Present for Confirmation
|
|
180
|
+
|
|
181
|
+
```markdown
|
|
182
|
+
📊 **Analyzing changes...**
|
|
183
|
+
|
|
184
|
+
Detected:
|
|
185
|
+
📄 5 modified documentation files
|
|
186
|
+
📁 1 new increment folder (0001-academy-restructure)
|
|
187
|
+
📁 1 new docs section (academy/)
|
|
188
|
+
|
|
189
|
+
🤖 **Auto-generated commit message:**
|
|
190
|
+
|
|
191
|
+
`docs(docs-site): add academy section and update learning journey`
|
|
192
|
+
|
|
193
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
194
|
+
|
|
195
|
+
? **Choose action:**
|
|
196
|
+
1️⃣ Use this message
|
|
197
|
+
2️⃣ Edit message
|
|
198
|
+
3️⃣ Enter custom message
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Example Auto-Generations
|
|
202
|
+
|
|
203
|
+
**Example 1: Documentation updates**
|
|
204
|
+
```
|
|
205
|
+
Input:
|
|
206
|
+
M docs-site/docs/guides/specweave-learning-journey.md
|
|
207
|
+
M docs-site/docs/intro.md
|
|
208
|
+
M docs-site/docs/overview/features.md
|
|
209
|
+
?? docs-site/docs/academy/
|
|
210
|
+
|
|
211
|
+
Output: docs(docs-site): add academy section and update documentation
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Example 2: Feature development**
|
|
215
|
+
```
|
|
216
|
+
Input:
|
|
217
|
+
?? src/services/payment.ts
|
|
218
|
+
?? src/services/payment.test.ts
|
|
219
|
+
M src/types/index.ts
|
|
220
|
+
|
|
221
|
+
Output: feat: add payment service with tests
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**Example 3: CI/CD changes**
|
|
225
|
+
```
|
|
226
|
+
Input:
|
|
227
|
+
M .github/workflows/ci.yml
|
|
228
|
+
M .github/workflows/release.yml
|
|
229
|
+
|
|
230
|
+
Output: ci: update CI and release workflows
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**Example 4: Dependency update**
|
|
234
|
+
```
|
|
235
|
+
Input:
|
|
236
|
+
M package.json
|
|
237
|
+
M package-lock.json
|
|
238
|
+
|
|
239
|
+
Output: chore(deps): update dependencies
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
**Example 5: Refactoring**
|
|
243
|
+
```
|
|
244
|
+
Input:
|
|
245
|
+
M src/cli/commands/init.ts
|
|
246
|
+
M src/cli/helpers/init/types.ts
|
|
247
|
+
M src/cli/helpers/init/config-detection.ts
|
|
248
|
+
|
|
249
|
+
Output: refactor(cli): update init command structure
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
**Example 6: Mixed changes with increment**
|
|
253
|
+
```
|
|
254
|
+
Input:
|
|
255
|
+
M src/components/Menu.tsx
|
|
256
|
+
M docs/api.md
|
|
257
|
+
?? .specweave/increments/0042-menu-builder/
|
|
258
|
+
|
|
259
|
+
Active increment: 0042-menu-builder
|
|
260
|
+
|
|
261
|
+
Output: feat: implement menu builder (0042)
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
**Example 7: Test additions**
|
|
265
|
+
```
|
|
266
|
+
Input:
|
|
267
|
+
?? tests/integration/auth.test.ts
|
|
268
|
+
?? tests/integration/payment.test.ts
|
|
269
|
+
M jest.config.js
|
|
270
|
+
|
|
271
|
+
Output: test: add integration tests for auth and payment
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
**Example 8: Single file**
|
|
275
|
+
```
|
|
276
|
+
Input:
|
|
277
|
+
M README.md
|
|
278
|
+
|
|
279
|
+
Output: docs: update README
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Fallback Behavior
|
|
283
|
+
|
|
284
|
+
If analysis cannot determine a meaningful message:
|
|
285
|
+
|
|
286
|
+
```markdown
|
|
287
|
+
⚠️ Could not auto-generate a meaningful commit message.
|
|
288
|
+
|
|
289
|
+
Changes detected:
|
|
290
|
+
- 15 files across multiple categories
|
|
291
|
+
- No clear primary category
|
|
292
|
+
|
|
293
|
+
? Please enter a commit message:
|
|
294
|
+
> _
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### Multi-Repo Message Generation
|
|
298
|
+
|
|
299
|
+
For umbrella setups, generate per-repo messages:
|
|
300
|
+
|
|
301
|
+
```markdown
|
|
302
|
+
📊 Analyzing changes across repositories...
|
|
303
|
+
|
|
304
|
+
**frontend** (4 files):
|
|
305
|
+
Auto-generated: `feat(components): add menu builder UI`
|
|
306
|
+
|
|
307
|
+
**backend** (2 files):
|
|
308
|
+
Auto-generated: `feat(api): add menu endpoints`
|
|
309
|
+
|
|
310
|
+
**shared** (1 file):
|
|
311
|
+
Auto-generated: `chore: update shared types`
|
|
312
|
+
|
|
313
|
+
? Use same message for all, or per-repo messages?
|
|
314
|
+
1️⃣ Same message (enter custom)
|
|
315
|
+
2️⃣ Use auto-generated per-repo messages
|
|
316
|
+
3️⃣ Edit each message
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
## Workflow
|
|
320
|
+
|
|
321
|
+
### Step 1: Detect Repositories
|
|
322
|
+
|
|
323
|
+
```markdown
|
|
324
|
+
Scanning for repositories...
|
|
325
|
+
|
|
326
|
+
Mode: Umbrella (3 child repos)
|
|
327
|
+
|
|
328
|
+
Repositories found:
|
|
329
|
+
1. sw-qr-menu-fe (./sw-qr-menu-fe)
|
|
330
|
+
2. sw-qr-menu-be (./sw-qr-menu-be)
|
|
331
|
+
3. sw-qr-menu-shared (./sw-qr-menu-shared)
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
**For single repo:**
|
|
335
|
+
```markdown
|
|
336
|
+
Scanning for repositories...
|
|
337
|
+
|
|
338
|
+
Mode: Single repository
|
|
339
|
+
|
|
340
|
+
Repository: my-project (.)
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Step 2: Check Git Status
|
|
344
|
+
|
|
345
|
+
```markdown
|
|
346
|
+
Checking git status...
|
|
347
|
+
|
|
348
|
+
sw-qr-menu-fe:
|
|
349
|
+
Status: 3 files changed
|
|
350
|
+
- src/components/MenuBuilder.tsx (modified)
|
|
351
|
+
- src/hooks/useMenu.ts (new)
|
|
352
|
+
- package.json (modified)
|
|
353
|
+
Remote: origin -> github.com/user/sw-qr-menu-fe
|
|
354
|
+
|
|
355
|
+
sw-qr-menu-be:
|
|
356
|
+
Status: 5 files changed
|
|
357
|
+
- src/routes/menu.ts (modified)
|
|
358
|
+
- src/models/MenuItem.ts (new)
|
|
359
|
+
- src/services/MenuService.ts (modified)
|
|
360
|
+
- tests/menu.test.ts (new)
|
|
361
|
+
- package.json (modified)
|
|
362
|
+
Remote: origin -> github.com/user/sw-qr-menu-be
|
|
363
|
+
|
|
364
|
+
sw-qr-menu-shared:
|
|
365
|
+
Status: No changes
|
|
366
|
+
Skipping (nothing to commit)
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Step 3: Handle Missing Remotes
|
|
370
|
+
|
|
371
|
+
```markdown
|
|
372
|
+
sw-qr-menu-fe:
|
|
373
|
+
No remote configured.
|
|
374
|
+
|
|
375
|
+
Options:
|
|
376
|
+
1. Enter remote URL manually
|
|
377
|
+
2. Use GitHub convention (github.com/[user]/sw-qr-menu-fe)
|
|
378
|
+
3. Skip this repo
|
|
379
|
+
|
|
380
|
+
? Choice: [1/2/3]
|
|
381
|
+
|
|
382
|
+
> 2
|
|
383
|
+
|
|
384
|
+
Using: https://github.com/user/sw-qr-menu-fe
|
|
385
|
+
git remote add origin https://github.com/user/sw-qr-menu-fe
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### Step 4: Get or Generate Commit Message
|
|
389
|
+
|
|
390
|
+
**If message was provided in command:**
|
|
391
|
+
```markdown
|
|
392
|
+
Commit message: "feat: Add menu builder with drag-drop support"
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
**If NO message provided (auto-generate):**
|
|
396
|
+
```markdown
|
|
397
|
+
📊 Analyzing changes...
|
|
398
|
+
|
|
399
|
+
Detected:
|
|
400
|
+
📄 3 modified source files (src/components/)
|
|
401
|
+
📄 2 new test files
|
|
402
|
+
📁 1 new increment folder
|
|
403
|
+
|
|
404
|
+
🤖 Auto-generated commit message:
|
|
405
|
+
|
|
406
|
+
feat(components): add menu builder with drag-drop support
|
|
407
|
+
|
|
408
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
409
|
+
|
|
410
|
+
? Choose action:
|
|
411
|
+
1. ✅ Use this message
|
|
412
|
+
2. ✏️ Edit message
|
|
413
|
+
3. 📝 Enter custom message
|
|
414
|
+
|
|
415
|
+
> 1
|
|
416
|
+
|
|
417
|
+
Using: "feat(components): add menu builder with drag-drop support"
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Step 5: Execute Save
|
|
421
|
+
|
|
422
|
+
```markdown
|
|
423
|
+
Saving changes...
|
|
424
|
+
|
|
425
|
+
sw-qr-menu-fe:
|
|
426
|
+
Staging: git add -A
|
|
427
|
+
Committing: feat: Add menu builder with drag-drop support
|
|
428
|
+
Pushing: origin/main
|
|
429
|
+
Done
|
|
430
|
+
|
|
431
|
+
sw-qr-menu-be:
|
|
432
|
+
Staging: git add -A
|
|
433
|
+
Committing: feat: Add menu builder with drag-drop support
|
|
434
|
+
Pushing: origin/main
|
|
435
|
+
Done
|
|
436
|
+
|
|
437
|
+
Summary:
|
|
438
|
+
Saved: 2/3 repositories
|
|
439
|
+
Skipped: 1 (no changes)
|
|
440
|
+
Commit: feat: Add menu builder with drag-drop support
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
## Remote Setup Options
|
|
444
|
+
|
|
445
|
+
When a repository has no remote configured:
|
|
446
|
+
|
|
447
|
+
### Option 1: Manual URL
|
|
448
|
+
|
|
449
|
+
```markdown
|
|
450
|
+
Enter remote URL: https://github.com/myorg/my-repo.git
|
|
451
|
+
|
|
452
|
+
git remote add origin https://github.com/myorg/my-repo.git
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### Option 2: GitHub Convention
|
|
456
|
+
|
|
457
|
+
Uses the folder name as repo name under your GitHub username/org:
|
|
458
|
+
|
|
459
|
+
```markdown
|
|
460
|
+
GitHub organization/user: myorg
|
|
461
|
+
Repo name (folder): sw-qr-menu-fe
|
|
462
|
+
|
|
463
|
+
Remote: https://github.com/myorg/sw-qr-menu-fe
|
|
464
|
+
git remote add origin https://github.com/myorg/sw-qr-menu-fe
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### Option 3: From Umbrella Config
|
|
468
|
+
|
|
469
|
+
If `githubUrl` is configured in umbrella config:
|
|
470
|
+
|
|
471
|
+
```json
|
|
472
|
+
{
|
|
473
|
+
"umbrella": {
|
|
474
|
+
"childRepos": [
|
|
475
|
+
{
|
|
476
|
+
"id": "sw-qr-menu-fe",
|
|
477
|
+
"path": "./sw-qr-menu-fe",
|
|
478
|
+
"githubUrl": "https://github.com/myorg/sw-qr-menu-fe"
|
|
479
|
+
}
|
|
480
|
+
]
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
```markdown
|
|
486
|
+
Using URL from umbrella config:
|
|
487
|
+
git remote add origin https://github.com/myorg/sw-qr-menu-fe
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### Option 4: Skip
|
|
491
|
+
|
|
492
|
+
```markdown
|
|
493
|
+
Skipping sw-qr-menu-fe (no remote, user chose to skip)
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
## Error Handling
|
|
497
|
+
|
|
498
|
+
### Push Failure (Authentication)
|
|
499
|
+
|
|
500
|
+
```markdown
|
|
501
|
+
sw-qr-menu-fe:
|
|
502
|
+
Pushing failed!
|
|
503
|
+
|
|
504
|
+
Error: Permission denied (publickey)
|
|
505
|
+
|
|
506
|
+
Troubleshooting:
|
|
507
|
+
1. Check SSH key is added: ssh -T git@github.com
|
|
508
|
+
2. Use HTTPS instead: git remote set-url origin https://...
|
|
509
|
+
3. Check GitHub token has 'repo' scope
|
|
510
|
+
|
|
511
|
+
? Continue with other repos? [Yes / No]
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
### Push Failure (Divergent History)
|
|
515
|
+
|
|
516
|
+
```markdown
|
|
517
|
+
sw-qr-menu-be:
|
|
518
|
+
Pushing failed!
|
|
519
|
+
|
|
520
|
+
Error: Updates were rejected (remote contains work not in local)
|
|
521
|
+
|
|
522
|
+
Options:
|
|
523
|
+
1. Pull and merge: git pull --rebase origin main
|
|
524
|
+
2. Force push (DANGEROUS): git push --force
|
|
525
|
+
3. Skip this repo
|
|
526
|
+
|
|
527
|
+
? Choice: [1/2/3]
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
### Branch Not Tracking
|
|
531
|
+
|
|
532
|
+
```markdown
|
|
533
|
+
sw-qr-menu-shared:
|
|
534
|
+
Current branch 'feature-x' has no upstream.
|
|
535
|
+
|
|
536
|
+
Options:
|
|
537
|
+
1. Push with tracking: git push -u origin feature-x
|
|
538
|
+
2. Push to main: git push origin HEAD:main
|
|
539
|
+
3. Skip this repo
|
|
540
|
+
|
|
541
|
+
? Choice: [1/2/3]
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
## Integration with Umbrella Config
|
|
545
|
+
|
|
546
|
+
This command reads from `.specweave/config.json`:
|
|
547
|
+
|
|
548
|
+
```json
|
|
549
|
+
{
|
|
550
|
+
"umbrella": {
|
|
551
|
+
"enabled": true,
|
|
552
|
+
"childRepos": [
|
|
553
|
+
{
|
|
554
|
+
"id": "sw-qr-menu-fe",
|
|
555
|
+
"path": "./sw-qr-menu-fe",
|
|
556
|
+
"prefix": "FE",
|
|
557
|
+
"githubUrl": "https://github.com/myorg/sw-qr-menu-fe"
|
|
558
|
+
},
|
|
559
|
+
{
|
|
560
|
+
"id": "sw-qr-menu-be",
|
|
561
|
+
"path": "./sw-qr-menu-be",
|
|
562
|
+
"prefix": "BE",
|
|
563
|
+
"githubUrl": "https://github.com/myorg/sw-qr-menu-be"
|
|
564
|
+
}
|
|
565
|
+
]
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
### ID Strategy
|
|
571
|
+
|
|
572
|
+
**IMPORTANT**: The `id` field MUST match your canonical source name:
|
|
573
|
+
|
|
574
|
+
| Scenario | ID Source | Example |
|
|
575
|
+
|----------|-----------|---------|
|
|
576
|
+
| 1:1 Repo Mapping | Exact repo name | `sw-qr-menu-fe` |
|
|
577
|
+
| JIRA Project | Project key (lowercase) | `WEBAPP` → `webapp` |
|
|
578
|
+
| ADO Project | Project name (kebab-case) | `Frontend Team` → `frontend-team` |
|
|
579
|
+
|
|
580
|
+
```
|
|
581
|
+
✅ CORRECT: id: "sw-qr-menu-fe" (matches repo name)
|
|
582
|
+
❌ WRONG: id: "fe" (arbitrary abbreviation)
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
**Benefits:**
|
|
586
|
+
- Auto-discovers all child repos
|
|
587
|
+
- Uses `githubUrl` for remote setup
|
|
588
|
+
- Skips repos not in config (optional: `--all` to include)
|
|
589
|
+
|
|
590
|
+
## Single Repo Mode
|
|
591
|
+
|
|
592
|
+
Without umbrella config, operates on current repository:
|
|
593
|
+
|
|
594
|
+
```markdown
|
|
595
|
+
/specweave:save "chore: Update dependencies"
|
|
596
|
+
|
|
597
|
+
Scanning for repositories...
|
|
598
|
+
Mode: Single repository
|
|
599
|
+
Repository: my-project (.)
|
|
600
|
+
|
|
601
|
+
my-project:
|
|
602
|
+
Status: 2 files changed
|
|
603
|
+
- package.json (modified)
|
|
604
|
+
- package-lock.json (modified)
|
|
605
|
+
Remote: origin -> github.com/user/my-project
|
|
606
|
+
|
|
607
|
+
Saving changes...
|
|
608
|
+
|
|
609
|
+
my-project:
|
|
610
|
+
Staging: git add -A
|
|
611
|
+
Committing: chore: Update dependencies
|
|
612
|
+
Pushing: origin/main
|
|
613
|
+
Done
|
|
614
|
+
|
|
615
|
+
Summary:
|
|
616
|
+
Saved: 1/1 repository
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
## Flags and Options
|
|
620
|
+
|
|
621
|
+
| Flag | Description |
|
|
622
|
+
|------|-------------|
|
|
623
|
+
| `--dry-run` | Show what would happen, don't execute |
|
|
624
|
+
| `--repos <list>` | Only save specific repos (comma-separated) |
|
|
625
|
+
| `--skip-no-remote` | Skip repos without remotes (don't prompt) |
|
|
626
|
+
| `--all` | Include repos outside umbrella config |
|
|
627
|
+
| `--no-push` | Commit but don't push |
|
|
628
|
+
| `--force` | Force push (use with caution!) |
|
|
629
|
+
| `--yes` or `-y` | Accept auto-generated message without confirmation |
|
|
630
|
+
|
|
631
|
+
## Best Practices
|
|
632
|
+
|
|
633
|
+
1. **Use descriptive commit messages** - Same message applies to all repos
|
|
634
|
+
2. **Review changes first** - Use `--dry-run` to see what will happen
|
|
635
|
+
3. **Configure githubUrl** - Set in umbrella config for seamless remote setup
|
|
636
|
+
4. **Handle failures** - Don't ignore push failures, resolve before continuing
|
|
637
|
+
|
|
638
|
+
## Example Interactions
|
|
639
|
+
|
|
640
|
+
### Quick Save
|
|
641
|
+
|
|
642
|
+
```
|
|
643
|
+
User: /specweave:save "feat: Complete user registration flow"
|
|
644
|
+
|
|
645
|
+
Claude:
|
|
646
|
+
Scanning for repositories...
|
|
647
|
+
Mode: Umbrella (3 child repos)
|
|
648
|
+
|
|
649
|
+
Checking git status...
|
|
650
|
+
|
|
651
|
+
frontend:
|
|
652
|
+
Status: 4 files changed
|
|
653
|
+
Remote: origin -> github.com/user/frontend
|
|
654
|
+
|
|
655
|
+
backend:
|
|
656
|
+
Status: 2 files changed
|
|
657
|
+
Remote: origin -> github.com/user/backend
|
|
658
|
+
|
|
659
|
+
shared:
|
|
660
|
+
Status: No changes (skipping)
|
|
661
|
+
|
|
662
|
+
Saving changes...
|
|
663
|
+
|
|
664
|
+
frontend:
|
|
665
|
+
git add -A
|
|
666
|
+
git commit -m "feat: Complete user registration flow"
|
|
667
|
+
git push origin main
|
|
668
|
+
|
|
669
|
+
backend:
|
|
670
|
+
git add -A
|
|
671
|
+
git commit -m "feat: Complete user registration flow"
|
|
672
|
+
git push origin main
|
|
673
|
+
|
|
674
|
+
Summary:
|
|
675
|
+
Saved: 2/3 repositories
|
|
676
|
+
Skipped: 1 (no changes)
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
### Auto-Generated Message (No Args)
|
|
680
|
+
|
|
681
|
+
```
|
|
682
|
+
User: /specweave:save
|
|
683
|
+
|
|
684
|
+
Claude:
|
|
685
|
+
Scanning for repositories...
|
|
686
|
+
Mode: Single repository
|
|
687
|
+
Repository: my-app (.)
|
|
688
|
+
|
|
689
|
+
Checking git status...
|
|
690
|
+
|
|
691
|
+
my-app:
|
|
692
|
+
Status: 7 files changed
|
|
693
|
+
Remote: origin -> github.com/user/my-app
|
|
694
|
+
|
|
695
|
+
📊 Analyzing changes...
|
|
696
|
+
|
|
697
|
+
Detected:
|
|
698
|
+
📄 5 modified documentation files
|
|
699
|
+
📁 1 new docs section (academy/)
|
|
700
|
+
📁 1 new increment folder
|
|
701
|
+
|
|
702
|
+
🤖 Auto-generated commit message:
|
|
703
|
+
|
|
704
|
+
docs(docs-site): add academy section and update documentation
|
|
705
|
+
|
|
706
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
707
|
+
|
|
708
|
+
? Choose action:
|
|
709
|
+
1. ✅ Use this message
|
|
710
|
+
2. ✏️ Edit message
|
|
711
|
+
3. 📝 Enter custom message
|
|
712
|
+
|
|
713
|
+
User: 1
|
|
714
|
+
|
|
715
|
+
Saving changes...
|
|
716
|
+
|
|
717
|
+
my-app:
|
|
718
|
+
git add -A
|
|
719
|
+
git commit -m "docs(docs-site): add academy section and update documentation"
|
|
720
|
+
git push origin develop
|
|
721
|
+
|
|
722
|
+
Summary:
|
|
723
|
+
✅ Saved: 1/1 repository
|
|
724
|
+
📝 Message: docs(docs-site): add academy section and update documentation
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
### Quick Auto-Save (--yes flag)
|
|
728
|
+
|
|
729
|
+
```
|
|
730
|
+
User: /specweave:save --yes
|
|
731
|
+
|
|
732
|
+
Claude:
|
|
733
|
+
Scanning for repositories...
|
|
734
|
+
Mode: Single repository
|
|
735
|
+
|
|
736
|
+
📊 Auto-analyzing changes...
|
|
737
|
+
|
|
738
|
+
Detected: 3 modified source files in src/cli/
|
|
739
|
+
|
|
740
|
+
🤖 Auto-generated: refactor(cli): update command handlers
|
|
741
|
+
|
|
742
|
+
Saving changes (auto-confirmed)...
|
|
743
|
+
|
|
744
|
+
my-app:
|
|
745
|
+
git add -A
|
|
746
|
+
git commit -m "refactor(cli): update command handlers"
|
|
747
|
+
git push origin develop
|
|
748
|
+
|
|
749
|
+
✅ Done! Saved with auto-generated message.
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
### First-Time Remote Setup
|
|
753
|
+
|
|
754
|
+
```
|
|
755
|
+
User: /specweave:save "Initial commit"
|
|
756
|
+
|
|
757
|
+
Claude:
|
|
758
|
+
Scanning for repositories...
|
|
759
|
+
Mode: Umbrella (2 child repos)
|
|
760
|
+
|
|
761
|
+
frontend:
|
|
762
|
+
Status: 15 files changed
|
|
763
|
+
Remote: Not configured
|
|
764
|
+
|
|
765
|
+
? No remote configured for frontend. Choose:
|
|
766
|
+
1. Enter URL manually
|
|
767
|
+
2. Use GitHub convention
|
|
768
|
+
3. Skip this repo
|
|
769
|
+
|
|
770
|
+
User: 2
|
|
771
|
+
|
|
772
|
+
? GitHub organization/user: myorg
|
|
773
|
+
|
|
774
|
+
Claude:
|
|
775
|
+
Adding remote: git remote add origin https://github.com/myorg/frontend
|
|
776
|
+
|
|
777
|
+
backend:
|
|
778
|
+
Status: 10 files changed
|
|
779
|
+
Remote: Not configured (using from umbrella config)
|
|
780
|
+
Adding remote: git remote add origin https://github.com/myorg/backend
|
|
781
|
+
|
|
782
|
+
Saving changes...
|
|
783
|
+
[continues with commit and push]
|
|
784
|
+
```
|
|
785
|
+
|
|
786
|
+
### Dry Run Preview
|
|
787
|
+
|
|
788
|
+
```
|
|
789
|
+
User: /specweave:save --dry-run
|
|
790
|
+
|
|
791
|
+
Claude:
|
|
792
|
+
DRY RUN MODE - No changes will be made
|
|
793
|
+
|
|
794
|
+
Scanning for repositories...
|
|
795
|
+
Mode: Umbrella (3 child repos)
|
|
796
|
+
|
|
797
|
+
Would process:
|
|
798
|
+
|
|
799
|
+
frontend:
|
|
800
|
+
Status: 3 files changed
|
|
801
|
+
Would: git add -A
|
|
802
|
+
Would: git commit -m "[message]"
|
|
803
|
+
Would: git push origin main
|
|
804
|
+
|
|
805
|
+
backend:
|
|
806
|
+
Status: 1 file changed
|
|
807
|
+
Would: git add -A
|
|
808
|
+
Would: git commit -m "[message]"
|
|
809
|
+
Would: git push origin main
|
|
810
|
+
|
|
811
|
+
shared:
|
|
812
|
+
Status: No changes
|
|
813
|
+
Would: Skip (nothing to commit)
|
|
814
|
+
|
|
815
|
+
? Enter commit message to see full preview: feat: Update API
|
|
816
|
+
|
|
817
|
+
Preview complete. Run without --dry-run to execute.
|
|
818
|
+
```
|
|
819
|
+
|
|
820
|
+
## Related Commands
|
|
821
|
+
|
|
822
|
+
- `/specweave-release:align` - Align versions across repos (for releases)
|
|
823
|
+
- `/specweave:sync-progress` - Sync task progress to external tools
|
|
824
|
+
- `/specweave-github:sync` - Sync increments to GitHub issues
|
|
825
|
+
|
|
826
|
+
## Dependencies
|
|
827
|
+
|
|
828
|
+
**Required:**
|
|
829
|
+
- Git installed and configured
|
|
830
|
+
- SSH key or HTTPS credentials for push
|
|
831
|
+
|
|
832
|
+
**Optional:**
|
|
833
|
+
- Umbrella config (for multi-repo mode)
|
|
834
|
+
- GitHub CLI (`gh`) for repo creation
|
|
835
|
+
|
|
836
|
+
---
|
|
837
|
+
|
|
838
|
+
**Use this command** to save and push changes across all your repositories with a single command, handling remote setup automatically.
|