@facet-coverage/core 0.3.0 → 0.4.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/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  **Test every facet of your features**
6
6
 
7
- *Natural specifications. Multiple perspectives. Rigorous coverage.*
7
+ *Write requirements naturally. Know what's tested. Track multi-stakeholder coverage automatically.*
8
8
 
9
9
  [![npm version](https://img.shields.io/npm/v/@facet-coverage/core.svg)](https://www.npmjs.com/package/@facet-coverage/core)
10
10
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
@@ -15,641 +15,132 @@
15
15
 
16
16
  ---
17
17
 
18
- ## Table of Contents
19
-
20
- - [What is Facet?](#what-is-facet)
21
- - [Installation](#installation)
22
- - [Quick Start](#quick-start)
23
- - [Linking Tests to Facets](#linking-tests-to-facets)
24
- - [Project Structure](#project-structure)
25
- - [CLI Commands](#cli-commands)
26
- - [Playwright Integration](#playwright-integration)
27
- - [Configuration](#configuration)
28
- - [ID Patterns](#id-patterns)
29
- - [Programmatic API](#programmatic-api)
30
- - [Benefits](#benefits)
31
- - [How Facet Differs](#how-facet-differs)
32
- - [Key Principles](#key-principles)
33
- - [Contributing](#contributing)
34
- - [License](#license)
18
+ ## Why Facet?
35
19
 
36
- ---
37
-
38
- ## What is Facet?
39
-
40
- Facet is a modern testing framework that lets you document features from multiple stakeholder perspectives while maintaining exact traceability to your tests.
20
+ Traditional testing asks "what did developers test?" Facet asks "what do stakeholders need, and is it tested?"
41
21
 
42
- **One feature. Many facets.**
22
+ Real products serve multiple stakeholders—product owners, compliance teams, UX designers, security architects—each with their own requirements. Facet lets every stakeholder write requirements in natural language, then tracks whether tests actually cover them.
43
23
 
44
- | Perspective | Description |
45
- |-------------|-------------|
46
- | **Business requirements** | Product owner specifications |
47
- | **Compliance mandates** | Regulatory requirements (PCI-DSS, GDPR, etc.) |
48
- | **UX standards** | Design system and accessibility rules |
49
- | **Technical specs** | Architecture and API contracts |
50
-
51
- All connected to the same tests. All tracked for coverage.
52
-
53
- ---
54
-
55
- ## Installation
56
-
57
- ```bash
58
- bun add -d @facet-coverage/core
59
- ```
24
+ **One feature. Many facets. All tracked.**
60
25
 
61
26
  ---
62
27
 
63
28
  ## Quick Start
64
29
 
65
- ### 1. Create Your First Facets
30
+ ### Install
66
31
 
67
32
  ```bash
68
- mkdir -p features/checkout/facets
33
+ bun add -d @facet-coverage/core
69
34
  ```
70
35
 
71
- Write in natural language:
36
+ ### 1. Each stakeholder writes their requirements
72
37
 
73
- **features/checkout/facets/business.md**
38
+ **Business Team** — `facets/business.md`
74
39
  ```markdown
75
40
  ## Guest Purchase Flow
76
-
77
- A user who isn't logged in should be able to buy products. They add
78
- items to cart, click checkout, provide email and payment details,
79
- and get an order confirmation.
80
-
81
- ### Edge Cases
82
- - Empty cart at checkout
83
- - Invalid email format
84
- - Payment gateway timeout
41
+ Users should complete purchases without creating an account.
85
42
  ```
86
43
 
87
- **features/checkout/facets/compliance.md**
44
+ **Compliance Team** — `facets/compliance.md`
88
45
  ```markdown
89
- ## PCI-DSS Payment Requirements
90
-
91
- We handle credit card data, so PCI-DSS compliance is mandatory:
92
-
93
- 1. **Encryption in transit** - TLS 1.2+ required
94
- 2. **No CVV storage** - Use payment gateway, never store CVV
95
- 3. **Card masking** - Display only last 4 digits
96
- ```
97
-
98
- ### 2. Generate Structure & Types
99
-
100
- ```bash
101
- bunx facet generate features/checkout/facets/
46
+ ## PCI-DSS Payment Requirements {#pci-dss}
47
+ 1. **Encryption in transit** {#tls} - TLS 1.2+ required
48
+ 2. **No CVV storage** {#cvv} - Never store CVV
49
+ 3. **Card masking** {#masking} - Show only last 4 digits
102
50
  ```
103
51
 
104
- This creates two files in `features/checkout/.facet/`:
105
- - `structure.json` - facet definitions
106
- - `facets.ts` - TypeScript types for type-safe linking
107
-
108
- **structure.json:**
109
-
110
- ```json
111
- {
112
- "feature": "checkout",
113
- "facets": [
114
- {
115
- "id": "business:guest-purchase-flow",
116
- "source": {
117
- "file": "facets/business.md",
118
- "section": "guest-purchase-flow"
119
- },
120
- "type": "business"
121
- },
122
- {
123
- "id": "compliance:pci-dss-payment-requirements",
124
- "source": {
125
- "file": "facets/compliance.md",
126
- "section": "pci-dss-payment-requirements"
127
- },
128
- "type": "compliance"
129
- }
130
- ]
131
- }
52
+ **UX Team** `facets/ux.md`
53
+ ```markdown
54
+ ## Mobile Checkout Experience
55
+ Large touch targets (44px min), single column layout, inline validation.
132
56
  ```
133
57
 
134
- ### 3. Link Tests
135
-
136
- Import the generated types and use `facet()` in your tests:
58
+ ### 2. Tests link to requirements
137
59
 
138
60
  ```typescript
139
- // features/checkout/tests/checkout.spec.ts
140
- import { test, expect } from 'bun:test'; // or jest, vitest, mocha...
141
61
  import { Facets, facet } from '../.facet/facets';
142
62
 
143
- test('guest user completes purchase', () => {
144
- // Declare which facets this test covers
63
+ test('guest user completes purchase on mobile', () => {
64
+ // This test proves requirements for 3 different stakeholders
145
65
  facet(Facets.BUSINESS_GUEST_PURCHASE_FLOW);
146
- facet(Facets.COMPLIANCE_PCI_DSS_PAYMENT_REQUIREMENTS);
147
-
148
- // Your test code
149
- const order = checkout(cart, 'user@example.com', '4242...');
150
- expect(order.confirmed).toBe(true);
151
- expect(order.maskedCard).toBe('•••• 4242'); // PCI-DSS compliance
152
- });
153
- ```
154
-
155
- The `facet()` function is type-safe - TypeScript will error if you use an invalid facet ID!
156
-
157
- ### 4. Run Coverage
158
-
159
- ```bash
160
- bunx facet analyze
161
- ```
162
-
163
- **Output:**
164
- ```
165
- Facet Coverage Report
166
-
167
- Overall: 100%
168
-
169
- By Type:
170
- business: 100% (1/1)
171
- compliance: 100% (1/1)
172
-
173
- Reports generated:
174
- .facet-coverage/coverage.json
175
- .facet-coverage/coverage.html
176
- .facet-coverage/coverage.md
177
- ```
178
-
179
- ---
180
-
181
- ## Project Structure
182
-
183
- ```
184
- project/
185
- ├── features/
186
- │ ├── checkout/
187
- │ │ ├── facets/
188
- │ │ │ ├── business.md # Product owner writes
189
- │ │ │ ├── compliance.md # Compliance team writes
190
- │ │ │ └── ux.md # UX designer writes
191
- │ │ ├── .facet/
192
- │ │ │ ├── structure.json # Generated facet definitions
193
- │ │ │ └── facets.ts # Generated TypeScript types
194
- │ │ └── tests/
195
- │ │ └── checkout.spec.ts
196
- │ │
197
- │ └── authentication/
198
- │ ├── facets/
199
- │ ├── .facet/
200
- │ └── tests/
201
-
202
- ├── .facet-coverage/ # Coverage reports
203
- │ ├── coverage.json
204
- │ ├── coverage.html
205
- │ └── coverage.md
206
-
207
- └── facet.config.js # Configuration
208
- ```
209
-
210
- ---
211
-
212
- ## Linking Tests to Facets
213
-
214
- Use the `facet()` function inside your tests - just like `expect()` but for coverage tracking!
215
-
216
- ### Recommended: Type-Safe with `facet()` Function
66
+ facet(Facets.COMPLIANCE_PCI_DSS);
67
+ facet(Facets.UX_MOBILE_CHECKOUT_EXPERIENCE);
217
68
 
218
- ```typescript
219
- import { test, expect } from 'bun:test'; // or jest, vitest, mocha...
220
- import { Facets, facet } from '../.facet/facets';
69
+ const order = checkout(cart, 'user@example.com', '4242424242424242');
221
70
 
222
- test('guest user can complete a purchase', () => {
223
- // Declare which facets this test covers - type-safe with autocomplete!
224
- facet(Facets.BUSINESS_GUEST_PURCHASE_FLOW);
225
- facet(Facets.COMPLIANCE_PCI_DSS_PAYMENT_REQUIREMENTS);
226
-
227
- // Your test code
228
- const order = checkout(cart, email, card);
229
71
  expect(order.confirmed).toBe(true);
72
+ expect(order.maskedCard).toBe('•••• 4242'); // PCI-DSS compliance
230
73
  });
231
74
 
232
- test('payment meets compliance', () => {
233
- // Multiple facets in one call
234
- facet(Facets.COMPLIANCE_PCI_DSS, Facets.COMPLIANCE_GDPR);
75
+ test('TLS encryption enforced', () => {
76
+ // Track specific compliance sub-requirements
77
+ facet(Facets.COMPLIANCE_PCI_DSS__TLS);
235
78
 
236
- expect(payment.encrypted).toBe(true);
79
+ expect(paymentEndpoint.protocol).toBe('https');
237
80
  });
238
81
  ```
239
82
 
240
- **Benefits:**
241
- - Full TypeScript autocomplete
242
- - Compile-time validation (invalid facet IDs cause errors)
243
- - Clean, readable syntax
244
- - Works with any testing framework
245
-
246
- **Generated `facets.ts` includes:**
247
- - `FacetId` - Union type of all valid facet IDs
248
- - `Facets` - Object with constants for each facet
249
- - `facet()` - Type-safe function to declare coverage
250
-
251
- ### Alternative: Comment Annotations
252
-
253
- For quick setup without imports, use comment annotations:
254
-
255
- ```typescript
256
- // @facet business:guest-purchase-flow, compliance:pci-dss
257
- test('guest user completes purchase', () => {
258
- // Your test code
259
- });
260
- ```
261
-
262
- ### All Linking Methods
263
-
264
- | Method | Type-Safe | Syntax |
265
- |--------|-----------|--------|
266
- | `facet()` function | Yes | `facet(Facets.ID)` inside test body |
267
- | Comment annotation | No | `// @facet id` above test |
268
- | Playwright annotation | Yes | `{ annotation: facet(...) }` in test options |
269
-
270
- ---
271
-
272
- ## CLI Commands
273
-
274
- ### Generate Structure & Types
83
+ ### 3. See coverage across all perspectives
275
84
 
276
85
  ```bash
277
- # Generate structure.json and facets.ts from facet documents
278
- bunx facet generate <facets-dir>
279
-
280
- # Options
281
- bunx facet generate features/checkout/facets/ -o ./custom-output # Custom output dir
282
- bunx facet generate features/checkout/facets/ -t business # Override type
283
- bunx facet generate features/checkout/facets/ --no-types # Skip TypeScript generation
284
- ```
285
-
286
- ### Analyze Coverage
287
-
288
- ```bash
289
- # Run coverage analysis
290
86
  bunx facet analyze
291
-
292
- # Options
293
- bunx facet analyze -c facet.config.js # Custom config
294
- bunx facet analyze -f html # Specific format
295
- bunx facet analyze -t 80 # Set threshold
296
- bunx facet analyze --json # JSON output for CI
297
- bunx facet analyze --silent # No console output
298
- ```
299
-
300
- ### Validate
301
-
302
- ```bash
303
- # Validate structure and test links
304
- bunx facet validate
305
-
306
- # Options
307
- bunx facet validate --strict # Require all tests linked
308
- bunx facet validate --json # JSON output
309
- ```
310
-
311
- ### Watch Mode
312
-
313
- ```bash
314
- # Re-run on changes
315
- bunx facet watch
316
-
317
- # Options
318
- bunx facet watch -v # Validate before analysis
319
87
  ```
320
88
 
321
- ---
322
-
323
- ## Playwright Integration
324
-
325
- > **Note:** Playwright works with [comment annotations](#method-1-comment-annotations-any-framework) and [generated types](#method-2-type-safe-with-generated-types-recommended) out of the box. This section covers the **optional** enhanced integration with a custom reporter and annotation helper.
326
-
327
- ### Why Use the Playwright Integration?
328
-
329
- - **Automatic coverage on test run** - Coverage reports generated after `playwright test`
330
- - **Runtime annotation capture** - Works with dynamic test generation
331
- - **Native annotation syntax** - Uses Playwright's built-in annotation system
332
-
333
- ### Reporter Setup
334
-
335
- ```typescript
336
- // playwright.config.ts
337
- import { FacetCoverageReporter } from '@facet-coverage/core/playwright';
338
-
339
- export default {
340
- reporter: [
341
- ['html'],
342
- [FacetCoverageReporter, {
343
- output: {
344
- dir: '.facet-coverage',
345
- formats: ['json', 'html', 'markdown']
346
- },
347
- thresholds: {
348
- global: 80,
349
- byType: {
350
- compliance: 100
351
- }
352
- }
353
- }]
354
- ]
355
- };
356
89
  ```
90
+ Facet Coverage Report
91
+ Overall: 83% (5/6)
357
92
 
358
- ### Test Annotations
359
-
360
- ```typescript
361
- import { test } from '@playwright/test';
362
- import { facet } from '@facet-coverage/core/playwright';
363
-
364
- // Single facet
365
- test('my test', {
366
- annotation: facet('guest-checkout-flow')
367
- }, async ({ page }) => {
368
- // ...
369
- });
370
-
371
- // Multiple facets
372
- test('comprehensive test', {
373
- annotation: facet(
374
- 'guest-checkout-flow',
375
- 'pci-card-masking',
376
- 'mobile-checkout-ux'
377
- )
378
- }, async ({ page }) => {
379
- // ...
380
- });
381
- ```
382
-
383
- ---
384
-
385
- ## Configuration
386
-
387
- Facet Coverage supports multiple configuration file formats. The CLI looks for config files in this order:
388
-
389
- 1. `facet.config.js` (ESM or CommonJS)
390
- 2. `facet.config.mjs` (ESM only)
391
- 3. `facet.config.json` (JSON)
392
-
393
- ### Configuration Formats
394
-
395
- **JavaScript (ESM):**
396
-
397
- ```javascript
398
- // facet.config.js
399
- export default {
400
- // Glob pattern(s) for finding facet markdown files
401
- facetPattern: ['features/**/*.facet.md', 'features/**/facets/*.md'],
402
-
403
- // Where structure files are generated
404
- structureFiles: ['features/**/.facet/structure.json'],
405
-
406
- // Where tests live
407
- testDir: './features/**/tests',
408
- testPatterns: ['**/*.spec.ts', '**/*.test.ts'],
409
-
410
- // Validation options
411
- validation: {
412
- requireSourceExists: true,
413
- requireSectionExists: true,
414
- requireAllTestsLinked: false
415
- },
416
-
417
- // Output options
418
- output: {
419
- dir: '.facet-coverage',
420
- formats: ['json', 'html', 'markdown']
421
- },
422
-
423
- // Coverage thresholds
424
- thresholds: {
425
- global: 75,
426
- byType: {
427
- compliance: 100,
428
- business: 80,
429
- ux: 70
430
- }
431
- }
432
- };
433
- ```
434
-
435
- **JSON:**
436
-
437
- ```json
438
- {
439
- "facetPattern": ["features/**/*.facet.md", "features/**/facets/*.md"],
440
- "structureFiles": ["features/**/.facet/structure.json"],
441
- "testDir": "./features/**/tests",
442
- "testPatterns": ["**/*.spec.ts", "**/*.test.ts"],
443
- "validation": {
444
- "requireSourceExists": true,
445
- "requireSectionExists": true,
446
- "requireAllTestsLinked": false
447
- },
448
- "output": {
449
- "dir": ".facet-coverage",
450
- "formats": ["json", "html", "markdown"]
451
- },
452
- "thresholds": {
453
- "global": 75,
454
- "byType": {
455
- "compliance": 100
456
- }
457
- }
458
- }
459
- ```
460
-
461
- ### Configuration Options
462
-
463
- | Option | Type | Default | Description |
464
- |--------|------|---------|-------------|
465
- | `facetPattern` | `string \| string[]` | `['features/**/*.facet.md', 'features/**/facets/*.md']` | Glob pattern(s) for finding facet files |
466
- | `structureFiles` | `string[]` | `['features/**/.facet/structure.json']` | Glob patterns for structure files |
467
- | `testDir` | `string` | `'./features/**/tests'` | Test directory pattern |
468
- | `testPatterns` | `string[]` | `['**/*.spec.ts', '**/*.test.ts']` | Test file patterns |
469
- | `validation.requireSourceExists` | `boolean` | `true` | Check if source files exist |
470
- | `validation.requireSectionExists` | `boolean` | `true` | Check if sections exist in files |
471
- | `validation.requireAllTestsLinked` | `boolean` | `false` | Require every test links to a facet |
472
- | `output.dir` | `string` | `'.facet-coverage'` | Output directory for reports |
473
- | `output.formats` | `string[]` | `['json', 'html', 'markdown']` | Report formats to generate |
474
- | `thresholds.global` | `number` | `75` | Overall coverage threshold % |
475
- | `thresholds.byType` | `object` | `{}` | Per-type coverage thresholds |
476
-
477
- ---
478
-
479
- ## ID Patterns
480
-
481
- ### Auto-Generated (Recommended)
482
-
483
- ```
484
- Pattern: {filename}:{section-slug}
485
-
486
- Examples:
487
- - business:guest-purchase-flow
488
- - compliance:pci-dss-payment-requirements
489
- - ux:mobile-checkout-experience
490
- ```
491
-
492
- ### Custom Slugs
493
-
494
- ```json
495
- {
496
- "id": "guest-checkout-flow",
497
- "source": {
498
- "file": "facets/business.md",
499
- "section": "guest-purchase-flow"
500
- },
501
- "type": "business"
502
- }
503
- ```
504
-
505
- ### Flexible Linking
506
-
507
- ```typescript
508
- // All three formats work:
509
- facet('guest-checkout-flow') // Custom slug
510
- facet('business:guest-purchase-flow') // Auto-generated
511
- facet('facets/business.md#guest-purchase-flow') // Direct path
512
- ```
513
-
514
- ---
515
-
516
- ## Programmatic API
517
-
518
- ```typescript
519
- import {
520
- StructureReader,
521
- TestScanner,
522
- CoverageCalculator,
523
- Validator,
524
- JsonReporter,
525
- HtmlReporter,
526
- MarkdownReporter
527
- } from '@facet-coverage/core';
528
-
529
- // Read structures
530
- const reader = new StructureReader();
531
- const structures = await reader.readAllStructures();
532
-
533
- // Scan tests
534
- const scanner = new TestScanner();
535
- const tests = await scanner.scanAllTests();
536
-
537
- // Calculate coverage
538
- const calculator = new CoverageCalculator();
539
- const report = await calculator.calculateCoverage();
540
-
541
- // Validate
542
- const validator = new Validator();
543
- const result = await validator.validate();
544
-
545
- // Generate reports
546
- const jsonReporter = new JsonReporter();
547
- jsonReporter.write(report);
548
-
549
- const htmlReporter = new HtmlReporter();
550
- htmlReporter.write(report);
551
-
552
- const mdReporter = new MarkdownReporter();
553
- mdReporter.write(report);
93
+ business: 100% (1/1) ✓
94
+ compliance: 80% (4/5)
95
+ ✗ pci-dss/cvv - No CVV storage
96
+ ux: 100% (1/1) ✓
554
97
  ```
555
98
 
556
- ---
557
-
558
- ## Benefits
559
-
560
- <table>
561
- <tr>
562
- <td width="50%">
563
-
564
- ### For Product Owners
565
- - Write in natural language
566
- - Focus on business value
567
- - See what's tested immediately
568
- - Documentation evolves with product
569
-
570
- ### For Compliance Teams
571
- - Direct regulation mapping
572
- - Audit-ready traceability
573
- - 100% coverage enforcement
574
- - Automated compliance reports
575
-
576
- ### For UX Designers
577
- - Document user flows naturally
578
- - Link designs to tests
579
- - Track accessibility coverage
580
- - Mobile/desktop requirements clear
581
-
582
- </td>
583
- <td width="50%">
584
-
585
- ### For Developers
586
- - One test covers multiple facets
587
- - Clear requirements from all stakeholders
588
- - Know exactly what's covered
589
- - Easy maintenance
590
-
591
- ### For QA Teams
592
- - Complete visibility
593
- - Automated gap detection
594
- - Multi-perspective coverage
595
- - Progress tracking
596
-
597
- </td>
598
- </tr>
599
- </table>
99
+ **Now you know:** The compliance team's CVV requirement isn't tested yet.
600
100
 
601
101
  ---
602
102
 
603
- ## How Facet Differs
604
-
605
- | Approach | Focus | Facet's Difference |
606
- |----------|-------|-------------------|
607
- | **TDD** | Code correctness via unit tests | Facet tracks *what* is covered, not *how* to write code |
608
- | **BDD** | Behavior via Given-When-Then | Facet uses free-form natural language, not structured syntax |
609
- | **ATDD** | Acceptance criteria drive development | Facet maps multiple perspectives to tests, not just acceptance |
610
- | **Traditional Coverage** | Lines/branches executed | Facet measures *requirement* coverage, not code coverage |
611
-
612
- **Key insight:** TDD/BDD/ATDD are *development methodologies*. Facet is a *coverage framework*. Use them together.
613
-
614
- ### Why Facet Works for AI-Driven Testing
103
+ ## Documentation
615
104
 
616
- AI coding assistants excel at generating tests but struggle with *what to test*. Facet solves this:
105
+ | Guide | Description |
106
+ |-------|-------------|
107
+ | [Getting Started](docs/getting-started.md) | Full quickstart with project structure |
108
+ | [Core Concepts](docs/concepts.md) | What Facet is and how it works |
109
+ | [Configuration](docs/configuration.md) | Config options and examples |
110
+ | [CLI Reference](docs/cli.md) | All available commands |
111
+ | [Playwright Integration](docs/playwright.md) | Enhanced Playwright support |
112
+ | [Programmatic API](docs/api.md) | Use Facet in code |
113
+ | [ID Patterns](docs/id-patterns.md) | Stable IDs, sub-facets, and nested features |
617
114
 
618
- - **Natural language specs** → AI understands requirements without parsing Gherkin
619
- - **Multi-perspective facets** → AI generates tests covering business, compliance, UX in one pass
620
- - **Type-safe linking** → AI can programmatically verify coverage completeness
621
- - **Gap detection** → AI identifies untested facets and generates missing tests
115
+ ### Background
622
116
 
623
- ```
624
- Human: "Generate tests for checkout"
625
- AI: Reads facets Understands business rules, PCI compliance, UX requirements → Generates comprehensive tests → Links to facets automatically
626
- ```
627
-
628
- Facet bridges human intent and AI execution with traceable, verifiable coverage.
117
+ | Document | Description |
118
+ |----------|-------------|
119
+ | [Vision](docs/vision.md) | Philosophy behind multi-stakeholder coverage |
120
+ | [Testing Phases](docs/testing-phases.md) | Where Facet fits in testing |
121
+ | [Comparisons](docs/comparisons.md) | How Facet differs from BDD, Cucumber, etc. |
629
122
 
630
123
  ---
631
124
 
632
- ## Key Principles
125
+ ## Key Features
633
126
 
634
- | Principle | Description |
635
- |-----------|-------------|
636
- | **Multi-Perspective** | Every feature has multiple facets |
637
- | **Natural Language** | Write like humans, not machines |
638
- | **Evolutionary** | Documentation grows with understanding |
639
- | **Traceable** | Exact test-to-facet mapping |
640
- | **Feature-Modular** | Self-contained, team-owned |
641
- | **Lightweight** | Markdown + JSON, nothing heavy |
642
- | **Flexible** | Adopt incrementally, customize freely |
127
+ - **Natural language** - Write requirements as Markdown, no Gherkin syntax
128
+ - **Multi-perspective** - Business, compliance, UX, technical facets per feature
129
+ - **Sub-facets** - Track fine-grained requirements with hierarchical IDs
130
+ - **Type-safe linking** - Generated TypeScript types prevent broken references
131
+ - **Framework agnostic** - Works with Jest, Vitest, Playwright, Mocha, Bun
132
+ - **Gap detection** - See what's untested across all stakeholder perspectives
133
+ - **CI-ready** - Threshold enforcement and JSON output for pipelines
643
134
 
644
135
  ---
645
136
 
646
137
  ## Contributing
647
138
 
648
- Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
139
+ Contributions are welcome! Please feel free to submit a Pull Request.
649
140
 
650
141
  1. Fork the repository
651
142
  2. Create your feature branch (`git checkout -b feature/amazing-feature`)
652
- 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
143
+ 3. Commit your changes
653
144
  4. Push to the branch (`git push origin feature/amazing-feature`)
654
145
  5. Open a Pull Request
655
146
 
@@ -665,6 +156,4 @@ MIT License - see the [LICENSE](LICENSE) file for details.
665
156
 
666
157
  **[Report Bug](https://github.com/iraycd/facet-coverage/issues) | [Request Feature](https://github.com/iraycd/facet-coverage/issues)**
667
158
 
668
- If you find this project useful, please consider giving it a star!
669
-
670
159
  </div>