@anhth2/spec-driven-dev-plugin 0.6.0 → 0.8.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/bin/index.js +285 -11
- package/commands/debug.md +233 -11
- package/commands/debug.tmpl +170 -6
- package/commands/define-product.md +68 -6
- package/commands/define-product.tmpl +5 -1
- package/commands/fix-bug.md +111 -11
- package/commands/fix-bug.tmpl +48 -6
- package/commands/generate-bdd.md +86 -9
- package/commands/generate-bdd.tmpl +23 -4
- package/commands/generate-code.md +146 -19
- package/commands/generate-code.tmpl +83 -14
- package/commands/generate-design-spec.md +754 -0
- package/commands/generate-design-spec.tmpl +399 -0
- package/commands/generate-prd.md +91 -7
- package/commands/generate-prd.tmpl +28 -2
- package/commands/generate-spec-manifest.md +519 -0
- package/commands/generate-spec-manifest.tmpl +164 -0
- package/commands/generate-tech-docs.md +122 -9
- package/commands/generate-tech-docs.tmpl +59 -4
- package/commands/generate-tests.md +491 -37
- package/commands/generate-tests.tmpl +428 -32
- package/commands/refine-prd.md +76 -8
- package/commands/refine-prd.tmpl +13 -3
- package/commands/review-code.md +94 -6
- package/commands/review-code.tmpl +31 -1
- package/commands/review-context.md +118 -12
- package/commands/review-context.tmpl +55 -7
- package/commands/review-tech-docs.md +76 -9
- package/commands/review-tech-docs.tmpl +13 -4
- package/commands/run-tests.md +196 -18
- package/commands/run-tests.tmpl +133 -13
- package/commands/setup-ai-first.md +192 -6
- package/commands/setup-ai-first.tmpl +136 -5
- package/commands/smoke-test.md +228 -22
- package/commands/smoke-test.tmpl +165 -17
- package/commands/validate-traces.md +77 -8
- package/commands/validate-traces.tmpl +14 -3
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/commands/debug.md +233 -11
- package/core/commands/define-product.md +68 -6
- package/core/commands/fix-bug.md +111 -11
- package/core/commands/generate-bdd.md +86 -9
- package/core/commands/generate-code.md +146 -19
- package/core/commands/generate-design-spec.md +754 -0
- package/core/commands/generate-prd.md +91 -7
- package/core/commands/generate-spec-manifest.md +519 -0
- package/core/commands/generate-tech-docs.md +122 -9
- package/core/commands/generate-tests.md +491 -37
- package/core/commands/refine-prd.md +76 -8
- package/core/commands/review-code.md +94 -6
- package/core/commands/review-context.md +118 -12
- package/core/commands/review-tech-docs.md +76 -9
- package/core/commands/run-tests.md +196 -18
- package/core/commands/setup-ai-first.md +192 -6
- package/core/commands/smoke-test.md +228 -22
- package/core/commands/validate-traces.md +77 -8
- package/core/skills/code/SKILL.md +68 -8
- package/core/skills/debug/SKILL.md +72 -10
- package/core/skills/design-spec/SKILL.md +450 -0
- package/core/skills/discovery/SKILL.md +62 -4
- package/core/skills/prd/SKILL.md +12 -8
- package/core/skills/setup-ai-first/SKILL.md +5 -3
- package/core/skills/spec/SKILL.md +11 -7
- package/core/skills/test/SKILL.md +130 -12
- package/core/steps/context-loader.md +57 -1
- package/core/steps/gate.md +1 -1
- package/core/steps/report-footer.md +5 -3
- package/core/steps/spawn-agent.md +3 -1
- package/core/templates/design-spec.template.md +209 -0
- package/core/templates/project-context.yaml +29 -0
- package/package.json +1 -1
- package/skills/code/SKILL.md +68 -8
- package/skills/debug/SKILL.md +72 -10
- package/skills/design-spec/SKILL.md +450 -0
- package/skills/design-spec/SKILL.tmpl +95 -0
- package/skills/discovery/SKILL.md +62 -4
- package/skills/prd/SKILL.md +12 -8
- package/skills/setup-ai-first/SKILL.md +5 -3
- package/skills/spec/SKILL.md +11 -7
- package/skills/test/SKILL.md +130 -12
- package/steps/context-loader.md +57 -1
- package/steps/gate.md +1 -1
- package/steps/report-footer.md +5 -3
- package/steps/spawn-agent.md +3 -1
- package/templates/design-spec.template.md +209 -0
- package/templates/project-context.yaml +29 -0
|
@@ -33,7 +33,7 @@ Display and wait for response:
|
|
|
33
33
|
```
|
|
34
34
|
⚙️ MODEL CHECK
|
|
35
35
|
──────────────────────────────────────────────────────────────────
|
|
36
|
-
Recommended : claude-opus-4
|
|
36
|
+
Recommended : claude-opus-4 (or latest Opus model)
|
|
37
37
|
Why needed : Spec analysis, architecture review, code generation
|
|
38
38
|
require deep reasoning. Smaller models miss edge cases.
|
|
39
39
|
|
|
@@ -133,6 +133,7 @@ Read `.agent/project-context.yaml`. Extract and store:
|
|
|
133
133
|
- `paths.core_entities` → path to core-entities.md
|
|
134
134
|
- `paths.tech_docs_dir` → technical documentation root
|
|
135
135
|
- `paths.trace_dir` → trace state directory
|
|
136
|
+
- `paths.design_spec_dir` → Design Spec documents root (FE/App only)
|
|
136
137
|
|
|
137
138
|
If `paths` section is absent, use these defaults:
|
|
138
139
|
- `specs_dir` = `specs/bdd`
|
|
@@ -142,13 +143,46 @@ If `paths` section is absent, use these defaults:
|
|
|
142
143
|
- `domain_knowledge_dir` = `specs/domain-knowledge`
|
|
143
144
|
- `business_dictionary` = `specs/domain-knowledge/business-dictionary.md`
|
|
144
145
|
- `core_entities` = `specs/domain-knowledge/core-entities.md`
|
|
145
|
-
- `tech_docs_dir` = `tech-docs`
|
|
146
|
+
- `tech_docs_dir` = `specs/tech-docs`
|
|
146
147
|
- `trace_dir` = `.trace`
|
|
148
|
+
- `design_spec_dir` = `specs/design-spec`
|
|
147
149
|
|
|
148
150
|
If `tech_stack.module` is set, also load `.agent/modules/{module}/stack-profile.yaml` if it exists.
|
|
149
151
|
|
|
150
152
|
---
|
|
151
153
|
|
|
154
|
+
## Step 1.5 — [SERVICE ROUTING] Resolve service paths (umbrella mode)
|
|
155
|
+
|
|
156
|
+
*Skip this step entirely if `setup.mode` is not `"umbrella"` and `services` section is absent from project-context.yaml.*
|
|
157
|
+
|
|
158
|
+
If `services` section is present:
|
|
159
|
+
|
|
160
|
+
**1. Detect active domain** (in priority order):
|
|
161
|
+
- Read `@trace.domain` from target file frontmatter (if Gate loaded a target file)
|
|
162
|
+
- Extract from target file path: segment immediately after `prd_dir` base path
|
|
163
|
+
*(e.g., `specs/prd/user/FEAT-01.md` → domain = `user`)*
|
|
164
|
+
- If `$ARGUMENTS` contains a path, extract the segment after `prd_dir`
|
|
165
|
+
|
|
166
|
+
**2. Route to service** — if active domain matches a key in `services`:
|
|
167
|
+
- Override `paths.specs_dir` → `services.{domain}.specs_dir`
|
|
168
|
+
- Override `paths.tech_docs_dir` → `services.{domain}.tech_docs_dir`
|
|
169
|
+
- Store `active_service` = `services.{domain}.path`
|
|
170
|
+
- Store `active_service_module` = `services.{domain}.module`
|
|
171
|
+
- If service has its own `module` → use it as `active_module` (overrides `tech_stack.module`)
|
|
172
|
+
|
|
173
|
+
**3. Fallback** — if domain not detected or no matching service key:
|
|
174
|
+
- Keep default paths from Step 1
|
|
175
|
+
- Set `active_service = unresolved`
|
|
176
|
+
|
|
177
|
+
**4. Spec source auto-override** — if `setup.spec_source` is set AND the corresponding path was not already explicitly set in `paths:`:
|
|
178
|
+
- Override `paths.prd_dir` → `{spec_source}/specs/prd`
|
|
179
|
+
- Override `paths.design_spec_dir` → `{spec_source}/specs/design-spec`
|
|
180
|
+
- Override `paths.domain_knowledge_dir` → `{spec_source}/specs/domain-knowledge`
|
|
181
|
+
- Override `paths.business_dictionary` → `{spec_source}/specs/domain-knowledge/business-dictionary.md`
|
|
182
|
+
- Override `paths.core_entities` → `{spec_source}/specs/domain-knowledge/core-entities.md`
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
152
186
|
## Step 2 — [PROJECT-CONFIG] Load module stack profile (conditional)
|
|
153
187
|
|
|
154
188
|
If `tech_stack.module` is set, read `.agent/modules/{module}/stack-profile.yaml`.
|
|
@@ -219,6 +253,26 @@ If the file does not exist → skip silently.
|
|
|
219
253
|
|
|
220
254
|
---
|
|
221
255
|
|
|
256
|
+
## Step 6.5 — [PLATFORM] Derive active_module and platform_type
|
|
257
|
+
|
|
258
|
+
Using `tech_stack.module` loaded in Step 1, derive and store two variables for use by all downstream commands:
|
|
259
|
+
|
|
260
|
+
```
|
|
261
|
+
active_module = tech_stack.module (e.g. "java-spring", "react", "flutter")
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
| `platform_type` | Modules |
|
|
265
|
+
|---|---|
|
|
266
|
+
| `backend` | `java-spring`, `golang`, `dotnet`, `php-laravel`, `context-engineering` |
|
|
267
|
+
| `web-frontend` | `react`, `nextjs`, `vue`, `nuxt`, `angular` |
|
|
268
|
+
| `mobile` | `flutter`, `react-native`, `ios-swiftui`, `android-compose` |
|
|
269
|
+
|
|
270
|
+
If `tech_stack.module` is blank or not recognized → set `platform_type = "unknown"` and flag as ⚠️ in the Step 7 recap.
|
|
271
|
+
|
|
272
|
+
These two variables (`active_module`, `platform_type`) are the canonical source for all branching logic in commands that need platform-specific behavior (generate-tests, debug, fix-bug, smoke-test).
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
222
276
|
## Step 7 — [RECAP] Working Memory Recap (anti-lost-in-middle)
|
|
223
277
|
|
|
224
278
|
After loading all context, synthesize and output a compact summary block.
|
|
@@ -229,10 +283,12 @@ Output exactly this block:
|
|
|
229
283
|
```
|
|
230
284
|
[CTX LOADED]
|
|
231
285
|
Stack : {language} / {framework} / {database}
|
|
286
|
+
Platform : {active_module} ({platform_type})
|
|
232
287
|
Layers : {layer order from CLAUDE.md §2, e.g., Controller → Facade → Service → Repository}
|
|
233
288
|
Ticket : {ticket_prefix}-
|
|
234
289
|
Dict : {loaded — N canonical terms, M banned terms | missing}
|
|
235
290
|
Entities : {loaded — EntityA, EntityB, EntityC | missing}
|
|
291
|
+
Service : {active_service} ({active_service_module}) | single-service
|
|
236
292
|
Status : {FULL | PARTIAL — missing: CLAUDE.md / business-dict / core-entities | MINIMAL}
|
|
237
293
|
```
|
|
238
294
|
|
|
@@ -263,6 +319,13 @@ Proceed to the next step of the calling command.
|
|
|
263
319
|
Read all `{paths.trace_dir}/{UC-ID}.tsv` files matching the target domain (or all domains if no domain filter).
|
|
264
320
|
Each file gives the persisted trace state for that UC.
|
|
265
321
|
|
|
322
|
+
**If no `.tsv` files found** in `{paths.trace_dir}`:
|
|
323
|
+
- Scan all `{paths.specs_dir}/**/*.feature` files in the target domain to build an in-memory list of all scenarios.
|
|
324
|
+
- Treat all scenarios as `UNTRACKED` (no code generated yet).
|
|
325
|
+
- Print: "⚠️ No trace files found. All {N} scenarios across {M} UCs are UNTRACKED."
|
|
326
|
+
- Suggest: "Run `/generate-bdd {prd-file}` to initialize trace state, or `/generate-code {feature-file}` to generate code."
|
|
327
|
+
- **Skip Steps 2–6 entirely.** Proceed directly to Step 7 using this in-memory state — do NOT abort.
|
|
328
|
+
|
|
266
329
|
### Step 2 — Reconcile with current `.feature` files
|
|
267
330
|
|
|
268
331
|
For each `.tsv` row, read the corresponding `.feature` file and get the **current** `@trace.sc_version` for that SC.
|
|
@@ -300,6 +363,8 @@ If code was generated from an older revision → flag `TECHDOC_DRIFT`.
|
|
|
300
363
|
|
|
301
364
|
### Step 6 — Write status back to TSV
|
|
302
365
|
|
|
366
|
+
*Skip this step if no TSV files existed (handled by Step 1 no-TSV path).*
|
|
367
|
+
|
|
303
368
|
For each `.tsv` file processed: write updated `spec_ver`, `status`, `last_updated` back to disk.
|
|
304
369
|
|
|
305
370
|
### Step 7 — Compute dashboard aggregates
|
|
@@ -309,6 +374,7 @@ total_prds = count distinct PRD files in {paths.prd_dir}/{domain}/
|
|
|
309
374
|
approved_prds = PRDs with | Status | approved
|
|
310
375
|
total_ucs = count distinct UC-IDs across all .tsv files
|
|
311
376
|
approved_ucs = UCs with uc_status == approved
|
|
377
|
+
draft_ucs = UCs with uc_status == draft
|
|
312
378
|
total_scs = total rows across all .tsv files
|
|
313
379
|
code_coverage = rows where implemented_by != — / total_scs
|
|
314
380
|
test_coverage = rows where test_count > 0 / total_scs
|
|
@@ -320,7 +386,7 @@ tech_docs_count = count .md files in {paths.tech_docs_dir}/{domain}/
|
|
|
320
386
|
|
|
321
387
|
### Step 8 — Write JSON report
|
|
322
388
|
|
|
323
|
-
Write
|
|
389
|
+
Write `{paths.trace_dir}/trace-report.json` (overwrite if exists). This file is the single source of truth for web dashboards — it contains the full snapshot at the time `/validate-traces` was last run.
|
|
324
390
|
|
|
325
391
|
Schema:
|
|
326
392
|
|
|
@@ -430,7 +496,8 @@ Schema:
|
|
|
430
496
|
- `test_classes`: use `[]` (not `"—"`) when no test classes
|
|
431
497
|
- `tech_doc_revision`: use integer; `0` if not yet generated
|
|
432
498
|
- `code_coverage_pct` / `test_coverage_pct`: round to nearest integer (0–100)
|
|
433
|
-
- Always write to
|
|
499
|
+
- Always write to `{paths.trace_dir}/trace-report.json` regardless of domain filter — if a domain filter was applied, include only those PRDs in `prds[]` but note the domain in the `domain` field
|
|
500
|
+
- **TSV `"—"` mapping**: when reading TSV files, map dash values to JSON types: `implemented_by: "—"` → `null`; `test_count: "—"` → `0`; `test_classes: "—"` → `[]`; `tech_doc_revision: "—"` → `0`
|
|
434
501
|
|
|
435
502
|
## Output
|
|
436
503
|
|
|
@@ -462,21 +529,23 @@ Suggest the logical next command based on workflow phase:
|
|
|
462
529
|
|
|
463
530
|
| Current command | Suggest next |
|
|
464
531
|
|-------------------------|-----------------------------------------------|
|
|
532
|
+
| /setup-ai-first | `/define-product` to start your first feature |
|
|
465
533
|
| /define-product | `/generate-prd {product-definition-file}` |
|
|
466
534
|
| /generate-prd | `/refine-prd {prd-file}` then `/review-context {prd-file}` |
|
|
467
535
|
| /refine-prd | Open Review Board → update PRD → `/review-context {prd-file}` |
|
|
468
|
-
| /review-context (PRD) | `/generate-
|
|
536
|
+
| /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 |
|
|
537
|
+
| /generate-design-spec | Designer review → Figma links confirmed → PO + Designer sign-off → `/generate-bdd {prd-file}` |
|
|
469
538
|
| /generate-bdd | `/review-context {feature-file}` to verify coverage |
|
|
470
539
|
| /review-context (BDD) | `/generate-tech-docs {UC-ID}` if APPROVED; regenerate if NEEDS_FIX |
|
|
471
540
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
472
541
|
| /review-tech-docs | `/generate-code {feature-file}` if APPROVED; fix doc if NEEDS_FIX |
|
|
473
|
-
| /generate-code | `/generate-tests {UC-ID}`
|
|
542
|
+
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/generate-tests {UC-ID}` |
|
|
474
543
|
| /generate-tests | `/run-tests {UC-ID}` |
|
|
475
544
|
| /run-tests (passing) | `/review-code {UC-ID}` |
|
|
476
545
|
| /run-tests (failing) | `/fix-bug {ticket-id}` or `/debug {error}` |
|
|
477
546
|
| /review-code | `/smoke-test {UC-ID}` or create PR |
|
|
478
547
|
| /smoke-test | Create PR and link to ticket |
|
|
479
|
-
| /validate-traces | `/generate-code {UC-ID}
|
|
548
|
+
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/generate-tests {UC-ID}`; all OK → create PR |
|
|
480
549
|
| /fix-bug | Create PR and link to ticket |
|
|
481
550
|
| /debug | `/fix-bug {ticket-id}` if fix needed |
|
|
482
551
|
|
|
@@ -492,7 +561,7 @@ Next : {suggested command with example arguments}
|
|
|
492
561
|
```
|
|
493
562
|
/validate-traces — {domain}
|
|
494
563
|
|
|
495
|
-
📄 .
|
|
564
|
+
📄 {paths.trace_dir}/trace-report.json ← updated
|
|
496
565
|
|
|
497
566
|
┌─────────────────────────────────────────────────────────────────────────────────────┐
|
|
498
567
|
│ PRDs Use Cases Scenarios Code Cov. Test Cov. Drift Untracked Gap │
|
|
@@ -19,6 +19,13 @@ Read-only check of coverage between specs, code, and tests — including PRD ver
|
|
|
19
19
|
Read all `{paths.trace_dir}/{UC-ID}.tsv` files matching the target domain (or all domains if no domain filter).
|
|
20
20
|
Each file gives the persisted trace state for that UC.
|
|
21
21
|
|
|
22
|
+
**If no `.tsv` files found** in `{paths.trace_dir}`:
|
|
23
|
+
- Scan all `{paths.specs_dir}/**/*.feature` files in the target domain to build an in-memory list of all scenarios.
|
|
24
|
+
- Treat all scenarios as `UNTRACKED` (no code generated yet).
|
|
25
|
+
- Print: "⚠️ No trace files found. All {N} scenarios across {M} UCs are UNTRACKED."
|
|
26
|
+
- Suggest: "Run `/generate-bdd {prd-file}` to initialize trace state, or `/generate-code {feature-file}` to generate code."
|
|
27
|
+
- **Skip Steps 2–6 entirely.** Proceed directly to Step 7 using this in-memory state — do NOT abort.
|
|
28
|
+
|
|
22
29
|
### Step 2 — Reconcile with current `.feature` files
|
|
23
30
|
|
|
24
31
|
For each `.tsv` row, read the corresponding `.feature` file and get the **current** `@trace.sc_version` for that SC.
|
|
@@ -56,6 +63,8 @@ If code was generated from an older revision → flag `TECHDOC_DRIFT`.
|
|
|
56
63
|
|
|
57
64
|
### Step 6 — Write status back to TSV
|
|
58
65
|
|
|
66
|
+
*Skip this step if no TSV files existed (handled by Step 1 no-TSV path).*
|
|
67
|
+
|
|
59
68
|
For each `.tsv` file processed: write updated `spec_ver`, `status`, `last_updated` back to disk.
|
|
60
69
|
|
|
61
70
|
### Step 7 — Compute dashboard aggregates
|
|
@@ -65,6 +74,7 @@ total_prds = count distinct PRD files in {paths.prd_dir}/{domain}/
|
|
|
65
74
|
approved_prds = PRDs with | Status | approved
|
|
66
75
|
total_ucs = count distinct UC-IDs across all .tsv files
|
|
67
76
|
approved_ucs = UCs with uc_status == approved
|
|
77
|
+
draft_ucs = UCs with uc_status == draft
|
|
68
78
|
total_scs = total rows across all .tsv files
|
|
69
79
|
code_coverage = rows where implemented_by != — / total_scs
|
|
70
80
|
test_coverage = rows where test_count > 0 / total_scs
|
|
@@ -76,7 +86,7 @@ tech_docs_count = count .md files in {paths.tech_docs_dir}/{domain}/
|
|
|
76
86
|
|
|
77
87
|
### Step 8 — Write JSON report
|
|
78
88
|
|
|
79
|
-
Write
|
|
89
|
+
Write `{paths.trace_dir}/trace-report.json` (overwrite if exists). This file is the single source of truth for web dashboards — it contains the full snapshot at the time `/validate-traces` was last run.
|
|
80
90
|
|
|
81
91
|
Schema:
|
|
82
92
|
|
|
@@ -186,7 +196,8 @@ Schema:
|
|
|
186
196
|
- `test_classes`: use `[]` (not `"—"`) when no test classes
|
|
187
197
|
- `tech_doc_revision`: use integer; `0` if not yet generated
|
|
188
198
|
- `code_coverage_pct` / `test_coverage_pct`: round to nearest integer (0–100)
|
|
189
|
-
- Always write to
|
|
199
|
+
- Always write to `{paths.trace_dir}/trace-report.json` regardless of domain filter — if a domain filter was applied, include only those PRDs in `prds[]` but note the domain in the `domain` field
|
|
200
|
+
- **TSV `"—"` mapping**: when reading TSV files, map dash values to JSON types: `implemented_by: "—"` → `null`; `test_count: "—"` → `0`; `test_classes: "—"` → `[]`; `tech_doc_revision: "—"` → `0`
|
|
190
201
|
|
|
191
202
|
## Output
|
|
192
203
|
|
|
@@ -195,7 +206,7 @@ Schema:
|
|
|
195
206
|
```
|
|
196
207
|
/validate-traces — {domain}
|
|
197
208
|
|
|
198
|
-
📄 .
|
|
209
|
+
📄 {paths.trace_dir}/trace-report.json ← updated
|
|
199
210
|
|
|
200
211
|
┌─────────────────────────────────────────────────────────────────────────────────────┐
|
|
201
212
|
│ PRDs Use Cases Scenarios Code Cov. Test Cov. Drift Untracked Gap │
|
package/core/FRAMEWORK_VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.8.0
|
package/core/commands/debug.md
CHANGED
|
@@ -34,7 +34,7 @@ Display and wait for response:
|
|
|
34
34
|
```
|
|
35
35
|
⚙️ MODEL CHECK
|
|
36
36
|
──────────────────────────────────────────────────────────────────
|
|
37
|
-
Recommended : claude-opus-4
|
|
37
|
+
Recommended : claude-opus-4 (or latest Opus model)
|
|
38
38
|
Why needed : Spec analysis, architecture review, code generation
|
|
39
39
|
require deep reasoning. Smaller models miss edge cases.
|
|
40
40
|
|
|
@@ -134,6 +134,7 @@ Read `.agent/project-context.yaml`. Extract and store:
|
|
|
134
134
|
- `paths.core_entities` → path to core-entities.md
|
|
135
135
|
- `paths.tech_docs_dir` → technical documentation root
|
|
136
136
|
- `paths.trace_dir` → trace state directory
|
|
137
|
+
- `paths.design_spec_dir` → Design Spec documents root (FE/App only)
|
|
137
138
|
|
|
138
139
|
If `paths` section is absent, use these defaults:
|
|
139
140
|
- `specs_dir` = `specs/bdd`
|
|
@@ -143,13 +144,46 @@ If `paths` section is absent, use these defaults:
|
|
|
143
144
|
- `domain_knowledge_dir` = `specs/domain-knowledge`
|
|
144
145
|
- `business_dictionary` = `specs/domain-knowledge/business-dictionary.md`
|
|
145
146
|
- `core_entities` = `specs/domain-knowledge/core-entities.md`
|
|
146
|
-
- `tech_docs_dir` = `tech-docs`
|
|
147
|
+
- `tech_docs_dir` = `specs/tech-docs`
|
|
147
148
|
- `trace_dir` = `.trace`
|
|
149
|
+
- `design_spec_dir` = `specs/design-spec`
|
|
148
150
|
|
|
149
151
|
If `tech_stack.module` is set, also load `.agent/modules/{module}/stack-profile.yaml` if it exists.
|
|
150
152
|
|
|
151
153
|
---
|
|
152
154
|
|
|
155
|
+
## Step 1.5 — [SERVICE ROUTING] Resolve service paths (umbrella mode)
|
|
156
|
+
|
|
157
|
+
*Skip this step entirely if `setup.mode` is not `"umbrella"` and `services` section is absent from project-context.yaml.*
|
|
158
|
+
|
|
159
|
+
If `services` section is present:
|
|
160
|
+
|
|
161
|
+
**1. Detect active domain** (in priority order):
|
|
162
|
+
- Read `@trace.domain` from target file frontmatter (if Gate loaded a target file)
|
|
163
|
+
- Extract from target file path: segment immediately after `prd_dir` base path
|
|
164
|
+
*(e.g., `specs/prd/user/FEAT-01.md` → domain = `user`)*
|
|
165
|
+
- If `$ARGUMENTS` contains a path, extract the segment after `prd_dir`
|
|
166
|
+
|
|
167
|
+
**2. Route to service** — if active domain matches a key in `services`:
|
|
168
|
+
- Override `paths.specs_dir` → `services.{domain}.specs_dir`
|
|
169
|
+
- Override `paths.tech_docs_dir` → `services.{domain}.tech_docs_dir`
|
|
170
|
+
- Store `active_service` = `services.{domain}.path`
|
|
171
|
+
- Store `active_service_module` = `services.{domain}.module`
|
|
172
|
+
- If service has its own `module` → use it as `active_module` (overrides `tech_stack.module`)
|
|
173
|
+
|
|
174
|
+
**3. Fallback** — if domain not detected or no matching service key:
|
|
175
|
+
- Keep default paths from Step 1
|
|
176
|
+
- Set `active_service = unresolved`
|
|
177
|
+
|
|
178
|
+
**4. Spec source auto-override** — if `setup.spec_source` is set AND the corresponding path was not already explicitly set in `paths:`:
|
|
179
|
+
- Override `paths.prd_dir` → `{spec_source}/specs/prd`
|
|
180
|
+
- Override `paths.design_spec_dir` → `{spec_source}/specs/design-spec`
|
|
181
|
+
- Override `paths.domain_knowledge_dir` → `{spec_source}/specs/domain-knowledge`
|
|
182
|
+
- Override `paths.business_dictionary` → `{spec_source}/specs/domain-knowledge/business-dictionary.md`
|
|
183
|
+
- Override `paths.core_entities` → `{spec_source}/specs/domain-knowledge/core-entities.md`
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
153
187
|
## Step 2 — [PROJECT-CONFIG] Load module stack profile (conditional)
|
|
154
188
|
|
|
155
189
|
If `tech_stack.module` is set, read `.agent/modules/{module}/stack-profile.yaml`.
|
|
@@ -220,6 +254,26 @@ If the file does not exist → skip silently.
|
|
|
220
254
|
|
|
221
255
|
---
|
|
222
256
|
|
|
257
|
+
## Step 6.5 — [PLATFORM] Derive active_module and platform_type
|
|
258
|
+
|
|
259
|
+
Using `tech_stack.module` loaded in Step 1, derive and store two variables for use by all downstream commands:
|
|
260
|
+
|
|
261
|
+
```
|
|
262
|
+
active_module = tech_stack.module (e.g. "java-spring", "react", "flutter")
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
| `platform_type` | Modules |
|
|
266
|
+
|---|---|
|
|
267
|
+
| `backend` | `java-spring`, `golang`, `dotnet`, `php-laravel`, `context-engineering` |
|
|
268
|
+
| `web-frontend` | `react`, `nextjs`, `vue`, `nuxt`, `angular` |
|
|
269
|
+
| `mobile` | `flutter`, `react-native`, `ios-swiftui`, `android-compose` |
|
|
270
|
+
|
|
271
|
+
If `tech_stack.module` is blank or not recognized → set `platform_type = "unknown"` and flag as ⚠️ in the Step 7 recap.
|
|
272
|
+
|
|
273
|
+
These two variables (`active_module`, `platform_type`) are the canonical source for all branching logic in commands that need platform-specific behavior (generate-tests, debug, fix-bug, smoke-test).
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
223
277
|
## Step 7 — [RECAP] Working Memory Recap (anti-lost-in-middle)
|
|
224
278
|
|
|
225
279
|
After loading all context, synthesize and output a compact summary block.
|
|
@@ -230,10 +284,12 @@ Output exactly this block:
|
|
|
230
284
|
```
|
|
231
285
|
[CTX LOADED]
|
|
232
286
|
Stack : {language} / {framework} / {database}
|
|
287
|
+
Platform : {active_module} ({platform_type})
|
|
233
288
|
Layers : {layer order from CLAUDE.md §2, e.g., Controller → Facade → Service → Repository}
|
|
234
289
|
Ticket : {ticket_prefix}-
|
|
235
290
|
Dict : {loaded — N canonical terms, M banned terms | missing}
|
|
236
291
|
Entities : {loaded — EntityA, EntityB, EntityC | missing}
|
|
292
|
+
Service : {active_service} ({active_service_module}) | single-service
|
|
237
293
|
Status : {FULL | PARTIAL — missing: CLAUDE.md / business-dict / core-entities | MINIMAL}
|
|
238
294
|
```
|
|
239
295
|
|
|
@@ -257,13 +313,112 @@ Proceed to the next step of the calling command.
|
|
|
257
313
|
|
|
258
314
|
---
|
|
259
315
|
|
|
260
|
-
##
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
316
|
+
## Step 1 — Classify debug type
|
|
317
|
+
|
|
318
|
+
After loading context, display this prompt and wait for the user's choice:
|
|
319
|
+
|
|
320
|
+
```
|
|
321
|
+
DEBUG SESSION
|
|
322
|
+
──────────────────────────────────────────────────────────────
|
|
323
|
+
What's your situation?
|
|
324
|
+
|
|
325
|
+
1 I already have a stack trace / error log → paste it
|
|
326
|
+
2 I need to reproduce the error first → show me the run command
|
|
327
|
+
3 A test is failing → I'll run tests, then paste output
|
|
328
|
+
4 Code question (no runtime needed) → ask away
|
|
329
|
+
──────────────────────────────────────────────────────────────
|
|
330
|
+
Enter 1 / 2 / 3 / 4:
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
Wait for the user's choice, then follow the corresponding path below.
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
### Path 1 — Already have error output
|
|
338
|
+
|
|
339
|
+
Ask:
|
|
340
|
+
```
|
|
341
|
+
Paste your stack trace / error log below:
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
Wait for input, then proceed to [Stack Trace Analysis](#stack-trace-analysis).
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
### Path 2 — Need to reproduce first
|
|
349
|
+
|
|
350
|
+
Display the run command from `conventions.service_run` in `project-context.yaml`:
|
|
351
|
+
|
|
352
|
+
```
|
|
353
|
+
Start your service first:
|
|
354
|
+
|
|
355
|
+
{conventions.service_run}
|
|
356
|
+
|
|
357
|
+
(If you use Docker: `docker compose up -d`, then verify with `docker compose ps`)
|
|
358
|
+
|
|
359
|
+
Once the service is running:
|
|
360
|
+
1. Trigger the behavior that causes the error
|
|
361
|
+
2. Copy the full stack trace or error log
|
|
362
|
+
3. Paste it here
|
|
363
|
+
|
|
364
|
+
Waiting for your error output...
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
Wait for the user to paste the error, then proceed to [Stack Trace Analysis](#stack-trace-analysis).
|
|
368
|
+
|
|
369
|
+
If `conventions.service_run` is not set → show:
|
|
370
|
+
```
|
|
371
|
+
⚠️ service_run is not configured in .agent/project-context.yaml.
|
|
372
|
+
Add it so this command can show the correct start command:
|
|
373
|
+
|
|
374
|
+
conventions:
|
|
375
|
+
service_run: "mvn spring-boot:run" # or: npm run dev / go run . / etc.
|
|
376
|
+
```
|
|
377
|
+
Then ask the user to start the service manually and paste the error when ready.
|
|
378
|
+
|
|
379
|
+
---
|
|
380
|
+
|
|
381
|
+
### Path 3 — Test is failing
|
|
382
|
+
|
|
383
|
+
Display the test command from `conventions.test_command` in `project-context.yaml`:
|
|
384
|
+
|
|
385
|
+
```
|
|
386
|
+
Run your tests first:
|
|
387
|
+
|
|
388
|
+
{conventions.test_command}
|
|
389
|
+
|
|
390
|
+
Once the run finishes, paste the full test failure output here.
|
|
391
|
+
|
|
392
|
+
Waiting...
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
Wait for the user to paste the failure output, then proceed to [Test Failure Analysis](#test-failure-analysis).
|
|
396
|
+
|
|
397
|
+
If `conventions.test_command` is not set → show:
|
|
398
|
+
```
|
|
399
|
+
⚠️ test_command is not configured in .agent/project-context.yaml.
|
|
400
|
+
Add it so this command can show the correct test command:
|
|
401
|
+
|
|
402
|
+
conventions:
|
|
403
|
+
test_command: "mvn test" # or: npm test / go test ./... / etc.
|
|
404
|
+
```
|
|
405
|
+
Then ask the user to run tests manually and paste the output when ready.
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
### Path 4 — Code question
|
|
410
|
+
|
|
411
|
+
Ask:
|
|
412
|
+
```
|
|
413
|
+
Describe your question or paste the code snippet you're asking about:
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
Wait for input, then answer directly using loaded project context (architecture rules, layer order, coding standards from CLAUDE.md).
|
|
417
|
+
|
|
418
|
+
---
|
|
265
419
|
|
|
266
420
|
## Stack Trace Analysis
|
|
421
|
+
|
|
267
422
|
Read from **bottom up** — `Caused by:` is the real root cause:
|
|
268
423
|
```
|
|
269
424
|
Caused by: {RealException} ← start here
|
|
@@ -272,20 +427,83 @@ Caused by: {RealException} ← start here
|
|
|
272
427
|
|
|
273
428
|
## Common Error Patterns
|
|
274
429
|
|
|
430
|
+
Use `active_module` from context to select the relevant table.
|
|
431
|
+
|
|
432
|
+
### If `platform_type = backend`
|
|
433
|
+
|
|
434
|
+
#### java-spring / golang / dotnet / php-laravel
|
|
435
|
+
|
|
275
436
|
| Error | Likely Cause | Fix Direction |
|
|
276
437
|
|-------|-------------|---------------|
|
|
277
438
|
| NullPointerException | Null object access; Optional not handled | Check Optional.orElseThrow, null guards |
|
|
278
439
|
| ClassCastException | Wrong type assumption | Check type at assignment/return |
|
|
279
440
|
| OutOfMemoryError | Loading too much data | Add pagination |
|
|
280
441
|
| StackOverflowError | Infinite recursion | Find recursive call with no base case |
|
|
281
|
-
| Connection refused | Dependency not running | Check config URLs |
|
|
442
|
+
| Connection refused | Dependency not running | Check config URLs / start service |
|
|
282
443
|
| 401 Unauthorized | Token expired, wrong config | Verify token, check auth config |
|
|
283
444
|
| 403 Forbidden | Wrong role | Check auth annotations |
|
|
284
445
|
| DB constraint violation | Duplicate key, null in NOT NULL | Check data and constraints |
|
|
285
446
|
| Serialization error | Circular reference | Check DTO/mapper config |
|
|
286
447
|
| Test assertion mismatch | Wrong mock or wrong expected | Re-read mock setup |
|
|
287
448
|
|
|
449
|
+
#### context-engineering (AI/LLM pipelines)
|
|
450
|
+
|
|
451
|
+
| Error | Likely Cause | Fix Direction |
|
|
452
|
+
|-------|-------------|---------------|
|
|
453
|
+
| `APIError` / `RateLimitError` | LLM quota exceeded or service down | Check API key, rate limits; add exponential backoff |
|
|
454
|
+
| `TokenLimitError` / `context_length_exceeded` | Input prompt too long | Truncate/chunk input; review prompt template size |
|
|
455
|
+
| `AuthenticationError` | API key invalid or expired | Check env var; rotate key |
|
|
456
|
+
| Response validation / schema mismatch | LLM output doesn't match expected format | Add output parser; retry with stricter prompt |
|
|
457
|
+
| `JSONDecodeError` on LLM output | Model returned non-JSON text | Add JSON extraction post-processing or stricter system prompt |
|
|
458
|
+
| Hanging / slow test | Real LLM called in test instead of mock | Verify `patch('...')` applied; add timeout guard |
|
|
459
|
+
| Flaky results across runs | Non-deterministic LLM response | Use fixed mock in tests; check temperature = 0 for determinism |
|
|
460
|
+
|
|
461
|
+
### If `platform_type = web-frontend`
|
|
462
|
+
|
|
463
|
+
| Error | Likely Cause | Fix Direction |
|
|
464
|
+
|-------|-------------|---------------|
|
|
465
|
+
| `Cannot read properties of undefined` | Data not loaded yet | Add loading guard / optional chaining `?.` |
|
|
466
|
+
| `useEffect` infinite loop | Dependency array wrong | Review deps, use stable refs / `useCallback` |
|
|
467
|
+
| `Cannot update state on unmounted component` | Async resolves after unmount | Cancel in cleanup / use AbortController |
|
|
468
|
+
| CORS error | API not configured | Check backend CORS config or dev proxy setup |
|
|
469
|
+
| 401 Unauthorized | Token expired or missing | Refresh token / check Authorization header |
|
|
470
|
+
| White screen / no output | Unhandled render error | Check browser console, add ErrorBoundary |
|
|
471
|
+
| Type error (Zod / TypeScript) | API response shape mismatch | Compare actual response vs type definition |
|
|
472
|
+
| `act(...)` warning in test | Async state update | Wrap in `act(async () => {...})` |
|
|
473
|
+
| Module not found | Import path wrong | Check relative path / tsconfig alias |
|
|
474
|
+
|
|
475
|
+
### If `platform_type = mobile`
|
|
476
|
+
|
|
477
|
+
#### Flutter
|
|
478
|
+
| Error | Likely Cause | Fix Direction |
|
|
479
|
+
|-------|-------------|---------------|
|
|
480
|
+
| `Null check operator on null value` | Nullable not guarded | Add `?` or null check before `!` |
|
|
481
|
+
| `pumpAndSettle timed out` | Async not completing in test | Use `pump(Duration(...))` |
|
|
482
|
+
| `setState called after dispose` | Async continues after widget removed | Cancel in `dispose()` |
|
|
483
|
+
| `RenderFlex overflow` | Widget too wide for screen | Wrap with `Flexible`, `Expanded`, or `SingleChildScrollView` |
|
|
484
|
+
| BLoC state not updating | Event not dispatched | Verify `bloc.add(Event())` is called |
|
|
485
|
+
| `MissingPluginException` | Native plugin not linked | Run `flutter clean && flutter pub get` |
|
|
486
|
+
|
|
487
|
+
#### React Native
|
|
488
|
+
| Error | Likely Cause | Fix Direction |
|
|
489
|
+
|-------|-------------|---------------|
|
|
490
|
+
| `undefined is not an object` | Null prop access | Add null check / optional chaining |
|
|
491
|
+
| Metro bundler error | Cache stale | `npx react-native start --reset-cache` |
|
|
492
|
+
| `VirtualizedLists nested` | FlatList inside ScrollView | Use `nestedScrollEnabled` or restructure |
|
|
493
|
+
| Navigation `undefined` | `useNavigation` outside navigator | Wrap component inside correct navigator |
|
|
494
|
+
| `act(...)` warning | Async state update in test | Wrap in `act(async () => {...})` |
|
|
495
|
+
|
|
496
|
+
#### iOS / Android
|
|
497
|
+
| Error | Likely Cause | Fix Direction |
|
|
498
|
+
|-------|-------------|---------------|
|
|
499
|
+
| `SIGABRT` / `EXC_BAD_ACCESS` (iOS) | Nil dereference | Add optional binding `if let` / `guard let` |
|
|
500
|
+
| `IllegalStateException` (Android) | Lifecycle violation | Check if fragment/activity still attached |
|
|
501
|
+
| `NetworkOnMainThreadException` | Network call on UI thread | Move to coroutine / background thread |
|
|
502
|
+
| Build fails after pod install | Pod cache stale | `pod deintegrate && pod install` |
|
|
503
|
+
| `Hilt injection failed` | Missing `@AndroidEntryPoint` | Add annotation to Activity/Fragment |
|
|
504
|
+
|
|
288
505
|
## Test Failure Analysis
|
|
506
|
+
|
|
289
507
|
```
|
|
290
508
|
Expected: {value}
|
|
291
509
|
Actual : {value}
|
|
@@ -293,6 +511,8 @@ Actual : {value}
|
|
|
293
511
|
```
|
|
294
512
|
1. What is the gap? 2. Is mock setup correct? 3. Is assertion logically correct?
|
|
295
513
|
|
|
514
|
+
---
|
|
515
|
+
|
|
296
516
|
## Output
|
|
297
517
|
|
|
298
518
|
# Report Footer — Standard Command Output Format
|
|
@@ -323,21 +543,23 @@ Suggest the logical next command based on workflow phase:
|
|
|
323
543
|
|
|
324
544
|
| Current command | Suggest next |
|
|
325
545
|
|-------------------------|-----------------------------------------------|
|
|
546
|
+
| /setup-ai-first | `/define-product` to start your first feature |
|
|
326
547
|
| /define-product | `/generate-prd {product-definition-file}` |
|
|
327
548
|
| /generate-prd | `/refine-prd {prd-file}` then `/review-context {prd-file}` |
|
|
328
549
|
| /refine-prd | Open Review Board → update PRD → `/review-context {prd-file}` |
|
|
329
|
-
| /review-context (PRD) | `/generate-
|
|
550
|
+
| /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 |
|
|
551
|
+
| /generate-design-spec | Designer review → Figma links confirmed → PO + Designer sign-off → `/generate-bdd {prd-file}` |
|
|
330
552
|
| /generate-bdd | `/review-context {feature-file}` to verify coverage |
|
|
331
553
|
| /review-context (BDD) | `/generate-tech-docs {UC-ID}` if APPROVED; regenerate if NEEDS_FIX |
|
|
332
554
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
333
555
|
| /review-tech-docs | `/generate-code {feature-file}` if APPROVED; fix doc if NEEDS_FIX |
|
|
334
|
-
| /generate-code | `/generate-tests {UC-ID}`
|
|
556
|
+
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/generate-tests {UC-ID}` |
|
|
335
557
|
| /generate-tests | `/run-tests {UC-ID}` |
|
|
336
558
|
| /run-tests (passing) | `/review-code {UC-ID}` |
|
|
337
559
|
| /run-tests (failing) | `/fix-bug {ticket-id}` or `/debug {error}` |
|
|
338
560
|
| /review-code | `/smoke-test {UC-ID}` or create PR |
|
|
339
561
|
| /smoke-test | Create PR and link to ticket |
|
|
340
|
-
| /validate-traces | `/generate-code {UC-ID}
|
|
562
|
+
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/generate-tests {UC-ID}`; all OK → create PR |
|
|
341
563
|
| /fix-bug | Create PR and link to ticket |
|
|
342
564
|
| /debug | `/fix-bug {ticket-id}` if fix needed |
|
|
343
565
|
|