specky-sdd 2.2.2 → 2.3.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbt.js","sourceRoot":"","sources":["../../src/schemas/pbt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEjE,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,SAAS,EAAE,CAAC;SACT,IAAI,CAAC,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;SAClC,QAAQ,CAAC,qFAAqF,CAAC;IAClG,cAAc,EAAE,mBAAmB;IACnC,QAAQ,EAAE,aAAa;IACvB,UAAU,EAAE,CAAC;SACV,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,OAAO,CAAC,OAAO,CAAC;SAChB,QAAQ,CAAC,0CAA0C,CAAC;CACxD,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2HAA2H,CAAC,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * PbtGenerator — Generates property-based tests from SPECIFICATION.md.
3
+ * Reads EARS requirements and produces framework-specific PBT files
4
+ * for fast-check (TypeScript) or hypothesis (Python).
5
+ */
6
+ import type { FileManager } from "./file-manager.js";
7
+ export type PbtFramework = "fast-check" | "hypothesis";
8
+ export type PbtPropertyType = "invariant" | "state_transition" | "conditional" | "negative" | "round_trip" | "idempotence";
9
+ export interface PbtProperty {
10
+ id: string;
11
+ requirement_id: string;
12
+ property_type: PbtPropertyType;
13
+ description: string;
14
+ test_code: string;
15
+ }
16
+ export interface PbtGenerationResult {
17
+ framework: PbtFramework;
18
+ properties: PbtProperty[];
19
+ output_file: string;
20
+ content: string;
21
+ total_properties: number;
22
+ property_types: Record<string, number>;
23
+ }
24
+ export declare class PbtGenerator {
25
+ private fileManager;
26
+ constructor(fileManager: FileManager);
27
+ generate(featureDir: string, framework: PbtFramework, outputDir: string): Promise<PbtGenerationResult>;
28
+ extractEarsRequirements(text: string): Array<{
29
+ line: string;
30
+ reqId: string;
31
+ }>;
32
+ classifyPropertyType(line: string): PbtPropertyType;
33
+ private buildProperties;
34
+ private generateTestCode;
35
+ private generateFastCheckTest;
36
+ private generateHypothesisTest;
37
+ renderFile(properties: PbtProperty[], framework: PbtFramework, featureDir: string): string;
38
+ private snakeCase;
39
+ private safeRead;
40
+ }
41
+ //# sourceMappingURL=pbt-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbt-generator.d.ts","sourceRoot":"","sources":["../../src/services/pbt-generator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,YAAY,CAAC;AAEvD,MAAM,MAAM,eAAe,GACvB,WAAW,GACX,kBAAkB,GAClB,aAAa,GACb,UAAU,GACV,YAAY,GACZ,aAAa,CAAC;AAElB,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,eAAe,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,YAAY,CAAC;IACxB,UAAU,EAAE,WAAW,EAAE,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAOD,qBAAa,YAAY;IACX,OAAO,CAAC,WAAW;gBAAX,WAAW,EAAE,WAAW;IAEtC,QAAQ,CACZ,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,YAAY,EACvB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,mBAAmB,CAAC;IAyB/B,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAe7E,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe;IAsDnD,OAAO,CAAC,eAAe;IAqBvB,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,qBAAqB;IAyG7B,OAAO,CAAC,sBAAsB;IA+E9B,UAAU,CAAC,UAAU,EAAE,WAAW,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;IAmD1F,OAAO,CAAC,SAAS;YAOH,QAAQ;CASvB"}
@@ -0,0 +1,326 @@
1
+ const FRAMEWORK_CONFIG = {
2
+ "fast-check": { ext: ".pbt.test.ts" },
3
+ hypothesis: { ext: "_pbt_test.py" },
4
+ };
5
+ export class PbtGenerator {
6
+ fileManager;
7
+ constructor(fileManager) {
8
+ this.fileManager = fileManager;
9
+ }
10
+ async generate(featureDir, framework, outputDir) {
11
+ const spec = await this.safeRead(featureDir, "SPECIFICATION.md");
12
+ const requirements = this.extractEarsRequirements(spec);
13
+ const properties = this.buildProperties(requirements, framework, featureDir);
14
+ const content = this.renderFile(properties, framework, featureDir);
15
+ const featureName = featureDir.replace(/.*\d{3}-/, "").replace(/[^a-zA-Z0-9-]/g, "");
16
+ const cfg = FRAMEWORK_CONFIG[framework];
17
+ const outputFile = `${outputDir}/${featureName}${cfg.ext}`;
18
+ const propertyTypes = {};
19
+ for (const prop of properties) {
20
+ propertyTypes[prop.property_type] = (propertyTypes[prop.property_type] || 0) + 1;
21
+ }
22
+ return {
23
+ framework,
24
+ properties,
25
+ output_file: outputFile,
26
+ content,
27
+ total_properties: properties.length,
28
+ property_types: propertyTypes,
29
+ };
30
+ }
31
+ extractEarsRequirements(text) {
32
+ const results = [];
33
+ const lines = text.split("\n");
34
+ for (const line of lines) {
35
+ if (/^(When|While|Where|If|The)\s+.+shall\s+/im.test(line)) {
36
+ const reqMatch = line.match(/REQ-[A-Z]+-\d{3}/);
37
+ const reqId = reqMatch ? reqMatch[0] : `REQ-GEN-${String(results.length + 1).padStart(3, "0")}`;
38
+ results.push({ line: line.trim(), reqId });
39
+ }
40
+ }
41
+ return results;
42
+ }
43
+ classifyPropertyType(line) {
44
+ const lower = line.toLowerCase();
45
+ // Detect special patterns first
46
+ if (lower.includes("parse") &&
47
+ (lower.includes("serialize") ||
48
+ lower.includes("format") ||
49
+ lower.includes("render") ||
50
+ lower.includes("print") ||
51
+ lower.includes("export"))) {
52
+ return "round_trip";
53
+ }
54
+ if (lower.includes("convert") ||
55
+ lower.includes("transform") ||
56
+ lower.includes("encode") ||
57
+ lower.includes("decode")) {
58
+ return "round_trip";
59
+ }
60
+ if (lower.includes("delete") ||
61
+ lower.includes("remove") ||
62
+ lower.includes("reset") ||
63
+ lower.includes("apply") ||
64
+ lower.includes("update")) {
65
+ return "idempotence";
66
+ }
67
+ // Classify by EARS pattern
68
+ if (/^the\s+system\s+shall\b/i.test(line)) {
69
+ return "invariant";
70
+ }
71
+ if (/^when\b/i.test(line)) {
72
+ return "state_transition";
73
+ }
74
+ if (/^while\b/i.test(line)) {
75
+ return "conditional";
76
+ }
77
+ if (/^if\b/i.test(line)) {
78
+ return "negative";
79
+ }
80
+ if (/^where\b/i.test(line)) {
81
+ return "conditional";
82
+ }
83
+ return "invariant";
84
+ }
85
+ buildProperties(requirements, framework, featureDir) {
86
+ return requirements.map((req, i) => {
87
+ const propId = `PROP-${String(i + 1).padStart(3, "0")}`;
88
+ const propertyType = this.classifyPropertyType(req.line);
89
+ const description = req.line.length > 100 ? req.line.slice(0, 97) + "..." : req.line;
90
+ const testCode = this.generateTestCode(propId, description, req.line, propertyType, framework, featureDir);
91
+ return {
92
+ id: propId,
93
+ requirement_id: req.reqId,
94
+ property_type: propertyType,
95
+ description,
96
+ test_code: testCode,
97
+ };
98
+ });
99
+ }
100
+ generateTestCode(propId, description, requirementText, propertyType, framework, _featureDir) {
101
+ const safeDesc = description.replace(/"/g, '\\"');
102
+ if (framework === "fast-check") {
103
+ return this.generateFastCheckTest(propId, safeDesc, requirementText, propertyType);
104
+ }
105
+ return this.generateHypothesisTest(propId, description, requirementText, propertyType);
106
+ }
107
+ generateFastCheckTest(propId, description, requirementText, propertyType) {
108
+ const safeReq = requirementText.replace(/"/g, '\\"');
109
+ switch (propertyType) {
110
+ case "invariant":
111
+ return [
112
+ ` it("${propId}: ${description}", () => {`,
113
+ ` fc.assert(`,
114
+ ` fc.property(fc.string(), fc.integer(), (input1, input2) => {`,
115
+ ` // TODO: Replace with actual system call`,
116
+ ` // Property: ${safeReq}`,
117
+ ` const result = systemUnderTest(input1, input2);`,
118
+ ` expect(result).toBeDefined();`,
119
+ ` return true; // Replace with actual invariant check`,
120
+ ` }),`,
121
+ ` { numRuns: 100 }`,
122
+ ` );`,
123
+ ` });`,
124
+ ].join("\n");
125
+ case "round_trip":
126
+ return [
127
+ ` it("${propId}: round-trip — ${description}", () => {`,
128
+ ` fc.assert(`,
129
+ ` fc.property(fc.jsonValue(), (input) => {`,
130
+ ` // TODO: Verify round-trip: parse(serialize(x)) === x`,
131
+ ` const serialized = serialize(input);`,
132
+ ` const parsed = parse(serialized);`,
133
+ ` expect(parsed).toEqual(input);`,
134
+ ` return true;`,
135
+ ` }),`,
136
+ ` { numRuns: 100 }`,
137
+ ` );`,
138
+ ` });`,
139
+ ].join("\n");
140
+ case "idempotence":
141
+ return [
142
+ ` it("${propId}: idempotence — ${description}", () => {`,
143
+ ` fc.assert(`,
144
+ ` fc.property(fc.anything(), (input) => {`,
145
+ ` // TODO: Verify f(f(x)) === f(x)`,
146
+ ` const once = operation(input);`,
147
+ ` const twice = operation(once);`,
148
+ ` expect(twice).toEqual(once);`,
149
+ ` return true;`,
150
+ ` }),`,
151
+ ` { numRuns: 100 }`,
152
+ ` );`,
153
+ ` });`,
154
+ ].join("\n");
155
+ case "state_transition":
156
+ return [
157
+ ` it("${propId}: state transition — ${description}", () => {`,
158
+ ` fc.assert(`,
159
+ ` fc.property(fc.record({ event: fc.string(), state: fc.string() }), ({ event, state }) => {`,
160
+ ` // TODO: Verify state transition is valid`,
161
+ ` const newState = transition(state, event);`,
162
+ ` expect(newState).toBeDefined();`,
163
+ ` return true;`,
164
+ ` }),`,
165
+ ` { numRuns: 100 }`,
166
+ ` );`,
167
+ ` });`,
168
+ ].join("\n");
169
+ case "negative":
170
+ return [
171
+ ` it("${propId}: negative — ${description}", () => {`,
172
+ ` fc.assert(`,
173
+ ` fc.property(fc.string(), (maliciousInput) => {`,
174
+ ` // TODO: Verify unwanted behavior never occurs`,
175
+ ` const result = systemUnderTest(maliciousInput);`,
176
+ ` expect(result.error).not.toContain("crash");`,
177
+ ` return true;`,
178
+ ` }),`,
179
+ ` { numRuns: 100 }`,
180
+ ` );`,
181
+ ` });`,
182
+ ].join("\n");
183
+ case "conditional":
184
+ return [
185
+ ` it("${propId}: conditional — ${description}", () => {`,
186
+ ` fc.assert(`,
187
+ ` fc.property(fc.boolean(), fc.anything(), (condition, input) => {`,
188
+ ` // TODO: Verify behavior only when condition holds`,
189
+ ` fc.pre(condition); // Only test when condition is true`,
190
+ ` const result = systemUnderTest(input);`,
191
+ ` expect(result).toBeDefined();`,
192
+ ` return true;`,
193
+ ` }),`,
194
+ ` { numRuns: 100 }`,
195
+ ` );`,
196
+ ` });`,
197
+ ].join("\n");
198
+ }
199
+ }
200
+ generateHypothesisTest(propId, description, requirementText, propertyType) {
201
+ const descSnake = this.snakeCase(description);
202
+ switch (propertyType) {
203
+ case "invariant":
204
+ return [
205
+ ` @given(input1=st.text(), input2=st.integers())`,
206
+ ` @settings(max_examples=100)`,
207
+ ` def test_${this.snakeCase(propId)}_${descSnake}(self, input1, input2):`,
208
+ ` """${propId}: ${requirementText}"""`,
209
+ ` # TODO: Replace with actual system call`,
210
+ ` result = system_under_test(input1, input2)`,
211
+ ` assert result is not None`,
212
+ ].join("\n");
213
+ case "round_trip":
214
+ return [
215
+ ` @given(data=st.from_type(dict))`,
216
+ ` @settings(max_examples=100)`,
217
+ ` def test_${this.snakeCase(propId)}_round_trip_${descSnake}(self, data):`,
218
+ ` """${propId}: round-trip — ${requirementText}"""`,
219
+ ` # TODO: Verify round-trip: parse(serialize(x)) == x`,
220
+ ` serialized = serialize(data)`,
221
+ ` parsed = parse(serialized)`,
222
+ ` assert parsed == data`,
223
+ ].join("\n");
224
+ case "idempotence":
225
+ return [
226
+ ` @given(data=st.text())`,
227
+ ` @settings(max_examples=100)`,
228
+ ` def test_${this.snakeCase(propId)}_idempotence_${descSnake}(self, data):`,
229
+ ` """${propId}: idempotence — ${requirementText}"""`,
230
+ ` # TODO: Verify f(f(x)) == f(x)`,
231
+ ` once = operation(data)`,
232
+ ` twice = operation(once)`,
233
+ ` assert twice == once`,
234
+ ].join("\n");
235
+ case "state_transition":
236
+ return [
237
+ ` @given(event=st.text(), state=st.text())`,
238
+ ` @settings(max_examples=100)`,
239
+ ` def test_${this.snakeCase(propId)}_transition_${descSnake}(self, event, state):`,
240
+ ` """${propId}: ${requirementText}"""`,
241
+ ` # TODO: Verify state transition`,
242
+ ` new_state = transition(state, event)`,
243
+ ` assert new_state is not None`,
244
+ ].join("\n");
245
+ case "negative":
246
+ return [
247
+ ` @given(malicious_input=st.text())`,
248
+ ` @settings(max_examples=100)`,
249
+ ` def test_${this.snakeCase(propId)}_negative_${descSnake}(self, malicious_input):`,
250
+ ` """${propId}: ${requirementText}"""`,
251
+ ` # TODO: Verify unwanted behavior never occurs`,
252
+ ` result = system_under_test(malicious_input)`,
253
+ ` assert "crash" not in str(result)`,
254
+ ].join("\n");
255
+ case "conditional":
256
+ return [
257
+ ` @given(condition=st.booleans(), data=st.text())`,
258
+ ` @settings(max_examples=100)`,
259
+ ` def test_${this.snakeCase(propId)}_conditional_${descSnake}(self, condition, data):`,
260
+ ` """${propId}: ${requirementText}"""`,
261
+ ` assume(condition) # Only test when condition holds`,
262
+ ` result = system_under_test(data)`,
263
+ ` assert result is not None`,
264
+ ].join("\n");
265
+ }
266
+ }
267
+ renderFile(properties, framework, featureDir) {
268
+ const featureName = featureDir.replace(/.*\d{3}-/, "").replace(/[^a-zA-Z0-9 -]/g, "") || "Feature";
269
+ const date = new Date().toISOString().split("T")[0];
270
+ const body = properties.map((p) => p.test_code).join("\n\n");
271
+ if (framework === "fast-check") {
272
+ const header = [
273
+ `/**`,
274
+ ` * Auto-generated property-based tests from Specky SDD`,
275
+ ` * Feature: ${featureName}`,
276
+ ` * Framework: fast-check`,
277
+ ` * Generated: ${date}`,
278
+ ` *`,
279
+ ` * Each property traces to an EARS requirement from SPECIFICATION.md.`,
280
+ ` * Replace the TODO placeholders with real system calls.`,
281
+ ` */`,
282
+ ].join("\n");
283
+ const imports = [
284
+ `import { fc } from "fast-check";`,
285
+ `import { describe, it, expect } from "vitest";`,
286
+ ].join("\n");
287
+ return `${header}\n\n${imports}\n\ndescribe("Property-Based Tests — ${featureName}", () => {\n${body}\n});\n`;
288
+ }
289
+ // hypothesis (Python)
290
+ const header = [
291
+ `"""`,
292
+ `Auto-generated property-based tests from Specky SDD`,
293
+ `Feature: ${featureName}`,
294
+ `Framework: hypothesis`,
295
+ `Generated: ${date}`,
296
+ ``,
297
+ `Each property traces to an EARS requirement from SPECIFICATION.md.`,
298
+ `Replace the TODO placeholders with real system calls.`,
299
+ `"""`,
300
+ ].join("\n");
301
+ const imports = [
302
+ `import hypothesis`,
303
+ `from hypothesis import given, assume, settings`,
304
+ `from hypothesis import strategies as st`,
305
+ ].join("\n");
306
+ const className = featureName.replace(/[^a-zA-Z0-9]/g, "");
307
+ return `${header}\n\n${imports}\n\n\nclass TestPropertyBased_${className}:\n """Property-based tests generated from EARS requirements."""\n\n${body}\n`;
308
+ }
309
+ snakeCase(s) {
310
+ return s
311
+ .replace(/[^a-zA-Z0-9]+/g, "_")
312
+ .toLowerCase()
313
+ .slice(0, 60);
314
+ }
315
+ async safeRead(featureDir, file) {
316
+ try {
317
+ const parts = featureDir.split("/");
318
+ const specDir = parts.slice(0, -1).join("/") || ".specs";
319
+ return await this.fileManager.readSpecFile(specDir, `${parts[parts.length - 1]}/${file}`);
320
+ }
321
+ catch {
322
+ return "";
323
+ }
324
+ }
325
+ }
326
+ //# sourceMappingURL=pbt-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbt-generator.js","sourceRoot":"","sources":["../../src/services/pbt-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Checkpoint Tools — sdd_checkpoint, sdd_restore.
3
+ * Snapshot and rollback spec artifacts.
4
+ */
5
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
6
+ import type { FileManager } from "../services/file-manager.js";
7
+ import type { StateMachine } from "../services/state-machine.js";
8
+ export declare function registerCheckpointTools(server: McpServer, fileManager: FileManager, stateMachine: StateMachine): void;
9
+ //# sourceMappingURL=checkpoint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint.d.ts","sourceRoot":"","sources":["../../src/tools/checkpoint.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AA0CjE,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,YAAY,GACzB,IAAI,CA+SN"}