@anhth2/spec-driven-dev-plugin 0.7.0 → 0.9.0
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/ARCHITECTURE.md +6 -2
- package/bin/index.js +105 -0
- package/commands/debug.md +189 -1
- package/commands/debug.tmpl +16 -0
- package/commands/define-product.md +94 -1
- package/commands/fix-bug.md +190 -1
- package/commands/fix-bug.tmpl +17 -0
- package/commands/generate-bdd.md +314 -14
- package/commands/generate-bdd.tmpl +220 -13
- package/commands/generate-code.md +191 -3
- package/commands/generate-code.tmpl +97 -2
- package/commands/generate-design-spec.md +811 -0
- package/commands/generate-design-spec.tmpl +399 -0
- package/commands/generate-prd.md +133 -1
- package/commands/generate-prd.tmpl +39 -0
- package/commands/generate-spec-manifest.md +576 -0
- package/commands/generate-spec-manifest.tmpl +164 -0
- package/commands/generate-tech-docs.md +116 -2
- package/commands/generate-tech-docs.tmpl +22 -1
- package/commands/generate-tests.md +94 -1
- package/commands/learn.md +554 -0
- package/commands/learn.tmpl +63 -0
- package/commands/propose-scenario.md +521 -0
- package/commands/propose-scenario.tmpl +109 -0
- package/commands/refine-prd.md +94 -1
- package/commands/report-bug.md +543 -0
- package/commands/report-bug.tmpl +131 -0
- package/commands/review-code.md +190 -1
- package/commands/review-code.tmpl +17 -0
- package/commands/review-context.md +134 -1
- package/commands/review-context.tmpl +40 -0
- package/commands/review-tech-docs.md +176 -5
- package/commands/review-tech-docs.tmpl +82 -4
- package/commands/run-tests.md +119 -1
- package/commands/run-tests.tmpl +25 -0
- package/commands/setup-ai-first.md +142 -4
- package/commands/setup-ai-first.tmpl +135 -3
- package/commands/smoke-test.md +94 -1
- package/commands/sync.md +405 -0
- package/commands/sync.tmpl +345 -0
- package/commands/update-framework.md +211 -0
- package/commands/update-framework.tmpl +151 -0
- package/commands/validate-traces.md +152 -3
- package/commands/validate-traces.tmpl +58 -2
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/commands/debug.md +189 -1
- package/core/commands/define-product.md +94 -1
- package/core/commands/fix-bug.md +190 -1
- package/core/commands/generate-bdd.md +314 -14
- package/core/commands/generate-code.md +191 -3
- package/core/commands/generate-design-spec.md +811 -0
- package/core/commands/generate-prd.md +133 -1
- package/core/commands/generate-spec-manifest.md +576 -0
- package/core/commands/generate-tech-docs.md +116 -2
- package/core/commands/generate-tests.md +94 -1
- package/core/commands/learn.md +554 -0
- package/core/commands/propose-scenario.md +521 -0
- package/core/commands/refine-prd.md +94 -1
- package/core/commands/report-bug.md +543 -0
- package/core/commands/review-code.md +190 -1
- package/core/commands/review-context.md +134 -1
- package/core/commands/review-tech-docs.md +176 -5
- package/core/commands/run-tests.md +119 -1
- package/core/commands/setup-ai-first.md +142 -4
- package/core/commands/smoke-test.md +94 -1
- package/core/commands/sync.md +405 -0
- package/core/commands/update-framework.md +211 -0
- package/core/commands/validate-traces.md +152 -3
- package/core/skills/code/SKILL.md +101 -2
- package/core/skills/debug/SKILL.md +108 -3
- package/core/skills/design-spec/SKILL.md +507 -0
- package/core/skills/discovery/SKILL.md +94 -1
- package/core/skills/prd/SKILL.md +14 -2
- package/core/skills/setup-ai-first/SKILL.md +7 -1
- package/core/skills/spec/SKILL.md +14 -2
- package/core/skills/test/SKILL.md +195 -3
- package/core/steps/capture-lesson.md +79 -0
- package/core/steps/context-loader.md +87 -0
- package/core/steps/report-footer.md +7 -1
- package/core/templates/design-spec.template.md +209 -0
- package/core/templates/project-context.yaml +40 -0
- package/package.json +1 -1
- package/skills/code/SKILL.md +101 -2
- package/skills/debug/SKILL.md +108 -3
- package/skills/design-spec/SKILL.md +507 -0
- package/skills/design-spec/SKILL.tmpl +95 -0
- package/skills/discovery/SKILL.md +94 -1
- package/skills/prd/SKILL.md +14 -2
- package/skills/setup-ai-first/SKILL.md +7 -1
- package/skills/spec/SKILL.md +14 -2
- package/skills/test/SKILL.md +195 -3
- package/steps/capture-lesson.md +79 -0
- package/steps/context-loader.md +87 -0
- package/steps/report-footer.md +7 -1
- package/templates/design-spec.template.md +209 -0
- package/templates/project-context.yaml +40 -0
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
# /sync — Sync & Refresh Umbrella Project
|
|
2
|
+
|
|
3
|
+
One command for both **first-time setup** and **daily update** of an umbrella repo with git submodules.
|
|
4
|
+
Safe to run repeatedly — detects what needs to be done automatically.
|
|
5
|
+
|
|
6
|
+
**Optional argument:** `/sync [spec-branch]` — branch of the spec submodule to pull (e.g. `/sync develop`). If omitted, the branch is resolved automatically (see Step 0-D).
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Step 0 — Pre-flight Checks
|
|
11
|
+
|
|
12
|
+
**A. Git repo check**
|
|
13
|
+
|
|
14
|
+
Verify current directory is inside a git repo. If not → stop:
|
|
15
|
+
```
|
|
16
|
+
❌ Not a git repository. Open Claude Code from umbrella root and retry.
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**B. Read project config early**
|
|
20
|
+
|
|
21
|
+
Read `.agent/project-context.yaml` before running any git commands. Extract:
|
|
22
|
+
- `setup.spec_source` → path of the spec submodule (e.g., `"my-project-specs"`)
|
|
23
|
+
- `services` → map of domain → `{path, module, ...}` for each service submodule
|
|
24
|
+
|
|
25
|
+
This is needed to differentiate spec vs service submodules in Step 1.
|
|
26
|
+
|
|
27
|
+
If `.agent/project-context.yaml` does not exist → warn and set `spec_source = null`, `services = {}`.
|
|
28
|
+
|
|
29
|
+
**C. Submodule status scan**
|
|
30
|
+
|
|
31
|
+
Run `git submodule status --recursive` and classify each entry by its first character:
|
|
32
|
+
|
|
33
|
+
| Char | Meaning | Action |
|
|
34
|
+
|------|---------|--------|
|
|
35
|
+
| `-` | Not initialized | → **Setup mode** |
|
|
36
|
+
| ` ` | Matches recorded pointer | → OK |
|
|
37
|
+
| `+` | Ahead of recorded pointer (local advance uncommitted) | → warn per submodule |
|
|
38
|
+
| `U` | Merge conflict | → **STOP** |
|
|
39
|
+
|
|
40
|
+
If **any** entry has `U`:
|
|
41
|
+
```
|
|
42
|
+
❌ Merge conflict in submodule: {path}
|
|
43
|
+
Resolve manually before running /sync:
|
|
44
|
+
cd {path} && git status
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
If **any** entry has `+` (checked-out commit differs from the recorded pointer):
|
|
48
|
+
```
|
|
49
|
+
ℹ️ {path} is ahead of the umbrella's recorded pointer.
|
|
50
|
+
/sync classifies it in Step 1b — if you're on a branch there, it stays untouched.
|
|
51
|
+
```
|
|
52
|
+
Do not act on `+` here — Step 1b decides the right handling per submodule.
|
|
53
|
+
|
|
54
|
+
Print detected mode: `Mode: Setup (first-time init)` or `Mode: Update (sync latest)`.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Step 1 — Umbrella Pull
|
|
59
|
+
|
|
60
|
+
Note the current umbrella branch first (this is what `git pull` updates):
|
|
61
|
+
`git rev-parse --abbrev-ref HEAD` → store as `umbrella_branch` and display it.
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# 1. Pull latest umbrella (includes updated submodule pointer records)
|
|
65
|
+
git pull
|
|
66
|
+
|
|
67
|
+
# 2. Sync .gitmodules config into local git config
|
|
68
|
+
# (needed when new submodules were added since last clone)
|
|
69
|
+
git submodule sync --recursive
|
|
70
|
+
|
|
71
|
+
# 3. Initialize any NOT-yet-cloned submodules ONLY (the '-' entries from Step 0-C).
|
|
72
|
+
# Do NOT run a blanket `git submodule update --recursive` — that would detach
|
|
73
|
+
# a submodule you are actively working in. Per-submodule handling is Step 1b.
|
|
74
|
+
git submodule update --init {paths that were '-' in Step 0-C}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
If `git pull` exits non-zero → print the error and stop with `❌`.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Step 1b — Classify & Sync Each Submodule
|
|
82
|
+
|
|
83
|
+
**The key idea:** `/sync` never imposes a branch on a submodule. It **inspects each submodule's current checkout** and respects it. This is how it knows which submodule you are working in vs which are passive dependencies.
|
|
84
|
+
|
|
85
|
+
For each submodule (use `git submodule foreach` or iterate the paths), read its state:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# Inside each submodule:
|
|
89
|
+
git symbolic-ref --short -q HEAD # → branch name, or empty/non-zero if DETACHED
|
|
90
|
+
git status --porcelain # → non-empty means uncommitted local changes
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Classify into one of four cases and act accordingly:
|
|
94
|
+
|
|
95
|
+
| Case | Detected state | Action |
|
|
96
|
+
|------|----------------|--------|
|
|
97
|
+
| **Spec submodule** | `path == spec_source` | Advance to `spec_branch` (Step 1c below) |
|
|
98
|
+
| **Active (on a branch)** | HEAD is a branch, not detached | **Do NOT checkout.** This is where you (or a teammate) are coding. Just `git -C {path} fetch` and report branch + ahead/behind. Leave the working tree exactly as-is. |
|
|
99
|
+
| **Passive (detached, clean)** | Detached HEAD, no local changes | Safe to align to the umbrella's recorded pointer: `git submodule update {path}` |
|
|
100
|
+
| **Dirty (uncommitted changes)** | `git status --porcelain` non-empty | **Never touch.** Warn: `⚠️ {path} has uncommitted changes — skipped. Commit or stash before syncing this submodule.` |
|
|
101
|
+
|
|
102
|
+
> **Why this matters:** A blanket `git submodule update` checks every submodule out to a **detached HEAD** at the recorded pointer. If you have `feature/FEAT-01` checked out inside `user-service/` and are mid-work, that would silently move you off your branch. Classifying first protects your active work.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Step 1c — Advance Spec Submodule *(only if `spec_source` is configured)*
|
|
107
|
+
|
|
108
|
+
The spec submodule is the one submodule we deliberately advance to a branch HEAD (PO pushes specs continuously).
|
|
109
|
+
|
|
110
|
+
**Resolve the spec branch** (now that the submodule is initialized), in priority order:
|
|
111
|
+
|
|
112
|
+
1. **Command argument** — if `$ARGUMENTS` contains a branch name → use it (one-off override)
|
|
113
|
+
2. **`.gitmodules` config** — `git config -f .gitmodules --get submodule.{spec_source}.branch`. If set → use it (team's committed default)
|
|
114
|
+
3. **Remote default** — else the spec repo's default branch: `git -C {spec_source} rev-parse --abbrev-ref origin/HEAD` (strip the `origin/` prefix)
|
|
115
|
+
|
|
116
|
+
Store as `spec_branch` + `spec_branch_source` (argument | .gitmodules | remote-default). If it fell through to remote-default with nothing pinned, add this hint to the output:
|
|
117
|
+
```
|
|
118
|
+
ℹ️ Spec submodule branch not pinned in .gitmodules — using remote default '{spec_branch}'.
|
|
119
|
+
To pin it for the whole team:
|
|
120
|
+
git config -f .gitmodules submodule.{spec_source}.branch {spec_branch}
|
|
121
|
+
git add .gitmodules && git commit -m "chore: pin spec submodule branch"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Then check it is safe: if the spec submodule has uncommitted changes → warn and skip (devs should treat specs as read-only). Otherwise use an **explicit checkout** (not bare `--remote`) so the branch is unambiguous:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
cd {spec_source}
|
|
128
|
+
git fetch origin
|
|
129
|
+
git checkout {spec_branch} # branch resolved in Step 0-D
|
|
130
|
+
git pull origin {spec_branch}
|
|
131
|
+
cd - # back to umbrella root
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Print: `Spec submodule {spec_source}: pulled branch '{spec_branch}' (source: {spec_branch_source})`
|
|
135
|
+
|
|
136
|
+
> **Why not `--remote` for service submodules?** Service submodules are version-locked by the umbrella's recorded pointer — this is intentional so all devs work from the same commit. `--remote` would bypass this lock and create uncommitted pointer drift. The spec submodule is the exception: PO pushes continuously, so we advance it to a branch HEAD — but we do it with an explicit `checkout {spec_branch}` rather than `--remote` so it never silently follows the wrong branch.
|
|
137
|
+
|
|
138
|
+
If `git pull` or `git submodule update` exits non-zero → print the error and stop with `❌`.
|
|
139
|
+
|
|
140
|
+
Collect from output:
|
|
141
|
+
- Which submodules changed SHA
|
|
142
|
+
- Which were already up to date
|
|
143
|
+
- The spec submodule's `{old_sha}..{new_sha}` (needed by Step 1d)
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Step 1d — Surface Tester Feedback *(new bug reports / scenario proposals)*
|
|
148
|
+
|
|
149
|
+
Tester `/report-bug` and `/propose-scenario` commit feedback into the spec repo. This step tells PO/Dev what arrived in **this** pull, so they are notified through their normal routine. It covers both audiences:
|
|
150
|
+
|
|
151
|
+
- **Dev/tester in umbrella** → feedback came in via the spec submodule advance (Step 1c)
|
|
152
|
+
- **PO working directly in the spec repo** → feedback came in via the umbrella/current-repo `git pull` (Step 1)
|
|
153
|
+
|
|
154
|
+
Pick the repo + range that pulled the feedback:
|
|
155
|
+
- Umbrella with `spec_source` → `REPO={spec_source}`, range = spec submodule `{old_sha}..{new_sha}`
|
|
156
|
+
- Otherwise (running inside the spec repo itself) → `REPO=.`, range = the `git pull` `{old_sha}..{new_sha}` from Step 1
|
|
157
|
+
|
|
158
|
+
If `feedback/` does not exist in REPO → skip silently.
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
git -C {REPO} diff --name-status {old_sha}..{new_sha} -- feedback/bug-reports/ feedback/bdd-proposals/
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
For each entry, read its title/summary and report:
|
|
165
|
+
```
|
|
166
|
+
📥 New tester feedback (pulled this sync):
|
|
167
|
+
Bug reports:
|
|
168
|
+
BUG-20260608-01 FT-001 — account locks after 6 fails (spec says 5) [layer: Code]
|
|
169
|
+
Scenario proposals:
|
|
170
|
+
FT-001-trailing-spaces.md → maps to AC2 (pending review)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
If none changed → print `📥 Tester feedback: none new this sync`.
|
|
174
|
+
|
|
175
|
+
If the reader is a PO/Dev, add a one-line nudge:
|
|
176
|
+
`→ Review feedback/ then act: /fix-bug {BUG-ID} · promote proposal into BDD · or update PRD.`
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Step 2 — Post-sync State Check
|
|
181
|
+
|
|
182
|
+
Run `git status --short` and check for modified submodule entries (lines starting with ` M` where the path matches a submodule).
|
|
183
|
+
|
|
184
|
+
If any submodule pointer changed (typically the spec submodule after `--remote`):
|
|
185
|
+
```
|
|
186
|
+
⚠️ Submodule pointer(s) updated — commit to lock new version into umbrella:
|
|
187
|
+
git add {spec_source} && git commit -m "chore: sync {spec_source} to latest"
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
If no changes → `✅ Umbrella state clean — no commit needed`.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Step 3 — Bootstrap Service Configs
|
|
195
|
+
|
|
196
|
+
*Skip if `services` is empty.*
|
|
197
|
+
|
|
198
|
+
For each entry in `services[]`:
|
|
199
|
+
|
|
200
|
+
**A. If `{service.path}/.agent/project-context.yaml` already exists:**
|
|
201
|
+
- Read `conventions.test_command` and `conventions.build_command`
|
|
202
|
+
- Report: `✅ {service.path} — test: {test_command} | build: {build_command}`
|
|
203
|
+
|
|
204
|
+
**B. If missing — auto-create it:**
|
|
205
|
+
|
|
206
|
+
1. Determine `module` from umbrella `services[].module` (authoritative). If not set, auto-detect from files in `{service.path}/`:
|
|
207
|
+
|
|
208
|
+
| File present | Detected module | test_command | build_command |
|
|
209
|
+
|---|---|---|---|
|
|
210
|
+
| `pom.xml` | `java-spring` | `mvn test` | `mvn compile` |
|
|
211
|
+
| `build.gradle` or `build.gradle.kts` | `java-spring` | `./gradlew test` | `./gradlew build` |
|
|
212
|
+
| `go.mod` | `golang` | `go test ./...` | `go build ./...` |
|
|
213
|
+
| `*.csproj` or `*.sln` | `dotnet` | `dotnet test` | `dotnet build` |
|
|
214
|
+
| `composer.json` | `php-laravel` | `php artisan test` | `composer install` |
|
|
215
|
+
| `pubspec.yaml` | `flutter` | `flutter test` | `flutter build apk` |
|
|
216
|
+
| `angular.json` | `angular` | `npx ng test --watch=false` | `npm run build` |
|
|
217
|
+
| `next.config.*` | `nextjs` | `npx vitest run` | `npm run build` |
|
|
218
|
+
| `package.json` + `nest-cli.json` | `nestjs` | `npm test` | `npm run build` |
|
|
219
|
+
| `package.json` (fallback) | `react` | `npx vitest run` | `npm run build` |
|
|
220
|
+
| `requirements.txt` or `pyproject.toml` | `context-engineering` | `pytest tests/ -v` | `pip install -r requirements.txt` |
|
|
221
|
+
| *(none matched)* | `unknown` | `{{TEST_COMMAND}}` | `{{BUILD_COMMAND}}` |
|
|
222
|
+
|
|
223
|
+
2. Create `{service.path}/.agent/` directory if it does not exist.
|
|
224
|
+
|
|
225
|
+
3. Write `{service.path}/.agent/project-context.yaml`:
|
|
226
|
+
|
|
227
|
+
```yaml
|
|
228
|
+
# Auto-generated by /sync — review and update as needed
|
|
229
|
+
tech_stack:
|
|
230
|
+
language: "{detected or from module}"
|
|
231
|
+
framework: "{detected or from module}"
|
|
232
|
+
module: "{module}"
|
|
233
|
+
|
|
234
|
+
conventions:
|
|
235
|
+
test_command: "{test_command}"
|
|
236
|
+
build_command: "{build_command}"
|
|
237
|
+
|
|
238
|
+
paths:
|
|
239
|
+
trace_dir: ".trace"
|
|
240
|
+
lessons_file: ".agent/project-lessons.md" # per-service guardrails (see /learn)
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
4. Report:
|
|
244
|
+
- If auto-detected: `✅ Created {service.path}/.agent/project-context.yaml (module: {module}, test: {test_command})`
|
|
245
|
+
- If unknown/placeholder: `⚠️ Created {service.path}/.agent/project-context.yaml — fill in {{TEST_COMMAND}} and {{BUILD_COMMAND}}`
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Step 4 — Check `.gitignore`
|
|
250
|
+
|
|
251
|
+
Check if `.trace/` appears in the umbrella root's `.gitignore` (or `.git/info/exclude`).
|
|
252
|
+
|
|
253
|
+
If missing:
|
|
254
|
+
```
|
|
255
|
+
⚠️ .trace/ is not in umbrella .gitignore
|
|
256
|
+
Add it to prevent accidentally committing generated trace artifacts:
|
|
257
|
+
echo ".trace/" >> .gitignore
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Step 5 — Refresh Living Docs *(umbrella mode only)*
|
|
263
|
+
|
|
264
|
+
*Skip if `services` is empty.*
|
|
265
|
+
|
|
266
|
+
For each service in `services[]`:
|
|
267
|
+
1. Check if `{service.path}/.trace/` directory exists and contains `.tsv` files
|
|
268
|
+
2. If yes → copy TSVs to `{umbrella_root}/.trace/{service-name}/` (create dir if needed)
|
|
269
|
+
|
|
270
|
+
After copying all services, write merged `{umbrella_root}/.trace/trace-report.json`:
|
|
271
|
+
- Aggregate data from each service's `.trace/` TSVs
|
|
272
|
+
- Include `"service"` field per scenario row
|
|
273
|
+
- Recalculate summary totals
|
|
274
|
+
|
|
275
|
+
Print sync result:
|
|
276
|
+
```
|
|
277
|
+
Living Docs → .trace/ synced
|
|
278
|
+
{service-name}: {N} TSVs
|
|
279
|
+
trace-report.json: {total} scenarios across {S} services
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
If no `.trace/` dirs found → `Living Docs: no trace data yet — run /generate-bdd then /generate-code first.`
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Step 6 — Refresh Spec Manifest *(if spec_source present)*
|
|
287
|
+
|
|
288
|
+
*Skip if `setup.spec_source` is absent.*
|
|
289
|
+
|
|
290
|
+
If `spec-manifest.yaml` exists OR `setup.spec_source` is configured:
|
|
291
|
+
- Re-scan `{spec_source}/specs/prd/**/*.md` files
|
|
292
|
+
- Rebuild `spec-manifest.yaml` mapping TICKET-ID → PRD/BDD/tech-doc paths
|
|
293
|
+
- Print: `spec-manifest.yaml refreshed — {N} features indexed`
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Output
|
|
298
|
+
|
|
299
|
+
{{include:steps/report-footer.md}}
|
|
300
|
+
|
|
301
|
+
```
|
|
302
|
+
/sync — {Setup | Update}
|
|
303
|
+
|
|
304
|
+
Git
|
|
305
|
+
✅ git pull — umbrella on branch '{umbrella_branch}'
|
|
306
|
+
✅ submodule sync — .gitmodules config refreshed
|
|
307
|
+
|
|
308
|
+
Submodules (each handled by its current state)
|
|
309
|
+
✅ {spec_source} [spec] — pulled branch '{spec_branch}' ({spec_branch_source}) → {new-sha}
|
|
310
|
+
✋ user-service [active] — on 'feature/FEAT-01' — left untouched, fetched (↓2 behind origin)
|
|
311
|
+
✅ order-service [passive] — aligned to umbrella pointer {sha}
|
|
312
|
+
⚠️ payment-service [dirty] — uncommitted changes, skipped (commit/stash first)
|
|
313
|
+
|
|
314
|
+
Umbrella state
|
|
315
|
+
⚠️ Pointer changed: git add {spec_source} && git commit -m "chore: sync specs"
|
|
316
|
+
(or: ✅ Clean — no commit needed)
|
|
317
|
+
|
|
318
|
+
Tester feedback (pulled this sync)
|
|
319
|
+
📥 1 bug report: BUG-20260608-01 FT-001 [Code]
|
|
320
|
+
1 proposal: FT-001-trailing-spaces → AC2 (pending review)
|
|
321
|
+
(or: 📥 none new this sync)
|
|
322
|
+
→ /fix-bug {BUG-ID} · promote proposal into BDD · or update PRD
|
|
323
|
+
|
|
324
|
+
Service Configs
|
|
325
|
+
✅ user-service — test: mvn test | build: mvn compile
|
|
326
|
+
✅ order-service — test: mvn test | build: mvn compile
|
|
327
|
+
⚠️ payment-service — .agent/project-context.yaml missing
|
|
328
|
+
→ create it so /run-tests works correctly
|
|
329
|
+
|
|
330
|
+
.gitignore
|
|
331
|
+
✅ .trace/ is gitignored
|
|
332
|
+
(or: ⚠️ Add .trace/ to .gitignore)
|
|
333
|
+
|
|
334
|
+
Living Docs
|
|
335
|
+
✅ .trace/ synced — {N} TSVs across {S} services
|
|
336
|
+
(run /validate-traces for full coverage report)
|
|
337
|
+
|
|
338
|
+
Spec Manifest
|
|
339
|
+
✅ spec-manifest.yaml — {N} features indexed
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
Status : ✅ Complete | ⚠️ Warnings
|
|
343
|
+
Output Artifacts: updated .trace/ (umbrella mirror), spec-manifest.yaml
|
|
344
|
+
Next : /validate-traces (full coverage check) | /generate-code {UC-ID} (start coding)
|
|
345
|
+
```
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# /update-framework — Update the Spec-Driven Dev Framework
|
|
2
|
+
|
|
3
|
+
Upgrades the **framework tooling** (`.agent/commands/`, `steps/`, `modules/`, `hooks/`, `rules/`, `templates/`, `skills/`) to the latest published version from npm.
|
|
4
|
+
|
|
5
|
+
> **Not the same as `/sync`.**
|
|
6
|
+
> - `/sync` → pulls **project content** (submodule code/specs) + refreshes Living Docs. Run daily.
|
|
7
|
+
> - `/update-framework` → upgrades the **framework command files themselves**. Run occasionally, when a new framework version ships.
|
|
8
|
+
|
|
9
|
+
This command wraps `npx @anhth2/spec-driven-dev-plugin@latest --init`. It requires network + npm access.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Step 0 — Detect Current State
|
|
14
|
+
|
|
15
|
+
1. Read `.agent/FRAMEWORK_VERSION` → current installed version.
|
|
16
|
+
- If missing → this project was not installed via `--init`. Stop:
|
|
17
|
+
```
|
|
18
|
+
❌ .agent/FRAMEWORK_VERSION not found.
|
|
19
|
+
This project was not set up with the framework installer.
|
|
20
|
+
Run: npx @anhth2/spec-driven-dev-plugin --init
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
2. Read `.agent/project-context.yaml` → extract `setup.mode` (`umbrella` / absent = single) and `services`.
|
|
24
|
+
|
|
25
|
+
3. List `.agent/modules/` → record installed module names (these must be re-passed on upgrade so they update too).
|
|
26
|
+
|
|
27
|
+
Print:
|
|
28
|
+
```
|
|
29
|
+
Current framework : v{current}
|
|
30
|
+
Mode : {umbrella | single-service}
|
|
31
|
+
Installed modules : {list or "none"}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Step 1 — Check Latest Version
|
|
37
|
+
|
|
38
|
+
Run:
|
|
39
|
+
```bash
|
|
40
|
+
npm view @anhth2/spec-driven-dev-plugin version
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Compare `current` vs `latest`:
|
|
44
|
+
|
|
45
|
+
| Result | Action |
|
|
46
|
+
|--------|--------|
|
|
47
|
+
| Network/registry unreachable | Warn `⚠️ Could not reach npm registry — check connection.` and stop |
|
|
48
|
+
| `current == latest` | Print `✅ Already up to date (v{current}). Nothing to do.` and stop |
|
|
49
|
+
| `latest > current` | Print `Update available: v{current} → v{latest}` and continue |
|
|
50
|
+
|
|
51
|
+
Ask: `Proceed with upgrade? (Y/N)` — wait for `Y`.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Step 2 — Umbrella Awareness *(umbrella mode only)*
|
|
56
|
+
|
|
57
|
+
If `setup.mode == umbrella`, print this note before upgrading:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
ℹ️ Umbrella mode — framework tooling lives ONLY at this umbrella root.
|
|
61
|
+
Service submodules contain just .agent/project-context.yaml (config), not
|
|
62
|
+
command files — they read commands from the umbrella root. No per-service
|
|
63
|
+
framework update is needed here.
|
|
64
|
+
|
|
65
|
+
Exception: if a teammate opens Claude Code directly INSIDE a service repo
|
|
66
|
+
(outside the umbrella), that repo has its own .agent/ — its owning team runs
|
|
67
|
+
/update-framework there independently.
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Step 3 — Pre-flight Git Check
|
|
73
|
+
|
|
74
|
+
Run `git status --short .agent/ .claude/commands/`.
|
|
75
|
+
|
|
76
|
+
If there are uncommitted changes in those paths:
|
|
77
|
+
```
|
|
78
|
+
⚠️ Uncommitted changes in .agent/ or .claude/commands/.
|
|
79
|
+
The upgrade overwrites framework files. Commit or stash first so you can
|
|
80
|
+
cleanly review the upgrade diff:
|
|
81
|
+
git add .agent/ .claude/commands/ && git commit -m "wip" (or git stash)
|
|
82
|
+
```
|
|
83
|
+
Ask whether to continue anyway `(Y/N)`. Default to stopping.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Step 4 — Run the Upgrade
|
|
88
|
+
|
|
89
|
+
Build the module flags from Step 0 (one `--module {name}` per installed module), then run:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npx -y @anhth2/spec-driven-dev-plugin@latest --init {--module X ...}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
This **overwrites** (refreshes to the new version):
|
|
96
|
+
- `.agent/commands/`, `.agent/steps/`, `.agent/hooks/`, `.agent/rules/`, `.agent/templates/`, `.agent/skills/`, `.agent/modules/{installed}/`
|
|
97
|
+
- `.agent/FRAMEWORK_VERSION`
|
|
98
|
+
- `.claude/commands/` shortcuts
|
|
99
|
+
|
|
100
|
+
This **does NOT touch** (your content is safe):
|
|
101
|
+
- `.agent/project-context.yaml`
|
|
102
|
+
- `CLAUDE.md`
|
|
103
|
+
- `specs/domain-knowledge/` (business-dictionary, core-entities)
|
|
104
|
+
- `.trace/`
|
|
105
|
+
|
|
106
|
+
If the npx command exits non-zero → print the error and stop with `❌`.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Step 5 — Review Changes
|
|
111
|
+
|
|
112
|
+
Run:
|
|
113
|
+
```bash
|
|
114
|
+
git diff --stat .agent/ .claude/commands/
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Summarize for the user:
|
|
118
|
+
- **New commands** — `.md` files present now but not before
|
|
119
|
+
- **Updated commands** — files with changed content
|
|
120
|
+
- **Removed commands** — files deleted in the new version
|
|
121
|
+
|
|
122
|
+
If a new command appeared (e.g. a new slash command), call it out explicitly so the user knows it is now available.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Output
|
|
127
|
+
|
|
128
|
+
# Report Footer — Standard Command Output Format
|
|
129
|
+
|
|
130
|
+
Every command report must end with this standard footer section.
|
|
131
|
+
|
|
132
|
+
## Status Badge
|
|
133
|
+
|
|
134
|
+
Choose one based on outcome:
|
|
135
|
+
- `✅ Complete` — all steps succeeded, no issues found
|
|
136
|
+
- `❌ Failed` — command could not complete due to a blocking error
|
|
137
|
+
- `⚠️ Warnings` — completed with non-blocking issues that should be reviewed
|
|
138
|
+
|
|
139
|
+
## Output Artifacts
|
|
140
|
+
|
|
141
|
+
List every file created or modified by this command:
|
|
142
|
+
```
|
|
143
|
+
Output Artifacts:
|
|
144
|
+
{created|updated} {file-path} ({brief description})
|
|
145
|
+
{created|updated} {file-path} ({brief description})
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
If no files were written (e.g., review or analysis commands) → write `Output Artifacts: none (read-only)`.
|
|
149
|
+
|
|
150
|
+
## Next Command Suggestion
|
|
151
|
+
|
|
152
|
+
Suggest the logical next command based on workflow phase:
|
|
153
|
+
|
|
154
|
+
| Current command | Suggest next |
|
|
155
|
+
|-------------------------|-----------------------------------------------|
|
|
156
|
+
| /setup-ai-first | `/define-product` to start your first feature |
|
|
157
|
+
| /define-product | `/generate-prd {product-definition-file}` |
|
|
158
|
+
| /generate-prd | `/refine-prd {prd-file}` then `/review-context {prd-file}` |
|
|
159
|
+
| /refine-prd | Open Review Board → update PRD → `/review-context {prd-file}` |
|
|
160
|
+
| /review-context (PRD) | FE/App: `/generate-design-spec {prd-file}` (then BDD after sign-off); BE: `/generate-bdd {prd-file}` directly; fix PRD if NEEDS_FIX |
|
|
161
|
+
| /generate-design-spec | Designer review → Figma links confirmed → PO + Designer sign-off → `/generate-bdd {prd-file}` |
|
|
162
|
+
| /generate-bdd | `/review-context {feature-file}` to verify coverage |
|
|
163
|
+
| /review-context (BDD) | `/generate-tech-docs {UC-ID}` if APPROVED; regenerate if NEEDS_FIX |
|
|
164
|
+
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
165
|
+
| /review-tech-docs | `/generate-code {feature-file}` if APPROVED; fix doc if NEEDS_FIX |
|
|
166
|
+
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/generate-tests {UC-ID}` |
|
|
167
|
+
| /generate-tests | `/run-tests {UC-ID}` |
|
|
168
|
+
| /run-tests (passing) | `/review-code {UC-ID}` |
|
|
169
|
+
| /run-tests (failing) | `/fix-bug {ticket-id}` or `/debug {error}` |
|
|
170
|
+
| /review-code | `/smoke-test {UC-ID}` or create PR |
|
|
171
|
+
| /smoke-test | Create PR and link to ticket |
|
|
172
|
+
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/generate-tests {UC-ID}`; all OK → create PR |
|
|
173
|
+
| /fix-bug | Create PR and link to ticket |
|
|
174
|
+
| /debug | `/fix-bug {ticket-id}` if fix needed |
|
|
175
|
+
| /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
|
|
176
|
+
| /propose-scenario | Notify PO/Dev to review the proposal in `feedback/bdd-proposals/` |
|
|
177
|
+
| /learn | Continue working — lesson applies on next command |
|
|
178
|
+
| /sync | `/validate-traces` for full coverage; act on any `📥 tester feedback` surfaced |
|
|
179
|
+
| /update-framework | Review `git diff .agent/`, commit; `/sync` for project content |
|
|
180
|
+
|
|
181
|
+
Format the footer as:
|
|
182
|
+
```
|
|
183
|
+
---
|
|
184
|
+
Status : {badge}
|
|
185
|
+
{Output Artifacts block}
|
|
186
|
+
Next : {suggested command with example arguments}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
/update-framework — v{current} → v{latest}
|
|
192
|
+
|
|
193
|
+
✅ Framework upgraded
|
|
194
|
+
Updated : {N} command files, {M} step files
|
|
195
|
+
New : {list any new commands, e.g. /some-new-command}
|
|
196
|
+
Removed : {list any removed commands, or "none"}
|
|
197
|
+
|
|
198
|
+
Your content was preserved:
|
|
199
|
+
project-context.yaml, CLAUDE.md, domain-knowledge/, .trace/ — untouched
|
|
200
|
+
|
|
201
|
+
Review & commit:
|
|
202
|
+
git diff .agent/
|
|
203
|
+
git add .agent/ .claude/commands/
|
|
204
|
+
git commit -m "chore: upgrade spec-driven-dev v{current} → v{latest}"
|
|
205
|
+
{umbrella mode: this is the umbrella root — service submodules need no framework update}
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
Status : ✅ Complete | ⚠️ Warnings
|
|
209
|
+
Output Artifacts: refreshed .agent/ framework files, .claude/commands/ shortcuts
|
|
210
|
+
Next : review git diff, then commit | /sync to refresh project content
|
|
211
|
+
```
|