@specverse/engines 5.0.2 → 5.2.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/assets/prompts/core/standard/default/analyse.prompt.yaml +5 -5
- package/assets/prompts/core/standard/default/app-demo.prompt.yaml +21 -1
- package/assets/prompts/core/standard/default/behavior.prompt.yaml +150 -0
- package/assets/prompts/core/standard/default/create.prompt.yaml +3 -3
- package/assets/prompts/core/standard/default/materialise.prompt.yaml +804 -774
- package/assets/prompts/core/standard/default/realize.prompt.yaml +581 -544
- package/assets/prompts/core/standard/v9/analyse.prompt.yaml +5 -5
- package/assets/prompts/core/standard/v9/app-demo.prompt.yaml +233 -0
- package/assets/prompts/core/standard/v9/behavior.prompt.yaml +33 -9
- package/assets/prompts/core/standard/v9/create.prompt.yaml +3 -3
- package/assets/prompts/core/standard/v9/materialise.prompt.yaml +804 -774
- package/assets/prompts/core/standard/v9/realize.prompt.yaml +581 -544
- package/dist/ai/commands/fill.d.ts.map +1 -1
- package/dist/ai/commands/fill.js +16 -7
- package/dist/ai/commands/fill.js.map +1 -1
- package/dist/ai/commands/template.d.ts.map +1 -1
- package/dist/ai/commands/template.js +17 -8
- package/dist/ai/commands/template.js.map +1 -1
- package/dist/bundles/deriveCatalog.d.ts +18 -0
- package/dist/bundles/deriveCatalog.d.ts.map +1 -0
- package/dist/bundles/deriveCatalog.js +263 -0
- package/dist/bundles/deriveCatalog.js.map +1 -0
- package/dist/bundles/index.d.ts +15 -0
- package/dist/bundles/index.d.ts.map +1 -0
- package/dist/bundles/index.js +15 -0
- package/dist/bundles/index.js.map +1 -0
- package/dist/bundles/types.d.ts +53 -0
- package/dist/bundles/types.d.ts.map +1 -0
- package/dist/bundles/types.js +22 -0
- package/dist/bundles/types.js.map +1 -0
- package/dist/bundles/validate.d.ts +55 -0
- package/dist/bundles/validate.d.ts.map +1 -0
- package/dist/bundles/validate.js +471 -0
- package/dist/bundles/validate.js.map +1 -0
- package/dist/inference/quint-transpiler.js +2 -2
- package/dist/inference/quint-transpiler.js.map +1 -1
- package/dist/libs/instance-factories/applications/templates/react/runtime-package-json-generator.js +1 -1
- package/dist/libs/instance-factories/cli/templates/commander/command-generator.js +227 -0
- package/dist/libs/instance-factories/tools/templates/mcp/mcp-server-generator.js +295 -14
- package/libs/instance-factories/applications/templates/react/runtime-package-json-generator.ts +1 -1
- package/libs/instance-factories/cli/templates/commander/command-generator.ts +227 -0
- package/libs/instance-factories/tools/templates/mcp/mcp-server-generator.ts +328 -15
- package/package.json +9 -5
- package/assets/examples/09-api/ai-spec.yaml +0 -194
- package/assets/examples/09-api/converted.yaml +0 -95
- package/assets/examples/09-api/diagram-architecture.mmd +0 -10
- package/assets/examples/09-api/diagram-er.mmd +0 -10
- package/assets/examples/09-api/documentation.html +0 -104
- package/assets/examples/09-api/documentation.md +0 -95
- package/assets/examples/09-api/inferred-spec.yaml +0 -420
- package/assets/examples/09-api/openapi.json +0 -61
- package/assets/examples/10-api/README.md +0 -216
- package/assets/examples/10-api/ai-spec.yaml +0 -194
- package/assets/examples/10-api/converted.yaml +0 -96
- package/assets/examples/10-api/diagram-architecture.mmd +0 -10
- package/assets/examples/10-api/diagram-er.mmd +0 -10
- package/assets/examples/10-api/documentation.html +0 -104
- package/assets/examples/10-api/documentation.md +0 -95
- package/assets/examples/10-api/inferred-spec.yaml +0 -7
- package/assets/examples/10-api/metadata.yaml +0 -89
- package/assets/examples/10-api/openapi.json +0 -61
- package/assets/examples/10-api/package-integration-test.js +0 -177
- package/assets/examples/10-api/usage-example.js +0 -323
- package/assets/examples/10-api/usage-example.ts +0 -363
- package/assets/examples/10-api/workflow-test.js +0 -113
- package/assets/examples/validate-examples-with-expected-failures.cjs +0 -328
- package/assets/examples/validate-examples.cjs +0 -225
- package/assets/prompts/MOVED.md +0 -35
- package/assets/prompts/SUMMARY-v8-PROMOTION.md +0 -445
- package/assets/prompts/core/CHANGELOG.md +0 -158
- package/assets/prompts/core/MIGRATION-v6-to-v7.md +0 -379
- package/assets/prompts/core/base-terminal-prompt.md +0 -201
- package/assets/prompts/core/examples/example-usage.ts +0 -140
- package/assets/prompts/core/schemas/prompt.schema.json +0 -309
- package/assets/prompts/core/schemas/prompt.schema.yaml +0 -229
- package/assets/prompts/core/standard/archive/v1/analyse.prompt.yaml +0 -259
- package/assets/prompts/core/standard/archive/v1/create.prompt.yaml +0 -302
- package/assets/prompts/core/standard/archive/v1/materialise.prompt.yaml +0 -328
- package/assets/prompts/core/standard/archive/v1/realize.prompt.yaml +0 -606
- package/assets/prompts/core/standard/archive/v2/README.md +0 -110
- package/assets/prompts/core/standard/archive/v2/analyse.prompt.yaml +0 -151
- package/assets/prompts/core/standard/archive/v2/create.prompt.yaml +0 -151
- package/assets/prompts/core/standard/archive/v2/materialise.prompt.yaml +0 -132
- package/assets/prompts/core/standard/archive/v2/realize.prompt.yaml +0 -147
- package/assets/prompts/core/standard/archive/v3/README.md +0 -279
- package/assets/prompts/core/standard/archive/v3/analyse.prompt.yaml +0 -309
- package/assets/prompts/core/standard/archive/v3/create.prompt.yaml +0 -351
- package/assets/prompts/core/standard/archive/v3/materialise.prompt.yaml +0 -247
- package/assets/prompts/core/standard/archive/v3/realize.prompt.yaml +0 -344
- package/assets/prompts/core/standard/archive/v4/README.md +0 -79
- package/assets/prompts/core/standard/archive/v4/analyse.prompt.yaml +0 -204
- package/assets/prompts/core/standard/archive/v4/create.prompt.yaml +0 -185
- package/assets/prompts/core/standard/archive/v5/README.md +0 -224
- package/assets/prompts/core/standard/archive/v5/analyse.prompt.yaml +0 -209
- package/assets/prompts/core/standard/archive/v5/create.prompt.yaml +0 -225
- package/assets/prompts/core/standard/archive/v5/materialise.prompt.yaml +0 -242
- package/assets/prompts/core/standard/archive/v5/realize.prompt.yaml +0 -336
- package/assets/prompts/core/standard/archive/v6/README.md +0 -187
- package/assets/prompts/core/standard/archive/v6/analyse.prompt.yaml +0 -219
- package/assets/prompts/core/standard/archive/v6/create.prompt.yaml +0 -180
- package/assets/prompts/core/standard/archive/v6/materialise.prompt.yaml +0 -203
- package/assets/prompts/core/standard/archive/v6/realize.prompt.yaml +0 -215
- package/assets/prompts/core/standard/archive/v7/analyse.prompt.nick.yaml +0 -144
- package/assets/prompts/core/standard/archive/v7/analyse.prompt.old.yaml +0 -146
- package/assets/prompts/core/standard/archive/v7/analyse.prompt.yaml +0 -129
- package/assets/prompts/core/standard/archive/v7/create.prompt.yaml +0 -146
- package/assets/prompts/core/standard/archive/v7/materialise.prompt.yaml +0 -297
- package/assets/prompts/core/standard/archive/v7/realize.prompt.yaml +0 -294
- package/assets/prompts/core/standard/archive/v8/README.md +0 -400
- package/assets/prompts/core/standard/archive/v8/analyse.prompt.yaml +0 -185
- package/assets/prompts/core/standard/archive/v8/create.prompt.yaml +0 -203
- package/assets/prompts/core/standard/archive/v8/materialise.prompt.yaml +0 -297
- package/assets/prompts/core/standard/archive/v8/realize.prompt.yaml +0 -294
- package/assets/prompts/templates/api-orchestrator-template.yaml +0 -188
- package/assets/prompts/templates/claude-integration-template.md +0 -121
- package/assets/prompts/templates/terminal-prompt-template.md +0 -97
|
@@ -1,328 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* SpecVerse v3.1 Enhanced Examples Validation Harness with Expected Failures Support
|
|
5
|
-
*
|
|
6
|
-
* Validates and processes all .specly examples and test files
|
|
7
|
-
* Uses expected-failures.json to distinguish expected vs unexpected failures
|
|
8
|
-
*
|
|
9
|
-
* Usage: Run from project root directory
|
|
10
|
-
* node examples/validate-examples-with-expected-failures.cjs
|
|
11
|
-
*
|
|
12
|
-
* Features:
|
|
13
|
-
* - Comprehensive validation (examples + tests directories)
|
|
14
|
-
* - Expected failures management system
|
|
15
|
-
* - 3-phase validation with failure categorization
|
|
16
|
-
* - Integration with test suite expected failures
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
const fs = require('fs');
|
|
20
|
-
const path = require('path');
|
|
21
|
-
const { execSync } = require('child_process');
|
|
22
|
-
const ExpectedFailuresManager = require('../tests/expected-failures.cjs');
|
|
23
|
-
|
|
24
|
-
// ANSI Colors for better output
|
|
25
|
-
const colors = {
|
|
26
|
-
blue: '\x1b[1m\x1b[34m',
|
|
27
|
-
green: '\x1b[32m',
|
|
28
|
-
red: '\x1b[31m',
|
|
29
|
-
yellow: '\x1b[33m',
|
|
30
|
-
orange: '\x1b[38;5;208m',
|
|
31
|
-
reset: '\x1b[0m',
|
|
32
|
-
bold: '\x1b[1m'
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
class EnhancedExamplesValidator {
|
|
36
|
-
constructor() {
|
|
37
|
-
this.results = {
|
|
38
|
-
validation: { passed: 0, expectedFailures: 0, unexpectedFailures: 0, errors: [] },
|
|
39
|
-
processing: { passed: 0, expectedFailures: 0, unexpectedFailures: 0, errors: [] },
|
|
40
|
-
yamlValidation: { passed: 0, expectedFailures: 0, unexpectedFailures: 0, errors: [] }
|
|
41
|
-
};
|
|
42
|
-
this.cliPath = './dist/cli/specverse-cli.js';
|
|
43
|
-
this.expectedFailures = new ExpectedFailuresManager();
|
|
44
|
-
this.allTestedFiles = new Set();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
log(message, color = '') {
|
|
48
|
-
console.log(`${color}${message}${colors.reset}`);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
findSpeclyFiles() {
|
|
52
|
-
const speclyFiles = [];
|
|
53
|
-
|
|
54
|
-
function scanDirectory(dir) {
|
|
55
|
-
const items = fs.readdirSync(dir);
|
|
56
|
-
|
|
57
|
-
for (const item of items) {
|
|
58
|
-
const fullPath = path.join(dir, item);
|
|
59
|
-
const stat = fs.statSync(fullPath);
|
|
60
|
-
|
|
61
|
-
if (stat.isDirectory() && !item.startsWith('.') && item !== 'diagrams' && item !== 'docs' && item !== 'metadata' && item !== 'common' && item !== 'archive' && item !== 'templates') {
|
|
62
|
-
scanDirectory(fullPath);
|
|
63
|
-
} else if (item.endsWith('.specly') && !fullPath.includes('/archive/')) {
|
|
64
|
-
// Skip any .specly files that are in archive directories at any level
|
|
65
|
-
speclyFiles.push(fullPath);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Scan examples directory and test directories
|
|
71
|
-
// Note: Excluding templates as they contain {{variables}} that are invalid until processed
|
|
72
|
-
const searchPaths = [
|
|
73
|
-
'examples',
|
|
74
|
-
'tests'
|
|
75
|
-
];
|
|
76
|
-
|
|
77
|
-
searchPaths.forEach(searchPath => {
|
|
78
|
-
if (fs.existsSync(searchPath)) {
|
|
79
|
-
scanDirectory(searchPath);
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
return speclyFiles.sort();
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
handleValidationResult(filePath, success, error = null) {
|
|
87
|
-
const relativePath = path.relative('.', filePath);
|
|
88
|
-
this.allTestedFiles.add(relativePath);
|
|
89
|
-
|
|
90
|
-
if (success) {
|
|
91
|
-
this.log(`✅ ${path.basename(filePath)} validation passed`, colors.green);
|
|
92
|
-
this.results.validation.passed++;
|
|
93
|
-
} else {
|
|
94
|
-
const isExpected = this.expectedFailures.isExpectedFailure(relativePath);
|
|
95
|
-
|
|
96
|
-
if (isExpected) {
|
|
97
|
-
const reason = this.expectedFailures.getExpectedFailureReason(relativePath);
|
|
98
|
-
this.log(`⚠️ ${path.basename(filePath)} validation failed (EXPECTED: ${reason.category})`, colors.orange);
|
|
99
|
-
this.results.validation.expectedFailures++;
|
|
100
|
-
} else {
|
|
101
|
-
this.log(`❌ ${path.basename(filePath)} validation failed (UNEXPECTED!)`, colors.red);
|
|
102
|
-
this.results.validation.unexpectedFailures++;
|
|
103
|
-
if (error) {
|
|
104
|
-
this.log(` Error: ${error}`, colors.red);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
this.results.validation.errors.push({
|
|
109
|
-
file: relativePath,
|
|
110
|
-
error: error,
|
|
111
|
-
expected: isExpected
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
handleProcessingResult(filePath, success, error = null) {
|
|
117
|
-
const relativePath = path.relative('.', filePath);
|
|
118
|
-
|
|
119
|
-
if (success) {
|
|
120
|
-
this.log(`✅ ${path.basename(filePath)} processing succeeded`, colors.green);
|
|
121
|
-
this.results.processing.passed++;
|
|
122
|
-
} else {
|
|
123
|
-
const isExpected = this.expectedFailures.isExpectedFailure(relativePath);
|
|
124
|
-
|
|
125
|
-
if (isExpected) {
|
|
126
|
-
const reason = this.expectedFailures.getExpectedFailureReason(relativePath);
|
|
127
|
-
this.log(`⚠️ ${path.basename(filePath)} processing failed (EXPECTED: ${reason.category})`, colors.orange);
|
|
128
|
-
this.results.processing.expectedFailures++;
|
|
129
|
-
} else {
|
|
130
|
-
this.log(`❌ ${path.basename(filePath)} processing failed (UNEXPECTED!)`, colors.red);
|
|
131
|
-
this.results.processing.unexpectedFailures++;
|
|
132
|
-
if (error && error.length > 200) {
|
|
133
|
-
// Truncate very long errors
|
|
134
|
-
error = error.substring(0, 200) + '...';
|
|
135
|
-
}
|
|
136
|
-
if (error) {
|
|
137
|
-
this.log(`❌ Processing failed:\n ${error}`, colors.red);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
this.results.processing.errors.push({
|
|
142
|
-
file: relativePath,
|
|
143
|
-
error: error,
|
|
144
|
-
expected: isExpected
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
validateSpeclyFile(filePath) {
|
|
150
|
-
this.log(`🧪 Validating ${path.basename(filePath)}`, colors.blue);
|
|
151
|
-
|
|
152
|
-
try {
|
|
153
|
-
execSync(`node ${this.cliPath} validate "${filePath}"`, {
|
|
154
|
-
stdio: 'pipe',
|
|
155
|
-
timeout: 10000
|
|
156
|
-
});
|
|
157
|
-
this.handleValidationResult(filePath, true);
|
|
158
|
-
} catch (error) {
|
|
159
|
-
this.handleValidationResult(filePath, false, error.message);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
processSpeclyFile(filePath) {
|
|
164
|
-
const fileName = path.basename(filePath, '.specly');
|
|
165
|
-
const outputPath = `/tmp/example-${fileName}.yaml`;
|
|
166
|
-
|
|
167
|
-
this.log(`🧪 Processing ${path.basename(filePath)} → .yaml`, colors.blue);
|
|
168
|
-
|
|
169
|
-
try {
|
|
170
|
-
const result = execSync(`node ${this.cliPath} gen yaml "${filePath}" -o "${outputPath}"`, {
|
|
171
|
-
stdio: 'pipe',
|
|
172
|
-
timeout: 15000,
|
|
173
|
-
encoding: 'utf8'
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
// Check if output file was created and has content
|
|
177
|
-
if (fs.existsSync(outputPath)) {
|
|
178
|
-
const content = fs.readFileSync(outputPath, 'utf8').trim();
|
|
179
|
-
if (content.length > 10) { // Minimal content check
|
|
180
|
-
this.handleProcessingResult(filePath, true);
|
|
181
|
-
|
|
182
|
-
// Validate the generated YAML
|
|
183
|
-
this.validateGeneratedYaml(outputPath, fileName);
|
|
184
|
-
} else {
|
|
185
|
-
this.handleProcessingResult(filePath, false, "Generated YAML is empty or minimal");
|
|
186
|
-
}
|
|
187
|
-
} else {
|
|
188
|
-
this.handleProcessingResult(filePath, false, "No output file generated");
|
|
189
|
-
}
|
|
190
|
-
} catch (error) {
|
|
191
|
-
this.handleProcessingResult(filePath, false, error.message);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
validateGeneratedYaml(yamlPath, baseName) {
|
|
196
|
-
this.log(`🧪 Validating generated ${path.basename(yamlPath)}`, colors.blue);
|
|
197
|
-
|
|
198
|
-
try {
|
|
199
|
-
execSync(`node ${this.cliPath} validate "${yamlPath}"`, {
|
|
200
|
-
stdio: 'pipe',
|
|
201
|
-
timeout: 10000
|
|
202
|
-
});
|
|
203
|
-
this.log(`✅ Generated ${path.basename(yamlPath)} validation passed`, colors.green);
|
|
204
|
-
this.results.yamlValidation.passed++;
|
|
205
|
-
} catch (error) {
|
|
206
|
-
this.log(`❌ Generated ${path.basename(yamlPath)} validation failed`, colors.red);
|
|
207
|
-
this.results.yamlValidation.unexpectedFailures++;
|
|
208
|
-
this.results.yamlValidation.errors.push({
|
|
209
|
-
file: yamlPath,
|
|
210
|
-
error: error.message,
|
|
211
|
-
expected: false
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// Clean up
|
|
216
|
-
try {
|
|
217
|
-
fs.unlinkSync(yamlPath);
|
|
218
|
-
} catch (e) {
|
|
219
|
-
// Ignore cleanup errors
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
printSummary() {
|
|
224
|
-
this.log('', '');
|
|
225
|
-
this.log('📊 Enhanced Test Results Summary', colors.bold + colors.blue);
|
|
226
|
-
|
|
227
|
-
const phases = [
|
|
228
|
-
{ name: 'Phase 1: .specly Validation', results: this.results.validation },
|
|
229
|
-
{ name: 'Phase 2: .specly → .yaml Processing', results: this.results.processing },
|
|
230
|
-
{ name: 'Phase 3: Generated .yaml Validation', results: this.results.yamlValidation }
|
|
231
|
-
];
|
|
232
|
-
|
|
233
|
-
let totalPassed = 0;
|
|
234
|
-
let totalExpected = 0;
|
|
235
|
-
let totalUnexpected = 0;
|
|
236
|
-
|
|
237
|
-
phases.forEach(phase => {
|
|
238
|
-
const r = phase.results;
|
|
239
|
-
totalPassed += r.passed;
|
|
240
|
-
totalExpected += r.expectedFailures;
|
|
241
|
-
totalUnexpected += r.unexpectedFailures;
|
|
242
|
-
|
|
243
|
-
this.log(`\n${phase.name}:`, colors.bold);
|
|
244
|
-
this.log(` ✅ Passed: ${r.passed}`, colors.green);
|
|
245
|
-
if (r.expectedFailures > 0) {
|
|
246
|
-
this.log(` ⚠️ Expected Failures: ${r.expectedFailures}`, colors.orange);
|
|
247
|
-
}
|
|
248
|
-
if (r.unexpectedFailures > 0) {
|
|
249
|
-
this.log(` ❌ Unexpected Failures: ${r.unexpectedFailures}`, colors.red);
|
|
250
|
-
}
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
// Overall summary
|
|
254
|
-
this.log('\n=== OVERALL SUMMARY ===', colors.bold);
|
|
255
|
-
this.log(`Total Tests: ${totalPassed + totalExpected + totalUnexpected}`);
|
|
256
|
-
this.log(`✅ Passed: ${totalPassed}`, colors.green);
|
|
257
|
-
this.log(`⚠️ Expected Failures: ${totalExpected}`, colors.orange);
|
|
258
|
-
this.log(`❌ Unexpected Failures: ${totalUnexpected}`, colors.red);
|
|
259
|
-
|
|
260
|
-
// Generate expected failures report
|
|
261
|
-
const allActualFailures = [
|
|
262
|
-
...this.results.validation.errors.filter(e => !e.expected).map(e => e.file),
|
|
263
|
-
...this.results.processing.errors.filter(e => !e.expected).map(e => e.file),
|
|
264
|
-
...this.results.yamlValidation.errors.filter(e => !e.expected).map(e => e.file)
|
|
265
|
-
];
|
|
266
|
-
|
|
267
|
-
const analysis = this.expectedFailures.generateReport(
|
|
268
|
-
allActualFailures,
|
|
269
|
-
totalPassed + totalExpected + totalUnexpected
|
|
270
|
-
);
|
|
271
|
-
|
|
272
|
-
this.log(analysis.report, '');
|
|
273
|
-
|
|
274
|
-
// Return success status
|
|
275
|
-
return {
|
|
276
|
-
success: analysis.isHealthy,
|
|
277
|
-
summary: analysis.summary,
|
|
278
|
-
hasUnexpectedFailures: totalUnexpected > 0
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
async run() {
|
|
283
|
-
this.log('🚀 SpecVerse v3.1 Enhanced Examples Validation Harness', colors.bold + colors.blue);
|
|
284
|
-
this.log('Validating .specly examples with expected failures support\\n', '');
|
|
285
|
-
|
|
286
|
-
const speclyFiles = this.findSpeclyFiles();
|
|
287
|
-
this.log(`📁 Found ${speclyFiles.length} .specly example files\\n`, colors.blue);
|
|
288
|
-
|
|
289
|
-
// Phase 1: Validation
|
|
290
|
-
this.log('Phase 1: .specly File Validation', colors.bold + colors.blue);
|
|
291
|
-
for (const file of speclyFiles) {
|
|
292
|
-
this.validateSpeclyFile(file);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
// Phase 2: Processing (only for files that passed validation OR are expected to pass processing)
|
|
296
|
-
this.log('\\nPhase 2: .specly → .yaml Processing', colors.bold + colors.blue);
|
|
297
|
-
const validFiles = speclyFiles.filter(file => {
|
|
298
|
-
const relativePath = path.relative('.', file);
|
|
299
|
-
const validationError = this.results.validation.errors.find(e => e.file === relativePath);
|
|
300
|
-
return !validationError || validationError.expected;
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
for (const file of validFiles) {
|
|
304
|
-
// Only process if validation passed OR it's an expected validation failure
|
|
305
|
-
const relativePath = path.relative('.', file);
|
|
306
|
-
const validationFailed = this.results.validation.errors.some(e => e.file === relativePath);
|
|
307
|
-
|
|
308
|
-
if (!validationFailed || this.expectedFailures.isExpectedFailure(relativePath)) {
|
|
309
|
-
this.processSpeclyFile(file);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
return this.printSummary();
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// Run if called directly
|
|
318
|
-
if (require.main === module) {
|
|
319
|
-
const validator = new EnhancedExamplesValidator();
|
|
320
|
-
validator.run().then(result => {
|
|
321
|
-
process.exit(result.hasUnexpectedFailures ? 1 : 0);
|
|
322
|
-
}).catch(error => {
|
|
323
|
-
console.error('Fatal error:', error);
|
|
324
|
-
process.exit(1);
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
module.exports = EnhancedExamplesValidator;
|
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* SpecVerse v3.1 Examples Validation Harness (Basic)
|
|
5
|
-
*
|
|
6
|
-
* Validates and processes all .specly examples in the examples directory
|
|
7
|
-
*
|
|
8
|
-
* Usage: Run from examples/ directory
|
|
9
|
-
* cd examples && node validate-examples.cjs
|
|
10
|
-
*
|
|
11
|
-
* Features:
|
|
12
|
-
* - Simple 3-phase validation (specly → yaml → validation)
|
|
13
|
-
* - No expected failures handling
|
|
14
|
-
* - Focused on examples directory only
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
const fs = require('fs');
|
|
18
|
-
const path = require('path');
|
|
19
|
-
const { execSync } = require('child_process');
|
|
20
|
-
|
|
21
|
-
// ANSI Colors for better output
|
|
22
|
-
const colors = {
|
|
23
|
-
blue: '\x1b[1m\x1b[34m',
|
|
24
|
-
green: '\x1b[32m',
|
|
25
|
-
red: '\x1b[31m',
|
|
26
|
-
yellow: '\x1b[33m',
|
|
27
|
-
reset: '\x1b[0m',
|
|
28
|
-
bold: '\x1b[1m'
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
class ExamplesValidator {
|
|
32
|
-
constructor() {
|
|
33
|
-
this.results = {
|
|
34
|
-
validation: { passed: 0, failed: 0, errors: [] },
|
|
35
|
-
processing: { passed: 0, failed: 0, errors: [] },
|
|
36
|
-
yamlValidation: { passed: 0, failed: 0, errors: [] }
|
|
37
|
-
};
|
|
38
|
-
this.cliPath = '../dist/cli/specverse-cli.js';
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
log(message, color = '') {
|
|
42
|
-
console.log(`${color}${message}${colors.reset}`);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
findSpeclyFiles() {
|
|
46
|
-
const speclyFiles = [];
|
|
47
|
-
|
|
48
|
-
function scanDirectory(dir) {
|
|
49
|
-
const items = fs.readdirSync(dir);
|
|
50
|
-
|
|
51
|
-
for (const item of items) {
|
|
52
|
-
const fullPath = path.join(dir, item);
|
|
53
|
-
const stat = fs.statSync(fullPath);
|
|
54
|
-
|
|
55
|
-
if (stat.isDirectory() && !item.startsWith('.') && item !== 'diagrams' && item !== 'docs' && item !== 'metadata' && item !== 'common') {
|
|
56
|
-
scanDirectory(fullPath);
|
|
57
|
-
} else if (item.endsWith('.specly')) {
|
|
58
|
-
speclyFiles.push(fullPath);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
scanDirectory('.');
|
|
64
|
-
return speclyFiles.sort();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
async validateSpeclyFile(filePath) {
|
|
68
|
-
try {
|
|
69
|
-
const cmd = `node ${this.cliPath} validate "${filePath}"`;
|
|
70
|
-
execSync(cmd, { stdio: 'pipe' });
|
|
71
|
-
this.results.validation.passed++;
|
|
72
|
-
this.log(`✅ ${path.basename(filePath)} validation passed`, colors.green);
|
|
73
|
-
return true;
|
|
74
|
-
} catch (error) {
|
|
75
|
-
this.results.validation.failed++;
|
|
76
|
-
this.results.validation.errors.push({
|
|
77
|
-
file: filePath,
|
|
78
|
-
error: error.message,
|
|
79
|
-
type: '.specly validation'
|
|
80
|
-
});
|
|
81
|
-
this.log(`❌ ${path.basename(filePath)} validation failed`, colors.red);
|
|
82
|
-
this.log(` Error: ${error.message.split('\\n')[0]}`, '');
|
|
83
|
-
return false;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
async processSpeclyFile(filePath) {
|
|
88
|
-
try {
|
|
89
|
-
const outputPath = `/tmp/example-${path.basename(filePath, '.specly')}.yaml`;
|
|
90
|
-
const cmd = `node ${this.cliPath} gen yaml "${filePath}" -o "${outputPath}"`;
|
|
91
|
-
execSync(cmd, { stdio: 'pipe' });
|
|
92
|
-
|
|
93
|
-
// Check if output file was created and has content
|
|
94
|
-
if (fs.existsSync(outputPath)) {
|
|
95
|
-
const content = fs.readFileSync(outputPath, 'utf8');
|
|
96
|
-
if (content.trim().length > 50) { // More than just empty structure
|
|
97
|
-
this.results.processing.passed++;
|
|
98
|
-
this.log(`✅ ${path.basename(filePath)} processing succeeded`, colors.green);
|
|
99
|
-
return { success: true, outputPath };
|
|
100
|
-
} else {
|
|
101
|
-
throw new Error('Generated YAML is empty or minimal');
|
|
102
|
-
}
|
|
103
|
-
} else {
|
|
104
|
-
throw new Error('Output file was not created');
|
|
105
|
-
}
|
|
106
|
-
} catch (error) {
|
|
107
|
-
this.results.processing.failed++;
|
|
108
|
-
this.results.processing.errors.push({
|
|
109
|
-
file: filePath,
|
|
110
|
-
error: error.message,
|
|
111
|
-
type: '.specly → .yaml processing'
|
|
112
|
-
});
|
|
113
|
-
this.log(`❌ ${path.basename(filePath)} processing failed`, colors.red);
|
|
114
|
-
this.log(` Error: ${error.message.split('\\n')[0]}`, '');
|
|
115
|
-
return { success: false };
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
async validateYamlFile(filePath) {
|
|
120
|
-
try {
|
|
121
|
-
const cmd = `node ${this.cliPath} validate "${filePath}"`;
|
|
122
|
-
execSync(cmd, { stdio: 'pipe' });
|
|
123
|
-
this.results.yamlValidation.passed++;
|
|
124
|
-
this.log(`✅ Generated ${path.basename(filePath)} validation passed`, colors.green);
|
|
125
|
-
return true;
|
|
126
|
-
} catch (error) {
|
|
127
|
-
this.results.yamlValidation.failed++;
|
|
128
|
-
this.results.yamlValidation.errors.push({
|
|
129
|
-
file: filePath,
|
|
130
|
-
error: error.message,
|
|
131
|
-
type: 'Generated .yaml validation'
|
|
132
|
-
});
|
|
133
|
-
this.log(`❌ Generated ${path.basename(filePath)} validation failed`, colors.red);
|
|
134
|
-
this.log(` Error: ${error.message.split('\\n')[0]}`, '');
|
|
135
|
-
return false;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
printSummary() {
|
|
140
|
-
const total = this.results.validation.passed + this.results.validation.failed;
|
|
141
|
-
const validationRate = total > 0 ? ((this.results.validation.passed / total) * 100).toFixed(1) : 0;
|
|
142
|
-
const processingRate = total > 0 ? ((this.results.processing.passed / total) * 100).toFixed(1) : 0;
|
|
143
|
-
const yamlRate = this.results.processing.passed > 0 ?
|
|
144
|
-
((this.results.yamlValidation.passed / this.results.processing.passed) * 100).toFixed(1) : 0;
|
|
145
|
-
|
|
146
|
-
this.log('\\n🏆 Examples Validation Summary', colors.blue);
|
|
147
|
-
this.log(`Total Examples: ${total}`);
|
|
148
|
-
this.log(`✅ Specly Validation: ${this.results.validation.passed}/${total} (${validationRate}%)`, colors.green);
|
|
149
|
-
this.log(`✅ Processing: ${this.results.processing.passed}/${total} (${processingRate}%)`, colors.green);
|
|
150
|
-
this.log(`✅ Generated YAML Validation: ${this.results.yamlValidation.passed}/${this.results.processing.passed} (${yamlRate}%)`, colors.green);
|
|
151
|
-
|
|
152
|
-
const overallPassed = Math.min(this.results.validation.passed, this.results.processing.passed, this.results.yamlValidation.passed);
|
|
153
|
-
const overallRate = total > 0 ? ((overallPassed / total) * 100).toFixed(1) : 0;
|
|
154
|
-
|
|
155
|
-
this.log(`\\n🎯 Overall Success Rate: ${overallRate}%`, overallRate >= 90 ? colors.green : overallRate >= 70 ? colors.yellow : colors.red);
|
|
156
|
-
|
|
157
|
-
if (this.results.validation.errors.length > 0 ||
|
|
158
|
-
this.results.processing.errors.length > 0 ||
|
|
159
|
-
this.results.yamlValidation.errors.length > 0) {
|
|
160
|
-
this.log('\\n❌ Failed Examples Details', colors.red);
|
|
161
|
-
let errorIndex = 1;
|
|
162
|
-
|
|
163
|
-
for (const error of [...this.results.validation.errors, ...this.results.processing.errors, ...this.results.yamlValidation.errors]) {
|
|
164
|
-
this.log(`${errorIndex}. ${error.type}`, colors.red);
|
|
165
|
-
this.log(` File: ${error.file}`, '');
|
|
166
|
-
this.log(` Error: ${error.error.split('\\n')[0]}`, '');
|
|
167
|
-
this.log('');
|
|
168
|
-
errorIndex++;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
this.log('\\n🔧 Recommended Actions', colors.blue);
|
|
173
|
-
if (overallRate < 50) {
|
|
174
|
-
this.log('1. Update examples to v3.1 container format (components: structure)');
|
|
175
|
-
this.log('2. Fix data types (Text → String, etc.)');
|
|
176
|
-
this.log('3. Update import/export syntax to match v3.1 schema');
|
|
177
|
-
} else if (overallRate < 90) {
|
|
178
|
-
this.log('1. Fix specific validation errors shown above');
|
|
179
|
-
this.log('2. Ensure all examples use current v3.1 conventions');
|
|
180
|
-
} else {
|
|
181
|
-
this.log('1. Examples are in excellent shape!');
|
|
182
|
-
this.log('2. Consider adding more complex examples or edge cases');
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
async run() {
|
|
187
|
-
this.log('🚀 SpecVerse v3.1 Examples Validation Harness', colors.blue);
|
|
188
|
-
this.log('Validating .specly examples → processing → validating generated YAML\\n');
|
|
189
|
-
|
|
190
|
-
const speclyFiles = this.findSpeclyFiles();
|
|
191
|
-
|
|
192
|
-
if (speclyFiles.length === 0) {
|
|
193
|
-
this.log('❌ No .specly files found in examples directory', colors.red);
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
this.log(`📁 Found ${speclyFiles.length} .specly example files\\n`);
|
|
198
|
-
|
|
199
|
-
// Phase 1: Validate all .specly files
|
|
200
|
-
this.log('Phase 1: .specly File Validation', colors.blue);
|
|
201
|
-
for (const file of speclyFiles) {
|
|
202
|
-
this.log(`🧪 Validating ${path.basename(file)}`);
|
|
203
|
-
await this.validateSpeclyFile(file);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Phase 2: Process .specly → .yaml
|
|
207
|
-
this.log('\\nPhase 2: .specly → .yaml Processing', colors.blue);
|
|
208
|
-
for (const file of speclyFiles) {
|
|
209
|
-
this.log(`🧪 Processing ${path.basename(file)} → .yaml`);
|
|
210
|
-
const result = await this.processSpeclyFile(file);
|
|
211
|
-
|
|
212
|
-
// Phase 3: Validate generated YAML (only if processing succeeded)
|
|
213
|
-
if (result.success) {
|
|
214
|
-
this.log(`🧪 Validating generated ${path.basename(result.outputPath)}`);
|
|
215
|
-
await this.validateYamlFile(result.outputPath);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
this.printSummary();
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// Run the validator
|
|
224
|
-
const validator = new ExamplesValidator();
|
|
225
|
-
validator.run().catch(console.error);
|
package/assets/prompts/MOVED.md
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# Prompts Directory Migration Notice
|
|
2
|
-
|
|
3
|
-
## Important: Directory Structure Changed
|
|
4
|
-
|
|
5
|
-
The prompts directory has been reorganized as part of the SpecVerse v3.1 AI Support architecture enhancement.
|
|
6
|
-
|
|
7
|
-
### New Structure
|
|
8
|
-
|
|
9
|
-
All prompts have been moved to the `ai-support/prompts/` directory:
|
|
10
|
-
|
|
11
|
-
- **Standard prompts**: `ai-support/prompts/core/standard/`
|
|
12
|
-
- **Specialized prompts**: `ai-support/prompts/specialized/`
|
|
13
|
-
- **Template prompts**: `ai-support/prompts/templates/`
|
|
14
|
-
- **Library-aware prompts**: `ai-support/prompts/library-aware/`
|
|
15
|
-
|
|
16
|
-
### Legacy Compatibility
|
|
17
|
-
|
|
18
|
-
This directory (`prompts/`) now serves as a symbolic link to `ai-support/prompts/` for backward compatibility.
|
|
19
|
-
|
|
20
|
-
### For Developers
|
|
21
|
-
|
|
22
|
-
Update your import paths and references:
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
OLD: prompts/standard/create.prompt.yaml
|
|
26
|
-
NEW: ai-support/prompts/core/standard/create.prompt.yaml
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
Or use the symlink:
|
|
30
|
-
|
|
31
|
-
```
|
|
32
|
-
COMPATIBLE: prompts/core/standard/create.prompt.yaml
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
For more information, see the AI Support Migration Guide in `ai-support/docs/migration-guide.md`.
|