specweave 2.2.1 → 2.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CLAUDE.md +21 -36
  3. package/dist/src/cli/dispatcher.d.ts +1 -1
  4. package/dist/src/cli/dispatcher.js +1 -1
  5. package/dist/src/cli/helpers/init/instruction-file-merger.js +2 -2
  6. package/dist/src/cli/helpers/init/instruction-file-merger.js.map +1 -1
  7. package/dist/src/core/auto/completion-evaluator.d.ts +1 -1
  8. package/dist/src/core/auto/completion-evaluator.js +1 -1
  9. package/dist/src/core/fabric/security-judge.d.ts.map +1 -1
  10. package/dist/src/core/fabric/security-judge.js +37 -5
  11. package/dist/src/core/fabric/security-judge.js.map +1 -1
  12. package/dist/src/core/jev/browse.d.ts +2 -2
  13. package/dist/src/core/jev/browse.d.ts.map +1 -1
  14. package/dist/src/core/jev/browse.js +57 -11
  15. package/dist/src/core/jev/browse.js.map +1 -1
  16. package/dist/src/core/jev/client.d.ts.map +1 -1
  17. package/dist/src/core/jev/client.js +49 -20
  18. package/dist/src/core/jev/client.js.map +1 -1
  19. package/dist/src/core/jev/decide.d.ts.map +1 -1
  20. package/dist/src/core/jev/decide.js +12 -7
  21. package/dist/src/core/jev/decide.js.map +1 -1
  22. package/dist/src/core/llm/index.d.ts +1 -1
  23. package/dist/src/core/llm/index.js +1 -1
  24. package/dist/src/core/llm/model-capabilities.d.ts +79 -0
  25. package/dist/src/core/llm/model-capabilities.d.ts.map +1 -0
  26. package/dist/src/core/llm/model-capabilities.js +157 -0
  27. package/dist/src/core/llm/model-capabilities.js.map +1 -0
  28. package/dist/src/core/llm/provider-factory.js +1 -1
  29. package/dist/src/core/llm/providers/anthropic-provider.d.ts +1 -0
  30. package/dist/src/core/llm/providers/anthropic-provider.d.ts.map +1 -1
  31. package/dist/src/core/llm/providers/anthropic-provider.js +38 -11
  32. package/dist/src/core/llm/providers/anthropic-provider.js.map +1 -1
  33. package/dist/src/core/llm/providers/bedrock-provider.d.ts.map +1 -1
  34. package/dist/src/core/llm/providers/bedrock-provider.js +10 -5
  35. package/dist/src/core/llm/providers/bedrock-provider.js.map +1 -1
  36. package/dist/src/core/llm/providers/claude-code-provider.js +1 -1
  37. package/dist/src/core/llm/types.d.ts +20 -1
  38. package/dist/src/core/llm/types.d.ts.map +1 -1
  39. package/dist/src/core/llm/types.js.map +1 -1
  40. package/dist/src/core/session/handoff-secret-scrub.d.ts.map +1 -1
  41. package/dist/src/core/session/handoff-secret-scrub.js +2 -1
  42. package/dist/src/core/session/handoff-secret-scrub.js.map +1 -1
  43. package/dist/src/core/skill-gen/signal-collector.js +1 -1
  44. package/dist/src/core/skill-gen/signal-collector.js.map +1 -1
  45. package/dist/src/core/skill-gen/suggestion-engine.js +1 -1
  46. package/dist/src/core/skill-gen/suggestion-engine.js.map +1 -1
  47. package/dist/src/core/skill-gen/types.d.ts +1 -1
  48. package/dist/src/core/skill-gen/types.d.ts.map +1 -1
  49. package/dist/src/core/skill-refine/haiku-diff.d.ts +25 -2
  50. package/dist/src/core/skill-refine/haiku-diff.d.ts.map +1 -1
  51. package/dist/src/core/skill-refine/haiku-diff.js +18 -5
  52. package/dist/src/core/skill-refine/haiku-diff.js.map +1 -1
  53. package/dist/src/core/skills/skill-judge.d.ts +16 -17
  54. package/dist/src/core/skills/skill-judge.d.ts.map +1 -1
  55. package/dist/src/core/skills/skill-judge.js +39 -36
  56. package/dist/src/core/skills/skill-judge.js.map +1 -1
  57. package/dist/src/dashboard/server/data/cost-aggregator.d.ts.map +1 -1
  58. package/dist/src/dashboard/server/data/cost-aggregator.js +2 -0
  59. package/dist/src/dashboard/server/data/cost-aggregator.js.map +1 -1
  60. package/dist/src/utils/pricing-constants.d.ts +1 -1
  61. package/dist/src/utils/pricing-constants.d.ts.map +1 -1
  62. package/dist/src/utils/pricing-constants.js +3 -1
  63. package/dist/src/utils/pricing-constants.js.map +1 -1
  64. package/package.json +2 -2
  65. package/plugins/specweave/.claude-plugin/plugin.json +1 -1
  66. package/plugins/specweave/.lint/skill-lint.test.ts +104 -92
  67. package/plugins/specweave/skills/team/agents/_protocol.md +8 -52
  68. package/plugins/specweave/skills/team/agents/backend.md +2 -5
  69. package/plugins/specweave/skills/team/agents/brainstorm-advocate.md +4 -2
  70. package/plugins/specweave/skills/team/agents/brainstorm-critic.md +4 -2
  71. package/plugins/specweave/skills/team/agents/brainstorm-pragmatist.md +4 -2
  72. package/plugins/specweave/skills/team/agents/database.md +0 -2
  73. package/plugins/specweave/skills/team/agents/testing.md +0 -2
  74. package/dist/src/cli/helpers/init/ado-repo-cloning.d.ts +0 -32
  75. package/dist/src/cli/helpers/init/ado-repo-cloning.d.ts.map +0 -1
  76. package/dist/src/cli/helpers/init/ado-repo-cloning.js +0 -157
  77. package/dist/src/cli/helpers/init/ado-repo-cloning.js.map +0 -1
  78. package/dist/src/cli/helpers/init/api-docs-config.d.ts +0 -67
  79. package/dist/src/cli/helpers/init/api-docs-config.d.ts.map +0 -1
  80. package/dist/src/cli/helpers/init/api-docs-config.js +0 -426
  81. package/dist/src/cli/helpers/init/api-docs-config.js.map +0 -1
  82. package/dist/src/cli/helpers/init/bitbucket-repo-cloning.d.ts +0 -42
  83. package/dist/src/cli/helpers/init/bitbucket-repo-cloning.d.ts.map +0 -1
  84. package/dist/src/cli/helpers/init/bitbucket-repo-cloning.js +0 -261
  85. package/dist/src/cli/helpers/init/bitbucket-repo-cloning.js.map +0 -1
  86. package/dist/src/cli/helpers/init/brownfield-analysis.d.ts +0 -45
  87. package/dist/src/cli/helpers/init/brownfield-analysis.d.ts.map +0 -1
  88. package/dist/src/cli/helpers/init/brownfield-analysis.js +0 -431
  89. package/dist/src/cli/helpers/init/brownfield-analysis.js.map +0 -1
  90. package/dist/src/cli/helpers/init/claude-settings-lsp.d.ts +0 -55
  91. package/dist/src/cli/helpers/init/claude-settings-lsp.d.ts.map +0 -1
  92. package/dist/src/cli/helpers/init/claude-settings-lsp.js +0 -270
  93. package/dist/src/cli/helpers/init/claude-settings-lsp.js.map +0 -1
  94. package/dist/src/cli/helpers/init/multi-project-folders.d.ts +0 -15
  95. package/dist/src/cli/helpers/init/multi-project-folders.d.ts.map +0 -1
  96. package/dist/src/cli/helpers/init/multi-project-folders.js +0 -43
  97. package/dist/src/cli/helpers/init/multi-project-folders.js.map +0 -1
  98. package/dist/src/cli/helpers/init/plugin-install-flags.d.ts +0 -114
  99. package/dist/src/cli/helpers/init/plugin-install-flags.d.ts.map +0 -1
  100. package/dist/src/cli/helpers/init/plugin-install-flags.js +0 -202
  101. package/dist/src/cli/helpers/init/plugin-install-flags.js.map +0 -1
  102. package/dist/src/cli/helpers/init/prompt-flow.d.ts +0 -59
  103. package/dist/src/cli/helpers/init/prompt-flow.d.ts.map +0 -1
  104. package/dist/src/cli/helpers/init/prompt-flow.js +0 -127
  105. package/dist/src/cli/helpers/init/prompt-flow.js.map +0 -1
  106. package/dist/src/cli/helpers/init/testing-config.d.ts +0 -69
  107. package/dist/src/cli/helpers/init/testing-config.d.ts.map +0 -1
  108. package/dist/src/cli/helpers/init/testing-config.js +0 -433
  109. package/dist/src/cli/helpers/init/testing-config.js.map +0 -1
  110. package/dist/src/cli/helpers/init/umbrella-cloning.d.ts +0 -39
  111. package/dist/src/cli/helpers/init/umbrella-cloning.d.ts.map +0 -1
  112. package/dist/src/cli/helpers/init/umbrella-cloning.js +0 -121
  113. package/dist/src/cli/helpers/init/umbrella-cloning.js.map +0 -1
  114. package/plugins/specweave/.lint/skill-lint.ts +0 -51
@@ -1,433 +0,0 @@
1
- /**
2
- * Testing configuration prompts
3
- * Handles test mode selection and coverage targets
4
- */
5
- import * as fs from '../../../utils/fs-native.js';
6
- import * as path from 'path';
7
- import chalk from 'chalk';
8
- import { select, input } from '@inquirer/prompts';
9
- import { WIZARD_BACK, createGoBackChoice } from './wizard-navigation.js';
10
- /**
11
- * Get the default coverage target based on the selected test mode.
12
- * TDD mode defaults to 90%, test-after to 80%, manual/none to 0%.
13
- */
14
- export function getCoverageDefault(testMode) {
15
- switch (testMode) {
16
- case 'TDD': return 90;
17
- case 'test-after': return 80;
18
- default: return 0;
19
- }
20
- }
21
- /**
22
- * Get translated strings for testing configuration
23
- */
24
- export function getTestingStrings(language) {
25
- const strings = {
26
- en: {
27
- header: '🧪 Testing Configuration',
28
- subheader: 'Configure your default testing approach and coverage targets',
29
- guidance: '💡 Quick Guide:',
30
- tddHint: '🔴 TDD: Tests first → Better design (critical systems)',
31
- testAfterHint: '🔵 Test-After: Code first → Fast iteration (most projects)',
32
- manualHint: '🟡 Manual: Ad-hoc tests → Flexible (startups, MVPs)',
33
- noneHint: '⚪ None: No tests → Fastest (hackathons, experiments)',
34
- selectApproach: 'Select your testing approach:',
35
- tddOption: '🔴 TDD - Write tests first (Recommended)',
36
- testAfterOption: '🔵 Test-After - Implement first, test later (most projects)',
37
- manualOption: '🟡 Manual - Test when needed, no strict rules (flexible)',
38
- noneOption: '⚪ None - Skip testing entirely (hackathons, experiments)',
39
- selectCoverage: 'Select your coverage target level:',
40
- coverageNone: '0% - No coverage tracking (fastest iteration)',
41
- coverage50: '50% - Minimal (just critical paths)',
42
- coverage70: '70% - Moderate (good for most projects)',
43
- coverage80: '80% - Good (recommended for production)',
44
- coverage90: '90% - High (comprehensive coverage)',
45
- coverage100: '100% - Full coverage (strict)',
46
- coverageCustom: 'Custom (enter your own value 0-100)',
47
- enterCustom: 'Enter custom coverage target (0-100):',
48
- coverageValidation: 'Coverage target must be between 0% and 100%',
49
- selectedTesting: '✔ Testing:',
50
- selectedCoverage: '✔ Coverage Target:',
51
- noCoverageTarget: '✔ Coverage: Not tracked',
52
- configNotFound: '⚠️ config.json not found, cannot update testing configuration',
53
- },
54
- ru: {
55
- header: '🧪 Конфигурация тестирования',
56
- subheader: 'Настройте подход к тестированию по умолчанию и целевые показатели покрытия',
57
- guidance: '💡 Краткое руководство:',
58
- tddHint: '🔴 TDD: Сначала тесты → Лучший дизайн (критичные системы)',
59
- testAfterHint: '🔵 Test-After: Сначала код → Быстрая итерация (большинство проектов)',
60
- manualHint: '🟡 Ручное: Тесты по необходимости → Гибко (стартапы, MVP)',
61
- noneHint: '⚪ Без тестов: Пропустить → Быстро (хакатоны, эксперименты)',
62
- selectApproach: 'Выберите подход к тестированию:',
63
- tddOption: '🔴 TDD - Сначала тесты (Рекомендуется)',
64
- testAfterOption: '🔵 Test-After - Сначала код, потом тесты (большинство проектов)',
65
- manualOption: '🟡 Ручное - Тесты по необходимости, без строгих правил (гибко)',
66
- noneOption: '⚪ Без тестов - Пропустить тестирование (хакатоны, эксперименты)',
67
- selectCoverage: 'Выберите целевой уровень покрытия:',
68
- coverageNone: '0% - Без отслеживания покрытия (быстрая итерация)',
69
- coverage50: '50% - Минимум (только критичные пути)',
70
- coverage70: '70% - Умеренно (подходит для большинства проектов)',
71
- coverage80: '80% - Хорошо (рекомендуется для production)',
72
- coverage90: '90% - Высокое (полное покрытие)',
73
- coverage100: '100% - Полное покрытие (строгое)',
74
- coverageCustom: 'Свое значение (введите 0-100)',
75
- enterCustom: 'Введите целевое покрытие (0-100):',
76
- coverageValidation: 'Целевое покрытие должно быть между 0% и 100%',
77
- selectedTesting: '✔ Тестирование:',
78
- selectedCoverage: '✔ Целевое покрытие:',
79
- noCoverageTarget: '✔ Покрытие: Не отслеживается',
80
- configNotFound: '⚠️ config.json не найден, невозможно обновить конфигурацию тестирования',
81
- },
82
- es: {
83
- header: '🧪 Configuración de pruebas',
84
- subheader: 'Configure su enfoque de pruebas predeterminado y objetivos de cobertura',
85
- guidance: '💡 Guía rápida:',
86
- tddHint: '🔴 TDD: Pruebas primero → Mejor diseño (sistemas críticos)',
87
- testAfterHint: '🔵 Test-After: Código primero → Iteración rápida (mayoría de proyectos)',
88
- manualHint: '🟡 Manual: Pruebas ad-hoc → Flexible (startups, MVPs)',
89
- noneHint: '⚪ Ninguno: Sin pruebas → Más rápido (hackathons, experimentos)',
90
- selectApproach: 'Seleccione su enfoque de pruebas:',
91
- tddOption: '🔴 TDD - Escribir pruebas primero (Recomendado)',
92
- testAfterOption: '🔵 Test-After - Implementar primero, probar después (mayoría de proyectos)',
93
- manualOption: '🟡 Manual - Probar cuando sea necesario, sin reglas estrictas (flexible)',
94
- noneOption: '⚪ Ninguno - Omitir pruebas completamente (hackathons, experimentos)',
95
- selectCoverage: 'Seleccione su nivel de cobertura objetivo:',
96
- coverageNone: '0% - Sin seguimiento de cobertura (iteración más rápida)',
97
- coverage50: '50% - Mínimo (solo rutas críticas)',
98
- coverage70: '70% - Moderado (bueno para la mayoría de proyectos)',
99
- coverage80: '80% - Bueno (recomendado para producción)',
100
- coverage90: '90% - Alto (cobertura completa)',
101
- coverage100: '100% - Cobertura total (estricto)',
102
- coverageCustom: 'Personalizado (ingrese valor 0-100)',
103
- enterCustom: 'Ingrese cobertura objetivo personalizada (0-100):',
104
- coverageValidation: 'La cobertura objetivo debe estar entre 0% y 100%',
105
- selectedTesting: '✔ Pruebas:',
106
- selectedCoverage: '✔ Cobertura objetivo:',
107
- noCoverageTarget: '✔ Cobertura: No rastreada',
108
- configNotFound: '⚠️ config.json no encontrado, no se puede actualizar la configuración de pruebas',
109
- },
110
- zh: {
111
- header: '🧪 测试配置',
112
- subheader: '配置默认测试方法和覆盖率目标',
113
- guidance: '💡 快速指南:',
114
- tddHint: '🔴 TDD: 先测试 → 更好的设计 (关键系统)',
115
- testAfterHint: '🔵 后置测试: 先代码 → 快速迭代 (大多数项目)',
116
- manualHint: '🟡 手动: 按需测试 → 灵活 (初创企业, MVP)',
117
- noneHint: '⚪ 无测试: 跳过 → 最快 (黑客马拉松, 实验)',
118
- selectApproach: '选择您的测试方法:',
119
- tddOption: '🔴 TDD - 先写测试(推荐)',
120
- testAfterOption: '🔵 后置测试 - 先实现后测试(大多数项目)',
121
- manualOption: '🟡 手动 - 按需测试,无严格规则(灵活)',
122
- noneOption: '⚪ 无测试 - 完全跳过测试(黑客马拉松, 实验)',
123
- selectCoverage: '选择您的覆盖率目标级别:',
124
- coverageNone: '0% - 不跟踪覆盖率(最快迭代)',
125
- coverage50: '50% - 最低限度(仅关键路径)',
126
- coverage70: '70% - 中等(适合大多数项目)',
127
- coverage80: '80% - 良好(推荐用于生产)',
128
- coverage90: '90% - 高(全面覆盖)',
129
- coverage100: '100% - 完全覆盖(严格)',
130
- coverageCustom: '自定义(输入0-100)',
131
- enterCustom: '输入自定义覆盖率目标(0-100):',
132
- coverageValidation: '覆盖率目标必须在0%到100%之间',
133
- selectedTesting: '✔ 测试:',
134
- selectedCoverage: '✔ 覆盖率目标:',
135
- noCoverageTarget: '✔ 覆盖率:不跟踪',
136
- configNotFound: '⚠️ 未找到config.json,无法更新测试配置',
137
- },
138
- de: {
139
- header: '🧪 Test-Konfiguration',
140
- subheader: 'Konfigurieren Sie Ihren Standard-Testansatz und Abdeckungsziele',
141
- guidance: '💡 Kurzanleitung:',
142
- tddHint: '🔴 TDD: Tests zuerst → Besseres Design (kritische Systeme)',
143
- testAfterHint: '🔵 Test-After: Code zuerst → Schnelle Iteration (meiste Projekte)',
144
- manualHint: '🟡 Manuell: Tests bei Bedarf → Flexibel (Startups, MVPs)',
145
- noneHint: '⚪ Keine: Tests überspringen → Am schnellsten (Hackathons, Experimente)',
146
- selectApproach: 'Wählen Sie Ihren Testansatz:',
147
- tddOption: '🔴 TDD - Zuerst Tests schreiben (Empfohlen)',
148
- testAfterOption: '🔵 Test-After - Erst implementieren, dann testen (meiste Projekte)',
149
- manualOption: '🟡 Manuell - Testen bei Bedarf, keine strengen Regeln (flexibel)',
150
- noneOption: '⚪ Keine - Tests komplett überspringen (Hackathons, Experimente)',
151
- selectCoverage: 'Wählen Sie Ihr Abdeckungsziel:',
152
- coverageNone: '0% - Keine Abdeckungsverfolgung (schnellste Iteration)',
153
- coverage50: '50% - Minimal (nur kritische Pfade)',
154
- coverage70: '70% - Moderat (gut für die meisten Projekte)',
155
- coverage80: '80% - Gut (empfohlen für Produktion)',
156
- coverage90: '90% - Hoch (umfassende Abdeckung)',
157
- coverage100: '100% - Volle Abdeckung (streng)',
158
- coverageCustom: 'Benutzerdefiniert (Wert 0-100 eingeben)',
159
- enterCustom: 'Geben Sie ein benutzerdefiniertes Abdeckungsziel ein (0-100):',
160
- coverageValidation: 'Abdeckungsziel muss zwischen 0% und 100% liegen',
161
- selectedTesting: '✔ Testen:',
162
- selectedCoverage: '✔ Abdeckungsziel:',
163
- noCoverageTarget: '✔ Abdeckung: Nicht verfolgt',
164
- configNotFound: '⚠️ config.json nicht gefunden, kann Testkonfiguration nicht aktualisieren',
165
- },
166
- fr: {
167
- header: '🧪 Configuration des tests',
168
- subheader: 'Configurez votre approche de test par défaut et vos objectifs de couverture',
169
- guidance: '💡 Guide rapide:',
170
- tddHint: '🔴 TDD: Tests d\'abord → Meilleur design (systèmes critiques)',
171
- testAfterHint: '🔵 Test-After: Code d\'abord → Itération rapide (plupart des projets)',
172
- manualHint: '🟡 Manuel: Tests ad-hoc → Flexible (startups, MVPs)',
173
- noneHint: '⚪ Aucun: Pas de tests → Plus rapide (hackathons, expériences)',
174
- selectApproach: 'Sélectionnez votre approche de test :',
175
- tddOption: '🔴 TDD - Écrire les tests en premier (Recommandé)',
176
- testAfterOption: '🔵 Test-After - Implémenter d\'abord, tester ensuite (plupart des projets)',
177
- manualOption: '🟡 Manuel - Tester quand nécessaire, pas de règles strictes (flexible)',
178
- noneOption: '⚪ Aucun - Ignorer les tests complètement (hackathons, expériences)',
179
- selectCoverage: 'Sélectionnez votre niveau de couverture cible :',
180
- coverageNone: '0% - Pas de suivi de couverture (itération la plus rapide)',
181
- coverage50: '50% - Minimal (seulement les chemins critiques)',
182
- coverage70: '70% - Modéré (bon pour la plupart des projets)',
183
- coverage80: '80% - Bon (recommandé pour la production)',
184
- coverage90: '90% - Élevé (couverture complète)',
185
- coverage100: '100% - Couverture totale (strict)',
186
- coverageCustom: 'Personnalisé (entrez une valeur 0-100)',
187
- enterCustom: 'Entrez une couverture cible personnalisée (0-100) :',
188
- coverageValidation: 'La couverture cible doit être entre 0% et 100%',
189
- selectedTesting: '✔ Tests :',
190
- selectedCoverage: '✔ Couverture cible :',
191
- noCoverageTarget: '✔ Couverture : Non suivie',
192
- configNotFound: '⚠️ config.json non trouvé, impossible de mettre à jour la configuration des tests',
193
- },
194
- ja: {
195
- header: '🧪 テスト設定',
196
- subheader: 'デフォルトのテストアプローチとカバレッジ目標を設定します',
197
- guidance: '💡 クイックガイド:',
198
- tddHint: '🔴 TDD: テスト先行 → 良い設計 (クリティカルシステム)',
199
- testAfterHint: '🔵 後付け: コード先行 → 高速反復 (ほとんどのプロジェクト)',
200
- manualHint: '🟡 手動: 必要時テスト → 柔軟 (スタートアップ, MVP)',
201
- noneHint: '⚪ なし: テストスキップ → 最速 (ハッカソン, 実験)',
202
- selectApproach: 'テストアプローチを選択してください:',
203
- tddOption: '🔴 TDD - テストを先に書く(推奨)',
204
- testAfterOption: '🔵 テスト後付け - 先に実装、後でテスト(ほとんどのプロジェクト)',
205
- manualOption: '🟡 手動 - 必要時にテスト、厳格なルールなし(柔軟)',
206
- noneOption: '⚪ なし - テストを完全にスキップ(ハッカソン, 実験)',
207
- selectCoverage: 'カバレッジ目標レベルを選択してください:',
208
- coverageNone: '0% - カバレッジ追跡なし(最速反復)',
209
- coverage50: '50% - 最小限(クリティカルパスのみ)',
210
- coverage70: '70% - 中程度(ほとんどのプロジェクトに適切)',
211
- coverage80: '80% - 良好(本番に推奨)',
212
- coverage90: '90% - 高い(包括的カバレッジ)',
213
- coverage100: '100% - 完全カバレッジ(厳格)',
214
- coverageCustom: 'カスタム(0-100の値を入力)',
215
- enterCustom: 'カスタムカバレッジ目標を入力(0-100):',
216
- coverageValidation: 'カバレッジ目標は0%から100%の間でなければなりません',
217
- selectedTesting: '✔ テスト:',
218
- selectedCoverage: '✔ カバレッジ目標:',
219
- noCoverageTarget: '✔ カバレッジ:追跡なし',
220
- configNotFound: '⚠️ config.jsonが見つかりません。テスト設定を更新できません',
221
- },
222
- ko: {
223
- header: '🧪 테스트 구성',
224
- subheader: '기본 테스트 접근 방식과 커버리지 목표를 구성합니다',
225
- guidance: '💡 빠른 가이드:',
226
- tddHint: '🔴 TDD: 테스트 먼저 → 더 나은 설계 (핵심 시스템)',
227
- testAfterHint: '🔵 후행: 코드 먼저 → 빠른 반복 (대부분 프로젝트)',
228
- manualHint: '🟡 수동: 필요시 테스트 → 유연 (스타트업, MVP)',
229
- noneHint: '⚪ 없음: 테스트 건너뛰기 → 가장 빠름 (해커톤, 실험)',
230
- selectApproach: '테스트 접근 방식을 선택하세요:',
231
- tddOption: '🔴 TDD - 테스트 먼저 작성 (권장)',
232
- testAfterOption: '🔵 테스트 후행 - 먼저 구현, 나중에 테스트 (대부분 프로젝트)',
233
- manualOption: '🟡 수동 - 필요시 테스트, 엄격한 규칙 없음 (유연)',
234
- noneOption: '⚪ 없음 - 테스트 완전히 건너뛰기 (해커톤, 실험)',
235
- selectCoverage: '커버리지 목표 수준을 선택하세요:',
236
- coverageNone: '0% - 커버리지 추적 없음 (가장 빠른 반복)',
237
- coverage50: '50% - 최소 (핵심 경로만)',
238
- coverage70: '70% - 중간 (대부분 프로젝트에 적합)',
239
- coverage80: '80% - 좋음 (프로덕션에 권장)',
240
- coverage90: '90% - 높음 (포괄적 커버리지)',
241
- coverage100: '100% - 완전 커버리지 (엄격)',
242
- coverageCustom: '사용자 지정 (0-100 값 입력)',
243
- enterCustom: '사용자 지정 커버리지 목표 입력 (0-100):',
244
- coverageValidation: '커버리지 목표는 0%에서 100% 사이여야 합니다',
245
- selectedTesting: '✔ 테스트:',
246
- selectedCoverage: '✔ 커버리지 목표:',
247
- noCoverageTarget: '✔ 커버리지: 추적 안 함',
248
- configNotFound: '⚠️ config.json을 찾을 수 없어 테스트 구성을 업데이트할 수 없습니다',
249
- },
250
- pt: {
251
- header: '🧪 Configuração de Testes',
252
- subheader: 'Configure sua abordagem de teste padrão e metas de cobertura',
253
- guidance: '💡 Guia rápido:',
254
- tddHint: '🔴 TDD: Testes primeiro → Melhor design (sistemas críticos)',
255
- testAfterHint: '🔵 Test-After: Código primeiro → Iteração rápida (maioria dos projetos)',
256
- manualHint: '🟡 Manual: Testes ad-hoc → Flexível (startups, MVPs)',
257
- noneHint: '⚪ Nenhum: Sem testes → Mais rápido (hackathons, experimentos)',
258
- selectApproach: 'Selecione sua abordagem de teste:',
259
- tddOption: '🔴 TDD - Escrever testes primeiro (Recomendado)',
260
- testAfterOption: '🔵 Test-After - Implementar primeiro, testar depois (maioria dos projetos)',
261
- manualOption: '🟡 Manual - Testar quando necessário, sem regras rígidas (flexível)',
262
- noneOption: '⚪ Nenhum - Pular testes completamente (hackathons, experimentos)',
263
- selectCoverage: 'Selecione seu nível de cobertura alvo:',
264
- coverageNone: '0% - Sem rastreamento de cobertura (iteração mais rápida)',
265
- coverage50: '50% - Mínimo (apenas caminhos críticos)',
266
- coverage70: '70% - Moderado (bom para maioria dos projetos)',
267
- coverage80: '80% - Bom (recomendado para produção)',
268
- coverage90: '90% - Alto (cobertura abrangente)',
269
- coverage100: '100% - Cobertura total (estrito)',
270
- coverageCustom: 'Personalizado (digite valor 0-100)',
271
- enterCustom: 'Digite a cobertura alvo personalizada (0-100):',
272
- coverageValidation: 'A cobertura alvo deve estar entre 0% e 100%',
273
- selectedTesting: '✔ Testes:',
274
- selectedCoverage: '✔ Cobertura Alvo:',
275
- noCoverageTarget: '✔ Cobertura: Não rastreada',
276
- configNotFound: '⚠️ config.json não encontrado, não é possível atualizar a configuração de testes',
277
- },
278
- };
279
- return strings[language] || strings.en;
280
- }
281
- /**
282
- * Prompt user for testing configuration
283
- *
284
- * @param language - Language for translations
285
- * @returns Testing configuration
286
- */
287
- export async function promptTestingConfig(language = 'en') {
288
- const strings = getTestingStrings(language);
289
- console.log('');
290
- console.log(chalk.cyan.bold(strings.header));
291
- console.log(chalk.gray(' ' + strings.subheader));
292
- console.log('');
293
- // Quick guide on testing approaches
294
- console.log(chalk.white(strings.guidance));
295
- console.log(chalk.gray(' ' + strings.tddHint));
296
- console.log(chalk.gray(' ' + strings.testAfterHint));
297
- console.log(chalk.gray(' ' + strings.manualHint));
298
- console.log(chalk.gray(' ' + strings.noneHint));
299
- console.log('');
300
- const testModeChoice = await select({
301
- message: strings.selectApproach,
302
- choices: [
303
- {
304
- name: strings.tddOption,
305
- value: 'TDD',
306
- },
307
- {
308
- name: strings.testAfterOption,
309
- value: 'test-after',
310
- },
311
- {
312
- name: strings.manualOption,
313
- value: 'manual',
314
- },
315
- {
316
- name: strings.noneOption,
317
- value: 'none',
318
- },
319
- createGoBackChoice(language),
320
- ],
321
- default: 'TDD'
322
- });
323
- // Handle go back
324
- if (testModeChoice === 'back') {
325
- return { testMode: 'TDD', coverageTarget: 80, goBack: WIZARD_BACK };
326
- }
327
- const testMode = testModeChoice;
328
- let coverageTarget = 0;
329
- // Only ask for coverage if not 'none' or 'manual' testing mode
330
- // For 'none' mode: no testing at all, coverage = 0
331
- // For 'manual' mode: ad-hoc testing, no strict coverage target, default to 0
332
- if (testMode !== 'none' && testMode !== 'manual') {
333
- const selectedCoverageLevel = await select({
334
- message: strings.selectCoverage,
335
- choices: [
336
- {
337
- name: strings.coverageNone,
338
- value: 0,
339
- },
340
- {
341
- name: strings.coverage50,
342
- value: 50,
343
- },
344
- {
345
- name: strings.coverage70,
346
- value: 70,
347
- },
348
- {
349
- name: strings.coverage80,
350
- value: 80,
351
- },
352
- {
353
- name: strings.coverage90,
354
- value: 90,
355
- },
356
- {
357
- name: strings.coverage100,
358
- value: 100,
359
- },
360
- {
361
- name: strings.coverageCustom,
362
- value: 'custom',
363
- }
364
- ],
365
- default: getCoverageDefault(testMode)
366
- });
367
- if (selectedCoverageLevel === 'custom') {
368
- const customInput = await input({
369
- message: strings.enterCustom,
370
- default: '50',
371
- validate: (val) => {
372
- const num = parseInt(val, 10);
373
- if (isNaN(num) || num < 0 || num > 100) {
374
- return strings.coverageValidation;
375
- }
376
- return true;
377
- }
378
- });
379
- coverageTarget = parseInt(customInput, 10);
380
- }
381
- else {
382
- coverageTarget = selectedCoverageLevel;
383
- }
384
- }
385
- console.log('');
386
- console.log(chalk.green(` ${strings.selectedTesting} ${testMode}`));
387
- if (testMode !== 'none' && testMode !== 'manual') {
388
- if (coverageTarget > 0) {
389
- console.log(chalk.green(` ${strings.selectedCoverage} ${coverageTarget}%`));
390
- }
391
- else {
392
- console.log(chalk.green(` ${strings.noCoverageTarget}`));
393
- }
394
- }
395
- console.log('');
396
- return { testMode, coverageTarget };
397
- }
398
- /**
399
- * Update config.json with testing configuration
400
- *
401
- * @param targetDir - Project directory
402
- * @param testMode - Selected test mode
403
- * @param coverageTarget - Selected coverage target
404
- * @param language - Language for translations
405
- */
406
- export function updateConfigWithTesting(targetDir, testMode, coverageTarget, language = 'en') {
407
- const strings = getTestingStrings(language);
408
- const configPath = path.join(targetDir, '.specweave', 'config.json');
409
- if (!fs.existsSync(configPath)) {
410
- console.error(chalk.red(strings.configNotFound));
411
- return;
412
- }
413
- const config = fs.readJsonSync(configPath);
414
- // If coverage is 0 or mode is 'none'/'manual', don't track coverage at all
415
- const trackCoverage = coverageTarget > 0 && testMode !== 'none';
416
- config.testing = {
417
- mode: testMode,
418
- commands: Array.isArray(config.testing?.commands) ? config.testing.commands : [],
419
- coverage: trackCoverage
420
- ? {
421
- unit: Math.min(coverageTarget + 5, 100),
422
- integration: coverageTarget,
423
- e2e: Math.min(coverageTarget + 10, 100)
424
- }
425
- : {
426
- unit: 0,
427
- integration: 0,
428
- e2e: 0
429
- }
430
- };
431
- fs.writeJsonSync(configPath, config, { spaces: 2 });
432
- }
433
- //# sourceMappingURL=testing-config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"testing-config.js","sourceRoot":"","sources":["../../../../../src/cli/helpers/init/testing-config.ts"],"names":[],"mappings":"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"}
@@ -1,39 +0,0 @@
1
- /**
2
- * Umbrella Repository Cloning
3
- *
4
- * Clones a selected umbrella (parent) repository into the current project directory.
5
- * Used when the user picks "Select from GitHub" during init — the umbrella repo
6
- * becomes the git root of the project, with nested repos under repositories/{org}/.
7
- *
8
- * Strategy: clone --no-checkout to temp dir, move .git, checkout.
9
- * This avoids conflicts with files already created by specweave init (.specweave/).
10
- *
11
- * Key note: specweave init runs `git init` before the wizard. If .git exists with NO
12
- * remotes, it was created by our own git init and can be safely replaced by the umbrella
13
- * repo's .git. If .git has remotes, it's a pre-existing repo and we leave it alone.
14
- *
15
- * @module cli/helpers/init/umbrella-cloning
16
- */
17
- export interface UmbrellaCloningResult {
18
- success: boolean;
19
- error?: string;
20
- }
21
- /**
22
- * Clone an umbrella repository into the current project directory.
23
- *
24
- * Handles three scenarios:
25
- * - No .git: fresh directory → clone directly
26
- * - .git with no remotes: from `git init` during specweave init → replace with umbrella's .git
27
- * - .git with remotes: pre-existing real repo → skip (guard)
28
- *
29
- * After cloning, `git checkout .` merges umbrella repo files with any existing
30
- * files (like .specweave/) without overwriting untracked ones.
31
- *
32
- * @param projectPath - Target directory (current working directory during init)
33
- * @param org - GitHub organization or owner
34
- * @param repoName - Repository name
35
- * @param pat - Personal Access Token
36
- * @param gitUrlFormat - 'ssh' or 'https'
37
- */
38
- export declare function cloneUmbrellaIntoCurrentDir(projectPath: string, org: string, repoName: string, pat: string, gitUrlFormat?: 'ssh' | 'https'): Promise<UmbrellaCloningResult>;
39
- //# sourceMappingURL=umbrella-cloning.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"umbrella-cloning.d.ts","sourceRoot":"","sources":["../../../../../src/cli/helpers/init/umbrella-cloning.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AASH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAuBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,2BAA2B,CAC/C,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,YAAY,GAAE,KAAK,GAAG,OAAiB,GACtC,OAAO,CAAC,qBAAqB,CAAC,CAkFhC"}
@@ -1,121 +0,0 @@
1
- /**
2
- * Umbrella Repository Cloning
3
- *
4
- * Clones a selected umbrella (parent) repository into the current project directory.
5
- * Used when the user picks "Select from GitHub" during init — the umbrella repo
6
- * becomes the git root of the project, with nested repos under repositories/{org}/.
7
- *
8
- * Strategy: clone --no-checkout to temp dir, move .git, checkout.
9
- * This avoids conflicts with files already created by specweave init (.specweave/).
10
- *
11
- * Key note: specweave init runs `git init` before the wizard. If .git exists with NO
12
- * remotes, it was created by our own git init and can be safely replaced by the umbrella
13
- * repo's .git. If .git has remotes, it's a pre-existing repo and we leave it alone.
14
- *
15
- * @module cli/helpers/init/umbrella-cloning
16
- */
17
- import path from 'path';
18
- import os from 'os';
19
- import { existsSync } from 'fs';
20
- import { move, remove } from '../../../utils/fs-native.js';
21
- import chalk from 'chalk';
22
- import { execFileNoThrow } from '../../../utils/execFileNoThrow.js';
23
- /**
24
- * Build clone URL for a GitHub repository
25
- */
26
- function buildCloneUrl(owner, repo, pat, gitUrlFormat) {
27
- if (gitUrlFormat === 'ssh') {
28
- return `git@github.com:${owner}/${repo}.git`;
29
- }
30
- return `https://${pat}@github.com/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}.git`;
31
- }
32
- /** Sanitize PAT from any string (replace all occurrences) */
33
- function sanitize(text, pat) {
34
- if (!pat)
35
- return text;
36
- return text.split(pat).join('***');
37
- }
38
- /**
39
- * Clone an umbrella repository into the current project directory.
40
- *
41
- * Handles three scenarios:
42
- * - No .git: fresh directory → clone directly
43
- * - .git with no remotes: from `git init` during specweave init → replace with umbrella's .git
44
- * - .git with remotes: pre-existing real repo → skip (guard)
45
- *
46
- * After cloning, `git checkout .` merges umbrella repo files with any existing
47
- * files (like .specweave/) without overwriting untracked ones.
48
- *
49
- * @param projectPath - Target directory (current working directory during init)
50
- * @param org - GitHub organization or owner
51
- * @param repoName - Repository name
52
- * @param pat - Personal Access Token
53
- * @param gitUrlFormat - 'ssh' or 'https'
54
- */
55
- export async function cloneUmbrellaIntoCurrentDir(projectPath, org, repoName, pat, gitUrlFormat = 'https') {
56
- console.log('');
57
- console.log(chalk.blue.bold(' ┌─────────────────────────────────────────┐'));
58
- console.log(chalk.blue.bold(` │ 📥 Cloning umbrella: ${org}/${repoName}`));
59
- console.log(chalk.blue.bold(' └─────────────────────────────────────────┘'));
60
- console.log('');
61
- const gitDir = path.join(projectPath, '.git');
62
- // Step 0: Handle existing .git directory
63
- if (existsSync(gitDir)) {
64
- const remoteResult = await execFileNoThrow('git', ['remote'], { cwd: projectPath });
65
- const hasRemotes = remoteResult.success && remoteResult.stdout.trim().length > 0;
66
- if (hasRemotes) {
67
- console.log(chalk.yellow(' ⚠ Directory already has a git repo with remotes — skipping umbrella clone.'));
68
- console.log(chalk.gray(` Remotes: ${remoteResult.stdout.trim()}`));
69
- return { success: false, error: 'Directory already contains a git repository with remotes' };
70
- }
71
- console.log(chalk.gray(' Removing fresh git init (no remotes)...'));
72
- await remove(gitDir);
73
- console.log(chalk.gray(' ✓ Old .git removed'));
74
- }
75
- else {
76
- console.log(chalk.gray(' No existing .git — fresh directory'));
77
- }
78
- const cloneUrl = buildCloneUrl(org, repoName, pat, gitUrlFormat);
79
- const tmpDir = path.join(os.tmpdir(), `sw-umbrella-${Date.now()}`);
80
- const urlDisplay = gitUrlFormat === 'ssh' ? cloneUrl : `https://***@github.com/${org}/${repoName}.git`;
81
- console.log(chalk.gray(` URL: ${urlDisplay}`));
82
- console.log(chalk.gray(` Format: ${gitUrlFormat}`));
83
- console.log(chalk.gray(` Target: ${projectPath}`));
84
- try {
85
- // Step 1: Clone to temp dir (no checkout — avoids conflicts with .specweave/)
86
- console.log(chalk.cyan(' [1/3] Cloning to temp directory...'));
87
- const cloneResult = await execFileNoThrow('git', ['clone', '--no-checkout', cloneUrl, tmpDir], { timeout: 120000, maxBuffer: 10 * 1024 * 1024 });
88
- if (!cloneResult.success) {
89
- const cleanError = sanitize(cloneResult.stderr, pat);
90
- console.log(chalk.red(` ✗ Clone failed (exit code ${cloneResult.exitCode})`));
91
- console.log(chalk.red(` ${cleanError}`));
92
- return { success: false, error: `Clone failed: ${cleanError}` };
93
- }
94
- console.log(chalk.green(' ✓ Clone complete'));
95
- // Step 2: Move .git to project root
96
- console.log(chalk.cyan(' [2/3] Moving .git to project root...'));
97
- await move(path.join(tmpDir, '.git'), gitDir);
98
- console.log(chalk.green(' ✓ .git moved'));
99
- // Step 3: Checkout tracked files into current dir
100
- // CRITICAL: Use "checkout HEAD -- ." not "checkout ."
101
- // After --no-checkout clone, the index is empty. "checkout ." restores from the
102
- // index (nothing there), while "checkout HEAD -- ." reads directly from the HEAD
103
- // commit, populating both index and working tree.
104
- console.log(chalk.cyan(' [3/3] Checking out files...'));
105
- const checkoutResult = await execFileNoThrow('git', ['checkout', 'HEAD', '--', '.'], { cwd: projectPath, timeout: 60000 });
106
- if (!checkoutResult.success) {
107
- console.log(chalk.red(` ✗ Checkout failed: ${checkoutResult.stderr}`));
108
- return { success: false, error: `Checkout failed: ${checkoutResult.stderr}` };
109
- }
110
- console.log(chalk.green(' ✓ Files checked out'));
111
- console.log('');
112
- console.log(chalk.green.bold(` ✅ Umbrella repository "${org}/${repoName}" cloned successfully`));
113
- console.log('');
114
- return { success: true };
115
- }
116
- finally {
117
- // Always clean up temp dir
118
- await remove(tmpDir).catch(() => { });
119
- }
120
- }
121
- //# sourceMappingURL=umbrella-cloning.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"umbrella-cloning.js","sourceRoot":"","sources":["../../../../../src/cli/helpers/init/umbrella-cloning.ts"],"names":[],"mappings":"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"}