@hstm-labs/forge-verifier 0.1.11
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 +48 -0
- package/dist/compliance-builder.d.ts +26 -0
- package/dist/compliance-builder.d.ts.map +1 -0
- package/dist/compliance-builder.js +52 -0
- package/dist/compliance-builder.js.map +1 -0
- package/dist/coverage-calculator.d.ts +22 -0
- package/dist/coverage-calculator.d.ts.map +1 -0
- package/dist/coverage-calculator.js +29 -0
- package/dist/coverage-calculator.js.map +1 -0
- package/dist/criteria-extractor.d.ts +39 -0
- package/dist/criteria-extractor.d.ts.map +1 -0
- package/dist/criteria-extractor.js +93 -0
- package/dist/criteria-extractor.js.map +1 -0
- package/dist/formatters.d.ts +25 -0
- package/dist/formatters.d.ts.map +1 -0
- package/dist/formatters.js +84 -0
- package/dist/formatters.js.map +1 -0
- package/dist/gap-detector.d.ts +21 -0
- package/dist/gap-detector.d.ts.map +1 -0
- package/dist/gap-detector.js +73 -0
- package/dist/gap-detector.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/requirement-mapper.d.ts +21 -0
- package/dist/requirement-mapper.d.ts.map +1 -0
- package/dist/requirement-mapper.js +220 -0
- package/dist/requirement-mapper.js.map +1 -0
- package/dist/review-incorporator.d.ts +20 -0
- package/dist/review-incorporator.d.ts.map +1 -0
- package/dist/review-incorporator.js +33 -0
- package/dist/review-incorporator.js.map +1 -0
- package/dist/tech-stack-resolver.d.ts +45 -0
- package/dist/tech-stack-resolver.d.ts.map +1 -0
- package/dist/tech-stack-resolver.js +65 -0
- package/dist/tech-stack-resolver.js.map +1 -0
- package/dist/test-gen-types.d.ts +55 -0
- package/dist/test-gen-types.d.ts.map +1 -0
- package/dist/test-gen-types.js +8 -0
- package/dist/test-gen-types.js.map +1 -0
- package/dist/test-generate-stage.d.ts +52 -0
- package/dist/test-generate-stage.d.ts.map +1 -0
- package/dist/test-generate-stage.js +190 -0
- package/dist/test-generate-stage.js.map +1 -0
- package/dist/test-output-validator.d.ts +40 -0
- package/dist/test-output-validator.d.ts.map +1 -0
- package/dist/test-output-validator.js +171 -0
- package/dist/test-output-validator.js.map +1 -0
- package/dist/types.d.ts +94 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/verify-stage.d.ts +48 -0
- package/dist/verify-stage.d.ts.map +1 -0
- package/dist/verify-stage.js +155 -0
- package/dist/verify-stage.js.map +1 -0
- package/package.json +32 -0
package/README.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# @hstm-labs/forge-verifier
|
|
2
|
+
|
|
3
|
+
Specification compliance verification and automated test generation for Forge — maps requirements to artifacts, calculates coverage scores, detects gaps, incorporates review findings, and generates test files from acceptance criteria.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @hstm-labs/forge-verifier
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Public API
|
|
12
|
+
|
|
13
|
+
### Compliance Verification
|
|
14
|
+
|
|
15
|
+
- `VerifyStage` — pipeline stage for compliance verification
|
|
16
|
+
- `mapRequirementsToArtifacts()` — map spec requirements to generated artifacts
|
|
17
|
+
- `calculateCoverage()` — compute coverage score from mappings
|
|
18
|
+
- `detectGaps()` — identify uncovered or partially covered requirements
|
|
19
|
+
- `incorporateReviewFindings()` — merge AI review findings into compliance report
|
|
20
|
+
- `buildComplianceReport()` — assemble final compliance report
|
|
21
|
+
- `formatComplianceReport()`, `complianceReportToJson()` — output formatters
|
|
22
|
+
|
|
23
|
+
### Test Generation
|
|
24
|
+
|
|
25
|
+
- `TestGenerateStage` — pipeline stage for LLM-driven test generation
|
|
26
|
+
- `TestOutputValidator` — validates generated test output
|
|
27
|
+
- `extractTestCriteria()` — extract testable criteria from acceptance criteria
|
|
28
|
+
|
|
29
|
+
### Types
|
|
30
|
+
|
|
31
|
+
- `ComplianceReport`, `RequirementCoverage`, `CoverageEvidence` — compliance types
|
|
32
|
+
- `ComplianceGap`, `ReviewFindingSummary` — gap analysis types
|
|
33
|
+
- `TestArtifact`, `TestFile`, `TestTraceability`, `TestMetadata` — test generation types
|
|
34
|
+
- `TestCriterion` — extracted test criterion
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { VerifyStage, formatComplianceReport } from '@hstm-labs/forge-verifier';
|
|
40
|
+
|
|
41
|
+
const stage = new VerifyStage();
|
|
42
|
+
const result = await stage.execute(input);
|
|
43
|
+
console.log(formatComplianceReport(result.data));
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## License
|
|
47
|
+
|
|
48
|
+
[MIT](../../LICENSE)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compliance report builder for the verify stage.
|
|
3
|
+
*
|
|
4
|
+
* Assembles the final {@link ComplianceReport} from coverage results,
|
|
5
|
+
* gaps, review findings, and score data.
|
|
6
|
+
*/
|
|
7
|
+
import type { ComplianceReport, RequirementCoverage, ComplianceGap, ReviewFindingSummary } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Build the final compliance report.
|
|
10
|
+
*
|
|
11
|
+
* Assembles all verification results into a single {@link ComplianceReport}
|
|
12
|
+
* with an auto-generated summary and ISO timestamp.
|
|
13
|
+
*
|
|
14
|
+
* @param options - Report components
|
|
15
|
+
* @returns Assembled compliance report
|
|
16
|
+
*/
|
|
17
|
+
export declare function buildComplianceReport(options: {
|
|
18
|
+
runId: string;
|
|
19
|
+
coverage: RequirementCoverage[];
|
|
20
|
+
gaps: ComplianceGap[];
|
|
21
|
+
reviewFindings: ReviewFindingSummary[];
|
|
22
|
+
totalRequirements: number;
|
|
23
|
+
coveredRequirements: number;
|
|
24
|
+
score: number;
|
|
25
|
+
}): ComplianceReport;
|
|
26
|
+
//# sourceMappingURL=compliance-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compliance-builder.d.ts","sourceRoot":"","sources":["../src/compliance-builder.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAMpB;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,cAAc,EAAE,oBAAoB,EAAE,CAAC;IACvC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,gBAAgB,CAqCnB"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compliance report builder for the verify stage.
|
|
3
|
+
*
|
|
4
|
+
* Assembles the final {@link ComplianceReport} from coverage results,
|
|
5
|
+
* gaps, review findings, and score data.
|
|
6
|
+
*/
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Public API
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
/**
|
|
11
|
+
* Build the final compliance report.
|
|
12
|
+
*
|
|
13
|
+
* Assembles all verification results into a single {@link ComplianceReport}
|
|
14
|
+
* with an auto-generated summary and ISO timestamp.
|
|
15
|
+
*
|
|
16
|
+
* @param options - Report components
|
|
17
|
+
* @returns Assembled compliance report
|
|
18
|
+
*/
|
|
19
|
+
export function buildComplianceReport(options) {
|
|
20
|
+
const criticalGaps = options.gaps.filter((g) => g.severity === 'critical').length;
|
|
21
|
+
const majorGaps = options.gaps.filter((g) => g.severity === 'major').length;
|
|
22
|
+
const minorGaps = options.gaps.filter((g) => g.severity === 'minor').length;
|
|
23
|
+
const gapParts = [];
|
|
24
|
+
if (criticalGaps > 0)
|
|
25
|
+
gapParts.push(`${String(criticalGaps)} critical`);
|
|
26
|
+
if (majorGaps > 0)
|
|
27
|
+
gapParts.push(`${String(majorGaps)} major`);
|
|
28
|
+
if (minorGaps > 0)
|
|
29
|
+
gapParts.push(`${String(minorGaps)} minor`);
|
|
30
|
+
const gapSummary = options.gaps.length > 0
|
|
31
|
+
? ` ${String(options.gaps.length)} gaps detected (${gapParts.join(', ')}).`
|
|
32
|
+
: ' No gaps detected.';
|
|
33
|
+
const reviewSummary = options.reviewFindings.length > 0
|
|
34
|
+
? ` ${String(options.reviewFindings.length)} spec-adherence review finding${options.reviewFindings.length === 1 ? '' : 's'}.`
|
|
35
|
+
: '';
|
|
36
|
+
const summary = `Compliance verification complete: ${String(options.score)}% coverage ` +
|
|
37
|
+
`(${String(options.coveredRequirements)}/${String(options.totalRequirements)} requirements covered).` +
|
|
38
|
+
gapSummary +
|
|
39
|
+
reviewSummary;
|
|
40
|
+
return {
|
|
41
|
+
runId: options.runId,
|
|
42
|
+
score: options.score,
|
|
43
|
+
coverage: options.coverage,
|
|
44
|
+
gaps: options.gaps,
|
|
45
|
+
reviewFindings: options.reviewFindings,
|
|
46
|
+
totalRequirements: options.totalRequirements,
|
|
47
|
+
coveredRequirements: options.coveredRequirements,
|
|
48
|
+
generatedAt: new Date().toISOString(),
|
|
49
|
+
summary,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=compliance-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compliance-builder.js","sourceRoot":"","sources":["../src/compliance-builder.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAQrC;IACC,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC,MAAM,CAAC;IAClF,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;IAC5E,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;IAE5E,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,YAAY,GAAG,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;IACxE,IAAI,SAAS,GAAG,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC/D,IAAI,SAAS,GAAG,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAE/D,MAAM,UAAU,GACd,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;QACrB,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,mBAAmB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;QAC3E,CAAC,CAAC,oBAAoB,CAAC;IAE3B,MAAM,aAAa,GACjB,OAAO,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC;QAC/B,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,iCAAiC,OAAO,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG;QAC7H,CAAC,CAAC,EAAE,CAAC;IAET,MAAM,OAAO,GACX,qCAAqC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa;QACvE,IAAI,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,yBAAyB;QACrG,UAAU;QACV,aAAa,CAAC;IAEhB,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,cAAc,EAAE,OAAO,CAAC,cAAc;QACtC,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;QAC5C,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;QAChD,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,OAAO;KACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coverage score calculator for compliance verification.
|
|
3
|
+
*
|
|
4
|
+
* Computes the percentage of requirements covered by generated artifacts.
|
|
5
|
+
*/
|
|
6
|
+
import type { RequirementCoverage } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Calculate the coverage score from requirement coverage results.
|
|
9
|
+
*
|
|
10
|
+
* A requirement is considered covered if its coverage level is `'full'` or
|
|
11
|
+
* `'partial'`. The score is `(coveredCount / totalCount) * 100`, rounded
|
|
12
|
+
* to one decimal place.
|
|
13
|
+
*
|
|
14
|
+
* @param coverageResults - Per-requirement coverage results
|
|
15
|
+
* @returns Score (0–100), covered count, and total count
|
|
16
|
+
*/
|
|
17
|
+
export declare function calculateCoverage(coverageResults: RequirementCoverage[]): {
|
|
18
|
+
score: number;
|
|
19
|
+
coveredCount: number;
|
|
20
|
+
totalCount: number;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=coverage-calculator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage-calculator.d.ts","sourceRoot":"","sources":["../src/coverage-calculator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAMtD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,eAAe,EAAE,mBAAmB,EAAE,GACrC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAY7D"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coverage score calculator for compliance verification.
|
|
3
|
+
*
|
|
4
|
+
* Computes the percentage of requirements covered by generated artifacts.
|
|
5
|
+
*/
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Public API
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
/**
|
|
10
|
+
* Calculate the coverage score from requirement coverage results.
|
|
11
|
+
*
|
|
12
|
+
* A requirement is considered covered if its coverage level is `'full'` or
|
|
13
|
+
* `'partial'`. The score is `(coveredCount / totalCount) * 100`, rounded
|
|
14
|
+
* to one decimal place.
|
|
15
|
+
*
|
|
16
|
+
* @param coverageResults - Per-requirement coverage results
|
|
17
|
+
* @returns Score (0–100), covered count, and total count
|
|
18
|
+
*/
|
|
19
|
+
export function calculateCoverage(coverageResults) {
|
|
20
|
+
const totalCount = coverageResults.length;
|
|
21
|
+
// Edge case: no requirements to violate
|
|
22
|
+
if (totalCount === 0) {
|
|
23
|
+
return { score: 100, coveredCount: 0, totalCount: 0 };
|
|
24
|
+
}
|
|
25
|
+
const coveredCount = coverageResults.filter((r) => r.covered).length;
|
|
26
|
+
const score = Math.round((coveredCount / totalCount) * 1000) / 10;
|
|
27
|
+
return { score, coveredCount, totalCount };
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=coverage-calculator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage-calculator.js","sourceRoot":"","sources":["../src/coverage-calculator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAC/B,eAAsC;IAEtC,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC;IAE1C,wCAAwC;IACxC,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IACxD,CAAC;IAED,MAAM,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IACrE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,UAAU,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAElE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Acceptance criteria extractor for test generation.
|
|
3
|
+
*
|
|
4
|
+
* Transforms specification requirements into structured test criteria
|
|
5
|
+
* with entity matching and artifact cross-referencing.
|
|
6
|
+
*/
|
|
7
|
+
import type { SpecRequirement, SpecEntity } from '@hstm-labs/forge-spec-parser';
|
|
8
|
+
import type { ApiEndpoint } from '@hstm-labs/forge-services-generator';
|
|
9
|
+
import type { UiPage } from '@hstm-labs/forge-apps-generator';
|
|
10
|
+
/** A structured test criterion derived from a specification requirement. */
|
|
11
|
+
export interface TestCriterion {
|
|
12
|
+
/** Requirement ID (e.g., "REQ-001"). */
|
|
13
|
+
requirementId: string;
|
|
14
|
+
/** Requirement title. */
|
|
15
|
+
requirementTitle: string;
|
|
16
|
+
/** The acceptance criterion text. */
|
|
17
|
+
criterion: string;
|
|
18
|
+
/** Entity this criterion relates to (if detected). */
|
|
19
|
+
entity?: string | undefined;
|
|
20
|
+
/** Matching API endpoint paths for the detected entity. */
|
|
21
|
+
apiEndpoints: string[];
|
|
22
|
+
/** Matching UI page routes for the detected entity. */
|
|
23
|
+
uiPages: string[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Extract structured test criteria from specification requirements.
|
|
27
|
+
*
|
|
28
|
+
* For each requirement, iterates its `acceptanceCriteria` array, detects
|
|
29
|
+
* which entity the criterion relates to, and cross-references matching
|
|
30
|
+
* API endpoints and UI pages.
|
|
31
|
+
*
|
|
32
|
+
* @param requirements - Specification requirements with acceptance criteria
|
|
33
|
+
* @param entities - Specification entities for name matching
|
|
34
|
+
* @param apiEndpoints - API endpoints for cross-referencing (optional)
|
|
35
|
+
* @param uiPages - UI pages for cross-referencing (optional)
|
|
36
|
+
* @returns Structured test criteria grouped by requirement
|
|
37
|
+
*/
|
|
38
|
+
export declare function extractTestCriteria(requirements: SpecRequirement[], entities: SpecEntity[], apiEndpoints?: ApiEndpoint[], uiPages?: UiPage[]): TestCriterion[];
|
|
39
|
+
//# sourceMappingURL=criteria-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"criteria-extractor.d.ts","sourceRoot":"","sources":["../src/criteria-extractor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAChF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AAM9D,4EAA4E;AAC5E,MAAM,WAAW,aAAa;IAC5B,wCAAwC;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,yBAAyB;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,2DAA2D;IAC3D,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,uDAAuD;IACvD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAgED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,eAAe,EAAE,EAC/B,QAAQ,EAAE,UAAU,EAAE,EACtB,YAAY,CAAC,EAAE,WAAW,EAAE,EAC5B,OAAO,CAAC,EAAE,MAAM,EAAE,GACjB,aAAa,EAAE,CA+BjB"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Acceptance criteria extractor for test generation.
|
|
3
|
+
*
|
|
4
|
+
* Transforms specification requirements into structured test criteria
|
|
5
|
+
* with entity matching and artifact cross-referencing.
|
|
6
|
+
*/
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Helpers
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
/**
|
|
11
|
+
* Detect which entity a criterion text relates to (case-insensitive).
|
|
12
|
+
*
|
|
13
|
+
* @param text - Criterion text to search
|
|
14
|
+
* @param entities - Specification entities
|
|
15
|
+
* @returns The first matching entity name, or `undefined`
|
|
16
|
+
*/
|
|
17
|
+
function detectEntity(text, entities) {
|
|
18
|
+
const lower = text.toLowerCase();
|
|
19
|
+
for (const entity of entities) {
|
|
20
|
+
if (lower.includes(entity.name.toLowerCase())) {
|
|
21
|
+
return entity.name;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Find API endpoint paths that match a given entity.
|
|
28
|
+
*
|
|
29
|
+
* @param entityName - Entity name to match
|
|
30
|
+
* @param endpoints - Available API endpoints
|
|
31
|
+
* @returns Array of matching endpoint path strings (e.g., "GET /api/pets")
|
|
32
|
+
*/
|
|
33
|
+
function findMatchingEndpoints(entityName, endpoints) {
|
|
34
|
+
const lower = entityName.toLowerCase();
|
|
35
|
+
return endpoints
|
|
36
|
+
.filter((ep) => ep.entity.toLowerCase() === lower)
|
|
37
|
+
.map((ep) => `${ep.method} ${ep.path}`);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Find UI page routes that match a given entity.
|
|
41
|
+
*
|
|
42
|
+
* @param entityName - Entity name to match
|
|
43
|
+
* @param pages - Available UI pages
|
|
44
|
+
* @returns Array of matching page route strings
|
|
45
|
+
*/
|
|
46
|
+
function findMatchingPages(entityName, pages) {
|
|
47
|
+
const lower = entityName.toLowerCase();
|
|
48
|
+
return pages
|
|
49
|
+
.filter((p) => p.entity?.toLowerCase() === lower)
|
|
50
|
+
.map((p) => p.route);
|
|
51
|
+
}
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// Public API
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
/**
|
|
56
|
+
* Extract structured test criteria from specification requirements.
|
|
57
|
+
*
|
|
58
|
+
* For each requirement, iterates its `acceptanceCriteria` array, detects
|
|
59
|
+
* which entity the criterion relates to, and cross-references matching
|
|
60
|
+
* API endpoints and UI pages.
|
|
61
|
+
*
|
|
62
|
+
* @param requirements - Specification requirements with acceptance criteria
|
|
63
|
+
* @param entities - Specification entities for name matching
|
|
64
|
+
* @param apiEndpoints - API endpoints for cross-referencing (optional)
|
|
65
|
+
* @param uiPages - UI pages for cross-referencing (optional)
|
|
66
|
+
* @returns Structured test criteria grouped by requirement
|
|
67
|
+
*/
|
|
68
|
+
export function extractTestCriteria(requirements, entities, apiEndpoints, uiPages) {
|
|
69
|
+
const criteria = [];
|
|
70
|
+
for (const req of requirements) {
|
|
71
|
+
for (const criterion of req.acceptanceCriteria) {
|
|
72
|
+
// Detect entity from criterion text; fall back to requirement title + description
|
|
73
|
+
const combinedText = `${criterion} ${req.title} ${req.description}`;
|
|
74
|
+
const entity = detectEntity(combinedText, entities);
|
|
75
|
+
const apiMatches = entity !== undefined && apiEndpoints !== undefined
|
|
76
|
+
? findMatchingEndpoints(entity, apiEndpoints)
|
|
77
|
+
: [];
|
|
78
|
+
const uiMatches = entity !== undefined && uiPages !== undefined
|
|
79
|
+
? findMatchingPages(entity, uiPages)
|
|
80
|
+
: [];
|
|
81
|
+
criteria.push({
|
|
82
|
+
requirementId: req.id,
|
|
83
|
+
requirementTitle: req.title,
|
|
84
|
+
criterion,
|
|
85
|
+
entity,
|
|
86
|
+
apiEndpoints: apiMatches,
|
|
87
|
+
uiPages: uiMatches,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return criteria;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=criteria-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"criteria-extractor.js","sourceRoot":"","sources":["../src/criteria-extractor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA0BH,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;;GAMG;AACH,SAAS,YAAY,CACnB,IAAY,EACZ,QAAsB;IAEtB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YAC9C,OAAO,MAAM,CAAC,IAAI,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,qBAAqB,CAC5B,UAAkB,EAClB,SAAwB;IAExB,MAAM,KAAK,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;IACvC,OAAO,SAAS;SACb,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC;SACjD,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;GAMG;AACH,SAAS,iBAAiB,CACxB,UAAkB,EAClB,KAAe;IAEf,MAAM,KAAK,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;IACvC,OAAO,KAAK;SACT,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,KAAK,CAAC;SAChD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AACzB,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,mBAAmB,CACjC,YAA+B,EAC/B,QAAsB,EACtB,YAA4B,EAC5B,OAAkB;IAElB,MAAM,QAAQ,GAAoB,EAAE,CAAC;IAErC,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;QAC/B,KAAK,MAAM,SAAS,IAAI,GAAG,CAAC,kBAAkB,EAAE,CAAC;YAC/C,kFAAkF;YAClF,MAAM,YAAY,GAAG,GAAG,SAAS,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;YACpE,MAAM,MAAM,GAAG,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;YAEpD,MAAM,UAAU,GACd,MAAM,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS;gBAChD,CAAC,CAAC,qBAAqB,CAAC,MAAM,EAAE,YAAY,CAAC;gBAC7C,CAAC,CAAC,EAAE,CAAC;YAET,MAAM,SAAS,GACb,MAAM,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS;gBAC3C,CAAC,CAAC,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC;gBACpC,CAAC,CAAC,EAAE,CAAC;YAET,QAAQ,CAAC,IAAI,CAAC;gBACZ,aAAa,EAAE,GAAG,CAAC,EAAE;gBACrB,gBAAgB,EAAE,GAAG,CAAC,KAAK;gBAC3B,SAAS;gBACT,MAAM;gBACN,YAAY,EAAE,UAAU;gBACxB,OAAO,EAAE,SAAS;aACnB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compliance report formatters for CLI output.
|
|
3
|
+
*
|
|
4
|
+
* Provides both human-readable and machine-readable (JSON)
|
|
5
|
+
* formatting of {@link ComplianceReport}.
|
|
6
|
+
*/
|
|
7
|
+
import type { ComplianceReport } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Format a compliance report as a human-readable string for terminal output.
|
|
10
|
+
*
|
|
11
|
+
* Produces a box-drawn report with score, coverage details, gaps,
|
|
12
|
+
* review findings, and summary.
|
|
13
|
+
*
|
|
14
|
+
* @param report - The compliance report to format
|
|
15
|
+
* @returns Formatted multi-line string
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatComplianceReport(report: ComplianceReport): string;
|
|
18
|
+
/**
|
|
19
|
+
* Convert a compliance report to a plain JSON-serialisable object.
|
|
20
|
+
*
|
|
21
|
+
* @param report - The compliance report
|
|
22
|
+
* @returns The report as a plain object (identity for JSON output)
|
|
23
|
+
*/
|
|
24
|
+
export declare function complianceReportToJson(report: ComplianceReport): Record<string, unknown>;
|
|
25
|
+
//# sourceMappingURL=formatters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../src/formatters.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAMnD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAqEvE;AAMD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,gBAAgB,GACvB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compliance report formatters for CLI output.
|
|
3
|
+
*
|
|
4
|
+
* Provides both human-readable and machine-readable (JSON)
|
|
5
|
+
* formatting of {@link ComplianceReport}.
|
|
6
|
+
*/
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Human-Readable Formatter
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
/**
|
|
11
|
+
* Format a compliance report as a human-readable string for terminal output.
|
|
12
|
+
*
|
|
13
|
+
* Produces a box-drawn report with score, coverage details, gaps,
|
|
14
|
+
* review findings, and summary.
|
|
15
|
+
*
|
|
16
|
+
* @param report - The compliance report to format
|
|
17
|
+
* @returns Formatted multi-line string
|
|
18
|
+
*/
|
|
19
|
+
export function formatComplianceReport(report) {
|
|
20
|
+
const lines = [];
|
|
21
|
+
// Header box
|
|
22
|
+
lines.push('╔══════════════════════════════════════════╗');
|
|
23
|
+
lines.push('║ Compliance Verification Report ║');
|
|
24
|
+
lines.push('╠══════════════════════════════════════════╣');
|
|
25
|
+
lines.push(`║ Score: ${String(report.score)}% (${String(report.coveredRequirements)}/${String(report.totalRequirements)} requirements)`.padEnd(43) + '║');
|
|
26
|
+
lines.push('╚══════════════════════════════════════════╝');
|
|
27
|
+
lines.push('');
|
|
28
|
+
// Coverage section
|
|
29
|
+
lines.push('Coverage:');
|
|
30
|
+
for (const cov of report.coverage) {
|
|
31
|
+
let symbol;
|
|
32
|
+
switch (cov.coverageLevel) {
|
|
33
|
+
case 'full':
|
|
34
|
+
symbol = '✓';
|
|
35
|
+
break;
|
|
36
|
+
case 'partial':
|
|
37
|
+
symbol = '~';
|
|
38
|
+
break;
|
|
39
|
+
case 'none':
|
|
40
|
+
symbol = '✗';
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
lines.push(` ${symbol} ${cov.requirementId}: ${cov.title}`.padEnd(45) +
|
|
44
|
+
`[${cov.coverageLevel}]`);
|
|
45
|
+
}
|
|
46
|
+
lines.push('');
|
|
47
|
+
// Gaps section
|
|
48
|
+
if (report.gaps.length > 0) {
|
|
49
|
+
lines.push(`Gaps (${String(report.gaps.length)}):`);
|
|
50
|
+
for (const gap of report.gaps) {
|
|
51
|
+
const severity = `[${gap.severity}]`.padEnd(10);
|
|
52
|
+
lines.push(` ${severity} ${gap.requirementId}: ${gap.title} — ${gap.description}`);
|
|
53
|
+
}
|
|
54
|
+
lines.push('');
|
|
55
|
+
}
|
|
56
|
+
// Review findings section
|
|
57
|
+
if (report.reviewFindings.length > 0) {
|
|
58
|
+
lines.push('Review Findings (spec-adherence):');
|
|
59
|
+
for (const finding of report.reviewFindings) {
|
|
60
|
+
const severity = `[${finding.severity}]`.padEnd(13);
|
|
61
|
+
const ref = finding.specReference !== undefined
|
|
62
|
+
? ` (${finding.specReference})`
|
|
63
|
+
: '';
|
|
64
|
+
lines.push(` ${severity} ${finding.findingId}: ${finding.title}${ref}`);
|
|
65
|
+
}
|
|
66
|
+
lines.push('');
|
|
67
|
+
}
|
|
68
|
+
// Summary
|
|
69
|
+
lines.push(`Summary: ${report.summary}`);
|
|
70
|
+
return lines.join('\n');
|
|
71
|
+
}
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
// JSON Formatter
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
/**
|
|
76
|
+
* Convert a compliance report to a plain JSON-serialisable object.
|
|
77
|
+
*
|
|
78
|
+
* @param report - The compliance report
|
|
79
|
+
* @returns The report as a plain object (identity for JSON output)
|
|
80
|
+
*/
|
|
81
|
+
export function complianceReportToJson(report) {
|
|
82
|
+
return report;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=formatters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatters.js","sourceRoot":"","sources":["../src/formatters.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gap detector for compliance verification.
|
|
3
|
+
*
|
|
4
|
+
* Identifies requirements not fully covered by generated artifacts
|
|
5
|
+
* and maps requirement priority to gap severity.
|
|
6
|
+
*/
|
|
7
|
+
import type { SpecRequirement } from '@hstm-labs/forge-spec-parser';
|
|
8
|
+
import type { RequirementCoverage, ComplianceGap } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Detect compliance gaps from coverage results.
|
|
11
|
+
*
|
|
12
|
+
* Creates a gap for each requirement with `coverageLevel: 'none'` or
|
|
13
|
+
* `coverageLevel: 'partial'`. Gap severity is derived from the requirement
|
|
14
|
+
* priority.
|
|
15
|
+
*
|
|
16
|
+
* @param coverageResults - Per-requirement coverage results
|
|
17
|
+
* @param requirements - Original specification requirements (for priority lookup)
|
|
18
|
+
* @returns Array of compliance gaps
|
|
19
|
+
*/
|
|
20
|
+
export declare function detectGaps(coverageResults: RequirementCoverage[], requirements: SpecRequirement[]): ComplianceGap[];
|
|
21
|
+
//# sourceMappingURL=gap-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gap-detector.d.ts","sourceRoot":"","sources":["../src/gap-detector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAgDrE;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CACxB,eAAe,EAAE,mBAAmB,EAAE,EACtC,YAAY,EAAE,eAAe,EAAE,GAC9B,aAAa,EAAE,CAuBjB"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gap detector for compliance verification.
|
|
3
|
+
*
|
|
4
|
+
* Identifies requirements not fully covered by generated artifacts
|
|
5
|
+
* and maps requirement priority to gap severity.
|
|
6
|
+
*/
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Helpers
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
/**
|
|
11
|
+
* Map a requirement priority to a gap severity.
|
|
12
|
+
*
|
|
13
|
+
* @param priority - Requirement priority from spec
|
|
14
|
+
* @returns Gap severity: must→critical, should→major, could/wont/undefined→minor
|
|
15
|
+
*/
|
|
16
|
+
function mapSeverity(priority) {
|
|
17
|
+
switch (priority) {
|
|
18
|
+
case 'must':
|
|
19
|
+
return 'critical';
|
|
20
|
+
case 'should':
|
|
21
|
+
return 'major';
|
|
22
|
+
case 'could':
|
|
23
|
+
case 'wont':
|
|
24
|
+
default:
|
|
25
|
+
return 'minor';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Build a gap description based on coverage level.
|
|
30
|
+
*
|
|
31
|
+
* @param req - The specification requirement
|
|
32
|
+
* @param coverageLevel - The detected coverage level
|
|
33
|
+
* @returns Human-readable description of the gap
|
|
34
|
+
*/
|
|
35
|
+
function buildGapDescription(req, coverageLevel) {
|
|
36
|
+
if (coverageLevel === 'none') {
|
|
37
|
+
return `No artifacts found covering requirement "${req.title}".`;
|
|
38
|
+
}
|
|
39
|
+
return `Partial coverage for requirement "${req.title}" — some artifact stages are missing evidence.`;
|
|
40
|
+
}
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// Public API
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
/**
|
|
45
|
+
* Detect compliance gaps from coverage results.
|
|
46
|
+
*
|
|
47
|
+
* Creates a gap for each requirement with `coverageLevel: 'none'` or
|
|
48
|
+
* `coverageLevel: 'partial'`. Gap severity is derived from the requirement
|
|
49
|
+
* priority.
|
|
50
|
+
*
|
|
51
|
+
* @param coverageResults - Per-requirement coverage results
|
|
52
|
+
* @param requirements - Original specification requirements (for priority lookup)
|
|
53
|
+
* @returns Array of compliance gaps
|
|
54
|
+
*/
|
|
55
|
+
export function detectGaps(coverageResults, requirements) {
|
|
56
|
+
const reqMap = new Map(requirements.map((r) => [r.id, r]));
|
|
57
|
+
const gaps = [];
|
|
58
|
+
for (const coverage of coverageResults) {
|
|
59
|
+
if (coverage.coverageLevel === 'full')
|
|
60
|
+
continue;
|
|
61
|
+
const req = reqMap.get(coverage.requirementId);
|
|
62
|
+
const priority = req?.priority;
|
|
63
|
+
const severity = mapSeverity(priority);
|
|
64
|
+
gaps.push({
|
|
65
|
+
requirementId: coverage.requirementId,
|
|
66
|
+
title: coverage.title,
|
|
67
|
+
description: buildGapDescription(req ?? { id: coverage.requirementId, title: coverage.title, description: '', acceptanceCriteria: [] }, coverage.coverageLevel),
|
|
68
|
+
severity,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return gaps;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=gap-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gap-detector.js","sourceRoot":"","sources":["../src/gap-detector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;GAKG;AACH,SAAS,WAAW,CAClB,QAA0D;IAE1D,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,MAAM;YACT,OAAO,UAAU,CAAC;QACpB,KAAK,QAAQ;YACX,OAAO,OAAO,CAAC;QACjB,KAAK,OAAO,CAAC;QACb,KAAK,MAAM,CAAC;QACZ;YACE,OAAO,OAAO,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,mBAAmB,CAC1B,GAAoB,EACpB,aAAiC;IAEjC,IAAI,aAAa,KAAK,MAAM,EAAE,CAAC;QAC7B,OAAO,4CAA4C,GAAG,CAAC,KAAK,IAAI,CAAC;IACnE,CAAC;IACD,OAAO,qCAAqC,GAAG,CAAC,KAAK,gDAAgD,CAAC;AACxG,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;;;;;GAUG;AACH,MAAM,UAAU,UAAU,CACxB,eAAsC,EACtC,YAA+B;IAE/B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,MAAM,IAAI,GAAoB,EAAE,CAAC;IAEjC,KAAK,MAAM,QAAQ,IAAI,eAAe,EAAE,CAAC;QACvC,IAAI,QAAQ,CAAC,aAAa,KAAK,MAAM;YAAE,SAAS;QAEhD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,GAAG,EAAE,QAAQ,CAAC;QAC/B,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QAEvC,IAAI,CAAC,IAAI,CAAC;YACR,aAAa,EAAE,QAAQ,CAAC,aAAa;YACrC,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,WAAW,EAAE,mBAAmB,CAC9B,GAAG,IAAI,EAAE,EAAE,EAAE,QAAQ,CAAC,aAAa,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,kBAAkB,EAAE,EAAE,EAAE,EACrG,QAAQ,CAAC,aAAa,CACvB;YACD,QAAQ;SACT,CAAC,CAAC;IACL,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hstm-labs/forge-verifier — Specification compliance verification for Forge.
|
|
3
|
+
*
|
|
4
|
+
* Provides the {@link VerifyStage} pipeline stage, requirement mapping,
|
|
5
|
+
* coverage scoring, gap detection, review finding incorporation, and
|
|
6
|
+
* report formatting.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
export type { ComplianceReport, RequirementCoverage, CoverageEvidence, ComplianceGap, ReviewFindingSummary, } from './types.js';
|
|
11
|
+
export { VerifyStage } from './verify-stage.js';
|
|
12
|
+
export { mapRequirementsToArtifacts } from './requirement-mapper.js';
|
|
13
|
+
export { calculateCoverage } from './coverage-calculator.js';
|
|
14
|
+
export { detectGaps } from './gap-detector.js';
|
|
15
|
+
export { incorporateReviewFindings } from './review-incorporator.js';
|
|
16
|
+
export { buildComplianceReport } from './compliance-builder.js';
|
|
17
|
+
export { formatComplianceReport, complianceReportToJson } from './formatters.js';
|
|
18
|
+
export type { TestArtifact, TestFile, TestTraceability, TestMetadata } from './test-gen-types.js';
|
|
19
|
+
export { TestGenerateStage } from './test-generate-stage.js';
|
|
20
|
+
export { TestOutputValidator } from './test-output-validator.js';
|
|
21
|
+
export { extractTestCriteria } from './criteria-extractor.js';
|
|
22
|
+
export type { TestCriterion } from './criteria-extractor.js';
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,YAAY,EACV,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,oBAAoB,GACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACjF,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAClG,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hstm-labs/forge-verifier — Specification compliance verification for Forge.
|
|
3
|
+
*
|
|
4
|
+
* Provides the {@link VerifyStage} pipeline stage, requirement mapping,
|
|
5
|
+
* coverage scoring, gap detection, review finding incorporation, and
|
|
6
|
+
* report formatting.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
export { VerifyStage } from './verify-stage.js';
|
|
11
|
+
export { mapRequirementsToArtifacts } from './requirement-mapper.js';
|
|
12
|
+
export { calculateCoverage } from './coverage-calculator.js';
|
|
13
|
+
export { detectGaps } from './gap-detector.js';
|
|
14
|
+
export { incorporateReviewFindings } from './review-incorporator.js';
|
|
15
|
+
export { buildComplianceReport } from './compliance-builder.js';
|
|
16
|
+
export { formatComplianceReport, complianceReportToJson } from './formatters.js';
|
|
17
|
+
export { TestGenerateStage } from './test-generate-stage.js';
|
|
18
|
+
export { TestOutputValidator } from './test-output-validator.js';
|
|
19
|
+
export { extractTestCriteria } from './criteria-extractor.js';
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAEjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Requirement-to-artifact mapper for compliance verification.
|
|
3
|
+
*
|
|
4
|
+
* Maps specification requirements to generated artifacts using
|
|
5
|
+
* entity name matching and operation keyword heuristics.
|
|
6
|
+
*/
|
|
7
|
+
import type { SpecRequirement, SpecEntity } from '@hstm-labs/forge-spec-parser';
|
|
8
|
+
import type { RequirementCoverage, GenerationStageOutputs } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Map specification requirements to generated artifacts.
|
|
11
|
+
*
|
|
12
|
+
* Uses entity name matching and operation keyword heuristics to determine
|
|
13
|
+
* which requirements are covered by generated artifacts.
|
|
14
|
+
*
|
|
15
|
+
* @param requirements - Specification requirements to evaluate
|
|
16
|
+
* @param entities - Specification entities for name matching
|
|
17
|
+
* @param outputs - Collected generation stage outputs
|
|
18
|
+
* @returns Per-requirement coverage results with evidence
|
|
19
|
+
*/
|
|
20
|
+
export declare function mapRequirementsToArtifacts(requirements: SpecRequirement[], entities: SpecEntity[], outputs: GenerationStageOutputs): RequirementCoverage[];
|
|
21
|
+
//# sourceMappingURL=requirement-mapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requirement-mapper.d.ts","sourceRoot":"","sources":["../src/requirement-mapper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAChF,OAAO,KAAK,EACV,mBAAmB,EAEnB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAiOpB;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,eAAe,EAAE,EAC/B,QAAQ,EAAE,UAAU,EAAE,EACtB,OAAO,EAAE,sBAAsB,GAC9B,mBAAmB,EAAE,CAevB"}
|