specweave 0.23.14 ā 0.23.16
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/CLAUDE.md +55 -0
- package/dist/src/core/spec-detector.d.ts +5 -0
- package/dist/src/core/spec-detector.d.ts.map +1 -1
- package/dist/src/core/spec-detector.js +91 -33
- package/dist/src/core/spec-detector.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave-github/.claude-plugin/plugin.json +15 -1
- package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +16 -0
- package/plugins/specweave-github/hooks/post-task-completion.sh +53 -0
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +24 -0
- package/plugins/specweave-alternatives/.claude-plugin/plugin.json +0 -21
- package/plugins/specweave-alternatives/skills/bmad-method-expert/SKILL.md +0 -626
- package/plugins/specweave-alternatives/skills/bmad-method-expert/scripts/analyze-project.js +0 -318
- package/plugins/specweave-alternatives/skills/bmad-method-expert/scripts/check-setup.js +0 -208
- package/plugins/specweave-alternatives/skills/bmad-method-expert/scripts/generate-template.js +0 -1149
- package/plugins/specweave-alternatives/skills/bmad-method-expert/scripts/validate-documents.js +0 -340
- package/plugins/specweave-alternatives/skills/spec-kit-expert/SKILL.md +0 -1010
- package/plugins/specweave-cost-optimizer/.claude-plugin/plugin.json +0 -20
- package/plugins/specweave-cost-optimizer/skills/cost-optimizer/SKILL.md +0 -190
- package/plugins/specweave-docs/.claude-plugin/plugin.json +0 -19
- package/plugins/specweave-docs/skills/docusaurus/SKILL.md +0 -613
- package/plugins/specweave-docs/skills/spec-driven-brainstorming/README.md +0 -264
- package/plugins/specweave-docs/skills/spec-driven-brainstorming/SKILL.md +0 -439
- package/plugins/specweave-docs/skills/spec-driven-debugging/README.md +0 -479
- package/plugins/specweave-docs/skills/spec-driven-debugging/SKILL.md +0 -652
- package/plugins/specweave-figma/.claude-plugin/.mcp.json +0 -12
- package/plugins/specweave-figma/.claude-plugin/plugin.json +0 -20
- package/plugins/specweave-figma/ARCHITECTURE.md +0 -453
- package/plugins/specweave-figma/README.md +0 -728
- package/plugins/specweave-figma/skills/figma-to-code/SKILL.md +0 -632
- package/plugins/specweave-figma/skills/figma-to-code/test-1-token-generation.yaml +0 -29
- package/plugins/specweave-figma/skills/figma-to-code/test-2-component-generation.yaml +0 -27
- package/plugins/specweave-figma/skills/figma-to-code/test-3-typescript-generation.yaml +0 -28
- package/plugins/specweave-frontend/.claude-plugin/plugin.json +0 -21
- package/plugins/specweave-frontend/skills/design-system-architect/SKILL.md +0 -107
- package/plugins/specweave-frontend/skills/frontend/SKILL.md +0 -177
- package/plugins/specweave-frontend/skills/nextjs/SKILL.md +0 -176
- package/plugins/specweave-testing/.claude-plugin/plugin.json +0 -20
- package/plugins/specweave-testing/skills/e2e-playwright/README.md +0 -506
- package/plugins/specweave-testing/skills/e2e-playwright/SKILL.md +0 -457
- package/plugins/specweave-testing/skills/e2e-playwright/execute.js +0 -373
- package/plugins/specweave-testing/skills/e2e-playwright/lib/utils.js +0 -514
- package/plugins/specweave-testing/skills/e2e-playwright/package.json +0 -33
- package/plugins/specweave-tooling/.claude-plugin/plugin.json +0 -19
- package/plugins/specweave-tooling/skills/skill-creator/LICENSE.txt +0 -202
- package/plugins/specweave-tooling/skills/skill-creator/SKILL.md +0 -209
- package/plugins/specweave-tooling/skills/skill-creator/scripts/init_skill.py +0 -303
- package/plugins/specweave-tooling/skills/skill-creator/scripts/package_skill.py +0 -110
- package/plugins/specweave-tooling/skills/skill-creator/scripts/quick_validate.py +0 -65
- package/plugins/specweave-tooling/skills/skill-router/SKILL.md +0 -479
- package/plugins/specweave-ui/.claude-plugin/plugin.json +0 -26
- package/plugins/specweave-ui/.mcp.json +0 -10
- package/plugins/specweave-ui/README.md +0 -492
- package/plugins/specweave-ui/skills/browser-automation/SKILL.md +0 -676
package/plugins/specweave-alternatives/skills/bmad-method-expert/scripts/validate-documents.js
DELETED
|
@@ -1,340 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* BMAD Document Validator
|
|
5
|
-
*
|
|
6
|
-
* Validates alignment between PRD and Architecture documents
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const fs = require('fs');
|
|
10
|
-
const path = require('path');
|
|
11
|
-
|
|
12
|
-
class DocumentValidator {
|
|
13
|
-
constructor(projectPath = process.cwd()) {
|
|
14
|
-
this.projectPath = projectPath;
|
|
15
|
-
this.issues = [];
|
|
16
|
-
this.warnings = [];
|
|
17
|
-
this.successes = [];
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
readDocument(relativePath) {
|
|
21
|
-
try {
|
|
22
|
-
const fullPath = path.join(this.projectPath, relativePath);
|
|
23
|
-
return fs.readFileSync(fullPath, 'utf-8');
|
|
24
|
-
} catch (error) {
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
extractSections(markdown) {
|
|
30
|
-
const sections = [];
|
|
31
|
-
const lines = markdown.split('\n');
|
|
32
|
-
let currentSection = null;
|
|
33
|
-
let currentContent = [];
|
|
34
|
-
|
|
35
|
-
for (const line of lines) {
|
|
36
|
-
const headerMatch = line.match(/^(#+)\s+(.+)$/);
|
|
37
|
-
|
|
38
|
-
if (headerMatch) {
|
|
39
|
-
if (currentSection) {
|
|
40
|
-
sections.push({
|
|
41
|
-
level: currentSection.level,
|
|
42
|
-
title: currentSection.title,
|
|
43
|
-
content: currentContent.join('\n')
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
currentSection = {
|
|
48
|
-
level: headerMatch[1].length,
|
|
49
|
-
title: headerMatch[2].trim()
|
|
50
|
-
};
|
|
51
|
-
currentContent = [];
|
|
52
|
-
} else if (currentSection) {
|
|
53
|
-
currentContent.push(line);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (currentSection) {
|
|
58
|
-
sections.push({
|
|
59
|
-
level: currentSection.level,
|
|
60
|
-
title: currentSection.title,
|
|
61
|
-
content: currentContent.join('\n')
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return sections;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
extractFeatures(content) {
|
|
69
|
-
const features = [];
|
|
70
|
-
const lines = content.split('\n');
|
|
71
|
-
|
|
72
|
-
for (const line of lines) {
|
|
73
|
-
// Look for feature headings
|
|
74
|
-
if (/^#{3,4}\s+(Feature|Epic|Story).*:/i.test(line)) {
|
|
75
|
-
features.push(line.replace(/^#+\s+/, '').trim());
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return features;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
extractTechnologies(content) {
|
|
83
|
-
const technologies = new Set();
|
|
84
|
-
const techPatterns = [
|
|
85
|
-
/React/gi, /Vue/gi, /Angular/gi, /Node\.js/gi, /Python/gi,
|
|
86
|
-
/PostgreSQL/gi, /MongoDB/gi, /MySQL/gi, /Redis/gi,
|
|
87
|
-
/Express/gi, /FastAPI/gi, /Django/gi, /Flask/gi,
|
|
88
|
-
/TypeScript/gi, /JavaScript/gi, /Go/gi, /Java/gi,
|
|
89
|
-
/Docker/gi, /Kubernetes/gi, /AWS/gi, /Azure/gi, /GCP/gi,
|
|
90
|
-
/REST/gi, /GraphQL/gi, /gRPC/gi
|
|
91
|
-
];
|
|
92
|
-
|
|
93
|
-
techPatterns.forEach(pattern => {
|
|
94
|
-
const matches = content.match(pattern);
|
|
95
|
-
if (matches) {
|
|
96
|
-
matches.forEach(match => technologies.add(match));
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
return Array.from(technologies);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
validatePRD(prdContent) {
|
|
104
|
-
console.log('\nš Validating PRD Structure...\n');
|
|
105
|
-
|
|
106
|
-
const sections = this.extractSections(prdContent);
|
|
107
|
-
const sectionTitles = sections.map(s => s.title.toLowerCase());
|
|
108
|
-
|
|
109
|
-
// Required PRD sections
|
|
110
|
-
const requiredSections = [
|
|
111
|
-
{ name: 'project overview', aliases: ['overview', 'executive summary'] },
|
|
112
|
-
{ name: 'functional requirements', aliases: ['requirements', 'features'] },
|
|
113
|
-
{ name: 'non-functional requirements', aliases: ['nfr', 'quality attributes'] },
|
|
114
|
-
{ name: 'user stories', aliases: ['stories'] }
|
|
115
|
-
];
|
|
116
|
-
|
|
117
|
-
requiredSections.forEach(req => {
|
|
118
|
-
const found = sectionTitles.some(title =>
|
|
119
|
-
title.includes(req.name) || req.aliases.some(alias => title.includes(alias))
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
if (found) {
|
|
123
|
-
this.successes.push(`ā PRD has '${req.name}' section`);
|
|
124
|
-
} else {
|
|
125
|
-
this.warnings.push(`ā PRD missing '${req.name}' section`);
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
// Check for epics
|
|
130
|
-
const hasEpics = /##\s*Epics?/i.test(prdContent);
|
|
131
|
-
if (hasEpics) {
|
|
132
|
-
this.successes.push('ā PRD contains Epics section');
|
|
133
|
-
} else {
|
|
134
|
-
this.warnings.push('ā PRD should include Epics section');
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Check document length
|
|
138
|
-
if (prdContent.length < 2000) {
|
|
139
|
-
this.warnings.push('ā PRD seems short (<2KB) - ensure comprehensive coverage');
|
|
140
|
-
} else {
|
|
141
|
-
this.successes.push(`ā PRD has substantial content (${(prdContent.length / 1024).toFixed(1)}KB)`);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Extract features
|
|
145
|
-
const features = this.extractFeatures(prdContent);
|
|
146
|
-
if (features.length > 0) {
|
|
147
|
-
this.successes.push(`ā PRD defines ${features.length} feature(s)/epic(s)`);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return features;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
validateArchitecture(archContent) {
|
|
154
|
-
console.log('\nšļø Validating Architecture Document...\n');
|
|
155
|
-
|
|
156
|
-
const sections = this.extractSections(archContent);
|
|
157
|
-
const sectionTitles = sections.map(s => s.title.toLowerCase());
|
|
158
|
-
|
|
159
|
-
// Required Architecture sections
|
|
160
|
-
const requiredSections = [
|
|
161
|
-
{ name: 'architecture overview', aliases: ['overview', 'system overview'] },
|
|
162
|
-
{ name: 'technology stack', aliases: ['tech stack', 'technologies'] },
|
|
163
|
-
{ name: 'system components', aliases: ['components', 'modules'] },
|
|
164
|
-
{ name: 'data architecture', aliases: ['data model', 'database schema', 'data design'] },
|
|
165
|
-
{ name: 'api design', aliases: ['api', 'endpoints', 'api specification'] },
|
|
166
|
-
{ name: 'security', aliases: ['security architecture', 'authentication'] }
|
|
167
|
-
];
|
|
168
|
-
|
|
169
|
-
requiredSections.forEach(req => {
|
|
170
|
-
const found = sectionTitles.some(title =>
|
|
171
|
-
title.includes(req.name) || req.aliases.some(alias => title.includes(alias))
|
|
172
|
-
);
|
|
173
|
-
|
|
174
|
-
if (found) {
|
|
175
|
-
this.successes.push(`ā Architecture has '${req.name}' section`);
|
|
176
|
-
} else {
|
|
177
|
-
this.warnings.push(`ā Architecture missing '${req.name}' section`);
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
// Check document length
|
|
182
|
-
if (archContent.length < 1500) {
|
|
183
|
-
this.warnings.push('ā Architecture seems short (<1.5KB) - ensure detailed design');
|
|
184
|
-
} else {
|
|
185
|
-
this.successes.push(`ā Architecture has substantial content (${(archContent.length / 1024).toFixed(1)}KB)`);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Extract technologies
|
|
189
|
-
const technologies = this.extractTechnologies(archContent);
|
|
190
|
-
if (technologies.length > 0) {
|
|
191
|
-
this.successes.push(`ā Architecture specifies ${technologies.length} technology(ies): ${technologies.slice(0, 5).join(', ')}${technologies.length > 5 ? '...' : ''}`);
|
|
192
|
-
} else {
|
|
193
|
-
this.warnings.push('ā Architecture should explicitly list technologies used');
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return technologies;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
validateAlignment(prdContent, archContent, prdFeatures, archTechnologies) {
|
|
200
|
-
console.log('\nš Validating PRD-Architecture Alignment...\n');
|
|
201
|
-
|
|
202
|
-
// Check if PRD features are mentioned in Architecture
|
|
203
|
-
if (prdFeatures.length > 0) {
|
|
204
|
-
const featuresMentioned = prdFeatures.filter(feature => {
|
|
205
|
-
// Extract key terms from feature name
|
|
206
|
-
const terms = feature.toLowerCase().split(/\s+/).filter(t => t.length > 3);
|
|
207
|
-
return terms.some(term => archContent.toLowerCase().includes(term));
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
if (featuresMentioned.length > 0) {
|
|
211
|
-
this.successes.push(`ā ${featuresMentioned.length}/${prdFeatures.length} PRD features referenced in Architecture`);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
if (featuresMentioned.length < prdFeatures.length) {
|
|
215
|
-
const unreferenced = prdFeatures.filter(f => !featuresMentioned.includes(f));
|
|
216
|
-
this.warnings.push(`ā ${unreferenced.length} PRD feature(s) not clearly referenced in Architecture`);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// Check if Architecture technologies align with PRD constraints
|
|
221
|
-
const prdMentionsTech = /technology|tech stack|framework|language|database/i.test(prdContent);
|
|
222
|
-
const archDefinesTech = archTechnologies.length > 0;
|
|
223
|
-
|
|
224
|
-
if (prdMentionsTech && !archDefinesTech) {
|
|
225
|
-
this.warnings.push('ā PRD mentions technology but Architecture doesn\'t specify tech stack');
|
|
226
|
-
} else if (archDefinesTech) {
|
|
227
|
-
this.successes.push('ā Architecture defines technology stack');
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// Check for API definitions
|
|
231
|
-
const prdHasAPI = /api|endpoint|rest|graphql/i.test(prdContent);
|
|
232
|
-
const archHasAPI = /api|endpoint|rest|graphql/i.test(archContent);
|
|
233
|
-
|
|
234
|
-
if (prdHasAPI && !archHasAPI) {
|
|
235
|
-
this.warnings.push('ā PRD mentions APIs but Architecture lacks API design section');
|
|
236
|
-
} else if (prdHasAPI && archHasAPI) {
|
|
237
|
-
this.successes.push('ā Both PRD and Architecture address API design');
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// Check for data/database mentions
|
|
241
|
-
const prdHasData = /database|data model|schema|entity|table/i.test(prdContent);
|
|
242
|
-
const archHasData = /database|data model|schema|entity|table/i.test(archContent);
|
|
243
|
-
|
|
244
|
-
if (prdHasData && !archHasData) {
|
|
245
|
-
this.warnings.push('ā PRD mentions data but Architecture lacks data model section');
|
|
246
|
-
} else if (prdHasData && archHasData) {
|
|
247
|
-
this.successes.push('ā Both PRD and Architecture address data design');
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// Check for security mentions
|
|
251
|
-
const prdHasSecurity = /security|authentication|authorization|auth/i.test(prdContent);
|
|
252
|
-
const archHasSecurity = /security|authentication|authorization|auth/i.test(archContent);
|
|
253
|
-
|
|
254
|
-
if (prdHasSecurity && !archHasSecurity) {
|
|
255
|
-
this.warnings.push('ā PRD has security requirements but Architecture lacks security design');
|
|
256
|
-
} else if (prdHasSecurity && archHasSecurity) {
|
|
257
|
-
this.successes.push('ā Both PRD and Architecture address security');
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
generateReport() {
|
|
262
|
-
console.log('\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
263
|
-
console.log(' BMAD DOCUMENT VALIDATION REPORT');
|
|
264
|
-
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
265
|
-
console.log(`\nProject Path: ${this.projectPath}\n`);
|
|
266
|
-
|
|
267
|
-
const prdPath = 'docs/prd.md';
|
|
268
|
-
const archPath = 'docs/architecture.md';
|
|
269
|
-
|
|
270
|
-
const prdContent = this.readDocument(prdPath);
|
|
271
|
-
const archContent = this.readDocument(archPath);
|
|
272
|
-
|
|
273
|
-
if (!prdContent) {
|
|
274
|
-
this.issues.push('ā PRD not found at docs/prd.md');
|
|
275
|
-
console.log('ā Cannot proceed - PRD not found\n');
|
|
276
|
-
console.log('Create a PRD using: node generate-template.js prd\n');
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
if (!archContent) {
|
|
281
|
-
this.issues.push('ā Architecture document not found at docs/architecture.md');
|
|
282
|
-
console.log('ā Cannot proceed - Architecture document not found\n');
|
|
283
|
-
console.log('Create an Architecture document using: node generate-template.js architecture\n');
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
const prdFeatures = this.validatePRD(prdContent);
|
|
288
|
-
const archTechnologies = this.validateArchitecture(archContent);
|
|
289
|
-
this.validateAlignment(prdContent, archContent, prdFeatures, archTechnologies);
|
|
290
|
-
|
|
291
|
-
// Print results
|
|
292
|
-
if (this.issues.length > 0) {
|
|
293
|
-
console.log('\nšØ CRITICAL ISSUES:\n');
|
|
294
|
-
this.issues.forEach(issue => console.log(` ${issue}`));
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
if (this.warnings.length > 0) {
|
|
298
|
-
console.log('\nā ļø WARNINGS:\n');
|
|
299
|
-
this.warnings.forEach(warning => console.log(` ${warning}`));
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
if (this.successes.length > 0) {
|
|
303
|
-
console.log('\nā
VALIDATIONS PASSED:\n');
|
|
304
|
-
this.successes.forEach(success => console.log(` ${success}`));
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
console.log('\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
308
|
-
|
|
309
|
-
const totalChecks = this.issues.length + this.warnings.length + this.successes.length;
|
|
310
|
-
const passRate = totalChecks > 0 ? ((this.successes.length / totalChecks) * 100).toFixed(1) : 0;
|
|
311
|
-
|
|
312
|
-
if (this.issues.length === 0 && this.warnings.length === 0) {
|
|
313
|
-
console.log(' ā ALL VALIDATIONS PASSED');
|
|
314
|
-
} else if (this.issues.length === 0) {
|
|
315
|
-
console.log(` VALIDATION SCORE: ${passRate}%`);
|
|
316
|
-
} else {
|
|
317
|
-
console.log(' ā CRITICAL ISSUES DETECTED');
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n');
|
|
321
|
-
|
|
322
|
-
if (this.issues.length === 0 && this.warnings.length === 0) {
|
|
323
|
-
console.log('š Documents are well-aligned and ready for development!\n');
|
|
324
|
-
console.log('Next steps:');
|
|
325
|
-
console.log(' 1. Use @po to shard documents into epics/stories');
|
|
326
|
-
console.log(' 2. Move to IDE for development phase');
|
|
327
|
-
console.log(' 3. Use @scrum to draft first story\n');
|
|
328
|
-
} else if (this.warnings.length > 0 && this.issues.length === 0) {
|
|
329
|
-
console.log('š Documents need minor improvements. Consider:');
|
|
330
|
-
console.log(' 1. Addressing warnings above');
|
|
331
|
-
console.log(' 2. Using @po to validate alignment');
|
|
332
|
-
console.log(' 3. Refining PRD or Architecture as needed\n');
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// Main execution
|
|
338
|
-
const projectPath = process.argv[2] || process.cwd();
|
|
339
|
-
const validator = new DocumentValidator(projectPath);
|
|
340
|
-
validator.generateReport();
|