@anhth2/spec-driven-dev-plugin 0.9.1 → 0.10.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 +20 -9
- package/bin/index.js +1 -2
- package/commands/debug.md +13 -12
- package/commands/define-product.md +12 -11
- package/commands/{generate-tests.md → dev-gen-test.md} +48 -15
- package/commands/{generate-tests.tmpl → dev-gen-test.tmpl} +18 -4
- package/{core/commands/run-tests.md → commands/dev-run-test.md} +62 -13
- package/commands/{run-tests.tmpl → dev-run-test.tmpl} +32 -2
- package/{core/commands/smoke-test.md → commands/dev-smoke-test.md} +17 -16
- package/commands/{smoke-test.tmpl → dev-smoke-test.tmpl} +5 -5
- package/commands/fix-bug.md +13 -12
- package/commands/generate-bdd.md +39 -13
- package/commands/generate-bdd.tmpl +9 -2
- package/commands/generate-code.md +86 -15
- package/commands/generate-code.tmpl +56 -4
- package/commands/generate-design-spec.md +105 -39
- package/commands/generate-design-spec.tmpl +93 -28
- package/commands/generate-prd.md +12 -11
- package/commands/generate-spec-manifest.md +12 -11
- package/commands/generate-tech-docs.md +63 -22
- package/commands/generate-tech-docs.tmpl +51 -11
- package/commands/learn.md +13 -12
- package/commands/propose-scenario.md +13 -12
- package/commands/propose-scenario.tmpl +1 -1
- package/commands/refine-prd.md +166 -16
- package/commands/refine-prd.tmpl +16 -5
- package/commands/report-bug.md +12 -11
- package/commands/review-code.md +14 -13
- package/commands/review-code.tmpl +1 -1
- package/commands/review-context.md +161 -12
- package/commands/review-context.tmpl +11 -1
- package/commands/review-tech-docs.md +13 -11
- package/commands/review-tech-docs.tmpl +1 -0
- package/commands/setup-ai-first.md +7 -7
- package/commands/sync.md +23 -20
- package/commands/sync.tmpl +16 -13
- package/commands/update-framework.md +7 -7
- package/commands/validate-traces.md +57 -37
- package/commands/validate-traces.tmpl +45 -26
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/commands/debug.md +13 -12
- package/core/commands/define-product.md +12 -11
- package/core/commands/{generate-tests.md → dev-gen-test.md} +48 -15
- package/{commands/run-tests.md → core/commands/dev-run-test.md} +62 -13
- package/{commands/smoke-test.md → core/commands/dev-smoke-test.md} +17 -16
- package/core/commands/fix-bug.md +13 -12
- package/core/commands/generate-bdd.md +39 -13
- package/core/commands/generate-code.md +86 -15
- package/core/commands/generate-design-spec.md +105 -39
- package/core/commands/generate-prd.md +12 -11
- package/core/commands/generate-spec-manifest.md +12 -11
- package/core/commands/generate-tech-docs.md +63 -22
- package/core/commands/learn.md +13 -12
- package/core/commands/propose-scenario.md +13 -12
- package/core/commands/refine-prd.md +166 -16
- package/core/commands/report-bug.md +12 -11
- package/core/commands/review-code.md +14 -13
- package/core/commands/review-context.md +161 -12
- package/core/commands/review-tech-docs.md +13 -11
- package/core/commands/setup-ai-first.md +7 -7
- package/core/commands/sync.md +23 -20
- package/core/commands/update-framework.md +7 -7
- package/core/commands/validate-traces.md +57 -37
- package/core/modules/android-compose/module.yaml +13 -0
- package/core/modules/android-compose/stack-profile.yaml +57 -0
- package/core/modules/flutter/module.yaml +14 -0
- package/core/modules/flutter/stack-profile.yaml +59 -0
- package/core/modules/ios-swiftui/module.yaml +13 -0
- package/core/modules/ios-swiftui/stack-profile.yaml +55 -0
- package/core/modules/nuxt/module.yaml +14 -0
- package/core/modules/nuxt/stack-profile.yaml +58 -0
- package/core/modules/react-native/module.yaml +14 -0
- package/core/modules/react-native/stack-profile.yaml +56 -0
- package/core/modules/vue/module.yaml +14 -0
- package/core/modules/vue/stack-profile.yaml +65 -0
- package/core/skills/code/SKILL.md +19 -18
- package/core/skills/debug/SKILL.md +27 -26
- package/core/skills/design-spec/SKILL.md +12 -11
- package/core/skills/discovery/SKILL.md +12 -11
- package/core/skills/prd/SKILL.md +14 -14
- package/core/skills/setup-ai-first/SKILL.md +7 -7
- package/core/skills/spec/SKILL.md +14 -14
- package/core/skills/test/SKILL.md +40 -38
- package/core/steps/capture-lesson.md +1 -1
- package/core/steps/context-loader.md +5 -4
- package/core/steps/report-footer.md +7 -7
- package/core/steps/review-fanout.md +138 -0
- package/core/steps/spawn-agent.md +1 -1
- package/core/steps/trace-mirror.md +18 -0
- package/core/templates/design-spec.template.md +16 -8
- package/core/templates/product-definition.template.md +3 -3
- package/core/templates/project-context.yaml +4 -1
- package/modules/android-compose/module.yaml +13 -0
- package/modules/android-compose/stack-profile.yaml +57 -0
- package/modules/flutter/module.yaml +14 -0
- package/modules/flutter/stack-profile.yaml +59 -0
- package/modules/ios-swiftui/module.yaml +13 -0
- package/modules/ios-swiftui/stack-profile.yaml +55 -0
- package/modules/nuxt/module.yaml +14 -0
- package/modules/nuxt/stack-profile.yaml +58 -0
- package/modules/react-native/module.yaml +14 -0
- package/modules/react-native/stack-profile.yaml +56 -0
- package/modules/vue/module.yaml +14 -0
- package/modules/vue/stack-profile.yaml +65 -0
- package/package.json +1 -1
- package/skills/code/SKILL.md +19 -18
- package/skills/debug/SKILL.md +27 -26
- package/skills/debug/SKILL.tmpl +1 -1
- package/skills/design-spec/SKILL.md +12 -11
- package/skills/discovery/SKILL.md +12 -11
- package/skills/prd/SKILL.md +14 -14
- package/skills/setup-ai-first/SKILL.md +7 -7
- package/skills/spec/SKILL.md +14 -14
- package/skills/test/SKILL.md +40 -38
- package/skills/test/SKILL.tmpl +9 -9
- package/steps/capture-lesson.md +1 -1
- package/steps/context-loader.md +5 -4
- package/steps/report-footer.md +7 -7
- package/steps/review-fanout.md +138 -0
- package/steps/spawn-agent.md +1 -1
- package/steps/trace-mirror.md +18 -0
- package/templates/design-spec.template.md +16 -8
- package/templates/product-definition.template.md +3 -3
- package/templates/project-context.yaml +4 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
name: "Flutter"
|
|
2
|
+
version: "1.0.0"
|
|
3
|
+
description: "Cross-platform mobile (iOS + Android) with Flutter/Dart"
|
|
4
|
+
language: "Dart"
|
|
5
|
+
framework: "Flutter"
|
|
6
|
+
stack_type: "mobile"
|
|
7
|
+
default_layer_order:
|
|
8
|
+
- Models / entities (domain)
|
|
9
|
+
- Repositories (data layer)
|
|
10
|
+
- Use cases (domain logic)
|
|
11
|
+
- BLoC / Cubit or Riverpod providers (state)
|
|
12
|
+
- Widgets (presentation)
|
|
13
|
+
- Pages / screens
|
|
14
|
+
test_framework: "flutter_test + mocktail"
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
build:
|
|
2
|
+
compile: "flutter build apk / flutter build ios"
|
|
3
|
+
test: "flutter test"
|
|
4
|
+
run: "flutter run"
|
|
5
|
+
lint: "flutter analyze"
|
|
6
|
+
|
|
7
|
+
architecture:
|
|
8
|
+
style: "Feature-based (presentation → domain → data)"
|
|
9
|
+
key_rules:
|
|
10
|
+
- "Widget tree is pure UI — business logic lives in BLoC/Cubit or Riverpod providers"
|
|
11
|
+
- "Repositories abstract data sources; services contain domain logic"
|
|
12
|
+
- "State management: BLoC (complex flows) or Riverpod (simple/medium)"
|
|
13
|
+
- "Never call API directly inside a Widget build() method"
|
|
14
|
+
- "Shared UI widgets in lib/shared/widgets/, feature widgets in lib/features/{name}/presentation/"
|
|
15
|
+
- "Use const constructors wherever possible for performance"
|
|
16
|
+
folder_structure: |
|
|
17
|
+
lib/
|
|
18
|
+
├── core/
|
|
19
|
+
│ ├── theme/ ← AppTheme, colors, text styles
|
|
20
|
+
│ ├── router/ ← GoRouter or auto_route
|
|
21
|
+
│ └── utils/
|
|
22
|
+
├── shared/
|
|
23
|
+
│ └── widgets/ ← reusable UI widgets (AppButton, AppInput...)
|
|
24
|
+
├── features/
|
|
25
|
+
│ └── {domain}/
|
|
26
|
+
│ ├── data/ ← repositories, data sources, models
|
|
27
|
+
│ ├── domain/ ← entities, use cases, repo interfaces
|
|
28
|
+
│ └── presentation/ ← pages, widgets, BLoC/Cubit
|
|
29
|
+
└── main.dart
|
|
30
|
+
|
|
31
|
+
coding_standards:
|
|
32
|
+
naming:
|
|
33
|
+
widgets: "PascalCase (e.g., OrderListPage, CreateOrderForm)"
|
|
34
|
+
blocs: "PascalCase + Bloc/Cubit suffix (e.g., OrderListCubit)"
|
|
35
|
+
repositories: "PascalCase + Repository suffix (e.g., OrderRepository)"
|
|
36
|
+
files:
|
|
37
|
+
page: "{feature}_page.dart"
|
|
38
|
+
widget: "{feature}_widget.dart"
|
|
39
|
+
cubit: "{feature}_cubit.dart"
|
|
40
|
+
repository: "{feature}_repository.dart"
|
|
41
|
+
model: "{feature}_model.dart"
|
|
42
|
+
patterns:
|
|
43
|
+
state_management: "BLoC / Cubit (flutter_bloc) or Riverpod"
|
|
44
|
+
navigation: "GoRouter or auto_route"
|
|
45
|
+
networking: "Dio with interceptors"
|
|
46
|
+
serialization: "json_serializable / freezed"
|
|
47
|
+
|
|
48
|
+
testing:
|
|
49
|
+
unit: "flutter_test + mocktail"
|
|
50
|
+
widget: "flutter_test WidgetTester"
|
|
51
|
+
integration: "integration_test package"
|
|
52
|
+
patterns:
|
|
53
|
+
- "Test BLoC/Cubit in isolation with fake repositories"
|
|
54
|
+
- "Widget tests pump the widget tree and find by key or semantics label"
|
|
55
|
+
- "Use goldenFileComparator for snapshot tests of complex widgets"
|
|
56
|
+
|
|
57
|
+
trace_tags:
|
|
58
|
+
implements: "// @trace.implements={UC-ID}-SC{N}"
|
|
59
|
+
source: "// @trace.source=specs/bdd/{domain}/{UC-ID}.feature"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
name: "iOS (SwiftUI)"
|
|
2
|
+
version: "1.0.0"
|
|
3
|
+
description: "Native iOS development with SwiftUI + Swift"
|
|
4
|
+
language: "Swift"
|
|
5
|
+
framework: "SwiftUI"
|
|
6
|
+
stack_type: "mobile"
|
|
7
|
+
default_layer_order:
|
|
8
|
+
- Models / entities
|
|
9
|
+
- Repository (data sources)
|
|
10
|
+
- UseCase (business operations)
|
|
11
|
+
- ViewModel (ObservableObject state)
|
|
12
|
+
- View (SwiftUI presentation)
|
|
13
|
+
test_framework: "XCTest + Quick/Nimble"
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
build:
|
|
2
|
+
compile: "xcodebuild -scheme {AppName} -configuration Release"
|
|
3
|
+
test: "xcodebuild test -scheme {AppName}"
|
|
4
|
+
run: "Open in Xcode → Run (⌘R)"
|
|
5
|
+
lint: "swiftlint"
|
|
6
|
+
|
|
7
|
+
architecture:
|
|
8
|
+
style: "MVVM + Clean Architecture (View → ViewModel → UseCase → Repository)"
|
|
9
|
+
key_rules:
|
|
10
|
+
- "Views are pure SwiftUI — no business logic, no direct API calls"
|
|
11
|
+
- "ViewModels are ObservableObject classes; bind via @StateObject / @ObservedObject"
|
|
12
|
+
- "UseCases encapsulate single business operations"
|
|
13
|
+
- "Repositories abstract data sources (network, cache, local DB)"
|
|
14
|
+
- "Dependency injection via environment or constructor injection"
|
|
15
|
+
- "Use Combine or async/await for async flows — never DispatchQueue in ViewModel"
|
|
16
|
+
folder_structure: |
|
|
17
|
+
Sources/
|
|
18
|
+
├── Core/
|
|
19
|
+
│ ├── Network/ ← URLSession wrapper, interceptors
|
|
20
|
+
│ ├── Theme/ ← Color, Font, Spacing tokens
|
|
21
|
+
│ └── Utils/
|
|
22
|
+
├── Shared/
|
|
23
|
+
│ └── Components/ ← reusable SwiftUI views (AppButton, AppTextField...)
|
|
24
|
+
├── Features/
|
|
25
|
+
│ └── {Domain}/
|
|
26
|
+
│ ├── Views/
|
|
27
|
+
│ ├── ViewModels/
|
|
28
|
+
│ ├── UseCases/
|
|
29
|
+
│ └── Repository/
|
|
30
|
+
|
|
31
|
+
coding_standards:
|
|
32
|
+
naming:
|
|
33
|
+
views: "PascalCase + View suffix (e.g., OrderListView, CreateOrderView)"
|
|
34
|
+
viewmodels: "PascalCase + ViewModel suffix (e.g., OrderListViewModel)"
|
|
35
|
+
usecases: "PascalCase + UseCase suffix (e.g., CreateOrderUseCase)"
|
|
36
|
+
files:
|
|
37
|
+
view: "{Feature}View.swift"
|
|
38
|
+
viewmodel: "{Feature}ViewModel.swift"
|
|
39
|
+
usecase: "{Feature}UseCase.swift"
|
|
40
|
+
patterns:
|
|
41
|
+
async: "async/await + Combine"
|
|
42
|
+
navigation: "NavigationStack (iOS 16+)"
|
|
43
|
+
persistence: "Core Data or SwiftData"
|
|
44
|
+
networking: "URLSession or Alamofire"
|
|
45
|
+
|
|
46
|
+
testing:
|
|
47
|
+
unit: "XCTest + Quick/Nimble"
|
|
48
|
+
ui: "XCUITest"
|
|
49
|
+
patterns:
|
|
50
|
+
- "Test ViewModel by injecting mock repositories"
|
|
51
|
+
- "UI tests use accessibility identifiers — set .accessibilityIdentifier on Views"
|
|
52
|
+
|
|
53
|
+
trace_tags:
|
|
54
|
+
implements: "// @trace.implements={UC-ID}-SC{N}"
|
|
55
|
+
source: "// @trace.source=specs/bdd/{domain}/{UC-ID}.feature"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
name: "Nuxt"
|
|
2
|
+
version: "1.0.0"
|
|
3
|
+
description: "Nuxt 3 with SSR/SSG, Composition API, Pinia, and useFetch"
|
|
4
|
+
language: "TypeScript"
|
|
5
|
+
framework: "Nuxt 3"
|
|
6
|
+
stack_type: "frontend"
|
|
7
|
+
default_layer_order:
|
|
8
|
+
- Types / interfaces
|
|
9
|
+
- Server API routes (server/api/)
|
|
10
|
+
- Composables (useFetch / useAsyncData)
|
|
11
|
+
- State store (Pinia)
|
|
12
|
+
- UI components (presentational)
|
|
13
|
+
- Page components (pages/)
|
|
14
|
+
test_framework: "Vitest + Vue Test Utils + @nuxt/test-utils"
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
build:
|
|
2
|
+
compile: "npm run build"
|
|
3
|
+
test: "npm run test"
|
|
4
|
+
run: "npm run dev"
|
|
5
|
+
lint: "npm run lint"
|
|
6
|
+
|
|
7
|
+
architecture:
|
|
8
|
+
style: "Pages + Composables + Server routes (SSR/SSG)"
|
|
9
|
+
key_rules:
|
|
10
|
+
- "Pages in pages/ are route-level containers — no business logic"
|
|
11
|
+
- "Business logic in composables/ using useAsyncData or useFetch"
|
|
12
|
+
- "Server-side logic in server/api/ routes (nitro)"
|
|
13
|
+
- "Client-only state in Pinia stores; server state via useAsyncData"
|
|
14
|
+
- "Shared UI primitives in components/ui/, auto-imported by Nuxt"
|
|
15
|
+
- "Use useRoute/useRouter instead of $route/$router in Composition API"
|
|
16
|
+
- "'use client' equivalent: wrap client-only code in onMounted or <ClientOnly>"
|
|
17
|
+
folder_structure: |
|
|
18
|
+
├── components/
|
|
19
|
+
│ └── ui/ ← auto-imported UI primitives (BaseButton, BaseInput...)
|
|
20
|
+
├── composables/ ← auto-imported composables (useOrderList...)
|
|
21
|
+
├── pages/ ← file-based routing
|
|
22
|
+
├── server/
|
|
23
|
+
│ └── api/ ← nitro server routes (GET /api/orders.ts)
|
|
24
|
+
├── stores/ ← Pinia stores (auto-imported)
|
|
25
|
+
├── plugins/ ← Nuxt plugins
|
|
26
|
+
└── utils/ ← auto-imported utilities
|
|
27
|
+
|
|
28
|
+
coding_standards:
|
|
29
|
+
naming:
|
|
30
|
+
components: "PascalCase (auto-imported, e.g., OrderList, BaseButton)"
|
|
31
|
+
composables: "camelCase with 'use' prefix (auto-imported, e.g., useOrderList)"
|
|
32
|
+
stores: "camelCase + Store suffix via defineStore()"
|
|
33
|
+
server_routes: "method.path.ts (e.g., get.orders.ts or [id].get.ts)"
|
|
34
|
+
files:
|
|
35
|
+
component: "{Feature}.vue"
|
|
36
|
+
composable: "use{Feature}.ts"
|
|
37
|
+
store: "{feature}.store.ts"
|
|
38
|
+
server_route: "{resource}.get.ts / {resource}.post.ts"
|
|
39
|
+
patterns:
|
|
40
|
+
data_fetching: "useAsyncData() for SSR data, useFetch() for client fetches"
|
|
41
|
+
global_state: "Pinia stores"
|
|
42
|
+
forms: "VeeValidate + Zod"
|
|
43
|
+
api_client: "$fetch (ofetch) — built-in to Nuxt, SSR-compatible"
|
|
44
|
+
ssr_hydration: "useState() for shared SSR/client state to avoid hydration mismatch"
|
|
45
|
+
|
|
46
|
+
testing:
|
|
47
|
+
unit: "Vitest + @nuxt/test-utils"
|
|
48
|
+
e2e: "Playwright via @nuxt/test-utils/e2e"
|
|
49
|
+
patterns:
|
|
50
|
+
- "Use mountSuspended() for components that need Nuxt context"
|
|
51
|
+
- "Use registerEndpoint() to mock server routes in tests"
|
|
52
|
+
- "Test pages with renderSuspended() from @nuxt/test-utils"
|
|
53
|
+
|
|
54
|
+
trace_tags:
|
|
55
|
+
implements: "// @trace.implements={UC-ID}-SC{N}"
|
|
56
|
+
source: "// @trace.source=specs/bdd/{domain}/{UC-ID}.feature"
|
|
57
|
+
verifies: "// @trace.verifies={UC-ID}"
|
|
58
|
+
test_type: "// @trace.test_type=unit|integration"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
name: "React Native"
|
|
2
|
+
version: "1.0.0"
|
|
3
|
+
description: "Cross-platform mobile (iOS + Android) with React Native / Expo"
|
|
4
|
+
language: "TypeScript"
|
|
5
|
+
framework: "React Native"
|
|
6
|
+
stack_type: "mobile"
|
|
7
|
+
default_layer_order:
|
|
8
|
+
- Types / interfaces
|
|
9
|
+
- API client (React Query hooks)
|
|
10
|
+
- State store (Zustand)
|
|
11
|
+
- Custom hooks (business logic)
|
|
12
|
+
- UI components (presentational)
|
|
13
|
+
- Screen / feature components (container)
|
|
14
|
+
test_framework: "Jest + React Native Testing Library"
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
build:
|
|
2
|
+
compile: "npx expo export / npx react-native build-android"
|
|
3
|
+
test: "jest"
|
|
4
|
+
run: "npx expo start / npx react-native run-ios"
|
|
5
|
+
lint: "eslint . && tsc --noEmit"
|
|
6
|
+
|
|
7
|
+
architecture:
|
|
8
|
+
style: "Feature-based (screens → hooks → queries → store)"
|
|
9
|
+
key_rules:
|
|
10
|
+
- "Business logic lives in custom hooks, not in screen components"
|
|
11
|
+
- "Server state managed by React Query (TanStack Query)"
|
|
12
|
+
- "Navigation state managed by React Navigation"
|
|
13
|
+
- "Native modules wrapped in a service layer — never called directly in components"
|
|
14
|
+
- "Shared UI primitives in src/components/ui/, feature screens in src/features/{name}/"
|
|
15
|
+
folder_structure: |
|
|
16
|
+
src/
|
|
17
|
+
├── api/ ← axios instance, interceptors
|
|
18
|
+
├── components/
|
|
19
|
+
│ └── ui/ ← reusable primitives (AppButton, AppInput...)
|
|
20
|
+
├── features/
|
|
21
|
+
│ └── {domain}/
|
|
22
|
+
│ ├── components/
|
|
23
|
+
│ ├── hooks/
|
|
24
|
+
│ ├── queries/
|
|
25
|
+
│ └── screens/
|
|
26
|
+
├── navigation/ ← React Navigation stacks/tabs
|
|
27
|
+
├── store/ ← Zustand slices
|
|
28
|
+
└── lib/ ← utils, formatters, constants
|
|
29
|
+
|
|
30
|
+
coding_standards:
|
|
31
|
+
naming:
|
|
32
|
+
components: "PascalCase (e.g., OrderListScreen, CreateOrderForm)"
|
|
33
|
+
hooks: "camelCase with 'use' prefix (e.g., useOrderList)"
|
|
34
|
+
screens: "PascalCase + Screen suffix (e.g., OrderDetailScreen)"
|
|
35
|
+
files:
|
|
36
|
+
screen: "{Feature}Screen.tsx"
|
|
37
|
+
component: "{Feature}.tsx"
|
|
38
|
+
hook: "use{Feature}.ts"
|
|
39
|
+
patterns:
|
|
40
|
+
state_management: "Zustand + React Query"
|
|
41
|
+
navigation: "React Navigation v6 (Stack + Tab + Drawer)"
|
|
42
|
+
networking: "Axios"
|
|
43
|
+
forms: "React Hook Form + Zod"
|
|
44
|
+
storage: "MMKV or AsyncStorage"
|
|
45
|
+
|
|
46
|
+
testing:
|
|
47
|
+
unit: "Jest + React Native Testing Library"
|
|
48
|
+
e2e: "Detox or Maestro"
|
|
49
|
+
patterns:
|
|
50
|
+
- "Test by accessibility label or testID — never by style/className"
|
|
51
|
+
- "Mock native modules in jest setup"
|
|
52
|
+
- "Use renderWithProviders() with NavigationContainer + QueryClient"
|
|
53
|
+
|
|
54
|
+
trace_tags:
|
|
55
|
+
implements: "// @trace.implements={UC-ID}-SC{N}"
|
|
56
|
+
source: "// @trace.source=specs/bdd/{domain}/{UC-ID}.feature"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
name: "Vue"
|
|
2
|
+
version: "1.0.0"
|
|
3
|
+
description: "Vue 3 SPA with Composition API, Pinia, and Vue Query"
|
|
4
|
+
language: "TypeScript"
|
|
5
|
+
framework: "Vue 3"
|
|
6
|
+
stack_type: "frontend"
|
|
7
|
+
default_layer_order:
|
|
8
|
+
- Types / interfaces
|
|
9
|
+
- API client (Vue Query / composables)
|
|
10
|
+
- State store (Pinia)
|
|
11
|
+
- Composables (business logic)
|
|
12
|
+
- UI components (presentational)
|
|
13
|
+
- Page / feature components (container)
|
|
14
|
+
test_framework: "Vitest + Vue Test Utils"
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
build:
|
|
2
|
+
compile: "npm run build"
|
|
3
|
+
test: "npm run test"
|
|
4
|
+
run: "npm run dev"
|
|
5
|
+
lint: "npm run lint"
|
|
6
|
+
|
|
7
|
+
architecture:
|
|
8
|
+
style: "Feature-based (components → composables → queries → store)"
|
|
9
|
+
key_rules:
|
|
10
|
+
- "Business logic lives in composables, not in component setup()"
|
|
11
|
+
- "Server state managed by Vue Query (@tanstack/vue-query)"
|
|
12
|
+
- "Client-only UI state managed by Pinia stores"
|
|
13
|
+
- "Components must be pure — no direct API calls inside <template> or setup()"
|
|
14
|
+
- "Shared UI primitives in components/ui/, feature logic in features/{name}/"
|
|
15
|
+
- "Never fetch data directly in a component — use a composable"
|
|
16
|
+
- "Props defined with defineProps<{}>(), emits with defineEmits<{}>()"
|
|
17
|
+
folder_structure: |
|
|
18
|
+
src/
|
|
19
|
+
├── api/ ← axios instance, interceptors
|
|
20
|
+
├── components/
|
|
21
|
+
│ └── ui/ ← reusable primitives (BaseButton, BaseInput...)
|
|
22
|
+
├── features/
|
|
23
|
+
│ └── {domain}/
|
|
24
|
+
│ ├── components/ ← feature-specific UI
|
|
25
|
+
│ ├── composables/ ← useOrderList, useCreateOrder...
|
|
26
|
+
│ ├── queries/ ← Vue Query definitions
|
|
27
|
+
│ ├── store/ ← Pinia slice (if needed)
|
|
28
|
+
│ └── types.ts
|
|
29
|
+
├── pages/ ← route-level page components (Vue Router)
|
|
30
|
+
├── router/ ← route definitions
|
|
31
|
+
└── lib/ ← utilities, formatters, constants
|
|
32
|
+
|
|
33
|
+
coding_standards:
|
|
34
|
+
naming:
|
|
35
|
+
components: "PascalCase (e.g., OrderList, CreateOrderModal)"
|
|
36
|
+
composables: "camelCase with 'use' prefix (e.g., useOrderList, useCreateOrder)"
|
|
37
|
+
stores: "camelCase + Store suffix (e.g., useCartStore) — defined with defineStore()"
|
|
38
|
+
query_keys: "SCREAMING_SNAKE_CASE string/array (e.g., ['ORDER_LIST', customerId])"
|
|
39
|
+
files:
|
|
40
|
+
component: "{Feature}.vue"
|
|
41
|
+
composable: "use{Feature}.ts"
|
|
42
|
+
query: "{feature}.queries.ts"
|
|
43
|
+
store: "{feature}.store.ts"
|
|
44
|
+
types: "{feature}.types.ts"
|
|
45
|
+
patterns:
|
|
46
|
+
data_fetching: "Vue Query (TanStack Query v5 for Vue)"
|
|
47
|
+
global_state: "Pinia stores"
|
|
48
|
+
forms: "VeeValidate + Zod"
|
|
49
|
+
api_client: "Axios with interceptors for auth + error handling"
|
|
50
|
+
reactivity: "ref() for primitives, reactive() for objects, computed() for derived state"
|
|
51
|
+
|
|
52
|
+
testing:
|
|
53
|
+
unit: "Vitest + Vue Test Utils"
|
|
54
|
+
e2e: "Playwright or Cypress"
|
|
55
|
+
patterns:
|
|
56
|
+
- "Test behavior, not implementation — query by role/label via @testing-library/vue"
|
|
57
|
+
- "Mock Vue Query with VueQueryPlugin wrapper in test setup"
|
|
58
|
+
- "Use MSW (Mock Service Worker) to mock API calls in tests"
|
|
59
|
+
- "mountWithProviders() helper wraps component with Pinia + VueQuery + Router"
|
|
60
|
+
|
|
61
|
+
trace_tags:
|
|
62
|
+
implements: "// @trace.implements={UC-ID}-SC{N}"
|
|
63
|
+
source: "// @trace.source=specs/bdd/{domain}/{UC-ID}.feature"
|
|
64
|
+
verifies: "// @trace.verifies={UC-ID}"
|
|
65
|
+
test_type: "// @trace.test_type=unit|integration"
|
package/package.json
CHANGED
package/skills/code/SKILL.md
CHANGED
|
@@ -190,7 +190,7 @@ If `services` section is present:
|
|
|
190
190
|
|
|
191
191
|
**2. Route to service** — if active domain matches a key in `services`:
|
|
192
192
|
- Override `paths.specs_dir` → `services.{domain}.specs_dir`
|
|
193
|
-
- Override `paths.tech_docs_dir` → `services.{domain}.tech_docs_dir`
|
|
193
|
+
- Override `paths.tech_docs_dir` → `services.{domain}.tech_docs_dir` — **only if `setup.spec_source` is NOT set.** When `spec_source` IS set, the tech-design (API contract) is a cross-team artifact and must live in the shared spec repo (handled in step 4), so leave `tech_docs_dir` for step 4 to route — do NOT pin it per-service here.
|
|
194
194
|
- Store `active_service` = `services.{domain}.path`
|
|
195
195
|
- Store `active_service_module` = `services.{domain}.module`
|
|
196
196
|
- If service has its own `module` → use it as `active_module` (overrides `tech_stack.module`)
|
|
@@ -202,13 +202,14 @@ If `services` section is present:
|
|
|
202
202
|
**4. Spec source auto-override** — if `setup.spec_source` is set AND the corresponding path was not already explicitly set in `paths:`:
|
|
203
203
|
- Override `paths.prd_dir` → `{spec_source}/specs/prd`
|
|
204
204
|
- Override `paths.design_spec_dir` → `{spec_source}/specs/design-spec`
|
|
205
|
+
- Override `paths.tech_docs_dir` → `{spec_source}/specs/tech-docs` — **always when `spec_source` is set** (step 2 no longer pins tech-docs per-service in this case). The tech-design IS the cross-team API contract: BE authors it here, and FE/App read it from the same spec submodule at `/generate-code --phase=integration`. *(Per-service tech-docs only happen when there is no `spec_source` — a pure multi-service BE repo with no shared spec module.)*
|
|
205
206
|
- Override `paths.domain_knowledge_dir` → `{spec_source}/specs/domain-knowledge`
|
|
206
207
|
- Override `paths.business_dictionary` → `{spec_source}/specs/domain-knowledge/business-dictionary.md`
|
|
207
208
|
- Override `paths.core_entities` → `{spec_source}/specs/domain-knowledge/core-entities.md`
|
|
208
209
|
- Override `paths.bug_reports_dir` → `{spec_source}/feedback/bug-reports`
|
|
209
210
|
- Override `paths.bdd_proposals_dir` → `{spec_source}/feedback/bdd-proposals`
|
|
210
211
|
|
|
211
|
-
> **Why under `spec_source`:**
|
|
212
|
+
> **Why under `spec_source`:** PRD, design-spec, domain knowledge, the **API contract (tech-docs)**, and tester feedback are all **cross-team artifacts** — they must live in the **shared spec repo** so every umbrella (FE/App/BE) reads the same source via `/sync`. Tech-docs specifically: BE authors the tech-design (API contract), commits + pushes it into the spec submodule (2-layer commit), and FE/App pull it on their next `/sync` to wire the real API in `/generate-code --phase=integration`. In single-service mode (no `spec_source`), these default under the repo root — still shared, same repo.
|
|
212
213
|
|
|
213
214
|
---
|
|
214
215
|
|
|
@@ -232,7 +233,7 @@ When `active_service` has been resolved to a real path in Step 1.5 (e.g., `user-
|
|
|
232
233
|
| `paths.specs_dir` | `{active_service}/{service paths.specs_dir}` (if set in service config, else keep Step 1.5 override) |
|
|
233
234
|
|
|
234
235
|
**3. Store** `service_root = {active_service}` as the working directory anchor for all downstream commands:
|
|
235
|
-
- Shell commands (`/run-
|
|
236
|
+
- Shell commands (`/dev-run-test`, `/dev-gen-test`) run **from within** `service_root`
|
|
236
237
|
- File write operations (test files, trace TSVs) use paths **relative to** `service_root`
|
|
237
238
|
|
|
238
239
|
**4. If service config not found** — keep umbrella defaults, still set `service_root = {active_service}` (path anchor is always needed even without a config override).
|
|
@@ -325,7 +326,7 @@ active_module = tech_stack.module (e.g. "java-spring", "react", "flutter")
|
|
|
325
326
|
|
|
326
327
|
If `tech_stack.module` is blank or not recognized → set `platform_type = "unknown"` and flag as ⚠️ in the Step 7 recap.
|
|
327
328
|
|
|
328
|
-
These two variables (`active_module`, `platform_type`) are the canonical source for all branching logic in commands that need platform-specific behavior (
|
|
329
|
+
These two variables (`active_module`, `platform_type`) are the canonical source for all branching logic in commands that need platform-specific behavior (dev-gen-test, debug, fix-bug, dev-smoke-test).
|
|
329
330
|
|
|
330
331
|
---
|
|
331
332
|
|
|
@@ -505,13 +506,13 @@ Suggest the logical next command based on workflow phase:
|
|
|
505
506
|
| /review-context (BDD) | `/generate-tech-docs {UC-ID}` if APPROVED; regenerate if NEEDS_FIX |
|
|
506
507
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
507
508
|
| /review-tech-docs | `/generate-code {feature-file}` if APPROVED; fix doc if NEEDS_FIX |
|
|
508
|
-
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/
|
|
509
|
-
| /
|
|
510
|
-
| /run-
|
|
511
|
-
| /run-
|
|
512
|
-
| /review-code | `/smoke-test {UC-ID}` or create PR |
|
|
513
|
-
| /smoke-test | Create PR and link to ticket |
|
|
514
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/
|
|
509
|
+
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/dev-gen-test {UC-ID}` |
|
|
510
|
+
| /dev-gen-test | `/dev-run-test {UC-ID}` |
|
|
511
|
+
| /dev-run-test (passing) | `/review-code {UC-ID}` |
|
|
512
|
+
| /dev-run-test (failing) | `/fix-bug {ticket-id}` or `/debug {error}` |
|
|
513
|
+
| /review-code | `/dev-smoke-test {UC-ID}` or create PR |
|
|
514
|
+
| /dev-smoke-test | Create PR and link to ticket |
|
|
515
|
+
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/dev-gen-test {UC-ID}`; all OK → create PR |
|
|
515
516
|
| /fix-bug | Create PR and link to ticket |
|
|
516
517
|
| /debug | `/fix-bug {ticket-id}` if fix needed |
|
|
517
518
|
| /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
|
|
@@ -623,13 +624,13 @@ Suggest the logical next command based on workflow phase:
|
|
|
623
624
|
| /review-context (BDD) | `/generate-tech-docs {UC-ID}` if APPROVED; regenerate if NEEDS_FIX |
|
|
624
625
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
625
626
|
| /review-tech-docs | `/generate-code {feature-file}` if APPROVED; fix doc if NEEDS_FIX |
|
|
626
|
-
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/
|
|
627
|
-
| /
|
|
628
|
-
| /run-
|
|
629
|
-
| /run-
|
|
630
|
-
| /review-code | `/smoke-test {UC-ID}` or create PR |
|
|
631
|
-
| /smoke-test | Create PR and link to ticket |
|
|
632
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/
|
|
627
|
+
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/dev-gen-test {UC-ID}` |
|
|
628
|
+
| /dev-gen-test | `/dev-run-test {UC-ID}` |
|
|
629
|
+
| /dev-run-test (passing) | `/review-code {UC-ID}` |
|
|
630
|
+
| /dev-run-test (failing) | `/fix-bug {ticket-id}` or `/debug {error}` |
|
|
631
|
+
| /review-code | `/dev-smoke-test {UC-ID}` or create PR |
|
|
632
|
+
| /dev-smoke-test | Create PR and link to ticket |
|
|
633
|
+
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/dev-gen-test {UC-ID}`; all OK → create PR |
|
|
633
634
|
| /fix-bug | Create PR and link to ticket |
|
|
634
635
|
| /debug | `/fix-bug {ticket-id}` if fix needed |
|
|
635
636
|
| /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
|
package/skills/debug/SKILL.md
CHANGED
|
@@ -105,7 +105,7 @@ If `services` section is present:
|
|
|
105
105
|
|
|
106
106
|
**2. Route to service** — if active domain matches a key in `services`:
|
|
107
107
|
- Override `paths.specs_dir` → `services.{domain}.specs_dir`
|
|
108
|
-
- Override `paths.tech_docs_dir` → `services.{domain}.tech_docs_dir`
|
|
108
|
+
- Override `paths.tech_docs_dir` → `services.{domain}.tech_docs_dir` — **only if `setup.spec_source` is NOT set.** When `spec_source` IS set, the tech-design (API contract) is a cross-team artifact and must live in the shared spec repo (handled in step 4), so leave `tech_docs_dir` for step 4 to route — do NOT pin it per-service here.
|
|
109
109
|
- Store `active_service` = `services.{domain}.path`
|
|
110
110
|
- Store `active_service_module` = `services.{domain}.module`
|
|
111
111
|
- If service has its own `module` → use it as `active_module` (overrides `tech_stack.module`)
|
|
@@ -117,13 +117,14 @@ If `services` section is present:
|
|
|
117
117
|
**4. Spec source auto-override** — if `setup.spec_source` is set AND the corresponding path was not already explicitly set in `paths:`:
|
|
118
118
|
- Override `paths.prd_dir` → `{spec_source}/specs/prd`
|
|
119
119
|
- Override `paths.design_spec_dir` → `{spec_source}/specs/design-spec`
|
|
120
|
+
- Override `paths.tech_docs_dir` → `{spec_source}/specs/tech-docs` — **always when `spec_source` is set** (step 2 no longer pins tech-docs per-service in this case). The tech-design IS the cross-team API contract: BE authors it here, and FE/App read it from the same spec submodule at `/generate-code --phase=integration`. *(Per-service tech-docs only happen when there is no `spec_source` — a pure multi-service BE repo with no shared spec module.)*
|
|
120
121
|
- Override `paths.domain_knowledge_dir` → `{spec_source}/specs/domain-knowledge`
|
|
121
122
|
- Override `paths.business_dictionary` → `{spec_source}/specs/domain-knowledge/business-dictionary.md`
|
|
122
123
|
- Override `paths.core_entities` → `{spec_source}/specs/domain-knowledge/core-entities.md`
|
|
123
124
|
- Override `paths.bug_reports_dir` → `{spec_source}/feedback/bug-reports`
|
|
124
125
|
- Override `paths.bdd_proposals_dir` → `{spec_source}/feedback/bdd-proposals`
|
|
125
126
|
|
|
126
|
-
> **Why under `spec_source`:**
|
|
127
|
+
> **Why under `spec_source`:** PRD, design-spec, domain knowledge, the **API contract (tech-docs)**, and tester feedback are all **cross-team artifacts** — they must live in the **shared spec repo** so every umbrella (FE/App/BE) reads the same source via `/sync`. Tech-docs specifically: BE authors the tech-design (API contract), commits + pushes it into the spec submodule (2-layer commit), and FE/App pull it on their next `/sync` to wire the real API in `/generate-code --phase=integration`. In single-service mode (no `spec_source`), these default under the repo root — still shared, same repo.
|
|
127
128
|
|
|
128
129
|
---
|
|
129
130
|
|
|
@@ -147,7 +148,7 @@ When `active_service` has been resolved to a real path in Step 1.5 (e.g., `user-
|
|
|
147
148
|
| `paths.specs_dir` | `{active_service}/{service paths.specs_dir}` (if set in service config, else keep Step 1.5 override) |
|
|
148
149
|
|
|
149
150
|
**3. Store** `service_root = {active_service}` as the working directory anchor for all downstream commands:
|
|
150
|
-
- Shell commands (`/run-
|
|
151
|
+
- Shell commands (`/dev-run-test`, `/dev-gen-test`) run **from within** `service_root`
|
|
151
152
|
- File write operations (test files, trace TSVs) use paths **relative to** `service_root`
|
|
152
153
|
|
|
153
154
|
**4. If service config not found** — keep umbrella defaults, still set `service_root = {active_service}` (path anchor is always needed even without a config override).
|
|
@@ -240,7 +241,7 @@ active_module = tech_stack.module (e.g. "java-spring", "react", "flutter")
|
|
|
240
241
|
|
|
241
242
|
If `tech_stack.module` is blank or not recognized → set `platform_type = "unknown"` and flag as ⚠️ in the Step 7 recap.
|
|
242
243
|
|
|
243
|
-
These two variables (`active_module`, `platform_type`) are the canonical source for all branching logic in commands that need platform-specific behavior (
|
|
244
|
+
These two variables (`active_module`, `platform_type`) are the canonical source for all branching logic in commands that need platform-specific behavior (dev-gen-test, debug, fix-bug, dev-smoke-test).
|
|
244
245
|
|
|
245
246
|
---
|
|
246
247
|
|
|
@@ -443,13 +444,13 @@ Suggest the logical next command based on workflow phase:
|
|
|
443
444
|
| /review-context (BDD) | `/generate-tech-docs {UC-ID}` if APPROVED; regenerate if NEEDS_FIX |
|
|
444
445
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
445
446
|
| /review-tech-docs | `/generate-code {feature-file}` if APPROVED; fix doc if NEEDS_FIX |
|
|
446
|
-
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/
|
|
447
|
-
| /
|
|
448
|
-
| /run-
|
|
449
|
-
| /run-
|
|
450
|
-
| /review-code | `/smoke-test {UC-ID}` or create PR |
|
|
451
|
-
| /smoke-test | Create PR and link to ticket |
|
|
452
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/
|
|
447
|
+
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/dev-gen-test {UC-ID}` |
|
|
448
|
+
| /dev-gen-test | `/dev-run-test {UC-ID}` |
|
|
449
|
+
| /dev-run-test (passing) | `/review-code {UC-ID}` |
|
|
450
|
+
| /dev-run-test (failing) | `/fix-bug {ticket-id}` or `/debug {error}` |
|
|
451
|
+
| /review-code | `/dev-smoke-test {UC-ID}` or create PR |
|
|
452
|
+
| /dev-smoke-test | Create PR and link to ticket |
|
|
453
|
+
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/dev-gen-test {UC-ID}`; all OK → create PR |
|
|
453
454
|
| /fix-bug | Create PR and link to ticket |
|
|
454
455
|
| /debug | `/fix-bug {ticket-id}` if fix needed |
|
|
455
456
|
| /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
|
|
@@ -587,13 +588,13 @@ Suggest the logical next command based on workflow phase:
|
|
|
587
588
|
| /review-context (BDD) | `/generate-tech-docs {UC-ID}` if APPROVED; regenerate if NEEDS_FIX |
|
|
588
589
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
589
590
|
| /review-tech-docs | `/generate-code {feature-file}` if APPROVED; fix doc if NEEDS_FIX |
|
|
590
|
-
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/
|
|
591
|
-
| /
|
|
592
|
-
| /run-
|
|
593
|
-
| /run-
|
|
594
|
-
| /review-code | `/smoke-test {UC-ID}` or create PR |
|
|
595
|
-
| /smoke-test | Create PR and link to ticket |
|
|
596
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/
|
|
591
|
+
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/dev-gen-test {UC-ID}` |
|
|
592
|
+
| /dev-gen-test | `/dev-run-test {UC-ID}` |
|
|
593
|
+
| /dev-run-test (passing) | `/review-code {UC-ID}` |
|
|
594
|
+
| /dev-run-test (failing) | `/fix-bug {ticket-id}` or `/debug {error}` |
|
|
595
|
+
| /review-code | `/dev-smoke-test {UC-ID}` or create PR |
|
|
596
|
+
| /dev-smoke-test | Create PR and link to ticket |
|
|
597
|
+
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/dev-gen-test {UC-ID}`; all OK → create PR |
|
|
597
598
|
| /fix-bug | Create PR and link to ticket |
|
|
598
599
|
| /debug | `/fix-bug {ticket-id}` if fix needed |
|
|
599
600
|
| /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
|
|
@@ -646,7 +647,7 @@ Gaps:
|
|
|
646
647
|
|
|
647
648
|
Recommendations:
|
|
648
649
|
- /generate-code {UC-ID} SC2
|
|
649
|
-
- /
|
|
650
|
+
- /dev-gen-test {UC-ID}
|
|
650
651
|
- Re-run /generate-code {UC-ID} for drifted scenarios
|
|
651
652
|
```
|
|
652
653
|
|
|
@@ -688,13 +689,13 @@ Suggest the logical next command based on workflow phase:
|
|
|
688
689
|
| /review-context (BDD) | `/generate-tech-docs {UC-ID}` if APPROVED; regenerate if NEEDS_FIX |
|
|
689
690
|
| /generate-tech-docs | `/review-tech-docs {tech-design-file}` |
|
|
690
691
|
| /review-tech-docs | `/generate-code {feature-file}` if APPROVED; fix doc if NEEDS_FIX |
|
|
691
|
-
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/
|
|
692
|
-
| /
|
|
693
|
-
| /run-
|
|
694
|
-
| /run-
|
|
695
|
-
| /review-code | `/smoke-test {UC-ID}` or create PR |
|
|
696
|
-
| /smoke-test | Create PR and link to ticket |
|
|
697
|
-
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/
|
|
692
|
+
| /generate-code | First gen → `/review-code {UC-ID}`; re-gen → `/dev-gen-test {UC-ID}` |
|
|
693
|
+
| /dev-gen-test | `/dev-run-test {UC-ID}` |
|
|
694
|
+
| /dev-run-test (passing) | `/review-code {UC-ID}` |
|
|
695
|
+
| /dev-run-test (failing) | `/fix-bug {ticket-id}` or `/debug {error}` |
|
|
696
|
+
| /review-code | `/dev-smoke-test {UC-ID}` or create PR |
|
|
697
|
+
| /dev-smoke-test | Create PR and link to ticket |
|
|
698
|
+
| /validate-traces | DRIFT/UNTRACKED → `/generate-code {UC-ID}`; GAP → `/dev-gen-test {UC-ID}`; all OK → create PR |
|
|
698
699
|
| /fix-bug | Create PR and link to ticket |
|
|
699
700
|
| /debug | `/fix-bug {ticket-id}` if fix needed |
|
|
700
701
|
| /report-bug | Send to dev (`/fix-bug {BUG-ID}`); if coverage gap → `/propose-scenario {UC-ID}` |
|