superspec 0.1.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.
Files changed (81) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +328 -0
  3. package/dist/cli/commands/archive.d.ts +7 -0
  4. package/dist/cli/commands/archive.d.ts.map +1 -0
  5. package/dist/cli/commands/archive.js +322 -0
  6. package/dist/cli/commands/archive.js.map +1 -0
  7. package/dist/cli/commands/init.d.ts +6 -0
  8. package/dist/cli/commands/init.d.ts.map +1 -0
  9. package/dist/cli/commands/init.js +306 -0
  10. package/dist/cli/commands/init.js.map +1 -0
  11. package/dist/cli/commands/list.d.ts +9 -0
  12. package/dist/cli/commands/list.d.ts.map +1 -0
  13. package/dist/cli/commands/list.js +268 -0
  14. package/dist/cli/commands/list.js.map +1 -0
  15. package/dist/cli/commands/show.d.ts +6 -0
  16. package/dist/cli/commands/show.d.ts.map +1 -0
  17. package/dist/cli/commands/show.js +273 -0
  18. package/dist/cli/commands/show.js.map +1 -0
  19. package/dist/cli/commands/validate.d.ts +8 -0
  20. package/dist/cli/commands/validate.d.ts.map +1 -0
  21. package/dist/cli/commands/validate.js +209 -0
  22. package/dist/cli/commands/validate.js.map +1 -0
  23. package/dist/cli/commands/verify.d.ts +7 -0
  24. package/dist/cli/commands/verify.d.ts.map +1 -0
  25. package/dist/cli/commands/verify.js +328 -0
  26. package/dist/cli/commands/verify.js.map +1 -0
  27. package/dist/cli/commands/view.d.ts +6 -0
  28. package/dist/cli/commands/view.d.ts.map +1 -0
  29. package/dist/cli/commands/view.js +290 -0
  30. package/dist/cli/commands/view.js.map +1 -0
  31. package/dist/cli/index.d.ts +3 -0
  32. package/dist/cli/index.d.ts.map +1 -0
  33. package/dist/cli/index.js +87 -0
  34. package/dist/cli/index.js.map +1 -0
  35. package/dist/cli/ui/display.d.ts +189 -0
  36. package/dist/cli/ui/display.d.ts.map +1 -0
  37. package/dist/cli/ui/display.js +449 -0
  38. package/dist/cli/ui/display.js.map +1 -0
  39. package/dist/cli/ui/index.d.ts +12 -0
  40. package/dist/cli/ui/index.d.ts.map +1 -0
  41. package/dist/cli/ui/index.js +71 -0
  42. package/dist/cli/ui/index.js.map +1 -0
  43. package/dist/cli/ui/interactive.d.ts +21 -0
  44. package/dist/cli/ui/interactive.d.ts.map +1 -0
  45. package/dist/cli/ui/interactive.js +60 -0
  46. package/dist/cli/ui/interactive.js.map +1 -0
  47. package/dist/cli/ui/palette.d.ts +301 -0
  48. package/dist/cli/ui/palette.d.ts.map +1 -0
  49. package/dist/cli/ui/palette.js +673 -0
  50. package/dist/cli/ui/palette.js.map +1 -0
  51. package/dist/cli/ui/prompts.d.ts +62 -0
  52. package/dist/cli/ui/prompts.d.ts.map +1 -0
  53. package/dist/cli/ui/prompts.js +119 -0
  54. package/dist/cli/ui/prompts.js.map +1 -0
  55. package/dist/cli/ui/spinner.d.ts +38 -0
  56. package/dist/cli/ui/spinner.d.ts.map +1 -0
  57. package/dist/cli/ui/spinner.js +72 -0
  58. package/dist/cli/ui/spinner.js.map +1 -0
  59. package/dist/core/config/project-config.d.ts +100 -0
  60. package/dist/core/config/project-config.d.ts.map +1 -0
  61. package/dist/core/config/project-config.js +87 -0
  62. package/dist/core/config/project-config.js.map +1 -0
  63. package/dist/core/parsers/spec-parser.d.ts +48 -0
  64. package/dist/core/parsers/spec-parser.d.ts.map +1 -0
  65. package/dist/core/parsers/spec-parser.js +322 -0
  66. package/dist/core/parsers/spec-parser.js.map +1 -0
  67. package/dist/core/validation/spec-validator.d.ts +32 -0
  68. package/dist/core/validation/spec-validator.d.ts.map +1 -0
  69. package/dist/core/validation/spec-validator.js +242 -0
  70. package/dist/core/validation/spec-validator.js.map +1 -0
  71. package/dist/index.d.ts +35 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +44 -0
  74. package/dist/index.js.map +1 -0
  75. package/package.json +66 -0
  76. package/schemas/superspec-workflow/schema.yaml +166 -0
  77. package/templates/design.md +71 -0
  78. package/templates/plan.md +78 -0
  79. package/templates/proposal.md +36 -0
  80. package/templates/spec.md +57 -0
  81. package/templates/tasks.md +29 -0
@@ -0,0 +1,322 @@
1
+ /**
2
+ * Spec Parser Module
3
+ *
4
+ * Parses spec documents into structured data.
5
+ */
6
+ import matter from 'gray-matter';
7
+ /**
8
+ * Parse a spec document into structured data
9
+ */
10
+ export function parseSpec(content) {
11
+ const { data, content: body } = matter(content);
12
+ const lines = body.split('\n');
13
+ const spec = {
14
+ title: '',
15
+ requirements: [],
16
+ metadata: data,
17
+ };
18
+ let currentRequirement = null;
19
+ let currentScenario = null;
20
+ let inDescription = false;
21
+ let descriptionLines = [];
22
+ for (const line of lines) {
23
+ // Title
24
+ const titleMatch = line.match(/^# (.+)$/);
25
+ if (titleMatch?.[1]) {
26
+ spec.title = titleMatch[1].replace(/\s*Specification\s*$/i, '').trim();
27
+ continue;
28
+ }
29
+ // Purpose
30
+ const purposeMatch = line.match(/^## Purpose\s*$/);
31
+ if (purposeMatch) {
32
+ inDescription = false;
33
+ continue;
34
+ }
35
+ // Requirements section
36
+ if (line.match(/^## Requirements\s*$/)) {
37
+ inDescription = false;
38
+ continue;
39
+ }
40
+ // Requirement
41
+ const reqMatch = line.match(/^### Requirement: (.+)$/);
42
+ if (reqMatch?.[1]) {
43
+ // Save previous
44
+ if (currentRequirement) {
45
+ if (currentScenario) {
46
+ currentRequirement.scenarios.push(currentScenario);
47
+ }
48
+ currentRequirement.description = descriptionLines.join('\n').trim();
49
+ spec.requirements.push(currentRequirement);
50
+ }
51
+ currentRequirement = {
52
+ name: reqMatch[1],
53
+ description: '',
54
+ scenarios: [],
55
+ };
56
+ currentScenario = null;
57
+ inDescription = true;
58
+ descriptionLines = [];
59
+ continue;
60
+ }
61
+ // Scenario
62
+ const scenarioMatch = line.match(/^#### Scenario: (.+)$/);
63
+ if (scenarioMatch?.[1]) {
64
+ // Save previous scenario
65
+ if (currentScenario && currentRequirement) {
66
+ currentRequirement.scenarios.push(currentScenario);
67
+ }
68
+ if (currentRequirement && inDescription) {
69
+ currentRequirement.description = descriptionLines.join('\n').trim();
70
+ inDescription = false;
71
+ }
72
+ currentScenario = {
73
+ name: scenarioMatch[1],
74
+ when: '',
75
+ then: [],
76
+ and: [],
77
+ };
78
+ continue;
79
+ }
80
+ // WHEN
81
+ const whenMatch = line.match(/^\s*-\s*\*\*WHEN\*\*\s*(.+)$/);
82
+ if (whenMatch?.[1] && currentScenario) {
83
+ currentScenario.when = whenMatch[1];
84
+ continue;
85
+ }
86
+ // THEN
87
+ const thenMatch = line.match(/^\s*-\s*\*\*THEN\*\*\s*(.+)$/);
88
+ if (thenMatch?.[1] && currentScenario) {
89
+ currentScenario.then.push(thenMatch[1]);
90
+ continue;
91
+ }
92
+ // AND
93
+ const andMatch = line.match(/^\s*-\s*\*\*AND\*\*\s*(.+)$/);
94
+ if (andMatch?.[1] && currentScenario) {
95
+ currentScenario.and.push(andMatch[1]);
96
+ continue;
97
+ }
98
+ // Description lines
99
+ if (inDescription && line.trim()) {
100
+ descriptionLines.push(line);
101
+ }
102
+ }
103
+ // Don't forget the last ones
104
+ if (currentRequirement) {
105
+ if (currentScenario) {
106
+ currentRequirement.scenarios.push(currentScenario);
107
+ }
108
+ if (inDescription) {
109
+ currentRequirement.description = descriptionLines.join('\n').trim();
110
+ }
111
+ spec.requirements.push(currentRequirement);
112
+ }
113
+ return spec;
114
+ }
115
+ /**
116
+ * Parse a delta spec document
117
+ */
118
+ export function parseDeltaSpec(content) {
119
+ const delta = {
120
+ added: [],
121
+ modified: [],
122
+ removed: [],
123
+ renamed: [],
124
+ };
125
+ const lines = content.split('\n');
126
+ let currentSection = null;
127
+ let currentRequirement = null;
128
+ let currentScenario = null;
129
+ let currentRemoved = null;
130
+ // Helper to save current state before section change
131
+ const saveCurrentState = () => {
132
+ if (currentRequirement) {
133
+ if (currentScenario) {
134
+ currentRequirement.scenarios.push(currentScenario);
135
+ currentScenario = null;
136
+ }
137
+ if (currentSection === 'added') {
138
+ delta.added.push(currentRequirement);
139
+ }
140
+ else if (currentSection === 'modified') {
141
+ delta.modified.push(currentRequirement);
142
+ }
143
+ currentRequirement = null;
144
+ }
145
+ if (currentRemoved) {
146
+ delta.removed.push(currentRemoved);
147
+ currentRemoved = null;
148
+ }
149
+ };
150
+ for (const line of lines) {
151
+ // Section headers - save state before changing section
152
+ if (line.match(/^## ADDED Requirements/i)) {
153
+ saveCurrentState();
154
+ currentSection = 'added';
155
+ continue;
156
+ }
157
+ if (line.match(/^## MODIFIED Requirements/i)) {
158
+ saveCurrentState();
159
+ currentSection = 'modified';
160
+ continue;
161
+ }
162
+ if (line.match(/^## REMOVED Requirements/i)) {
163
+ saveCurrentState();
164
+ currentSection = 'removed';
165
+ continue;
166
+ }
167
+ if (line.match(/^## RENAMED Requirements/i)) {
168
+ saveCurrentState();
169
+ currentSection = 'renamed';
170
+ continue;
171
+ }
172
+ // Requirement
173
+ const reqMatch = line.match(/^### Requirement: (.+)$/);
174
+ if (reqMatch?.[1] && currentSection) {
175
+ // Save previous
176
+ if (currentRequirement && (currentSection === 'added' || currentSection === 'modified')) {
177
+ if (currentScenario) {
178
+ currentRequirement.scenarios.push(currentScenario);
179
+ }
180
+ if (currentSection === 'added') {
181
+ delta.added.push(currentRequirement);
182
+ }
183
+ else {
184
+ delta.modified.push(currentRequirement);
185
+ }
186
+ }
187
+ if (currentRemoved && currentSection === 'removed') {
188
+ delta.removed.push(currentRemoved);
189
+ }
190
+ if (currentSection === 'removed') {
191
+ currentRemoved = { name: reqMatch[1] };
192
+ currentRequirement = null;
193
+ }
194
+ else {
195
+ currentRequirement = {
196
+ name: reqMatch[1],
197
+ description: '',
198
+ scenarios: [],
199
+ };
200
+ currentRemoved = null;
201
+ }
202
+ currentScenario = null;
203
+ continue;
204
+ }
205
+ // Reason/Migration for removed
206
+ if (currentSection === 'removed' && currentRemoved) {
207
+ const reasonMatch = line.match(/^\*\*Reason\*\*:\s*(.+)$/);
208
+ if (reasonMatch?.[1]) {
209
+ currentRemoved.reason = reasonMatch[1];
210
+ continue;
211
+ }
212
+ const migrationMatch = line.match(/^\*\*Migration\*\*:\s*(.+)$/);
213
+ if (migrationMatch?.[1]) {
214
+ currentRemoved.migration = migrationMatch[1];
215
+ continue;
216
+ }
217
+ }
218
+ // Renamed
219
+ if (currentSection === 'renamed') {
220
+ const fromMatch = line.match(/^- FROM:.*`### Requirement: (.+)`/);
221
+ const toMatch = line.match(/^- TO:.*`### Requirement: (.+)`/);
222
+ if (fromMatch?.[1]) {
223
+ delta.renamed.push({ from: fromMatch[1], to: '' });
224
+ }
225
+ if (toMatch?.[1] && delta.renamed.length > 0) {
226
+ const last = delta.renamed[delta.renamed.length - 1];
227
+ if (last) {
228
+ last.to = toMatch[1];
229
+ }
230
+ }
231
+ continue;
232
+ }
233
+ // Scenario (for added/modified)
234
+ const scenarioMatch = line.match(/^#### Scenario: (.+)$/);
235
+ if (scenarioMatch?.[1] && currentRequirement) {
236
+ if (currentScenario) {
237
+ currentRequirement.scenarios.push(currentScenario);
238
+ }
239
+ currentScenario = {
240
+ name: scenarioMatch[1],
241
+ when: '',
242
+ then: [],
243
+ and: [],
244
+ };
245
+ continue;
246
+ }
247
+ // WHEN/THEN/AND
248
+ if (currentScenario) {
249
+ const whenMatch = line.match(/^\s*-\s*\*\*WHEN\*\*\s*(.+)$/);
250
+ if (whenMatch?.[1]) {
251
+ currentScenario.when = whenMatch[1];
252
+ continue;
253
+ }
254
+ const thenMatch = line.match(/^\s*-\s*\*\*THEN\*\*\s*(.+)$/);
255
+ if (thenMatch?.[1]) {
256
+ currentScenario.then.push(thenMatch[1]);
257
+ continue;
258
+ }
259
+ const andMatch = line.match(/^\s*-\s*\*\*AND\*\*\s*(.+)$/);
260
+ if (andMatch?.[1]) {
261
+ currentScenario.and.push(andMatch[1]);
262
+ continue;
263
+ }
264
+ }
265
+ }
266
+ // Don't forget the last ones
267
+ if (currentRequirement) {
268
+ if (currentScenario) {
269
+ currentRequirement.scenarios.push(currentScenario);
270
+ }
271
+ if (currentSection === 'added') {
272
+ delta.added.push(currentRequirement);
273
+ }
274
+ else if (currentSection === 'modified') {
275
+ delta.modified.push(currentRequirement);
276
+ }
277
+ }
278
+ if (currentRemoved && currentSection === 'removed') {
279
+ delta.removed.push(currentRemoved);
280
+ }
281
+ return delta;
282
+ }
283
+ /**
284
+ * Serialize a spec back to markdown
285
+ */
286
+ export function serializeSpec(spec) {
287
+ const lines = [];
288
+ // Title
289
+ lines.push(`# ${spec.title} Specification`);
290
+ lines.push('');
291
+ // Purpose
292
+ if (spec.purpose) {
293
+ lines.push('## Purpose');
294
+ lines.push('');
295
+ lines.push(spec.purpose);
296
+ lines.push('');
297
+ }
298
+ // Requirements
299
+ lines.push('## Requirements');
300
+ lines.push('');
301
+ for (const req of spec.requirements) {
302
+ lines.push(`### Requirement: ${req.name}`);
303
+ lines.push('');
304
+ if (req.description) {
305
+ lines.push(req.description);
306
+ lines.push('');
307
+ }
308
+ for (const scenario of req.scenarios) {
309
+ lines.push(`#### Scenario: ${scenario.name}`);
310
+ lines.push(`- **WHEN** ${scenario.when}`);
311
+ for (const then of scenario.then) {
312
+ lines.push(`- **THEN** ${then}`);
313
+ }
314
+ for (const and of scenario.and) {
315
+ lines.push(`- **AND** ${and}`);
316
+ }
317
+ lines.push('');
318
+ }
319
+ }
320
+ return lines.join('\n');
321
+ }
322
+ //# sourceMappingURL=spec-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-parser.js","sourceRoot":"","sources":["../../../src/core/parsers/spec-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Spec Validation Module
3
+ *
4
+ * Validates spec documents for structure, content, consistency, and completeness.
5
+ */
6
+ export interface ValidationIssue {
7
+ type: 'error' | 'warning';
8
+ code: string;
9
+ message: string;
10
+ line?: number;
11
+ }
12
+ export interface ValidationResult {
13
+ valid: boolean;
14
+ errors: ValidationIssue[];
15
+ warnings: ValidationIssue[];
16
+ stats: {
17
+ requirements: number;
18
+ scenarios: number;
19
+ };
20
+ }
21
+ /**
22
+ * Validate a spec document
23
+ */
24
+ export declare function validateSpec(content: string, name: string, isDelta?: boolean): ValidationResult;
25
+ /**
26
+ * Validate multiple specs for cross-spec consistency
27
+ */
28
+ export declare function validateSpecSet(specs: Map<string, string>): {
29
+ valid: boolean;
30
+ issues: ValidationIssue[];
31
+ };
32
+ //# sourceMappingURL=spec-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-validator.d.ts","sourceRoot":"","sources":["../../../src/core/validation/spec-validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,OAAe,GACvB,gBAAgB,CAyMlB;AAgCD;;GAEG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACzB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,eAAe,EAAE,CAAA;CAAE,CAyB/C"}
@@ -0,0 +1,242 @@
1
+ /**
2
+ * Spec Validation Module
3
+ *
4
+ * Validates spec documents for structure, content, consistency, and completeness.
5
+ */
6
+ /**
7
+ * Validate a spec document
8
+ */
9
+ export function validateSpec(content, name, isDelta = false) {
10
+ const errors = [];
11
+ const warnings = [];
12
+ const lines = content.split('\n');
13
+ let requirementCount = 0;
14
+ let scenarioCount = 0;
15
+ let currentRequirement = null;
16
+ let currentScenario = null;
17
+ let hasWhen = false;
18
+ let hasThen = false;
19
+ const seenRequirements = new Set();
20
+ const seenScenarios = new Set();
21
+ // Check header
22
+ const hasTitle = lines.some(l => l.match(/^# .+/));
23
+ if (!hasTitle && !isDelta) {
24
+ errors.push({
25
+ type: 'error',
26
+ code: 'MISSING_TITLE',
27
+ message: 'Spec must have a title (# header)',
28
+ });
29
+ }
30
+ // Check Purpose section (not required for delta)
31
+ const hasPurpose = content.includes('## Purpose');
32
+ if (!hasPurpose && !isDelta) {
33
+ warnings.push({
34
+ type: 'warning',
35
+ code: 'MISSING_PURPOSE',
36
+ message: 'Spec should have a Purpose section',
37
+ });
38
+ }
39
+ // Parse line by line
40
+ for (let i = 0; i < lines.length; i++) {
41
+ const line = lines[i] ?? '';
42
+ const lineNum = i + 1;
43
+ // Check for requirement
44
+ const reqMatch = line.match(/^### Requirement: (.+)$/);
45
+ if (reqMatch?.[1]) {
46
+ // Save previous scenario state
47
+ if (currentScenario && !hasWhen) {
48
+ errors.push({
49
+ type: 'error',
50
+ code: 'MISSING_WHEN',
51
+ message: `Scenario "${currentScenario}" is missing WHEN clause`,
52
+ });
53
+ }
54
+ if (currentScenario && !hasThen) {
55
+ errors.push({
56
+ type: 'error',
57
+ code: 'MISSING_THEN',
58
+ message: `Scenario "${currentScenario}" is missing THEN clause`,
59
+ });
60
+ }
61
+ // Check for duplicate requirement
62
+ if (seenRequirements.has(reqMatch[1])) {
63
+ errors.push({
64
+ type: 'error',
65
+ code: 'DUPLICATE_REQUIREMENT',
66
+ message: `Duplicate requirement name: "${reqMatch[1]}"`,
67
+ line: lineNum,
68
+ });
69
+ }
70
+ seenRequirements.add(reqMatch[1]);
71
+ currentRequirement = reqMatch[1];
72
+ currentScenario = null;
73
+ hasWhen = false;
74
+ hasThen = false;
75
+ requirementCount++;
76
+ continue;
77
+ }
78
+ // Check for scenario
79
+ const scenarioMatch = line.match(/^#### Scenario: (.+)$/);
80
+ if (scenarioMatch?.[1]) {
81
+ // Save previous scenario state
82
+ if (currentScenario && !hasWhen) {
83
+ errors.push({
84
+ type: 'error',
85
+ code: 'MISSING_WHEN',
86
+ message: `Scenario "${currentScenario}" is missing WHEN clause`,
87
+ });
88
+ }
89
+ if (currentScenario && !hasThen) {
90
+ errors.push({
91
+ type: 'error',
92
+ code: 'MISSING_THEN',
93
+ message: `Scenario "${currentScenario}" is missing THEN clause`,
94
+ });
95
+ }
96
+ // Check if scenario is under a requirement
97
+ if (!currentRequirement && !isDelta) {
98
+ errors.push({
99
+ type: 'error',
100
+ code: 'ORPHAN_SCENARIO',
101
+ message: `Scenario "${scenarioMatch[1]}" is not under a Requirement`,
102
+ line: lineNum,
103
+ });
104
+ }
105
+ // Check for duplicate scenario
106
+ const scenarioKey = `${currentRequirement}/${scenarioMatch[1]}`;
107
+ if (seenScenarios.has(scenarioKey)) {
108
+ errors.push({
109
+ type: 'error',
110
+ code: 'DUPLICATE_SCENARIO',
111
+ message: `Duplicate scenario name: "${scenarioMatch[1]}" under "${currentRequirement}"`,
112
+ line: lineNum,
113
+ });
114
+ }
115
+ seenScenarios.add(scenarioKey);
116
+ currentScenario = scenarioMatch[1];
117
+ hasWhen = false;
118
+ hasThen = false;
119
+ scenarioCount++;
120
+ continue;
121
+ }
122
+ // Check for WHEN
123
+ if (line.match(/^\s*-\s*\*\*WHEN\*\*/)) {
124
+ if (!currentScenario) {
125
+ errors.push({
126
+ type: 'error',
127
+ code: 'ORPHAN_WHEN',
128
+ message: 'WHEN clause found outside of a Scenario',
129
+ line: lineNum,
130
+ });
131
+ }
132
+ hasWhen = true;
133
+ continue;
134
+ }
135
+ // Check for THEN
136
+ if (line.match(/^\s*-\s*\*\*THEN\*\*/)) {
137
+ if (!currentScenario) {
138
+ errors.push({
139
+ type: 'error',
140
+ code: 'ORPHAN_THEN',
141
+ message: 'THEN clause found outside of a Scenario',
142
+ line: lineNum,
143
+ });
144
+ }
145
+ hasThen = true;
146
+ continue;
147
+ }
148
+ // Check for weak language in requirements
149
+ if (currentRequirement && !currentScenario) {
150
+ if (line.match(/\bshould\b/i) && !line.match(/\bSHOULD\b/)) {
151
+ warnings.push({
152
+ type: 'warning',
153
+ code: 'WEAK_LANGUAGE',
154
+ message: 'Consider using SHALL/MUST for mandatory behavior',
155
+ line: lineNum,
156
+ });
157
+ }
158
+ }
159
+ }
160
+ // Check final scenario
161
+ if (currentScenario && !hasWhen) {
162
+ errors.push({
163
+ type: 'error',
164
+ code: 'MISSING_WHEN',
165
+ message: `Scenario "${currentScenario}" is missing WHEN clause`,
166
+ });
167
+ }
168
+ if (currentScenario && !hasThen) {
169
+ errors.push({
170
+ type: 'error',
171
+ code: 'MISSING_THEN',
172
+ message: `Scenario "${currentScenario}" is missing THEN clause`,
173
+ });
174
+ }
175
+ // Check for requirements without scenarios
176
+ if (!isDelta) {
177
+ // This requires more complex parsing, skip for now
178
+ }
179
+ // Validate delta-specific rules
180
+ if (isDelta) {
181
+ validateDeltaSpec(content, errors, warnings);
182
+ }
183
+ return {
184
+ valid: errors.length === 0,
185
+ errors,
186
+ warnings,
187
+ stats: {
188
+ requirements: requirementCount,
189
+ scenarios: scenarioCount,
190
+ },
191
+ };
192
+ }
193
+ function validateDeltaSpec(content, errors, warnings) {
194
+ // Check delta sections
195
+ const hasDeltaSections = content.includes('## ADDED') ||
196
+ content.includes('## MODIFIED') ||
197
+ content.includes('## REMOVED') ||
198
+ content.includes('## RENAMED');
199
+ // If has MODIFIED section, warn about exact name matching
200
+ if (content.includes('## MODIFIED')) {
201
+ // Could add validation against main spec here
202
+ }
203
+ // If has REMOVED section, check for reason
204
+ if (content.includes('## REMOVED')) {
205
+ const removedSection = content.match(/## REMOVED Requirements[\s\S]*?(?=## |$)/);
206
+ if (removedSection?.[0] && !removedSection[0].includes('**Reason**')) {
207
+ warnings.push({
208
+ type: 'warning',
209
+ code: 'REMOVED_NO_REASON',
210
+ message: 'REMOVED requirements should include a Reason',
211
+ });
212
+ }
213
+ }
214
+ }
215
+ /**
216
+ * Validate multiple specs for cross-spec consistency
217
+ */
218
+ export function validateSpecSet(specs) {
219
+ const issues = [];
220
+ const allRequirements = new Map();
221
+ for (const [name, content] of specs) {
222
+ // Check for duplicate requirements across specs
223
+ const reqMatches = content.matchAll(/^### Requirement: (.+)$/gm);
224
+ for (const match of reqMatches) {
225
+ if (match[1]) {
226
+ if (allRequirements.has(match[1])) {
227
+ issues.push({
228
+ type: 'error',
229
+ code: 'CROSS_SPEC_DUPLICATE',
230
+ message: `Requirement "${match[1]}" exists in both "${allRequirements.get(match[1])}" and "${name}"`,
231
+ });
232
+ }
233
+ allRequirements.set(match[1], name);
234
+ }
235
+ }
236
+ }
237
+ return {
238
+ valid: issues.filter(i => i.type === 'error').length === 0,
239
+ issues,
240
+ };
241
+ }
242
+ //# sourceMappingURL=spec-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-validator.js","sourceRoot":"","sources":["../../../src/core/validation/spec-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * SuperSpec - Unified Spec-Driven Development Framework
3
+ *
4
+ * Core Principle:
5
+ * Every Scenario becomes a test, every test traces to a Scenario.
6
+ *
7
+ * @module superspec
8
+ */
9
+ export { validateSpec, validateSpecSet } from './core/validation/spec-validator.js';
10
+ export type { ValidationResult, ValidationIssue } from './core/validation/spec-validator.js';
11
+ export { parseSpec, parseDeltaSpec, serializeSpec } from './core/parsers/spec-parser.js';
12
+ export type { Spec, DeltaSpec, Requirement, Scenario } from './core/parsers/spec-parser.js';
13
+ export { loadProjectConfig, getDefaultConfig, serializeConfig } from './core/config/project-config.js';
14
+ export type { ProjectConfig } from './core/config/project-config.js';
15
+ /**
16
+ * SuperSpec version
17
+ */
18
+ export declare const VERSION = "0.1.0";
19
+ /**
20
+ * Core principles (Iron Laws)
21
+ */
22
+ export declare const IRON_LAWS: {
23
+ readonly TDD: "NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST";
24
+ readonly SPECS: "SPECS ARE TRUTH. CHANGES ARE PROPOSALS.";
25
+ readonly SUPERSPEC: "EVERY SCENARIO BECOMES A TEST. EVERY TEST TRACES TO A SCENARIO.";
26
+ };
27
+ /**
28
+ * Workflow phases
29
+ */
30
+ export declare const WORKFLOW_PHASES: readonly ["brainstorm", "plan", "execute", "verify", "archive"];
31
+ /**
32
+ * Brainstorm sub-phases
33
+ */
34
+ export declare const BRAINSTORM_PHASES: readonly ["explore", "propose", "design", "spec"];
35
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACpF,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAE7F,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACzF,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAE5F,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvG,YAAY,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAErE;;GAEG;AACH,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B;;GAEG;AACH,eAAO,MAAM,SAAS;;;;CAIZ,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,eAAe,iEAMlB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,iBAAiB,mDAKpB,CAAC"}