speckeeper 0.10.0 → 0.11.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 +1 -0
- package/cli-contract.yaml +207 -209
- package/dist/cli.js +1316 -80
- package/dist/cli.js.map +1 -1
- package/dist/{config-api-CLVjdgIP.d.ts → config-api-coyCX1SB.d.ts} +21 -1
- package/dist/dsl/index.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +75 -3
- package/dist/index.js.map +1 -1
- package/docs/cli-reference.md +107 -154
- package/docs/design/cli-commands.md +217 -0
- package/docs/design/functional-requirements.md +101 -3
- package/docs/design/nonfunctional-requirements.md +3 -3
- package/docs/design/test-refs.md +26 -0
- package/docs/model-guide.md +102 -98
- package/package.json +3 -3
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
| init | Initialize a new speckeeper project with starter templates |
|
|
10
10
|
| new | Create a new element with auto-generated ID |
|
|
11
11
|
| scaffold | Generate _models/ from a mermaid flowchart definition |
|
|
12
|
+
| audit-requirements | Semantic requirement quality audit via LLM (verifiability, ambiguity, granularity, terminology, design-mixing) |
|
|
13
|
+
| propose-trace-links | Propose candidate traceability links between specs with confidence scores and rationale |
|
|
14
|
+
| explain-impact | Translate impact analysis JSON (from stdin) into human-readable explanation for PM/executive audiences |
|
|
15
|
+
| propose-acceptance-criteria | Propose testable acceptance criteria in Given/When/Then format for specified specs |
|
|
16
|
+
| convert | Convert a TS spec data file to YAML format |
|
|
12
17
|
| impact | Analyze the change impact scope of a specified ID |
|
|
13
18
|
|
|
14
19
|
---
|
|
@@ -293,6 +298,218 @@ speckeeper scaffold -s spec.md --dry-run
|
|
|
293
298
|
|
|
294
299
|
---
|
|
295
300
|
|
|
301
|
+
## CMD-AUDIT-REQ: audit-requirements
|
|
302
|
+
|
|
303
|
+
Semantic requirement quality audit via LLM (verifiability, ambiguity, granularity, terminology, design-mixing)
|
|
304
|
+
|
|
305
|
+
### Usage
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
speckeeper audit-requirements [options]
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Parameters
|
|
312
|
+
|
|
313
|
+
| Name | Kind | Type | Required | Default | Description |
|
|
314
|
+
|------|------|------|----------|---------|-------------|
|
|
315
|
+
| -c, --config | option | path | | - | Path to config file |
|
|
316
|
+
| -a, --adapter | option | enum | | - | SDK adapter for LLM execution |
|
|
317
|
+
| --model | option | string | | - | LLM model override |
|
|
318
|
+
| -n, --dry-run | option | boolean | | false | Output constructed prompt without calling LLM |
|
|
319
|
+
| --fail-on | option | enum | | error | Minimum severity for non-zero exit |
|
|
320
|
+
| -o, --output | option | path | | - | Write result to file instead of stdout |
|
|
321
|
+
| --report-format | option | enum | | json | Output format for audit report |
|
|
322
|
+
| --show-prompt | option | boolean | | false | Display constructed LLM prompt on stderr |
|
|
323
|
+
|
|
324
|
+
### Examples
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
speckeeper audit-requirements
|
|
328
|
+
speckeeper audit-requirements --adapter openai --dry-run
|
|
329
|
+
speckeeper audit-requirements --report-format json --output audit.json
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Exit Codes
|
|
333
|
+
|
|
334
|
+
| Code | Description |
|
|
335
|
+
|------|-------------|
|
|
336
|
+
| 0 | No blocking findings |
|
|
337
|
+
| 1 | Unexpected error |
|
|
338
|
+
| 2 | Configuration or input error |
|
|
339
|
+
| 10 | Completed with blocking findings |
|
|
340
|
+
| 11 | Runtime dependency missing |
|
|
341
|
+
| 12 | LLM provider or adapter error |
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## CMD-PROPOSE-TRACE: propose-trace-links
|
|
346
|
+
|
|
347
|
+
Propose candidate traceability links between specs with confidence scores and rationale
|
|
348
|
+
|
|
349
|
+
### Usage
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
speckeeper propose-trace-links [options]
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Parameters
|
|
356
|
+
|
|
357
|
+
| Name | Kind | Type | Required | Default | Description |
|
|
358
|
+
|------|------|------|----------|---------|-------------|
|
|
359
|
+
| -c, --config | option | path | | - | Path to config file |
|
|
360
|
+
| -a, --adapter | option | enum | | - | SDK adapter for LLM execution |
|
|
361
|
+
| --model | option | string | | - | LLM model override |
|
|
362
|
+
| -n, --dry-run | option | boolean | | false | Output constructed prompt without calling LLM |
|
|
363
|
+
| --fail-on | option | enum | | error | Minimum severity for non-zero exit |
|
|
364
|
+
| -o, --output | option | path | | - | Write result to file instead of stdout |
|
|
365
|
+
| --report-format | option | enum | | json | Output format for report |
|
|
366
|
+
| --show-prompt | option | boolean | | false | Display constructed LLM prompt on stderr |
|
|
367
|
+
|
|
368
|
+
### Examples
|
|
369
|
+
|
|
370
|
+
```bash
|
|
371
|
+
speckeeper propose-trace-links
|
|
372
|
+
speckeeper propose-trace-links --adapter claude --report-format json
|
|
373
|
+
speckeeper propose-trace-links --dry-run
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### Exit Codes
|
|
377
|
+
|
|
378
|
+
| Code | Description |
|
|
379
|
+
|------|-------------|
|
|
380
|
+
| 0 | No blocking findings |
|
|
381
|
+
| 1 | Unexpected error |
|
|
382
|
+
| 2 | Configuration or input error |
|
|
383
|
+
| 10 | Completed with blocking findings |
|
|
384
|
+
| 11 | Runtime dependency missing |
|
|
385
|
+
| 12 | LLM provider or adapter error |
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## CMD-EXPLAIN-IMPACT: explain-impact
|
|
390
|
+
|
|
391
|
+
Translate impact analysis JSON (from stdin) into human-readable explanation for PM/executive audiences
|
|
392
|
+
|
|
393
|
+
### Usage
|
|
394
|
+
|
|
395
|
+
```bash
|
|
396
|
+
speckeeper explain-impact [options]
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Parameters
|
|
400
|
+
|
|
401
|
+
| Name | Kind | Type | Required | Default | Description |
|
|
402
|
+
|------|------|------|----------|---------|-------------|
|
|
403
|
+
| -c, --config | option | path | | - | Path to config file |
|
|
404
|
+
| -a, --adapter | option | enum | | - | SDK adapter for LLM execution |
|
|
405
|
+
| --model | option | string | | - | LLM model override |
|
|
406
|
+
| -n, --dry-run | option | boolean | | false | Output constructed prompt without calling LLM |
|
|
407
|
+
| --fail-on | option | enum | | error | Minimum severity for non-zero exit |
|
|
408
|
+
| -o, --output | option | path | | - | Write result to file instead of stdout |
|
|
409
|
+
| --report-format | option | enum | | json | Output format for report |
|
|
410
|
+
| --show-prompt | option | boolean | | false | Display constructed LLM prompt on stderr |
|
|
411
|
+
|
|
412
|
+
### Examples
|
|
413
|
+
|
|
414
|
+
```bash
|
|
415
|
+
speckeeper impact FR-001 --format json | speckeeper explain-impact
|
|
416
|
+
speckeeper impact ENT-ORDER --format json | speckeeper explain-impact --adapter claude
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### Exit Codes
|
|
420
|
+
|
|
421
|
+
| Code | Description |
|
|
422
|
+
|------|-------------|
|
|
423
|
+
| 0 | Explanation completed |
|
|
424
|
+
| 1 | Unexpected error |
|
|
425
|
+
| 2 | Configuration or input error |
|
|
426
|
+
| 3 | No input on stdin |
|
|
427
|
+
| 10 | Completed with blocking findings |
|
|
428
|
+
| 11 | Runtime dependency missing |
|
|
429
|
+
| 12 | LLM provider or adapter error |
|
|
430
|
+
|
|
431
|
+
---
|
|
432
|
+
|
|
433
|
+
## CMD-PROPOSE-AC: propose-acceptance-criteria
|
|
434
|
+
|
|
435
|
+
Propose testable acceptance criteria in Given/When/Then format for specified specs
|
|
436
|
+
|
|
437
|
+
### Usage
|
|
438
|
+
|
|
439
|
+
```bash
|
|
440
|
+
speckeeper propose-acceptance-criteria [options]
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### Parameters
|
|
444
|
+
|
|
445
|
+
| Name | Kind | Type | Required | Default | Description |
|
|
446
|
+
|------|------|------|----------|---------|-------------|
|
|
447
|
+
| <specIds> | argument | string | | - | Spec IDs to propose criteria for (defaults to all) |
|
|
448
|
+
| -c, --config | option | path | | - | Path to config file |
|
|
449
|
+
| -a, --adapter | option | enum | | - | SDK adapter for LLM execution |
|
|
450
|
+
| --model | option | string | | - | LLM model override |
|
|
451
|
+
| -n, --dry-run | option | boolean | | false | Output constructed prompt without calling LLM |
|
|
452
|
+
| --fail-on | option | enum | | error | Minimum severity for non-zero exit |
|
|
453
|
+
| -o, --output | option | path | | - | Write result to file instead of stdout |
|
|
454
|
+
| --report-format | option | enum | | json | Output format for report |
|
|
455
|
+
| --show-prompt | option | boolean | | false | Display constructed LLM prompt on stderr |
|
|
456
|
+
|
|
457
|
+
### Examples
|
|
458
|
+
|
|
459
|
+
```bash
|
|
460
|
+
speckeeper propose-acceptance-criteria
|
|
461
|
+
speckeeper propose-acceptance-criteria FR-001 FR-002
|
|
462
|
+
speckeeper propose-acceptance-criteria --adapter gemini --dry-run
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### Exit Codes
|
|
466
|
+
|
|
467
|
+
| Code | Description |
|
|
468
|
+
|------|-------------|
|
|
469
|
+
| 0 | No blocking findings |
|
|
470
|
+
| 1 | Unexpected error |
|
|
471
|
+
| 2 | Configuration or input error |
|
|
472
|
+
| 10 | Completed with blocking findings |
|
|
473
|
+
| 11 | Runtime dependency missing |
|
|
474
|
+
| 12 | LLM provider or adapter error |
|
|
475
|
+
|
|
476
|
+
---
|
|
477
|
+
|
|
478
|
+
## CMD-CONVERT: convert
|
|
479
|
+
|
|
480
|
+
Convert a TS spec data file to YAML format
|
|
481
|
+
|
|
482
|
+
### Usage
|
|
483
|
+
|
|
484
|
+
```bash
|
|
485
|
+
speckeeper convert [options]
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
### Parameters
|
|
489
|
+
|
|
490
|
+
| Name | Kind | Type | Required | Default | Description |
|
|
491
|
+
|------|------|------|----------|---------|-------------|
|
|
492
|
+
| <file> | argument | path | ✓ | - | Path to TS spec data file |
|
|
493
|
+
| -o, --output | option | path | | - | Output file path (default: same name with .yaml extension) |
|
|
494
|
+
| -n, --dry-run | option | boolean | | false | Preview conversion without writing |
|
|
495
|
+
|
|
496
|
+
### Examples
|
|
497
|
+
|
|
498
|
+
```bash
|
|
499
|
+
speckeeper convert design/glossary.ts
|
|
500
|
+
speckeeper convert design/requirements.ts --output reqs.yaml
|
|
501
|
+
speckeeper convert design/glossary.ts --dry-run
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
### Exit Codes
|
|
505
|
+
|
|
506
|
+
| Code | Description |
|
|
507
|
+
|------|-------------|
|
|
508
|
+
| 0 | Conversion successful |
|
|
509
|
+
| 1 | Conversion error |
|
|
510
|
+
|
|
511
|
+
---
|
|
512
|
+
|
|
296
513
|
## CMD-IMPACT: impact
|
|
297
514
|
|
|
298
515
|
Analyze the change impact scope of a specified ID
|
|
@@ -51,6 +51,11 @@
|
|
|
51
51
|
| FR-1017 | Source Path Fallback | must | check |
|
|
52
52
|
| FR-1018 | Minimal New Dependencies | must | check |
|
|
53
53
|
| FR-1019 | Checker Documentation Accuracy | must | check |
|
|
54
|
+
| FR-1100 | LLM-Powered Requirement Audit | should | llm |
|
|
55
|
+
| FR-1101 | LLM-Powered Trace Link Proposal | should | llm |
|
|
56
|
+
| FR-1102 | LLM-Powered Impact Explanation | should | llm |
|
|
57
|
+
| FR-1103 | LLM-Powered Acceptance Criteria Proposal | should | llm |
|
|
58
|
+
| FR-1104 | TypeScript to YAML Conversion | should | conversion |
|
|
54
59
|
|
|
55
60
|
---
|
|
56
61
|
|
|
@@ -395,8 +400,8 @@ Since consistency checks are implemented per model, filter by model name
|
|
|
395
400
|
### Acceptance Criteria
|
|
396
401
|
|
|
397
402
|
- **FR-602-01**: speckeeper check runs external SSOT consistency check for all models [test]
|
|
398
|
-
- **FR-602-02**: speckeeper check
|
|
399
|
-
- **FR-602-03**:
|
|
403
|
+
- **FR-602-02**: speckeeper check [type] filters checks by type (openapi, ddl, iac, external-ssot, test, contract) [test]
|
|
404
|
+
- **FR-602-03**: Type argument corresponds to check categories, not model IDs [review]
|
|
400
405
|
- **FR-602-04**: Only models with externalChecker are targeted [test]
|
|
401
406
|
|
|
402
407
|
---
|
|
@@ -807,4 +812,97 @@ README and scaffold-mermaid-spec.md accurately describe all three built-in check
|
|
|
807
812
|
### Acceptance Criteria
|
|
808
813
|
|
|
809
814
|
- **FR-1019-01**: README checker table describes validation levels [review]
|
|
810
|
-
- **FR-1019-02**: scaffold-mermaid-spec.md Section 7 describes validation levels [review]
|
|
815
|
+
- **FR-1019-02**: scaffold-mermaid-spec.md Section 7 describes validation levels [review]
|
|
816
|
+
|
|
817
|
+
---
|
|
818
|
+
|
|
819
|
+
## FR-1100: LLM-Powered Requirement Audit
|
|
820
|
+
|
|
821
|
+
**Type**: functional | **Priority**: should | **Category**: llm
|
|
822
|
+
|
|
823
|
+
Provide LLM-based semantic quality audit for requirement definitions, detecting verifiability issues, ambiguity, granularity problems, terminology inconsistency, and design-mixing
|
|
824
|
+
|
|
825
|
+
### Rationale
|
|
826
|
+
|
|
827
|
+
Static lint rules cannot detect semantic issues such as ambiguous wording or design details mixed into requirements; LLM review complements structural checks
|
|
828
|
+
|
|
829
|
+
### Acceptance Criteria
|
|
830
|
+
|
|
831
|
+
- **FR-1100-01**: audit-requirements command constructs a prompt from all registered specs and sends it to configured LLM adapter [test]
|
|
832
|
+
- **FR-1100-02**: Audit report includes findings with severity (error/warning/info) and affected spec IDs [test]
|
|
833
|
+
- **FR-1100-03**: --dry-run outputs the constructed prompt without calling LLM [test]
|
|
834
|
+
- **FR-1100-04**: --fail-on controls minimum severity that causes non-zero exit [test]
|
|
835
|
+
- **FR-1100-05**: Report format is selectable via --report-format (json, text, yaml) [test]
|
|
836
|
+
|
|
837
|
+
---
|
|
838
|
+
|
|
839
|
+
## FR-1101: LLM-Powered Trace Link Proposal
|
|
840
|
+
|
|
841
|
+
**Type**: functional | **Priority**: should | **Category**: llm
|
|
842
|
+
|
|
843
|
+
Propose candidate traceability links between specs with confidence scores and rationale using LLM analysis
|
|
844
|
+
|
|
845
|
+
### Rationale
|
|
846
|
+
|
|
847
|
+
Manual traceability maintenance is error-prone; LLM can identify semantically related specs that humans may overlook
|
|
848
|
+
|
|
849
|
+
### Acceptance Criteria
|
|
850
|
+
|
|
851
|
+
- **FR-1101-01**: propose-trace-links command analyzes all specs and proposes missing trace links [test]
|
|
852
|
+
- **FR-1101-02**: Each proposed link includes source ID, target ID, relation type, confidence score, and rationale [test]
|
|
853
|
+
- **FR-1101-03**: --dry-run outputs the constructed prompt without calling LLM [test]
|
|
854
|
+
|
|
855
|
+
---
|
|
856
|
+
|
|
857
|
+
## FR-1102: LLM-Powered Impact Explanation
|
|
858
|
+
|
|
859
|
+
**Type**: functional | **Priority**: should | **Category**: llm
|
|
860
|
+
|
|
861
|
+
Translate impact analysis JSON output into human-readable explanation for PM/executive audiences using LLM
|
|
862
|
+
|
|
863
|
+
### Rationale
|
|
864
|
+
|
|
865
|
+
Raw impact analysis JSON is not consumable by non-technical stakeholders; LLM can generate natural language summaries
|
|
866
|
+
|
|
867
|
+
### Acceptance Criteria
|
|
868
|
+
|
|
869
|
+
- **FR-1102-01**: explain-impact command reads impact analysis JSON from stdin [test]
|
|
870
|
+
- **FR-1102-02**: Output is a human-readable explanation suitable for PM/executive audiences [review]
|
|
871
|
+
- **FR-1102-03**: --dry-run outputs the constructed prompt without calling LLM [test]
|
|
872
|
+
|
|
873
|
+
---
|
|
874
|
+
|
|
875
|
+
## FR-1103: LLM-Powered Acceptance Criteria Proposal
|
|
876
|
+
|
|
877
|
+
**Type**: functional | **Priority**: should | **Category**: llm
|
|
878
|
+
|
|
879
|
+
Propose testable acceptance criteria in Given/When/Then format for specified specs using LLM
|
|
880
|
+
|
|
881
|
+
### Rationale
|
|
882
|
+
|
|
883
|
+
Writing testable acceptance criteria is time-consuming; LLM can propose initial criteria that humans refine
|
|
884
|
+
|
|
885
|
+
### Acceptance Criteria
|
|
886
|
+
|
|
887
|
+
- **FR-1103-01**: propose-acceptance-criteria command generates criteria for specified spec IDs (or all) [test]
|
|
888
|
+
- **FR-1103-02**: Proposed criteria follow Given/When/Then format [review]
|
|
889
|
+
- **FR-1103-03**: --dry-run outputs the constructed prompt without calling LLM [test]
|
|
890
|
+
|
|
891
|
+
---
|
|
892
|
+
|
|
893
|
+
## FR-1104: TypeScript to YAML Conversion
|
|
894
|
+
|
|
895
|
+
**Type**: functional | **Priority**: should | **Category**: conversion
|
|
896
|
+
|
|
897
|
+
Convert TypeScript spec data files to equivalent YAML format, enabling non-TypeScript workflows and interoperability
|
|
898
|
+
|
|
899
|
+
### Rationale
|
|
900
|
+
|
|
901
|
+
YAML input lowers participation barriers for non-developers (NFR-005) and enables interoperability with external tools
|
|
902
|
+
|
|
903
|
+
### Acceptance Criteria
|
|
904
|
+
|
|
905
|
+
- **FR-1104-01**: convert command reads a TS file exporting a SpecModule via defineSpecs() and writes equivalent YAML [test]
|
|
906
|
+
- **FR-1104-02**: Output defaults to same filename with .yaml extension [test]
|
|
907
|
+
- **FR-1104-03**: --output allows specifying a custom output path [test]
|
|
908
|
+
- **FR-1104-04**: --dry-run previews conversion without writing files [test]
|
|
@@ -214,15 +214,15 @@ To ensure all acceptance criteria are covered by test cases and maintain spec-te
|
|
|
214
214
|
|
|
215
215
|
**Type**: non-functional | **Priority**: must | **Category**: testability
|
|
216
216
|
|
|
217
|
-
CLI command definitions in design/cli-commands.ts match
|
|
217
|
+
CLI command definitions in design/cli-commands.ts match cli-contract.yaml and generated code in src/generated/
|
|
218
218
|
|
|
219
219
|
### Rationale
|
|
220
220
|
|
|
221
|
-
To ensure specification and implementation stay synchronized
|
|
221
|
+
To ensure specification, DSL contract, and generated implementation stay synchronized
|
|
222
222
|
|
|
223
223
|
### Acceptance Criteria
|
|
224
224
|
|
|
225
|
-
- **NFR-014-01**: All command definitions in design/cli-commands.ts match
|
|
225
|
+
- **NFR-014-01**: All command definitions in design/cli-commands.ts match cli-contract.yaml and generated code (parameters, subcommands, exit codes) [test]
|
|
226
226
|
|
|
227
227
|
---
|
|
228
228
|
|
package/docs/design/test-refs.md
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
| TEST-023 | Impact command verification test | vitest | 1 |
|
|
13
13
|
| TEST-024 | Drift command verification test | vitest | 1 |
|
|
14
14
|
| TEST-025 | New command verification test | vitest | 1 |
|
|
15
|
+
| TEST-026 | Scaffold integration verification test (mermaid parsing, class-based generation) | vitest | 1 |
|
|
15
16
|
|
|
16
17
|
---
|
|
17
18
|
|
|
@@ -256,3 +257,28 @@
|
|
|
256
257
|
| FR-104-01 | `FR-104-01.*available model types header` | Outputs model types header when type omitted |
|
|
257
258
|
|
|
258
259
|
---
|
|
260
|
+
|
|
261
|
+
## TEST-026: Scaffold integration verification test (mermaid parsing, class-based generation)
|
|
262
|
+
|
|
263
|
+
### Test Source
|
|
264
|
+
|
|
265
|
+
- **Path**: `test/scaffold/integration.test.ts`
|
|
266
|
+
- **Framework**: vitest
|
|
267
|
+
|
|
268
|
+
### Verified Requirements
|
|
269
|
+
|
|
270
|
+
- FR-106
|
|
271
|
+
|
|
272
|
+
### Implemented Command
|
|
273
|
+
|
|
274
|
+
- CMD-SCAFFOLD
|
|
275
|
+
|
|
276
|
+
### Test Case Patterns
|
|
277
|
+
|
|
278
|
+
| Acceptance Criteria ID | Pattern | Description |
|
|
279
|
+
|------------------------|---------|-------------|
|
|
280
|
+
| FR-106-01 | `base template.*core factory|generated models.*base template` | Artifact class generates from base template |
|
|
281
|
+
| FR-106-03 | `SR.*FR.*NFR.*map to requirement.*de-duplicated` | Same-class node aggregation into single model file |
|
|
282
|
+
| FR-106-05 | `de-duplicated model files.*spec data` | Model file generation with naming conventions |
|
|
283
|
+
|
|
284
|
+
---
|
package/docs/model-guide.md
CHANGED
|
@@ -109,7 +109,10 @@ export interface Exporter<T> {
|
|
|
109
109
|
format: 'markdown' | 'json' | 'mermaid';
|
|
110
110
|
single?: (spec: T) => string;
|
|
111
111
|
index?: (specs: T[]) => string;
|
|
112
|
+
/** Subdirectory under docsDir (used with single + index/index.md) */
|
|
112
113
|
outputDir?: string;
|
|
114
|
+
/** Direct output file path relative to docsDir (used with index-only exporters) */
|
|
115
|
+
outputFile?: string;
|
|
113
116
|
filename?: (spec: T) => string;
|
|
114
117
|
}
|
|
115
118
|
|
|
@@ -138,34 +141,31 @@ export interface CheckResult {
|
|
|
138
141
|
}>;
|
|
139
142
|
}
|
|
140
143
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
144
|
+
// ============================================================================
|
|
145
|
+
// Deep Validation (replaces per-model externalChecker)
|
|
146
|
+
// ============================================================================
|
|
147
|
+
|
|
148
|
+
/** OpenAPI deep validation mapping */
|
|
149
|
+
export interface OpenAPIValidationMapping {
|
|
150
|
+
path: string;
|
|
151
|
+
method?: string;
|
|
152
|
+
parameters?: Array<{ name: string; in?: string; type?: string }>;
|
|
153
|
+
responseProperties?: Array<{ name: string; type?: string }>;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** DDL deep validation mapping */
|
|
157
|
+
export interface DDLValidationMapping {
|
|
158
|
+
tableName: string;
|
|
159
|
+
columns?: Array<{ name: string; type?: string }>;
|
|
160
|
+
checkTypes?: boolean;
|
|
157
161
|
}
|
|
158
162
|
|
|
159
163
|
/**
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
* Example: Whether TestRef covers acceptanceCriteria of Requirement
|
|
164
|
+
* Deep validation rule for a specific source type.
|
|
165
|
+
* The mapper extracts expected structure from a spec for detailed comparison
|
|
166
|
+
* against the matched source object.
|
|
164
167
|
*/
|
|
165
|
-
export interface
|
|
166
|
-
/** Target model ID for coverage (e.g. 'requirement') */
|
|
167
|
-
targetModel: string;
|
|
168
|
-
/** Description of coverage check */
|
|
168
|
+
export interface DeepValidationRule<T, TMapping = unknown> {
|
|
169
169
|
```
|
|
170
170
|
<!--@embedoc:end-->
|
|
171
171
|
|
|
@@ -175,54 +175,54 @@ export interface CoverageChecker<T> {
|
|
|
175
175
|
**src/core/model.ts (Model Class Properties)**
|
|
176
176
|
|
|
177
177
|
```typescript
|
|
178
|
-
/** Execute coverage check */
|
|
179
|
-
check: (
|
|
180
|
-
specs: T[],
|
|
181
|
-
registry: Record<string, Map<string, unknown>>
|
|
182
|
-
) => CoverageResult;
|
|
183
178
|
}
|
|
184
179
|
|
|
185
|
-
// ============================================================================
|
|
186
|
-
// Renderer (for embeds)
|
|
187
|
-
// ============================================================================
|
|
188
|
-
|
|
189
180
|
/**
|
|
190
|
-
*
|
|
191
|
-
*
|
|
181
|
+
* Deep validation configuration keyed by source type.
|
|
182
|
+
* Models define this to enable Level 2/3 checks beyond existence.
|
|
192
183
|
*/
|
|
193
|
-
export interface
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
markdown: {
|
|
198
|
-
/** Generate table */
|
|
199
|
-
table: (headers: string[], rows: (string | unknown)[][]) => string;
|
|
200
|
-
};
|
|
184
|
+
export interface DeepValidationConfig<T> {
|
|
185
|
+
openapi?: DeepValidationRule<T, OpenAPIValidationMapping>;
|
|
186
|
+
ddl?: DeepValidationRule<T, DDLValidationMapping>;
|
|
187
|
+
[sourceType: string]: DeepValidationRule<T, unknown> | undefined;
|
|
201
188
|
}
|
|
202
189
|
|
|
203
190
|
/**
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
191
|
+
* Lookup key configuration keyed by source type.
|
|
192
|
+
* When a model's spec ID differs from the external identifier
|
|
193
|
+
* (e.g. entity ID "user" vs DDL table name "users"),
|
|
194
|
+
* define a mapper per source type to derive the external key.
|
|
195
|
+
* If not defined for a source type, spec.id is used as-is.
|
|
207
196
|
*/
|
|
208
|
-
export interface
|
|
209
|
-
|
|
210
|
-
format: string;
|
|
211
|
-
/** Rendering process */
|
|
212
|
-
render: (specs: T[], ctx: RenderContext) => string;
|
|
197
|
+
export interface LookupKeyConfig<T> {
|
|
198
|
+
[sourceType: string]: ((spec: T) => string) | undefined;
|
|
213
199
|
}
|
|
214
200
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
201
|
+
/**
|
|
202
|
+
* Coverage result
|
|
203
|
+
*/
|
|
204
|
+
export interface CoverageResult {
|
|
205
|
+
/** Total target count */
|
|
206
|
+
total: number;
|
|
207
|
+
/** Covered count */
|
|
208
|
+
covered: number;
|
|
209
|
+
/** Uncovered count */
|
|
210
|
+
uncovered: number;
|
|
211
|
+
/** Coverage rate (%) */
|
|
212
|
+
coveragePercent: number;
|
|
213
|
+
/** Details of covered items */
|
|
214
|
+
coveredItems: { id: string; description?: string }[];
|
|
215
|
+
/** Details of uncovered items */
|
|
216
|
+
uncoveredItems: { id: string; description?: string; sourceId?: string }[];
|
|
217
|
+
}
|
|
218
218
|
|
|
219
219
|
/**
|
|
220
|
-
*
|
|
220
|
+
* Coverage checker definition
|
|
221
221
|
*
|
|
222
|
-
*
|
|
222
|
+
* Verify cross-model consistency (coverage).
|
|
223
|
+
* Example: Whether TestRef covers acceptanceCriteria of Requirement
|
|
223
224
|
*/
|
|
224
|
-
export
|
|
225
|
-
/** Singleton instance storage (per subclass) */
|
|
225
|
+
export interface CoverageChecker<T> {
|
|
226
226
|
```
|
|
227
227
|
<!--@embedoc:end-->
|
|
228
228
|
|
|
@@ -493,61 +493,65 @@ class TestRefModel extends Model<typeof TestRefSchema> {
|
|
|
493
493
|
protected exporters: Exporter<TestRef>[] = [
|
|
494
494
|
{
|
|
495
495
|
format: 'markdown',
|
|
496
|
-
|
|
496
|
+
index: (specs) => {
|
|
497
497
|
const lines: string[] = [];
|
|
498
|
-
lines.push(
|
|
499
|
-
lines.push('');
|
|
500
|
-
lines.push('## Test Source');
|
|
498
|
+
lines.push('# Test Reference List');
|
|
501
499
|
lines.push('');
|
|
502
|
-
lines.push(
|
|
503
|
-
lines.push(
|
|
504
|
-
|
|
505
|
-
lines.push(
|
|
500
|
+
lines.push('| ID | Description | Framework | Requirements Count |');
|
|
501
|
+
lines.push('|----|-------------|-----------|-------------------|');
|
|
502
|
+
for (const spec of specs) {
|
|
503
|
+
lines.push(
|
|
504
|
+
`| ${spec.id} | ${spec.description} | ${spec.source.framework} | ${spec.verifiesRequirements.length} |`,
|
|
505
|
+
);
|
|
506
506
|
}
|
|
507
507
|
lines.push('');
|
|
508
|
-
|
|
509
|
-
lines.push('## Verified Requirements');
|
|
510
|
-
lines.push('');
|
|
511
|
-
for (const reqId of spec.verifiesRequirements) {
|
|
512
|
-
lines.push(`- ${reqId}`);
|
|
513
|
-
}
|
|
508
|
+
lines.push('---');
|
|
514
509
|
lines.push('');
|
|
515
510
|
|
|
516
|
-
|
|
517
|
-
lines.push(
|
|
511
|
+
for (const spec of specs) {
|
|
512
|
+
lines.push(`## ${spec.id}: ${spec.description}`);
|
|
518
513
|
lines.push('');
|
|
519
|
-
lines.push(
|
|
514
|
+
lines.push('### Test Source');
|
|
515
|
+
lines.push('');
|
|
516
|
+
lines.push(`- **Path**: \`${spec.source.path}\``);
|
|
517
|
+
lines.push(`- **Framework**: ${spec.source.framework}`);
|
|
518
|
+
if (spec.source.resultPath) {
|
|
519
|
+
lines.push(`- **Result JSON**: \`${spec.source.resultPath}\``);
|
|
520
|
+
}
|
|
520
521
|
lines.push('');
|
|
521
|
-
}
|
|
522
522
|
|
|
523
|
-
|
|
524
|
-
lines.push('## Test Case Patterns');
|
|
523
|
+
lines.push('### Verified Requirements');
|
|
525
524
|
lines.push('');
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
for (const p of spec.testCasePatterns) {
|
|
529
|
-
lines.push(`| ${p.acceptanceCriteriaId} | \`${p.pattern}\` | ${p.description || '-'} |`);
|
|
525
|
+
for (const reqId of spec.verifiesRequirements) {
|
|
526
|
+
lines.push(`- ${reqId}`);
|
|
530
527
|
}
|
|
531
528
|
lines.push('');
|
|
532
|
-
}
|
|
533
529
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
530
|
+
if (spec.implementsCommand) {
|
|
531
|
+
lines.push('### Implemented Command');
|
|
532
|
+
lines.push('');
|
|
533
|
+
lines.push(`- ${spec.implementsCommand}`);
|
|
534
|
+
lines.push('');
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
if (spec.testCasePatterns && spec.testCasePatterns.length > 0) {
|
|
538
|
+
lines.push('### Test Case Patterns');
|
|
539
|
+
lines.push('');
|
|
540
|
+
lines.push('| Acceptance Criteria ID | Pattern | Description |');
|
|
541
|
+
lines.push('|------------------------|---------|-------------|');
|
|
542
|
+
for (const p of spec.testCasePatterns) {
|
|
543
|
+
lines.push(`| ${p.acceptanceCriteriaId} | \`${p.pattern}\` | ${p.description || '-'} |`);
|
|
544
|
+
}
|
|
545
|
+
lines.push('');
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
lines.push('---');
|
|
549
|
+
lines.push('');
|
|
546
550
|
}
|
|
547
|
-
|
|
551
|
+
|
|
552
|
+
return lines.join('\n').replace(/\n---\n\n$/s, '\n');
|
|
548
553
|
},
|
|
549
|
-
|
|
550
|
-
filename: (spec) => spec.id,
|
|
554
|
+
outputFile: 'design/test-refs.md',
|
|
551
555
|
},
|
|
552
556
|
];
|
|
553
557
|
|