@specsafe/core 0.4.0 → 0.6.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 (157) hide show
  1. package/dist/agents/adapters/base.d.ts +44 -0
  2. package/dist/agents/adapters/base.d.ts.map +1 -0
  3. package/dist/agents/adapters/base.js +164 -0
  4. package/dist/agents/adapters/base.js.map +1 -0
  5. package/dist/agents/adapters/claude-code.d.ts +14 -0
  6. package/dist/agents/adapters/claude-code.d.ts.map +1 -0
  7. package/dist/agents/adapters/claude-code.js +120 -0
  8. package/dist/agents/adapters/claude-code.js.map +1 -0
  9. package/dist/agents/adapters/copilot.d.ts +13 -0
  10. package/dist/agents/adapters/copilot.d.ts.map +1 -0
  11. package/dist/agents/adapters/copilot.js +115 -0
  12. package/dist/agents/adapters/copilot.js.map +1 -0
  13. package/dist/agents/adapters/cursor.d.ts +13 -0
  14. package/dist/agents/adapters/cursor.d.ts.map +1 -0
  15. package/dist/agents/adapters/cursor.js +105 -0
  16. package/dist/agents/adapters/cursor.js.map +1 -0
  17. package/dist/agents/adapters/gemini-cli.d.ts +13 -0
  18. package/dist/agents/adapters/gemini-cli.d.ts.map +1 -0
  19. package/dist/agents/adapters/gemini-cli.js +79 -0
  20. package/dist/agents/adapters/gemini-cli.js.map +1 -0
  21. package/dist/agents/adapters/index.d.ts +16 -0
  22. package/dist/agents/adapters/index.d.ts.map +1 -0
  23. package/dist/agents/adapters/index.js +47 -0
  24. package/dist/agents/adapters/index.js.map +1 -0
  25. package/dist/agents/adapters/opencode.d.ts +13 -0
  26. package/dist/agents/adapters/opencode.d.ts.map +1 -0
  27. package/dist/agents/adapters/opencode.js +67 -0
  28. package/dist/agents/adapters/opencode.js.map +1 -0
  29. package/dist/agents/index.d.ts +8 -0
  30. package/dist/agents/index.d.ts.map +1 -0
  31. package/dist/agents/index.js +9 -0
  32. package/dist/agents/index.js.map +1 -0
  33. package/dist/agents/registry.d.ts +70 -0
  34. package/dist/agents/registry.d.ts.map +1 -0
  35. package/dist/agents/registry.js +194 -0
  36. package/dist/agents/registry.js.map +1 -0
  37. package/dist/agents/types.d.ts +71 -0
  38. package/dist/agents/types.d.ts.map +1 -0
  39. package/dist/agents/types.js +6 -0
  40. package/dist/agents/types.js.map +1 -0
  41. package/dist/delta/merger.d.ts +36 -0
  42. package/dist/delta/merger.d.ts.map +1 -0
  43. package/dist/delta/merger.js +264 -0
  44. package/dist/delta/merger.js.map +1 -0
  45. package/dist/delta/parser.d.ts +27 -0
  46. package/dist/delta/parser.d.ts.map +1 -0
  47. package/dist/delta/parser.js +196 -0
  48. package/dist/delta/parser.js.map +1 -0
  49. package/dist/delta/types.d.ts +39 -0
  50. package/dist/delta/types.d.ts.map +1 -0
  51. package/dist/delta/types.js +6 -0
  52. package/dist/delta/types.js.map +1 -0
  53. package/dist/ears/index.d.ts +11 -0
  54. package/dist/ears/index.d.ts.map +1 -0
  55. package/dist/ears/index.js +11 -0
  56. package/dist/ears/index.js.map +1 -0
  57. package/dist/ears/parser.d.ts +22 -0
  58. package/dist/ears/parser.d.ts.map +1 -0
  59. package/dist/ears/parser.js +273 -0
  60. package/dist/ears/parser.js.map +1 -0
  61. package/dist/ears/template.d.ts +20 -0
  62. package/dist/ears/template.d.ts.map +1 -0
  63. package/dist/ears/template.js +364 -0
  64. package/dist/ears/template.js.map +1 -0
  65. package/dist/ears/types.d.ts +58 -0
  66. package/dist/ears/types.d.ts.map +1 -0
  67. package/dist/ears/types.js +6 -0
  68. package/dist/ears/types.js.map +1 -0
  69. package/dist/ears/validator.d.ts +37 -0
  70. package/dist/ears/validator.d.ts.map +1 -0
  71. package/dist/ears/validator.js +234 -0
  72. package/dist/ears/validator.js.map +1 -0
  73. package/dist/elicitation/engine.d.ts +75 -0
  74. package/dist/elicitation/engine.d.ts.map +1 -0
  75. package/dist/elicitation/engine.js +174 -0
  76. package/dist/elicitation/engine.js.map +1 -0
  77. package/dist/elicitation/flows.d.ts +18 -0
  78. package/dist/elicitation/flows.d.ts.map +1 -0
  79. package/dist/elicitation/flows.js +331 -0
  80. package/dist/elicitation/flows.js.map +1 -0
  81. package/dist/elicitation/generator.d.ts +20 -0
  82. package/dist/elicitation/generator.d.ts.map +1 -0
  83. package/dist/elicitation/generator.js +260 -0
  84. package/dist/elicitation/generator.js.map +1 -0
  85. package/dist/elicitation/index.d.ts +27 -0
  86. package/dist/elicitation/index.d.ts.map +1 -0
  87. package/dist/elicitation/index.js +29 -0
  88. package/dist/elicitation/index.js.map +1 -0
  89. package/dist/elicitation/types.d.ts +69 -0
  90. package/dist/elicitation/types.d.ts.map +1 -0
  91. package/dist/elicitation/types.js +6 -0
  92. package/dist/elicitation/types.js.map +1 -0
  93. package/dist/extensions/builtins/complexity.d.ts +7 -0
  94. package/dist/extensions/builtins/complexity.d.ts.map +1 -0
  95. package/dist/extensions/builtins/complexity.js +97 -0
  96. package/dist/extensions/builtins/complexity.js.map +1 -0
  97. package/dist/extensions/builtins/owasp.d.ts +7 -0
  98. package/dist/extensions/builtins/owasp.d.ts.map +1 -0
  99. package/dist/extensions/builtins/owasp.js +76 -0
  100. package/dist/extensions/builtins/owasp.js.map +1 -0
  101. package/dist/extensions/index.d.ts +54 -0
  102. package/dist/extensions/index.d.ts.map +1 -0
  103. package/dist/extensions/index.js +72 -0
  104. package/dist/extensions/index.js.map +1 -0
  105. package/dist/extensions/loader.d.ts +28 -0
  106. package/dist/extensions/loader.d.ts.map +1 -0
  107. package/dist/extensions/loader.js +62 -0
  108. package/dist/extensions/loader.js.map +1 -0
  109. package/dist/extensions/registry.d.ts +74 -0
  110. package/dist/extensions/registry.d.ts.map +1 -0
  111. package/dist/extensions/registry.js +159 -0
  112. package/dist/extensions/registry.js.map +1 -0
  113. package/dist/extensions/types.d.ts +70 -0
  114. package/dist/extensions/types.d.ts.map +1 -0
  115. package/dist/extensions/types.js +2 -0
  116. package/dist/extensions/types.js.map +1 -0
  117. package/dist/governance/builtins.d.ts +7 -0
  118. package/dist/governance/builtins.d.ts.map +1 -0
  119. package/dist/governance/builtins.js +105 -0
  120. package/dist/governance/builtins.js.map +1 -0
  121. package/dist/governance/constitution.d.ts +23 -0
  122. package/dist/governance/constitution.d.ts.map +1 -0
  123. package/dist/governance/constitution.js +245 -0
  124. package/dist/governance/constitution.js.map +1 -0
  125. package/dist/governance/index.d.ts +3 -0
  126. package/dist/governance/index.d.ts.map +1 -0
  127. package/dist/governance/index.js +2 -0
  128. package/dist/governance/index.js.map +1 -0
  129. package/dist/governance/template.d.ts +12 -0
  130. package/dist/governance/template.d.ts.map +1 -0
  131. package/dist/governance/template.js +84 -0
  132. package/dist/governance/template.js.map +1 -0
  133. package/dist/governance/types.d.ts +64 -0
  134. package/dist/governance/types.d.ts.map +1 -0
  135. package/dist/governance/types.js +2 -0
  136. package/dist/governance/types.js.map +1 -0
  137. package/dist/index.d.ts +23 -18
  138. package/dist/index.d.ts.map +1 -1
  139. package/dist/index.js +17 -18
  140. package/dist/index.js.map +1 -1
  141. package/dist/templates/checklist.d.ts +7 -0
  142. package/dist/templates/checklist.d.ts.map +1 -0
  143. package/dist/templates/checklist.js +131 -0
  144. package/dist/templates/checklist.js.map +1 -0
  145. package/dist/templates/delta-template.d.ts +18 -0
  146. package/dist/templates/delta-template.d.ts.map +1 -0
  147. package/dist/templates/delta-template.js +191 -0
  148. package/dist/templates/delta-template.js.map +1 -0
  149. package/dist/templates/engine.d.ts +20 -0
  150. package/dist/templates/engine.d.ts.map +1 -0
  151. package/dist/templates/engine.js +187 -0
  152. package/dist/templates/engine.js.map +1 -0
  153. package/dist/templates/types.d.ts +67 -0
  154. package/dist/templates/types.d.ts.map +1 -0
  155. package/dist/templates/types.js +5 -0
  156. package/dist/templates/types.js.map +1 -0
  157. package/package.json +1 -1
@@ -0,0 +1,364 @@
1
+ /**
2
+ * EARS Template Generator
3
+ * Creates spec templates with EARS requirement format
4
+ */
5
+ /**
6
+ * Generate an EARS-formatted spec template
7
+ */
8
+ export function generateEARSTemplate(id, name, author, priority = 'P1') {
9
+ const today = new Date().toISOString().split('T')[0];
10
+ return `# ${name} Specification (EARS Format)
11
+
12
+ **ID:** ${id}
13
+ **Status:** SPEC
14
+ **Created:** ${today}
15
+ **Author:** ${author}
16
+ **Priority:** ${priority}
17
+
18
+ ---
19
+
20
+ ## EARS Guide
21
+
22
+ This spec uses **EARS (Easy Approach to Requirements Syntax)** for testable requirements.
23
+
24
+ ### EARS Patterns
25
+
26
+ #### 🌐 Ubiquitous (Always Active)
27
+ **Pattern:** "The system shall [action]"
28
+ **Use when:** Requirement applies at all times, no conditions
29
+
30
+ **Example:**
31
+ - The system shall encrypt all data at rest using AES-256
32
+ - The system shall log all authentication attempts
33
+
34
+ ---
35
+
36
+ #### ⚡ Event-Driven (Triggered by Events)
37
+ **Pattern:** "When [event], the system shall [action]"
38
+ **Use when:** Requirement is triggered by a specific event
39
+
40
+ **Example:**
41
+ - When user clicks "Submit", the system shall validate all form fields
42
+ - When payment is received, the system shall send a confirmation email
43
+
44
+ ---
45
+
46
+ #### 🔄 State-Driven (Active During State)
47
+ **Pattern:** "While [state], the system shall [action]"
48
+ **Use when:** Requirement applies during a specific state
49
+
50
+ **Example:**
51
+ - While user session is active, the system shall refresh the authentication token every 30 minutes
52
+ - While processing a transaction, the system shall prevent duplicate submissions
53
+
54
+ ---
55
+
56
+ #### 🔀 Optional (Feature Available)
57
+ **Pattern:** "Where [condition], the system shall [action]"
58
+ **Use when:** Requirement applies when optional feature/condition is present
59
+
60
+ **Example:**
61
+ - Where user has admin privileges, the system shall display the settings menu
62
+ - Where GPS is enabled, the system shall track location history
63
+
64
+ ---
65
+
66
+ #### 🚫 Unwanted Behavior (Error Handling)
67
+ **Pattern:** "If [unwanted condition], then the system shall [action]"
68
+ **Use when:** Requirement handles errors or unwanted states
69
+
70
+ **Example:**
71
+ - If network connection is lost, then the system shall queue requests for retry
72
+ - If user enters invalid credentials 3 times, then the system shall lock the account
73
+
74
+ ---
75
+
76
+ #### 🔗 Complex (Multiple Conditions)
77
+ **Pattern:** "When [event], while [state], the system shall [action]"
78
+ **Use when:** Multiple conditions must be met
79
+
80
+ **Example:**
81
+ - When user uploads a file, while file size exceeds 10MB, the system shall compress the file
82
+ - Where user has premium subscription, when downloading content, the system shall allow offline access
83
+
84
+ ---
85
+
86
+ ## PRD (Product Requirements Document)
87
+
88
+ ### Problem Statement
89
+ <!-- Describe the problem this feature solves -->
90
+
91
+ ### User Stories
92
+ \`\`\`
93
+ As a [type of user]
94
+ I want [some goal]
95
+ So that [some reason]
96
+ \`\`\`
97
+
98
+ ### Success Criteria
99
+ - [ ] All requirements follow EARS patterns
100
+ - [ ] All requirements are testable
101
+ - [ ] All tests pass
102
+
103
+ ---
104
+
105
+ ## Requirements (EARS Format)
106
+
107
+ ### Functional Requirements
108
+
109
+ | ID | EARS Pattern | Requirement | Priority |
110
+ |----|--------------|-------------|----------|
111
+ | FR-1 | Ubiquitous | The system shall [action] | P0 |
112
+ | FR-2 | Event | When [event], the system shall [action] | P0 |
113
+ | FR-3 | State | While [state], the system shall [action] | P1 |
114
+ | FR-4 | Optional | Where [condition], the system shall [action] | P1 |
115
+ | FR-5 | Unwanted | If [error], then the system shall [action] | P2 |
116
+
117
+ **Example Requirements:**
118
+ - **Ubiquitous:** The system shall store all user data in encrypted format
119
+ - **Event-driven:** When user completes checkout, the system shall generate an order confirmation
120
+ - **State-driven:** While user is in offline mode, the system shall cache all changes locally
121
+ - **Optional:** Where user enables notifications, the system shall send real-time alerts
122
+ - **Unwanted:** If API request fails, then the system shall retry with exponential backoff
123
+
124
+ ### Non-Functional Requirements
125
+
126
+ | ID | EARS Pattern | Requirement | Metric |
127
+ |----|--------------|-------------|--------|
128
+ | NFR-1 | Ubiquitous | The system shall respond to requests | < 200ms (p95) |
129
+ | NFR-2 | State | While under peak load, the system shall maintain availability | > 99.9% |
130
+
131
+ **Example Requirements:**
132
+ - The system shall handle up to 10,000 concurrent users
133
+ - While processing batch jobs, the system shall maintain CPU usage below 80%
134
+
135
+ ---
136
+
137
+ ## Scenarios (Given/When/Then)
138
+
139
+ EARS requirements naturally map to test scenarios:
140
+
141
+ ### Scenario 1: [EARS Pattern Type]
142
+ **Requirement:** [Copy EARS requirement here]
143
+
144
+ - **Given** [initial state/context]
145
+ - **When** [action/event occurs]
146
+ - **Then** [expected outcome matching the EARS action]
147
+
148
+ **Example:**
149
+ **Requirement:** When user submits payment form, the system shall validate credit card number
150
+
151
+ - **Given** user has entered payment information
152
+ - **When** user clicks "Pay Now" button
153
+ - **Then** system validates card number format
154
+ - **And** system displays validation errors if invalid
155
+ - **And** system processes payment if valid
156
+
157
+ ---
158
+
159
+ ### Scenario 2: [Another Pattern]
160
+ **Requirement:** [Another EARS requirement]
161
+
162
+ - **Given** [context]
163
+ - **When** [trigger]
164
+ - **Then** [outcome]
165
+
166
+ ---
167
+
168
+ ## Technical Approach
169
+
170
+ ### Implementation Checklist
171
+ For each EARS requirement:
172
+ - [ ] Write unit test matching the EARS action
173
+ - [ ] Implement the action handler
174
+ - [ ] Add integration test for the complete flow
175
+ - [ ] Verify error handling (for "unwanted" patterns)
176
+
177
+ ### Testing Strategy
178
+
179
+ **Event-driven requirements:**
180
+ - Test the event trigger
181
+ - Test the action execution
182
+ - Test edge cases (event occurs multiple times, etc.)
183
+
184
+ **State-driven requirements:**
185
+ - Test state entry/exit
186
+ - Test action during state
187
+ - Test behavior outside the state
188
+
189
+ **Unwanted behavior requirements:**
190
+ - Test the error condition
191
+ - Test the recovery action
192
+ - Test system state after recovery
193
+
194
+ ---
195
+
196
+ ## EARS Quality Checklist
197
+
198
+ Before moving to TEST stage, verify:
199
+
200
+ - [ ] All requirements use EARS patterns (ubiquitous, event, state, optional, unwanted, or complex)
201
+ - [ ] Each requirement has exactly one "shall" statement
202
+ - [ ] Each requirement is testable (can write pass/fail test)
203
+ - [ ] No ambiguous words (should, may, might, could)
204
+ - [ ] No vague terms (appropriate, reasonable, user-friendly)
205
+ - [ ] Modal verbs are consistent (shall/must/will, not mixed)
206
+ - [ ] Requirements are atomic (one requirement = one capability)
207
+ - [ ] Complex requirements are justified (can't be split)
208
+
209
+ Run: \`specsafe qa ${id} --ears\` to validate EARS compliance
210
+
211
+ ---
212
+
213
+ ## Notes
214
+
215
+ ### EARS Benefits
216
+ 1. **Testability:** Each pattern directly maps to test scenarios
217
+ 2. **Clarity:** Explicit triggers and conditions
218
+ 3. **Completeness:** Forces you to think about edge cases (unwanted behavior)
219
+ 4. **Consistency:** Standardized language across team
220
+
221
+ ### Common Mistakes
222
+ - ❌ "The system should validate input" → Use "shall" not "should"
223
+ - ❌ "The system shall be fast" → Specify measurable criteria
224
+ - ❌ "When user clicks button, system processes data" → Add "the system shall"
225
+ - ❌ "The system shall validate and save data" → Split into two requirements
226
+
227
+ ---
228
+
229
+ *Generated by SpecSafe with EARS format*
230
+ `;
231
+ }
232
+ /**
233
+ * Generate EARS examples for a specific domain
234
+ */
235
+ export function generateEARSExamples(domain) {
236
+ const examples = {
237
+ web: {
238
+ ubiquitous: [
239
+ 'The system shall use HTTPS for all connections',
240
+ 'The system shall validate all user inputs before processing',
241
+ 'The system shall maintain session state using secure cookies'
242
+ ],
243
+ event: [
244
+ 'When user submits the form, the system shall validate all required fields',
245
+ 'When page load time exceeds 3 seconds, the system shall display a loading indicator',
246
+ 'When user clicks logout, the system shall clear all session data'
247
+ ],
248
+ state: [
249
+ 'While user is authenticated, the system shall display the user dashboard',
250
+ 'While form validation is in progress, the system shall disable the submit button',
251
+ 'While processing payment, the system shall prevent duplicate submissions'
252
+ ],
253
+ optional: [
254
+ 'Where user has enabled dark mode, the system shall apply dark color scheme',
255
+ 'Where user has admin role, the system shall display administrative controls',
256
+ 'Where browser supports service workers, the system shall enable offline mode'
257
+ ],
258
+ unwanted: [
259
+ 'If session expires, then the system shall redirect to login page',
260
+ 'If API request fails, then the system shall display error message to user',
261
+ 'If user enters invalid email format, then the system shall show format hint'
262
+ ],
263
+ complex: [
264
+ 'When user uploads a file, while file size exceeds 5MB, the system shall compress the file before upload',
265
+ 'Where user has premium subscription, when downloading content, the system shall allow offline access'
266
+ ]
267
+ },
268
+ mobile: {
269
+ ubiquitous: [
270
+ 'The system shall support iOS 15.0 and later',
271
+ 'The system shall cache user preferences locally',
272
+ 'The system shall request user permission before accessing location data'
273
+ ],
274
+ event: [
275
+ 'When app enters background, the system shall save current state',
276
+ 'When user pulls to refresh, the system shall reload content from server',
277
+ 'When notification is received, the system shall display badge count'
278
+ ],
279
+ state: [
280
+ 'While app is in offline mode, the system shall queue all network requests',
281
+ 'While device battery is below 20%, the system shall reduce background sync frequency',
282
+ 'While user is viewing media, the system shall prevent screen lock'
283
+ ],
284
+ optional: [
285
+ 'Where device supports biometric authentication, the system shall offer fingerprint login',
286
+ 'Where user grants camera permission, the system shall enable photo upload',
287
+ 'Where device supports push notifications, the system shall enable real-time alerts'
288
+ ],
289
+ unwanted: [
290
+ 'If network connection is lost, then the system shall display offline banner',
291
+ 'If location permission is denied, then the system shall use default location',
292
+ 'If app crashes, then the system shall restore previous state on relaunch'
293
+ ],
294
+ complex: [
295
+ 'When user takes a photo, while storage is nearly full, the system shall compress image quality',
296
+ 'Where user has disabled cellular data, when uploading content, the system shall wait for WiFi connection'
297
+ ]
298
+ },
299
+ api: {
300
+ ubiquitous: [
301
+ 'The system shall authenticate all API requests using JWT tokens',
302
+ 'The system shall rate limit requests to 100 per minute per API key',
303
+ 'The system shall log all API requests with timestamp and user ID'
304
+ ],
305
+ event: [
306
+ 'When API receives POST request, the system shall validate request body schema',
307
+ 'When rate limit is exceeded, the system shall return 429 Too Many Requests',
308
+ 'When authentication fails, the system shall return 401 Unauthorized'
309
+ ],
310
+ state: [
311
+ 'While maintenance mode is active, the system shall return 503 Service Unavailable',
312
+ 'While processing webhook, the system shall prevent concurrent processing of same event',
313
+ 'While database connection is unavailable, the system shall return 503 with retry-after header'
314
+ ],
315
+ optional: [
316
+ 'Where client provides API version header, the system shall use specified API version',
317
+ 'Where request includes pagination parameters, the system shall return paginated results',
318
+ 'Where client supports compression, the system shall compress response with gzip'
319
+ ],
320
+ unwanted: [
321
+ 'If request payload exceeds 10MB, then the system shall return 413 Payload Too Large',
322
+ 'If database query times out, then the system shall return 504 Gateway Timeout',
323
+ 'If request contains invalid JSON, then the system shall return 400 Bad Request with error details'
324
+ ],
325
+ complex: [
326
+ 'When API receives file upload, while file type is not allowed, the system shall return 415 Unsupported Media Type',
327
+ 'Where request includes webhook callback URL, when processing completes, the system shall POST results to callback'
328
+ ]
329
+ },
330
+ embedded: {
331
+ ubiquitous: [
332
+ 'The system shall monitor sensor readings every 100ms',
333
+ 'The system shall maintain operation within temperature range -40°C to 85°C',
334
+ 'The system shall consume less than 500mW in active mode'
335
+ ],
336
+ event: [
337
+ 'When button is pressed, the system shall debounce input for 50ms',
338
+ 'When power supply drops below 3.3V, the system shall trigger low battery warning',
339
+ 'When sensor detects motion, the system shall activate recording mode'
340
+ ],
341
+ state: [
342
+ 'While in sleep mode, the system shall reduce power consumption to < 10μW',
343
+ 'While calibrating sensors, the system shall ignore external inputs',
344
+ 'While firmware update is in progress, the system shall disable all other operations'
345
+ ],
346
+ optional: [
347
+ 'Where external RTC is available, the system shall use hardware clock',
348
+ 'Where temperature sensor is connected, the system shall log temperature data',
349
+ 'Where SD card is inserted, the system shall store logs to external storage'
350
+ ],
351
+ unwanted: [
352
+ 'If watchdog timer expires, then the system shall perform hardware reset',
353
+ 'If sensor reading is out of range, then the system shall use last known good value',
354
+ 'If memory allocation fails, then the system shall log error and continue with reduced functionality'
355
+ ],
356
+ complex: [
357
+ 'When motion is detected, while device is in power-save mode, the system shall wake up and begin recording',
358
+ 'Where battery level is below 10%, when sensor reading is requested, the system shall reduce sampling rate to conserve power'
359
+ ]
360
+ }
361
+ };
362
+ return examples[domain];
363
+ }
364
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/ears/template.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * EARS (Easy Approach to Requirements Syntax) Types
3
+ * Defines structured requirement patterns for testability
4
+ */
5
+ export type EARSType = 'ubiquitous' | 'event' | 'state' | 'optional' | 'unwanted' | 'complex' | 'unknown';
6
+ export interface EARSRequirement {
7
+ /** Original requirement text */
8
+ text: string;
9
+ /** EARS pattern type */
10
+ type: EARSType;
11
+ /** Event trigger (for event-driven requirements) */
12
+ event?: string;
13
+ /** State condition (for state-driven requirements) */
14
+ state?: string;
15
+ /** Optional condition (for optional requirements) */
16
+ condition?: string;
17
+ /** Unwanted condition (for unwanted behavior requirements) */
18
+ unwantedCondition?: string;
19
+ /** The system action/response */
20
+ action: string;
21
+ /** For complex requirements with multiple conditions */
22
+ conditions?: {
23
+ type: 'event' | 'state' | 'optional';
24
+ value: string;
25
+ }[];
26
+ /** Confidence score (0-1) that this matches EARS pattern */
27
+ confidence: number;
28
+ }
29
+ export interface EARSValidationResult {
30
+ /** Overall EARS compliance score (0-100) */
31
+ score: number;
32
+ /** Total requirements analyzed */
33
+ totalRequirements: number;
34
+ /** Number of EARS-compliant requirements */
35
+ compliantCount: number;
36
+ /** Detailed validation for each requirement */
37
+ requirements: RequirementValidation[];
38
+ /** Summary by EARS type */
39
+ summary: {
40
+ type: EARSType;
41
+ count: number;
42
+ }[];
43
+ /** Overall recommendation */
44
+ recommendation: string;
45
+ }
46
+ export interface RequirementValidation {
47
+ /** Original requirement text */
48
+ text: string;
49
+ /** Whether it follows EARS pattern */
50
+ isCompliant: boolean;
51
+ /** Detected EARS pattern (if any) */
52
+ earsRequirement?: EARSRequirement;
53
+ /** Issues found */
54
+ issues: string[];
55
+ /** Suggested EARS rewrite */
56
+ suggestion?: string;
57
+ }
58
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ears/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,QAAQ,GAChB,YAAY,GACZ,OAAO,GACP,OAAO,GACP,UAAU,GACV,UAAU,GACV,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,WAAW,eAAe;IAC9B,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IAEb,wBAAwB;IACxB,IAAI,EAAE,QAAQ,CAAC;IAEf,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,8DAA8D;IAC9D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;IAEf,wDAAwD;IACxD,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,UAAU,CAAC;QACrC,KAAK,EAAE,MAAM,CAAC;KACf,EAAE,CAAC;IAEJ,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IAEd,kCAAkC;IAClC,iBAAiB,EAAE,MAAM,CAAC;IAE1B,4CAA4C;IAC5C,cAAc,EAAE,MAAM,CAAC;IAEvB,+CAA+C;IAC/C,YAAY,EAAE,qBAAqB,EAAE,CAAC;IAEtC,2BAA2B;IAC3B,OAAO,EAAE;QACP,IAAI,EAAE,QAAQ,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACf,EAAE,CAAC;IAEJ,6BAA6B;IAC7B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IAEb,sCAAsC;IACtC,WAAW,EAAE,OAAO,CAAC;IAErB,qCAAqC;IACrC,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC,mBAAmB;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IAEjB,6BAA6B;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * EARS (Easy Approach to Requirements Syntax) Types
3
+ * Defines structured requirement patterns for testability
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/ears/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * EARS Validator
3
+ * Validates requirements against EARS patterns and suggests improvements
4
+ */
5
+ import type { Spec } from '../types.js';
6
+ import type { EARSValidationResult, RequirementValidation } from './types.js';
7
+ /**
8
+ * Validate all requirements in a spec for EARS compliance
9
+ */
10
+ export declare function validateRequirements(spec: Spec): EARSValidationResult;
11
+ /**
12
+ * Validate a single requirement text
13
+ *
14
+ * Note: A requirement is considered compliant (isCompliant = true) ONLY if it both:
15
+ * 1. Matches an EARS pattern with sufficient confidence, AND
16
+ * 2. Has zero quality issues (no ambiguous words, vague terms, etc.)
17
+ *
18
+ * @param text - The requirement text to validate
19
+ * @returns Validation result with compliance status, issues, and suggestions
20
+ */
21
+ export declare function validateRequirement(text: string): RequirementValidation;
22
+ /**
23
+ * Get EARS compliance score for a spec (0-100)
24
+ */
25
+ export declare function getEARSScore(spec: Spec): number;
26
+ /**
27
+ * Check if a spec meets minimum EARS compliance threshold
28
+ * @param spec - The spec to check
29
+ * @param threshold - Minimum score (0-100)
30
+ * @param precomputedScore - Optional pre-computed score to avoid re-validation
31
+ */
32
+ export declare function meetsEARSThreshold(spec: Spec, threshold?: number, precomputedScore?: number): boolean;
33
+ /**
34
+ * Generate a detailed EARS compliance report as markdown
35
+ */
36
+ export declare function generateEARSReport(spec: Spec): string;
37
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/ears/validator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAe,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,EAAY,MAAM,YAAY,CAAC;AAGxF;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,oBAAoB,CAgDrE;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,CAuDvE;AAgCD;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAG/C;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,IAAI,EACV,SAAS,GAAE,MAAW,EACtB,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAGT;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAmErD"}