qfai 0.4.7 → 0.5.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 +10 -2
- package/assets/init/.qfai/README.md +3 -0
- package/assets/init/.qfai/promptpack/commands/implement.md +2 -0
- package/assets/init/.qfai/promptpack/commands/plan.md +2 -0
- package/assets/init/.qfai/promptpack/commands/review.md +1 -0
- package/assets/init/.qfai/promptpack/steering/traceability.md +6 -1
- package/assets/init/.qfai/prompts/README.md +16 -0
- package/assets/init/.qfai/prompts/qfai-classify-change.md +33 -0
- package/assets/init/.qfai/prompts/qfai-maintain-contracts.md +35 -0
- package/assets/init/.qfai/prompts/qfai-maintain-traceability.md +36 -0
- package/dist/cli/index.cjs +26 -7
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.ts +0 -2
- package/dist/cli/index.mjs +26 -7
- package/dist/cli/index.mjs.map +1 -1
- package/dist/index.cjs +26 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +168 -2
- package/dist/index.mjs +26 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -1
- package/dist/cli/commands/init.d.ts +0 -8
- package/dist/cli/commands/init.d.ts.map +0 -1
- package/dist/cli/commands/init.js +0 -30
- package/dist/cli/commands/init.js.map +0 -1
- package/dist/cli/commands/report.d.ts +0 -7
- package/dist/cli/commands/report.d.ts.map +0 -1
- package/dist/cli/commands/report.js +0 -108
- package/dist/cli/commands/report.js.map +0 -1
- package/dist/cli/commands/validate.d.ts +0 -9
- package/dist/cli/commands/validate.d.ts.map +0 -1
- package/dist/cli/commands/validate.js +0 -57
- package/dist/cli/commands/validate.js.map +0 -1
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -7
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/lib/args.d.ts +0 -18
- package/dist/cli/lib/args.d.ts.map +0 -1
- package/dist/cli/lib/args.js +0 -98
- package/dist/cli/lib/args.js.map +0 -1
- package/dist/cli/lib/assets.d.ts +0 -2
- package/dist/cli/lib/assets.d.ts.map +0 -1
- package/dist/cli/lib/assets.js +0 -24
- package/dist/cli/lib/assets.js.map +0 -1
- package/dist/cli/lib/failOn.d.ts +0 -5
- package/dist/cli/lib/failOn.d.ts.map +0 -1
- package/dist/cli/lib/failOn.js +0 -10
- package/dist/cli/lib/failOn.js.map +0 -1
- package/dist/cli/lib/fs.d.ts +0 -11
- package/dist/cli/lib/fs.d.ts.map +0 -1
- package/dist/cli/lib/fs.js +0 -91
- package/dist/cli/lib/fs.js.map +0 -1
- package/dist/cli/lib/logger.d.ts +0 -4
- package/dist/cli/lib/logger.d.ts.map +0 -1
- package/dist/cli/lib/logger.js +0 -10
- package/dist/cli/lib/logger.js.map +0 -1
- package/dist/cli/main.d.ts +0 -2
- package/dist/cli/main.d.ts.map +0 -1
- package/dist/cli/main.js +0 -66
- package/dist/cli/main.js.map +0 -1
- package/dist/core/config.d.ts +0 -47
- package/dist/core/config.d.ts.map +0 -1
- package/dist/core/config.js +0 -224
- package/dist/core/config.js.map +0 -1
- package/dist/core/contractIndex.d.ts +0 -12
- package/dist/core/contractIndex.d.ts.map +0 -1
- package/dist/core/contractIndex.js +0 -38
- package/dist/core/contractIndex.js.map +0 -1
- package/dist/core/contracts.d.ts +0 -5
- package/dist/core/contracts.d.ts.map +0 -1
- package/dist/core/contracts.js +0 -42
- package/dist/core/contracts.js.map +0 -1
- package/dist/core/contractsDecl.d.ts +0 -3
- package/dist/core/contractsDecl.d.ts.map +0 -1
- package/dist/core/contractsDecl.js +0 -19
- package/dist/core/contractsDecl.js.map +0 -1
- package/dist/core/discovery.d.ts +0 -14
- package/dist/core/discovery.d.ts.map +0 -1
- package/dist/core/discovery.js +0 -55
- package/dist/core/discovery.js.map +0 -1
- package/dist/core/fs.d.ts +0 -11
- package/dist/core/fs.d.ts.map +0 -1
- package/dist/core/fs.js +0 -68
- package/dist/core/fs.js.map +0 -1
- package/dist/core/gherkin/parse.d.ts +0 -7
- package/dist/core/gherkin/parse.d.ts.map +0 -1
- package/dist/core/gherkin/parse.js +0 -25
- package/dist/core/gherkin/parse.js.map +0 -1
- package/dist/core/ids.d.ts +0 -6
- package/dist/core/ids.d.ts.map +0 -1
- package/dist/core/ids.js +0 -52
- package/dist/core/ids.js.map +0 -1
- package/dist/core/index.d.ts +0 -13
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js +0 -13
- package/dist/core/index.js.map +0 -1
- package/dist/core/parse/adr.d.ts +0 -13
- package/dist/core/parse/adr.d.ts.map +0 -1
- package/dist/core/parse/adr.js +0 -33
- package/dist/core/parse/adr.js.map +0 -1
- package/dist/core/parse/gherkin.d.ts +0 -12
- package/dist/core/parse/gherkin.d.ts.map +0 -1
- package/dist/core/parse/gherkin.js +0 -22
- package/dist/core/parse/gherkin.js.map +0 -1
- package/dist/core/parse/markdown.d.ts +0 -14
- package/dist/core/parse/markdown.d.ts.map +0 -1
- package/dist/core/parse/markdown.js +0 -45
- package/dist/core/parse/markdown.js.map +0 -1
- package/dist/core/parse/spec.d.ts +0 -36
- package/dist/core/parse/spec.d.ts.map +0 -1
- package/dist/core/parse/spec.js +0 -123
- package/dist/core/parse/spec.js.map +0 -1
- package/dist/core/report.d.ts +0 -55
- package/dist/core/report.d.ts.map +0 -1
- package/dist/core/report.js +0 -393
- package/dist/core/report.js.map +0 -1
- package/dist/core/scenarioModel.d.ts +0 -33
- package/dist/core/scenarioModel.d.ts.map +0 -1
- package/dist/core/scenarioModel.js +0 -128
- package/dist/core/scenarioModel.js.map +0 -1
- package/dist/core/specLayout.d.ts +0 -8
- package/dist/core/specLayout.d.ts.map +0 -1
- package/dist/core/specLayout.js +0 -36
- package/dist/core/specLayout.js.map +0 -1
- package/dist/core/traceability.d.ts +0 -26
- package/dist/core/traceability.d.ts.map +0 -1
- package/dist/core/traceability.js +0 -157
- package/dist/core/traceability.js.map +0 -1
- package/dist/core/types.d.ts +0 -31
- package/dist/core/types.d.ts.map +0 -1
- package/dist/core/types.js +0 -2
- package/dist/core/types.js.map +0 -1
- package/dist/core/validate.d.ts +0 -4
- package/dist/core/validate.d.ts.map +0 -1
- package/dist/core/validate.js +0 -45
- package/dist/core/validate.js.map +0 -1
- package/dist/core/validators/contracts.d.ts +0 -5
- package/dist/core/validators/contracts.d.ts.map +0 -1
- package/dist/core/validators/contracts.js +0 -189
- package/dist/core/validators/contracts.js.map +0 -1
- package/dist/core/validators/delta.d.ts +0 -4
- package/dist/core/validators/delta.d.ts.map +0 -1
- package/dist/core/validators/delta.js +0 -68
- package/dist/core/validators/delta.js.map +0 -1
- package/dist/core/validators/ids.d.ts +0 -4
- package/dist/core/validators/ids.d.ts.map +0 -1
- package/dist/core/validators/ids.js +0 -88
- package/dist/core/validators/ids.js.map +0 -1
- package/dist/core/validators/scenario.d.ts +0 -5
- package/dist/core/validators/scenario.d.ts.map +0 -1
- package/dist/core/validators/scenario.js +0 -127
- package/dist/core/validators/scenario.js.map +0 -1
- package/dist/core/validators/spec.d.ts +0 -5
- package/dist/core/validators/spec.d.ts.map +0 -1
- package/dist/core/validators/spec.js +0 -94
- package/dist/core/validators/spec.js.map +0 -1
- package/dist/core/validators/traceability.d.ts +0 -4
- package/dist/core/validators/traceability.d.ts.map +0 -1
- package/dist/core/validators/traceability.js +0 -222
- package/dist/core/validators/traceability.js.map +0 -1
- package/dist/core/version.d.ts +0 -2
- package/dist/core/version.d.ts.map +0 -1
- package/dist/core/version.js +0 -25
- package/dist/core/version.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -2
- package/dist/index.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,168 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
type ScCoverage = {
|
|
2
|
+
total: number;
|
|
3
|
+
covered: number;
|
|
4
|
+
missing: number;
|
|
5
|
+
missingIds: string[];
|
|
6
|
+
refs: Record<string, string[]>;
|
|
7
|
+
};
|
|
8
|
+
type TestFileScan = {
|
|
9
|
+
globs: string[];
|
|
10
|
+
excludeGlobs: string[];
|
|
11
|
+
matchedFileCount: number;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type IssueSeverity = "info" | "warning" | "error";
|
|
15
|
+
type IssueLocation = {
|
|
16
|
+
line: number;
|
|
17
|
+
column?: number;
|
|
18
|
+
};
|
|
19
|
+
type Issue = {
|
|
20
|
+
code: string;
|
|
21
|
+
severity: IssueSeverity;
|
|
22
|
+
message: string;
|
|
23
|
+
file?: string;
|
|
24
|
+
refs?: string[];
|
|
25
|
+
rule?: string;
|
|
26
|
+
loc?: IssueLocation;
|
|
27
|
+
};
|
|
28
|
+
type ValidationCounts = {
|
|
29
|
+
info: number;
|
|
30
|
+
warning: number;
|
|
31
|
+
error: number;
|
|
32
|
+
};
|
|
33
|
+
type ValidationTraceability = {
|
|
34
|
+
sc: ScCoverage;
|
|
35
|
+
testFiles: TestFileScan;
|
|
36
|
+
};
|
|
37
|
+
type ValidationResult = {
|
|
38
|
+
toolVersion: string;
|
|
39
|
+
issues: Issue[];
|
|
40
|
+
counts: ValidationCounts;
|
|
41
|
+
traceability: ValidationTraceability;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
type FailOn = "never" | "warning" | "error";
|
|
45
|
+
type OutputFormat = "text" | "github";
|
|
46
|
+
type TraceabilitySeverity = "warning" | "error";
|
|
47
|
+
type QfaiPaths = {
|
|
48
|
+
contractsDir: string;
|
|
49
|
+
specsDir: string;
|
|
50
|
+
rulesDir: string;
|
|
51
|
+
outDir: string;
|
|
52
|
+
promptsDir: string;
|
|
53
|
+
srcDir: string;
|
|
54
|
+
testsDir: string;
|
|
55
|
+
};
|
|
56
|
+
type QfaiValidationConfig = {
|
|
57
|
+
failOn: FailOn;
|
|
58
|
+
require: {
|
|
59
|
+
specSections: string[];
|
|
60
|
+
};
|
|
61
|
+
traceability: {
|
|
62
|
+
brMustHaveSc: boolean;
|
|
63
|
+
scMustHaveTest: boolean;
|
|
64
|
+
testFileGlobs: string[];
|
|
65
|
+
testFileExcludeGlobs: string[];
|
|
66
|
+
scNoTestSeverity: TraceabilitySeverity;
|
|
67
|
+
allowOrphanContracts: boolean;
|
|
68
|
+
unknownContractIdSeverity: TraceabilitySeverity;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
type QfaiOutputConfig = {
|
|
72
|
+
validateJsonPath: string;
|
|
73
|
+
};
|
|
74
|
+
type QfaiConfig = {
|
|
75
|
+
paths: QfaiPaths;
|
|
76
|
+
validation: QfaiValidationConfig;
|
|
77
|
+
output: QfaiOutputConfig;
|
|
78
|
+
};
|
|
79
|
+
type ConfigPathKey = keyof QfaiPaths;
|
|
80
|
+
type ConfigLoadResult = {
|
|
81
|
+
config: QfaiConfig;
|
|
82
|
+
issues: Issue[];
|
|
83
|
+
configPath: string;
|
|
84
|
+
};
|
|
85
|
+
declare const defaultConfig: QfaiConfig;
|
|
86
|
+
declare function getConfigPath(root: string): string;
|
|
87
|
+
declare function loadConfig(root: string): Promise<ConfigLoadResult>;
|
|
88
|
+
declare function resolvePath(root: string, config: QfaiConfig, key: ConfigPathKey): string;
|
|
89
|
+
|
|
90
|
+
type IdPrefix = "SPEC" | "BR" | "SC" | "UI" | "API" | "DB";
|
|
91
|
+
type IdFormatPrefix = IdPrefix | "ADR";
|
|
92
|
+
declare function extractIds(text: string, prefix: IdPrefix): string[];
|
|
93
|
+
declare function extractAllIds(text: string): string[];
|
|
94
|
+
declare function extractInvalidIds(text: string, prefixes: IdFormatPrefix[]): string[];
|
|
95
|
+
|
|
96
|
+
type ReportSummary = {
|
|
97
|
+
specs: number;
|
|
98
|
+
scenarios: number;
|
|
99
|
+
contracts: {
|
|
100
|
+
api: number;
|
|
101
|
+
ui: number;
|
|
102
|
+
db: number;
|
|
103
|
+
};
|
|
104
|
+
counts: ValidationCounts;
|
|
105
|
+
};
|
|
106
|
+
type ReportIds = {
|
|
107
|
+
spec: string[];
|
|
108
|
+
br: string[];
|
|
109
|
+
sc: string[];
|
|
110
|
+
ui: string[];
|
|
111
|
+
api: string[];
|
|
112
|
+
db: string[];
|
|
113
|
+
};
|
|
114
|
+
type ReportContractCoverage = {
|
|
115
|
+
total: number;
|
|
116
|
+
referenced: number;
|
|
117
|
+
orphan: number;
|
|
118
|
+
idToSpecs: Record<string, string[]>;
|
|
119
|
+
};
|
|
120
|
+
type ReportSpecCoverage = {
|
|
121
|
+
contractRefMissing: number;
|
|
122
|
+
missingRefSpecs: string[];
|
|
123
|
+
specToContractIds: Record<string, string[]>;
|
|
124
|
+
};
|
|
125
|
+
type ReportTraceability = {
|
|
126
|
+
upstreamIdsFound: number;
|
|
127
|
+
referencedInCodeOrTests: boolean;
|
|
128
|
+
sc: ScCoverage;
|
|
129
|
+
scSources: Record<string, string[]>;
|
|
130
|
+
testFiles: TestFileScan;
|
|
131
|
+
contracts: ReportContractCoverage;
|
|
132
|
+
specs: ReportSpecCoverage;
|
|
133
|
+
};
|
|
134
|
+
type ReportData = {
|
|
135
|
+
tool: "qfai";
|
|
136
|
+
version: string;
|
|
137
|
+
generatedAt: string;
|
|
138
|
+
root: string;
|
|
139
|
+
configPath: string;
|
|
140
|
+
summary: ReportSummary;
|
|
141
|
+
ids: ReportIds;
|
|
142
|
+
traceability: ReportTraceability;
|
|
143
|
+
issues: Issue[];
|
|
144
|
+
};
|
|
145
|
+
declare function createReportData(root: string, validation?: ValidationResult, configResult?: ConfigLoadResult): Promise<ReportData>;
|
|
146
|
+
declare function formatReportMarkdown(data: ReportData): string;
|
|
147
|
+
declare function formatReportJson(data: ReportData): string;
|
|
148
|
+
|
|
149
|
+
declare function validateProject(root: string, configResult?: ConfigLoadResult): Promise<ValidationResult>;
|
|
150
|
+
|
|
151
|
+
declare function resolveToolVersion(): Promise<string>;
|
|
152
|
+
|
|
153
|
+
declare function validateContracts(root: string, config: QfaiConfig): Promise<Issue[]>;
|
|
154
|
+
declare function lintSql(text: string, file: string): Issue[];
|
|
155
|
+
|
|
156
|
+
declare function validateDeltas(root: string, config: QfaiConfig): Promise<Issue[]>;
|
|
157
|
+
|
|
158
|
+
declare function validateDefinedIds(root: string, config: QfaiConfig): Promise<Issue[]>;
|
|
159
|
+
|
|
160
|
+
declare function validateScenarios(root: string, config: QfaiConfig): Promise<Issue[]>;
|
|
161
|
+
declare function validateScenarioContent(text: string, file: string): Issue[];
|
|
162
|
+
|
|
163
|
+
declare function validateSpecs(root: string, config: QfaiConfig): Promise<Issue[]>;
|
|
164
|
+
declare function validateSpecContent(text: string, file: string, requiredSections: string[]): Issue[];
|
|
165
|
+
|
|
166
|
+
declare function validateTraceability(root: string, config: QfaiConfig): Promise<Issue[]>;
|
|
167
|
+
|
|
168
|
+
export { type ConfigLoadResult, type ConfigPathKey, type FailOn, type IdFormatPrefix, type IdPrefix, type Issue, type IssueLocation, type IssueSeverity, type OutputFormat, type QfaiConfig, type QfaiOutputConfig, type QfaiPaths, type QfaiValidationConfig, type ReportContractCoverage, type ReportData, type ReportIds, type ReportSpecCoverage, type ReportSummary, type ReportTraceability, type TraceabilitySeverity, type ValidationCounts, type ValidationResult, type ValidationTraceability, createReportData, defaultConfig, extractAllIds, extractIds, extractInvalidIds, formatReportJson, formatReportMarkdown, getConfigPath, lintSql, loadConfig, resolvePath, resolveToolVersion, validateContracts, validateDefinedIds, validateDeltas, validateProject, validateScenarioContent, validateScenarios, validateSpecContent, validateSpecs, validateTraceability };
|
package/dist/index.mjs
CHANGED
|
@@ -1102,8 +1102,8 @@ import { readFile as readFile4 } from "fs/promises";
|
|
|
1102
1102
|
import path6 from "path";
|
|
1103
1103
|
import { fileURLToPath } from "url";
|
|
1104
1104
|
async function resolveToolVersion() {
|
|
1105
|
-
if ("0.
|
|
1106
|
-
return "0.
|
|
1105
|
+
if ("0.5.0".length > 0) {
|
|
1106
|
+
return "0.5.0";
|
|
1107
1107
|
}
|
|
1108
1108
|
try {
|
|
1109
1109
|
const packagePath = resolvePackageJsonPath();
|
|
@@ -2446,8 +2446,11 @@ async function createReportData(root, validation, configResult) {
|
|
|
2446
2446
|
db: dbFiles
|
|
2447
2447
|
} = await collectContractFiles(uiRoot, apiRoot, dbRoot);
|
|
2448
2448
|
const contractIndex = await buildContractIndex(root, config);
|
|
2449
|
-
const specContractRefs = await collectSpecContractRefs(specFiles);
|
|
2450
2449
|
const contractIdList = Array.from(contractIndex.ids);
|
|
2450
|
+
const specContractRefs = await collectSpecContractRefs(
|
|
2451
|
+
specFiles,
|
|
2452
|
+
contractIdList
|
|
2453
|
+
);
|
|
2451
2454
|
const referencedContracts = /* @__PURE__ */ new Set();
|
|
2452
2455
|
for (const ids of specContractRefs.specToContractIds.values()) {
|
|
2453
2456
|
ids.forEach((id) => referencedContracts.add(id));
|
|
@@ -2528,6 +2531,7 @@ async function createReportData(root, validation, configResult) {
|
|
|
2528
2531
|
},
|
|
2529
2532
|
specs: {
|
|
2530
2533
|
contractRefMissing: specContractRefs.missingRefSpecs.size,
|
|
2534
|
+
missingRefSpecs: toSortedArray2(specContractRefs.missingRefSpecs),
|
|
2531
2535
|
specToContractIds: specToContractIdsRecord
|
|
2532
2536
|
}
|
|
2533
2537
|
},
|
|
@@ -2610,6 +2614,16 @@ function formatReportMarkdown(data) {
|
|
|
2610
2614
|
}
|
|
2611
2615
|
}
|
|
2612
2616
|
lines.push("");
|
|
2617
|
+
lines.push("## Spec\u3067 contract-ref \u672A\u5BA3\u8A00");
|
|
2618
|
+
const missingRefSpecs = data.traceability.specs.missingRefSpecs;
|
|
2619
|
+
if (missingRefSpecs.length === 0) {
|
|
2620
|
+
lines.push("- (none)");
|
|
2621
|
+
} else {
|
|
2622
|
+
for (const specId of missingRefSpecs) {
|
|
2623
|
+
lines.push(`- ${specId}`);
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
lines.push("");
|
|
2613
2627
|
lines.push("## SC\u30AB\u30D0\u30EC\u30C3\u30B8");
|
|
2614
2628
|
lines.push(`- total: ${data.traceability.sc.total}`);
|
|
2615
2629
|
lines.push(`- covered: ${data.traceability.sc.covered}`);
|
|
@@ -2713,10 +2727,13 @@ function formatReportMarkdown(data) {
|
|
|
2713
2727
|
function formatReportJson(data) {
|
|
2714
2728
|
return JSON.stringify(data, null, 2);
|
|
2715
2729
|
}
|
|
2716
|
-
async function collectSpecContractRefs(specFiles) {
|
|
2730
|
+
async function collectSpecContractRefs(specFiles, contractIdList) {
|
|
2717
2731
|
const specToContractIds = /* @__PURE__ */ new Map();
|
|
2718
2732
|
const idToSpecs = /* @__PURE__ */ new Map();
|
|
2719
2733
|
const missingRefSpecs = /* @__PURE__ */ new Set();
|
|
2734
|
+
for (const contractId of contractIdList) {
|
|
2735
|
+
idToSpecs.set(contractId, /* @__PURE__ */ new Set());
|
|
2736
|
+
}
|
|
2720
2737
|
for (const file of specFiles) {
|
|
2721
2738
|
const text = await readFile11(file, "utf-8");
|
|
2722
2739
|
const parsed = parseSpec(text, file);
|
|
@@ -2724,13 +2741,15 @@ async function collectSpecContractRefs(specFiles) {
|
|
|
2724
2741
|
const refs = parsed.contractRefs;
|
|
2725
2742
|
if (refs.lines.length === 0) {
|
|
2726
2743
|
missingRefSpecs.add(specKey);
|
|
2744
|
+
continue;
|
|
2727
2745
|
}
|
|
2728
2746
|
const currentContracts = specToContractIds.get(specKey) ?? /* @__PURE__ */ new Set();
|
|
2729
2747
|
for (const id of refs.ids) {
|
|
2730
2748
|
currentContracts.add(id);
|
|
2731
|
-
const specs = idToSpecs.get(id)
|
|
2732
|
-
specs
|
|
2733
|
-
|
|
2749
|
+
const specs = idToSpecs.get(id);
|
|
2750
|
+
if (specs) {
|
|
2751
|
+
specs.add(specKey);
|
|
2752
|
+
}
|
|
2734
2753
|
}
|
|
2735
2754
|
specToContractIds.set(specKey, currentContracts);
|
|
2736
2755
|
}
|