@kb-labs/qa-core 2.89.0 → 2.93.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/dist/baseline/index.js +99 -23
- package/dist/baseline/index.js.map +1 -1
- package/dist/history/index.d.ts +15 -4
- package/dist/history/index.js +43 -6
- package/dist/history/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +178 -36
- package/dist/index.js.map +1 -1
- package/dist/{last-run-store-CVsUqnU0.d.ts → last-run-store-C1AkskWI.d.ts} +5 -2
- package/dist/report/index.d.ts +4 -3
- package/dist/report/index.js +35 -6
- package/dist/report/index.js.map +1 -1
- package/dist/runner/index.d.ts +1 -1
- package/dist/runner/index.js +102 -26
- package/dist/runner/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { QARunOptions, QARunResult, PackageFilter, PackagesConfig,
|
|
1
|
+
import { QARunOptions, QARunResult, QACheckConfig, WorkspacePackage, QAResults, PackageFilter, PackagesConfig, CheckResult, SubmoduleInfo } from '@kb-labs/qa-contracts';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Run all QA checks in order: build → lint → typeCheck → test.
|
|
@@ -7,6 +7,9 @@ import { QARunOptions, QARunResult, PackageFilter, PackagesConfig, WorkspacePack
|
|
|
7
7
|
*/
|
|
8
8
|
declare function runQA(options: QARunOptions): Promise<QARunResult>;
|
|
9
9
|
|
|
10
|
+
type ProgressFn = (checkId: string, pkg: string, status: 'pass' | 'fail' | 'skip', durationMs?: number) => void;
|
|
11
|
+
declare function runCustomChecks(checks: QACheckConfig[], packages: WorkspacePackage[], rootDir: string, onProgress?: ProgressFn, diffBase?: string): QAResults;
|
|
12
|
+
|
|
10
13
|
/**
|
|
11
14
|
* Discover all workspace packages in the monorepo.
|
|
12
15
|
*
|
|
@@ -75,4 +78,4 @@ declare function saveLastRun(rootDir: string, results: QAResults, packages: Work
|
|
|
75
78
|
*/
|
|
76
79
|
declare function loadLastRun(rootDir: string): LastRunData | null;
|
|
77
80
|
|
|
78
|
-
export { type LastRunData as L, getWorkspacePackages as a,
|
|
81
|
+
export { type LastRunData as L, getWorkspacePackages as a, runLintCheck as b, collectSubmoduleInfo as c, runQA as d, runTestCheck as e, runTypeCheck as f, getSubmoduleInfo as g, loadLastRun as l, runCustomChecks as r, saveLastRun as s };
|
package/dist/report/index.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { QAResults, GroupedResults, BaselineDiff, QAReport, BaselineSnapshot, HistoryEntry, RegressionResult, TrendResult, WorkspacePackage, QAPluginConfig, QAErrorGroupsResponse } from '@kb-labs/qa-contracts';
|
|
1
|
+
import { QAResults, GroupedResults, BaselineDiff, QACheckConfig, QAReport, BaselineSnapshot, HistoryEntry, RegressionResult, TrendResult, WorkspacePackage, QAPluginConfig, QAErrorGroupsResponse } from '@kb-labs/qa-contracts';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Build a structured JSON report from QA results.
|
|
5
|
+
* Pass checks config to populate blockers/warnings with severity info.
|
|
5
6
|
*/
|
|
6
|
-
declare function buildJsonReport(results: QAResults, diff?: BaselineDiff | null): QAReport;
|
|
7
|
+
declare function buildJsonReport(results: QAResults, diff?: BaselineDiff | null, checks?: QACheckConfig[]): QAReport;
|
|
7
8
|
/**
|
|
8
9
|
* Build a detailed JSON report with grouped results.
|
|
9
10
|
*/
|
|
10
|
-
declare function buildDetailedJsonReport(results: QAResults, grouped: GroupedResults, diff?: BaselineDiff | null): QAReport & {
|
|
11
|
+
declare function buildDetailedJsonReport(results: QAResults, grouped: GroupedResults, diff?: BaselineDiff | null, checks?: QACheckConfig[]): QAReport & {
|
|
11
12
|
grouped: GroupedResults;
|
|
12
13
|
};
|
|
13
14
|
|
package/dist/report/index.js
CHANGED
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
import { getCheckIcon, getCheckLabel } from '@kb-labs/qa-contracts';
|
|
2
2
|
|
|
3
3
|
// src/report/json-reporter.ts
|
|
4
|
-
function buildJsonReport(results, diff) {
|
|
5
|
-
const
|
|
4
|
+
function buildJsonReport(results, diff, checks) {
|
|
5
|
+
const severityMap = {};
|
|
6
|
+
if (checks) {
|
|
7
|
+
for (const c of checks) {
|
|
8
|
+
severityMap[c.id] = c.severity ?? "blocker";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
const hasBlockerFailures = Object.entries(results).some(([ct, r]) => {
|
|
12
|
+
const sev = severityMap[ct] ?? "blocker";
|
|
13
|
+
return sev !== "info" && sev !== "warning" && r.failed.length > 0;
|
|
14
|
+
});
|
|
6
15
|
const summary = {};
|
|
7
16
|
const failures = {};
|
|
8
17
|
const errors = {};
|
|
18
|
+
const blockers = [];
|
|
19
|
+
const warnings = [];
|
|
9
20
|
for (const ct of Object.keys(results)) {
|
|
10
21
|
const r = results[ct];
|
|
11
22
|
const total = r.passed.length + r.failed.length + r.skipped.length;
|
|
@@ -17,18 +28,36 @@ function buildJsonReport(results, diff) {
|
|
|
17
28
|
};
|
|
18
29
|
failures[ct] = [...r.failed];
|
|
19
30
|
errors[ct] = { ...r.errors };
|
|
31
|
+
if (r.failed.length > 0) {
|
|
32
|
+
const sev = severityMap[ct] ?? "blocker";
|
|
33
|
+
const items = r.failed.flatMap((target) => {
|
|
34
|
+
const detailItems = r.details?.[target];
|
|
35
|
+
if (detailItems && detailItems.length > 0) {
|
|
36
|
+
return detailItems;
|
|
37
|
+
}
|
|
38
|
+
const msg = r.errors[target];
|
|
39
|
+
return msg ? [{ target, message: msg }] : [{ target, message: `check ${ct} failed` }];
|
|
40
|
+
});
|
|
41
|
+
if (sev === "blocker") {
|
|
42
|
+
blockers.push({ check: ct, items });
|
|
43
|
+
} else if (sev === "warning") {
|
|
44
|
+
warnings.push({ check: ct, items });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
20
47
|
}
|
|
21
48
|
return {
|
|
22
|
-
status:
|
|
49
|
+
status: hasBlockerFailures ? "failed" : "passed",
|
|
23
50
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24
51
|
summary,
|
|
25
52
|
failures,
|
|
26
53
|
errors,
|
|
27
|
-
baseline: diff ?? null
|
|
54
|
+
baseline: diff ?? null,
|
|
55
|
+
blockers,
|
|
56
|
+
warnings
|
|
28
57
|
};
|
|
29
58
|
}
|
|
30
|
-
function buildDetailedJsonReport(results, grouped, diff) {
|
|
31
|
-
const base = buildJsonReport(results, diff);
|
|
59
|
+
function buildDetailedJsonReport(results, grouped, diff, checks) {
|
|
60
|
+
const base = buildJsonReport(results, diff, checks);
|
|
32
61
|
return { ...base, grouped };
|
|
33
62
|
}
|
|
34
63
|
function icon(ct) {
|
package/dist/report/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/report/json-reporter.ts","../../src/report/text-reporter.ts","../../src/report/grouped-reporter.ts","../../src/report/error-grouping.ts"],"names":["label"],"mappings":"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","file":"index.js","sourcesContent":["import type { QAResults, QAReport, BaselineDiff, GroupedResults } from '@kb-labs/qa-contracts';\n\n/**\n * Build a structured JSON report from QA results.\n */\nexport function buildJsonReport(\n results: QAResults,\n diff?: BaselineDiff | null,\n): QAReport {\n const hasFailures = Object.values(results).some((r) => r.failed.length > 0);\n\n const summary = {} as QAReport['summary'];\n const failures = {} as QAReport['failures'];\n const errors = {} as QAReport['errors'];\n\n for (const ct of Object.keys(results)) {\n const r = results[ct]!;\n const total = r.passed.length + r.failed.length + r.skipped.length;\n summary[ct] = {\n total,\n passed: r.passed.length,\n failed: r.failed.length,\n skipped: r.skipped.length,\n };\n failures[ct] = [...r.failed];\n errors[ct] = { ...r.errors };\n }\n\n return {\n status: hasFailures ? 'failed' : 'passed',\n timestamp: new Date().toISOString(),\n summary,\n failures,\n errors,\n baseline: diff ?? null,\n };\n}\n\n/**\n * Build a detailed JSON report with grouped results.\n */\nexport function buildDetailedJsonReport(\n results: QAResults,\n grouped: GroupedResults,\n diff?: BaselineDiff | null,\n): QAReport & { grouped: GroupedResults } {\n const base = buildJsonReport(results, diff);\n return { ...base, grouped };\n}\n","import type { QAResults, BaselineDiff, HistoryEntry, TrendResult, RegressionResult, BaselineSnapshot, GroupedResults } from '@kb-labs/qa-contracts';\nimport { getCheckLabel, getCheckIcon } from '@kb-labs/qa-contracts';\n\nexport interface ReportSection {\n header: string;\n lines: string[];\n}\n\nfunction icon(ct: string): string {\n return getCheckIcon(ct);\n}\n\nfunction label(ct: string): string {\n return getCheckLabel(ct);\n}\n\n/**\n * Build text report for a QA run.\n * Returns structured sections — CLI layer adds ANSI colors.\n */\nfunction buildBaselineDiffLines(diff: BaselineDiff): string[] {\n const lines: string[] = [];\n for (const ct of Object.keys(diff)) {\n const d = diff[ct]!;\n if (d.newFailures.length > 0) {\n lines.push(`${icon(ct)} ${label(ct)}: +${d.newFailures.length} new failures`);\n for (const pkg of d.newFailures) { lines.push(` - ${pkg}`); }\n }\n if (d.fixed.length > 0) {\n lines.push(`${icon(ct)} ${label(ct)}: -${d.fixed.length} fixed`);\n }\n }\n return lines;\n}\n\nexport function buildRunReport(results: QAResults, diff?: BaselineDiff | null): ReportSection[] {\n const sections: ReportSection[] = [];\n\n const summaryLines: string[] = [];\n let totalPassed = 0;\n let totalFailed = 0;\n let totalSkipped = 0;\n for (const ct of Object.keys(results)) {\n const r = results[ct]!;\n const total = r.passed.length + r.failed.length + r.skipped.length;\n const pct = total > 0 ? Math.round((r.passed.length / total) * 100) : 100;\n const status = r.failed.length === 0 ? 'PASS' : 'FAIL';\n summaryLines.push(`${status} ${icon(ct)} ${label(ct).padEnd(12)} ${r.passed.length}/${total} passed (${pct}%)`);\n if (r.failed.length > 0) {\n for (const pkg of r.failed.slice(0, 5)) { summaryLines.push(` - ${pkg}`); }\n if (r.failed.length > 5) { summaryLines.push(` ... and ${r.failed.length - 5} more`); }\n }\n totalPassed += r.passed.length;\n totalFailed += r.failed.length;\n totalSkipped += r.skipped.length;\n }\n sections.push({ header: 'QA Summary Report', lines: summaryLines });\n\n if (diff) {\n const diffLines = buildBaselineDiffLines(diff);\n if (diffLines.length > 0) { sections.push({ header: 'Baseline Comparison', lines: diffLines }); }\n }\n\n sections.push({\n header: 'Totals',\n lines: [`Total: ${totalPassed} passed, ${totalFailed} failed, ${totalSkipped} skipped`],\n });\n\n return sections;\n}\n\n/**\n * Build history table for display.\n */\nexport function buildHistoryTable(history: HistoryEntry[], limit: number = 20): ReportSection[] {\n const entries = history.slice(-limit);\n const lines: string[] = [];\n\n for (const entry of entries) {\n const date = new Date(entry.timestamp).toLocaleDateString();\n const status = entry.status === 'passed' ? 'PASS' : 'FAIL';\n const summary = Object.keys(entry.summary).map((ct) => {\n const s = entry.summary[ct]!;\n return `${icon(ct)} ${s.failed}F`;\n }).join(' ');\n\n lines.push(`${date} ${entry.git.commit} ${status} ${summary} ${entry.git.message.slice(0, 40)}`);\n }\n\n return [{ header: `QA History (last ${entries.length})`, lines }];\n}\n\n/**\n * Build trends report.\n */\nexport function buildTrendsReport(trends: TrendResult[], history: HistoryEntry[]): ReportSection[] {\n if (trends.length === 0) {\n return [{ header: 'QA Trends', lines: ['Not enough history (need at least 2 entries)'] }];\n }\n\n const lines: string[] = [];\n for (const t of trends) {\n const arrow = t.delta > 0 ? `+${t.delta} (regression)` : t.delta < 0 ? `${t.delta} (improvement)` : '→ no change';\n lines.push(`${icon(t.checkType)} ${label(t.checkType).padEnd(12)} ${t.previous} → ${t.current} ${arrow}`);\n }\n\n if (history.length >= 2) {\n const first = history[Math.max(0, history.length - 10)]!;\n const last = history[history.length - 1]!;\n lines.push('');\n lines.push(`Period: ${new Date(first.timestamp).toLocaleDateString()} → ${new Date(last.timestamp).toLocaleDateString()}`);\n }\n\n return [{ header: 'QA Trends', lines }];\n}\n\n/**\n * Build regressions report.\n */\nexport function buildRegressionsReport(result: RegressionResult, history: HistoryEntry[]): ReportSection[] {\n if (history.length < 2) {\n return [{ header: 'Regression Detection', lines: ['Not enough history (need at least 2 entries)'] }];\n }\n\n const prev = history[history.length - 2]!;\n const curr = history[history.length - 1]!;\n const lines: string[] = [\n `Comparing: ${prev.git.commit} → ${curr.git.commit}`,\n '',\n ];\n\n if (!result.hasRegressions) {\n lines.push('No regressions detected.');\n return [{ header: 'Regression Detection', lines }];\n }\n\n for (const r of result.regressions) {\n lines.push(`${r.checkType}: +${r.newFailures.length} new failures`);\n for (const pkg of r.newFailures) {\n lines.push(` - ${pkg}`);\n }\n }\n\n lines.push('');\n lines.push('REGRESSIONS DETECTED!');\n\n return [{ header: 'Regression Detection', lines }];\n}\n\n/**\n * Build baseline status report.\n */\nexport function buildBaselineReport(baseline: BaselineSnapshot | null): ReportSection[] {\n if (!baseline) {\n return [{ header: 'Baseline Status', lines: ['No baseline captured yet. Run baseline:update first.'] }];\n }\n\n const lines: string[] = [\n `Captured: ${new Date(baseline.timestamp).toLocaleString()}`,\n `Git: ${baseline.git.commit} (${baseline.git.branch})`,\n '',\n ];\n\n for (const ct of Object.keys(baseline.results)) {\n const r = baseline.results[ct]!;\n lines.push(`${icon(ct)} ${label(ct).padEnd(12)} ${r.passed} passed, ${r.failed} failed`);\n if (r.failedPackages.length > 0) {\n const shown = r.failedPackages.slice(0, 3);\n for (const pkg of shown) {\n lines.push(` - ${pkg}`);\n }\n if (r.failedPackages.length > 3) {\n lines.push(` ... and ${r.failedPackages.length - 3} more`);\n }\n }\n }\n\n return [{ header: 'Baseline Status', lines }];\n}\n\n/**\n * Format a check status tag. Failed checks are UPPERCASED.\n */\nfunction checkTag(status: 'passed' | 'failed' | 'skipped', ct: string): string {\n const short = ct === 'typeCheck' ? 'types' : ct;\n if (status === 'failed') {return short.toUpperCase();}\n if (status === 'skipped') {return `-${short}-`;}\n return short;\n}\n\n/**\n * Build a detailed report grouped by category → repo → packages.\n */\ntype PackageEntry = GroupedResults['categories'][string]['repos'][string]['packages'][number];\n\nfunction getErrorPreview(raw: string): string {\n const errLines = raw.split('\\n').filter((l) => l.trim().length > 0);\n for (const el of errLines) {\n const cleaned = el.replace(/^Command failed: .*/, '').trim();\n if (cleaned.length > 0) {\n return cleaned.replace(/\\/[^\\s]*\\/kb-labs\\//g, '').slice(0, 100);\n }\n }\n return '';\n}\n\nfunction renderPackageLines(pkg: PackageEntry, lines: string[]): void {\n const hasFail = Object.values(pkg.checks).some((v) => v === 'failed');\n const status = hasFail ? 'FAIL' : 'PASS';\n const tags = Object.keys(pkg.checks).map((ct) => checkTag(pkg.checks[ct]!, ct)).join(' ');\n lines.push(` ${status} ${pkg.name.padEnd(40)} ${tags}`);\n if (hasFail) {\n for (const ct of Object.keys(pkg.checks)) {\n if (pkg.checks[ct] === 'failed') {\n const preview = getErrorPreview((pkg.errors[ct] ?? '').trim());\n lines.push(` ${ct}: ${preview || 'failed'}`);\n }\n }\n }\n}\n\nfunction renderCategoryLines(catKey: string, grouped: GroupedResults): string[] {\n const cat = grouped.categories[catKey]!;\n const lines: string[] = [`PASS ${cat.summary.passed} | FAIL ${cat.summary.failed}`, ''];\n\n for (const repoKey of Object.keys(cat.repos).sort()) {\n const repo = cat.repos[repoKey]!;\n lines.push(` ${repoKey} (${repo.summary.total} packages)`);\n\n const sorted = [...repo.packages].sort((a, b) => {\n const aFail = Object.values(a.checks).some((v) => v === 'failed') ? 0 : 1;\n const bFail = Object.values(b.checks).some((v) => v === 'failed') ? 0 : 1;\n if (aFail !== bFail) { return aFail - bFail; }\n return a.name.localeCompare(b.name);\n });\n\n for (const pkg of sorted) { renderPackageLines(pkg, lines); }\n lines.push('');\n }\n return lines;\n}\n\nexport function buildDetailedRunReport(grouped: GroupedResults, diff?: BaselineDiff | null): ReportSection[] {\n const sections: ReportSection[] = [];\n\n const categoryKeys = Object.keys(grouped.categories).sort((a, b) => {\n if (a === 'uncategorized') { return 1; }\n if (b === 'uncategorized') { return -1; }\n return a.localeCompare(b);\n });\n\n for (const catKey of categoryKeys) {\n const cat = grouped.categories[catKey]!;\n sections.push({ header: `${cat.label} (${cat.summary.total} packages)`, lines: renderCategoryLines(catKey, grouped) });\n }\n\n if (diff) {\n const diffLines = buildBaselineDiffLines(diff);\n if (diffLines.length > 0) { sections.push({ header: 'Baseline Comparison', lines: diffLines }); }\n }\n\n let totalPassed = 0;\n let totalFailed = 0;\n for (const catKey of categoryKeys) {\n totalPassed += grouped.categories[catKey]!.summary.passed;\n totalFailed += grouped.categories[catKey]!.summary.failed;\n }\n sections.push({\n header: 'Totals',\n lines: [`Total: ${totalPassed} passed, ${totalFailed} failed (${categoryKeys.length} categories)`],\n });\n\n return sections;\n}\n","import type {\n QAResults,\n WorkspacePackage,\n QAPluginConfig,\n PackageStatus,\n GroupedResults,\n GroupSummary,\n} from '@kb-labs/qa-contracts';\n\nfunction emptyGroupSummary(checkTypes: string[]): GroupSummary {\n const checks = {} as GroupSummary['checks'];\n for (const ct of checkTypes) {\n checks[ct] = { passed: 0, failed: 0, skipped: 0 };\n }\n return { total: 0, passed: 0, failed: 0, checks };\n}\n\nfunction resolveCheckStatus(\n pkgName: string,\n ct: string,\n results: QAResults,\n): 'passed' | 'failed' | 'skipped' {\n const r = results[ct];\n if (!r) {return 'skipped';}\n if (r.failed.includes(pkgName)) {return 'failed';}\n if (r.passed.includes(pkgName)) {return 'passed';}\n return 'skipped';\n}\n\n/**\n * Build per-package status from QA results.\n */\nfunction buildPackageStatus(\n pkg: WorkspacePackage,\n results: QAResults,\n category: string,\n): PackageStatus {\n const checks = {} as PackageStatus['checks'];\n const errors: Record<string, string> = {};\n\n for (const ct of Object.keys(results)) {\n checks[ct] = resolveCheckStatus(pkg.name, ct, results);\n if (checks[ct] === 'failed' && results[ct]?.errors[pkg.name]) {\n errors[ct] = results[ct]!.errors[pkg.name]!;\n }\n }\n\n return {\n name: pkg.name,\n repo: pkg.repo,\n category,\n checks,\n errors,\n };\n}\n\n/**\n * Add a PackageStatus to a GroupSummary.\n */\nfunction addToSummary(summary: GroupSummary, status: PackageStatus): void {\n summary.total++;\n\n const hasFail = Object.values(status.checks).some((v) => v === 'failed');\n if (hasFail) {\n summary.failed++;\n } else {\n summary.passed++;\n }\n\n for (const ct of Object.keys(status.checks)) {\n const s = status.checks[ct];\n if (!summary.checks[ct]) {\n summary.checks[ct] = { passed: 0, failed: 0, skipped: 0 };\n }\n if (s === 'passed') {summary.checks[ct].passed++;}\n else if (s === 'failed') {summary.checks[ct].failed++;}\n else {summary.checks[ct].skipped++;}\n }\n}\n\n/**\n * Group QA results by category → repo → packages.\n *\n * A package can appear in multiple categories if its repo is listed\n * in multiple category configs (e.g., kb-labs-cli in both \"core\" and \"hosts\").\n */\nexport function groupResults(\n results: QAResults,\n packages: WorkspacePackage[],\n categoryMap: Map<string, string[]>,\n config?: QAPluginConfig,\n): GroupedResults {\n const checkTypes = Object.keys(results);\n const grouped: GroupedResults = { categories: {} };\n\n for (const pkg of packages) {\n const categoryKeys = categoryMap.get(pkg.name) ?? ['uncategorized'];\n\n for (const categoryKey of categoryKeys) {\n const status = buildPackageStatus(pkg, results, categoryKey);\n\n // Ensure category exists\n if (!grouped.categories[categoryKey]) {\n const label =\n categoryKey === 'uncategorized'\n ? 'Uncategorized'\n : config?.categories?.[categoryKey]?.label ?? categoryKey;\n\n grouped.categories[categoryKey] = {\n label,\n repos: {},\n summary: emptyGroupSummary(checkTypes),\n };\n }\n\n const categoryGroup = grouped.categories[categoryKey]!;\n\n // Ensure repo exists within category\n if (!categoryGroup.repos[pkg.repo]) {\n categoryGroup.repos[pkg.repo] = {\n packages: [],\n summary: emptyGroupSummary(checkTypes),\n };\n }\n\n const repoGroup = categoryGroup.repos[pkg.repo]!;\n\n repoGroup.packages.push(status);\n addToSummary(repoGroup.summary, status);\n addToSummary(categoryGroup.summary, status);\n }\n }\n\n return grouped;\n}\n","import type { QAResults } from '@kb-labs/qa-contracts';\nimport type { ErrorGroup, QAErrorGroupsResponse } from '@kb-labs/qa-contracts';\n\n/**\n * Extract an error pattern from raw error text.\n * Tries to identify ESLint rules, TS error codes, or common patterns.\n */\nfunction extractPattern(errorText: string, checkType: string): string {\n if (checkType === 'lint') {\n // ESLint: look for rule names like \"@typescript-eslint/no-explicit-any\"\n const ruleMatch = errorText.match(/(\\S+\\/[\\w-]+|no-[\\w-]+)/);\n if (ruleMatch?.[1]) {return ruleMatch[1];}\n }\n\n if (checkType === 'typeCheck') {\n // TypeScript: look for error codes like \"TS2345\" or \"error TS2345\"\n const tsMatch = errorText.match(/TS(\\d{4,5})/);\n if (tsMatch) {return `TS${tsMatch[1]}`;}\n }\n\n if (checkType === 'test') {\n // Test failures: look for \"FAIL\" + test file pattern\n const failMatch = errorText.match(/FAIL\\s+(\\S+)/);\n if (failMatch) {return `FAIL: ${failMatch[1]}`;}\n }\n\n if (checkType === 'build') {\n // Build: \"Module not found\", \"Cannot find module\"\n if (errorText.includes('Cannot find module')) {return 'Cannot find module';}\n if (errorText.includes('Module not found')) {return 'Module not found';}\n }\n\n // Fallback: first meaningful line (skip empty lines, trim)\n const firstLine = errorText.split('\\n').find((l) => l.trim().length > 0)?.trim() ?? '';\n return firstLine.slice(0, 100) || 'Unknown error';\n}\n\n/**\n * Group errors from QA results by error pattern.\n * Packages with the same error pattern (e.g., same ESLint rule) are grouped together.\n */\nexport function groupErrors(results: QAResults): QAErrorGroupsResponse {\n const groupMap = new Map<string, ErrorGroup>();\n let ungrouped = 0;\n\n for (const ct of Object.keys(results)) {\n const check = results[ct]!;\n if (!check.errors) {continue;}\n\n for (const [pkgName, errorText] of Object.entries(check.errors)) {\n const pattern = extractPattern(errorText, ct);\n const key = `${ct}::${pattern}`;\n\n const existing = groupMap.get(key);\n if (existing) {\n existing.count++;\n existing.packages.push(pkgName);\n } else {\n groupMap.set(key, {\n pattern,\n count: 1,\n packages: [pkgName],\n checkType: ct,\n example: errorText.slice(0, 200),\n });\n }\n }\n }\n\n // Groups with count=1 are \"ungrouped\" (unique errors)\n const groups: ErrorGroup[] = [];\n for (const group of groupMap.values()) {\n if (group.count === 1) {\n ungrouped++;\n } else {\n groups.push(group);\n }\n }\n\n // Sort by count descending\n groups.sort((a, b) => b.count - a.count);\n\n return { groups, ungrouped };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/report/json-reporter.ts","../../src/report/text-reporter.ts","../../src/report/grouped-reporter.ts","../../src/report/error-grouping.ts"],"names":["label"],"mappings":"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","file":"index.js","sourcesContent":["import type { QAResults, QAReport, BaselineDiff, GroupedResults, QACheckConfig, ReportCheckFindings } from '@kb-labs/qa-contracts';\n\n/**\n * Build a structured JSON report from QA results.\n * Pass checks config to populate blockers/warnings with severity info.\n */\nexport function buildJsonReport(\n results: QAResults,\n diff?: BaselineDiff | null,\n checks?: QACheckConfig[],\n): QAReport {\n // Build severity map from check config (default: blocker)\n const severityMap: Record<string, 'blocker' | 'warning' | 'info'> = {};\n if (checks) {\n for (const c of checks) {\n severityMap[c.id] = c.severity ?? 'blocker';\n }\n }\n\n // Only non-info failures affect status\n const hasBlockerFailures = Object.entries(results).some(([ct, r]) => {\n const sev = severityMap[ct] ?? 'blocker';\n return sev !== 'info' && sev !== 'warning' && r.failed.length > 0;\n });\n\n const summary = {} as QAReport['summary'];\n const failures = {} as QAReport['failures'];\n const errors = {} as QAReport['errors'];\n const blockers: ReportCheckFindings[] = [];\n const warnings: ReportCheckFindings[] = [];\n\n for (const ct of Object.keys(results)) {\n const r = results[ct]!;\n const total = r.passed.length + r.failed.length + r.skipped.length;\n summary[ct] = {\n total,\n passed: r.passed.length,\n failed: r.failed.length,\n skipped: r.skipped.length,\n };\n failures[ct] = [...r.failed];\n errors[ct] = { ...r.errors };\n\n if (r.failed.length > 0) {\n const sev = severityMap[ct] ?? 'blocker';\n // Collect structured items from details, or synthesize from errors\n const items = r.failed.flatMap(target => {\n const detailItems = r.details?.[target];\n if (detailItems && detailItems.length > 0) { return detailItems; }\n const msg = r.errors[target];\n return msg ? [{ target, message: msg }] : [{ target, message: `check ${ct} failed` }];\n });\n\n if (sev === 'blocker') {\n blockers.push({ check: ct, items });\n } else if (sev === 'warning') {\n warnings.push({ check: ct, items });\n }\n // info: skip\n }\n }\n\n return {\n status: hasBlockerFailures ? 'failed' : 'passed',\n timestamp: new Date().toISOString(),\n summary,\n failures,\n errors,\n baseline: diff ?? null,\n blockers,\n warnings,\n };\n}\n\n/**\n * Build a detailed JSON report with grouped results.\n */\nexport function buildDetailedJsonReport(\n results: QAResults,\n grouped: GroupedResults,\n diff?: BaselineDiff | null,\n checks?: QACheckConfig[],\n): QAReport & { grouped: GroupedResults } {\n const base = buildJsonReport(results, diff, checks);\n return { ...base, grouped };\n}\n","import type { QAResults, BaselineDiff, HistoryEntry, TrendResult, RegressionResult, BaselineSnapshot, GroupedResults } from '@kb-labs/qa-contracts';\nimport { getCheckLabel, getCheckIcon } from '@kb-labs/qa-contracts';\n\nexport interface ReportSection {\n header: string;\n lines: string[];\n}\n\nfunction icon(ct: string): string {\n return getCheckIcon(ct);\n}\n\nfunction label(ct: string): string {\n return getCheckLabel(ct);\n}\n\n/**\n * Build text report for a QA run.\n * Returns structured sections — CLI layer adds ANSI colors.\n */\nfunction buildBaselineDiffLines(diff: BaselineDiff): string[] {\n const lines: string[] = [];\n for (const ct of Object.keys(diff)) {\n const d = diff[ct]!;\n if (d.newFailures.length > 0) {\n lines.push(`${icon(ct)} ${label(ct)}: +${d.newFailures.length} new failures`);\n for (const pkg of d.newFailures) { lines.push(` - ${pkg}`); }\n }\n if (d.fixed.length > 0) {\n lines.push(`${icon(ct)} ${label(ct)}: -${d.fixed.length} fixed`);\n }\n }\n return lines;\n}\n\nexport function buildRunReport(results: QAResults, diff?: BaselineDiff | null): ReportSection[] {\n const sections: ReportSection[] = [];\n\n const summaryLines: string[] = [];\n let totalPassed = 0;\n let totalFailed = 0;\n let totalSkipped = 0;\n for (const ct of Object.keys(results)) {\n const r = results[ct]!;\n const total = r.passed.length + r.failed.length + r.skipped.length;\n const pct = total > 0 ? Math.round((r.passed.length / total) * 100) : 100;\n const status = r.failed.length === 0 ? 'PASS' : 'FAIL';\n summaryLines.push(`${status} ${icon(ct)} ${label(ct).padEnd(12)} ${r.passed.length}/${total} passed (${pct}%)`);\n if (r.failed.length > 0) {\n for (const pkg of r.failed.slice(0, 5)) { summaryLines.push(` - ${pkg}`); }\n if (r.failed.length > 5) { summaryLines.push(` ... and ${r.failed.length - 5} more`); }\n }\n totalPassed += r.passed.length;\n totalFailed += r.failed.length;\n totalSkipped += r.skipped.length;\n }\n sections.push({ header: 'QA Summary Report', lines: summaryLines });\n\n if (diff) {\n const diffLines = buildBaselineDiffLines(diff);\n if (diffLines.length > 0) { sections.push({ header: 'Baseline Comparison', lines: diffLines }); }\n }\n\n sections.push({\n header: 'Totals',\n lines: [`Total: ${totalPassed} passed, ${totalFailed} failed, ${totalSkipped} skipped`],\n });\n\n return sections;\n}\n\n/**\n * Build history table for display.\n */\nexport function buildHistoryTable(history: HistoryEntry[], limit: number = 20): ReportSection[] {\n const entries = history.slice(-limit);\n const lines: string[] = [];\n\n for (const entry of entries) {\n const date = new Date(entry.timestamp).toLocaleDateString();\n const status = entry.status === 'passed' ? 'PASS' : 'FAIL';\n const summary = Object.keys(entry.summary).map((ct) => {\n const s = entry.summary[ct]!;\n return `${icon(ct)} ${s.failed}F`;\n }).join(' ');\n\n lines.push(`${date} ${entry.git.commit} ${status} ${summary} ${entry.git.message.slice(0, 40)}`);\n }\n\n return [{ header: `QA History (last ${entries.length})`, lines }];\n}\n\n/**\n * Build trends report.\n */\nexport function buildTrendsReport(trends: TrendResult[], history: HistoryEntry[]): ReportSection[] {\n if (trends.length === 0) {\n return [{ header: 'QA Trends', lines: ['Not enough history (need at least 2 entries)'] }];\n }\n\n const lines: string[] = [];\n for (const t of trends) {\n const arrow = t.delta > 0 ? `+${t.delta} (regression)` : t.delta < 0 ? `${t.delta} (improvement)` : '→ no change';\n lines.push(`${icon(t.checkType)} ${label(t.checkType).padEnd(12)} ${t.previous} → ${t.current} ${arrow}`);\n }\n\n if (history.length >= 2) {\n const first = history[Math.max(0, history.length - 10)]!;\n const last = history[history.length - 1]!;\n lines.push('');\n lines.push(`Period: ${new Date(first.timestamp).toLocaleDateString()} → ${new Date(last.timestamp).toLocaleDateString()}`);\n }\n\n return [{ header: 'QA Trends', lines }];\n}\n\n/**\n * Build regressions report.\n */\nexport function buildRegressionsReport(result: RegressionResult, history: HistoryEntry[]): ReportSection[] {\n if (history.length < 2) {\n return [{ header: 'Regression Detection', lines: ['Not enough history (need at least 2 entries)'] }];\n }\n\n const prev = history[history.length - 2]!;\n const curr = history[history.length - 1]!;\n const lines: string[] = [\n `Comparing: ${prev.git.commit} → ${curr.git.commit}`,\n '',\n ];\n\n if (!result.hasRegressions) {\n lines.push('No regressions detected.');\n return [{ header: 'Regression Detection', lines }];\n }\n\n for (const r of result.regressions) {\n lines.push(`${r.checkType}: +${r.newFailures.length} new failures`);\n for (const pkg of r.newFailures) {\n lines.push(` - ${pkg}`);\n }\n }\n\n lines.push('');\n lines.push('REGRESSIONS DETECTED!');\n\n return [{ header: 'Regression Detection', lines }];\n}\n\n/**\n * Build baseline status report.\n */\nexport function buildBaselineReport(baseline: BaselineSnapshot | null): ReportSection[] {\n if (!baseline) {\n return [{ header: 'Baseline Status', lines: ['No baseline captured yet. Run baseline:update first.'] }];\n }\n\n const lines: string[] = [\n `Captured: ${new Date(baseline.timestamp).toLocaleString()}`,\n `Git: ${baseline.git.commit} (${baseline.git.branch})`,\n '',\n ];\n\n for (const ct of Object.keys(baseline.results)) {\n const r = baseline.results[ct]!;\n lines.push(`${icon(ct)} ${label(ct).padEnd(12)} ${r.passed} passed, ${r.failed} failed`);\n if (r.failedPackages.length > 0) {\n const shown = r.failedPackages.slice(0, 3);\n for (const pkg of shown) {\n lines.push(` - ${pkg}`);\n }\n if (r.failedPackages.length > 3) {\n lines.push(` ... and ${r.failedPackages.length - 3} more`);\n }\n }\n }\n\n return [{ header: 'Baseline Status', lines }];\n}\n\n/**\n * Format a check status tag. Failed checks are UPPERCASED.\n */\nfunction checkTag(status: 'passed' | 'failed' | 'skipped', ct: string): string {\n const short = ct === 'typeCheck' ? 'types' : ct;\n if (status === 'failed') {return short.toUpperCase();}\n if (status === 'skipped') {return `-${short}-`;}\n return short;\n}\n\n/**\n * Build a detailed report grouped by category → repo → packages.\n */\ntype PackageEntry = GroupedResults['categories'][string]['repos'][string]['packages'][number];\n\nfunction getErrorPreview(raw: string): string {\n const errLines = raw.split('\\n').filter((l) => l.trim().length > 0);\n for (const el of errLines) {\n const cleaned = el.replace(/^Command failed: .*/, '').trim();\n if (cleaned.length > 0) {\n return cleaned.replace(/\\/[^\\s]*\\/kb-labs\\//g, '').slice(0, 100);\n }\n }\n return '';\n}\n\nfunction renderPackageLines(pkg: PackageEntry, lines: string[]): void {\n const hasFail = Object.values(pkg.checks).some((v) => v === 'failed');\n const status = hasFail ? 'FAIL' : 'PASS';\n const tags = Object.keys(pkg.checks).map((ct) => checkTag(pkg.checks[ct]!, ct)).join(' ');\n lines.push(` ${status} ${pkg.name.padEnd(40)} ${tags}`);\n if (hasFail) {\n for (const ct of Object.keys(pkg.checks)) {\n if (pkg.checks[ct] === 'failed') {\n const preview = getErrorPreview((pkg.errors[ct] ?? '').trim());\n lines.push(` ${ct}: ${preview || 'failed'}`);\n }\n }\n }\n}\n\nfunction renderCategoryLines(catKey: string, grouped: GroupedResults): string[] {\n const cat = grouped.categories[catKey]!;\n const lines: string[] = [`PASS ${cat.summary.passed} | FAIL ${cat.summary.failed}`, ''];\n\n for (const repoKey of Object.keys(cat.repos).sort()) {\n const repo = cat.repos[repoKey]!;\n lines.push(` ${repoKey} (${repo.summary.total} packages)`);\n\n const sorted = [...repo.packages].sort((a, b) => {\n const aFail = Object.values(a.checks).some((v) => v === 'failed') ? 0 : 1;\n const bFail = Object.values(b.checks).some((v) => v === 'failed') ? 0 : 1;\n if (aFail !== bFail) { return aFail - bFail; }\n return a.name.localeCompare(b.name);\n });\n\n for (const pkg of sorted) { renderPackageLines(pkg, lines); }\n lines.push('');\n }\n return lines;\n}\n\nexport function buildDetailedRunReport(grouped: GroupedResults, diff?: BaselineDiff | null): ReportSection[] {\n const sections: ReportSection[] = [];\n\n const categoryKeys = Object.keys(grouped.categories).sort((a, b) => {\n if (a === 'uncategorized') { return 1; }\n if (b === 'uncategorized') { return -1; }\n return a.localeCompare(b);\n });\n\n for (const catKey of categoryKeys) {\n const cat = grouped.categories[catKey]!;\n sections.push({ header: `${cat.label} (${cat.summary.total} packages)`, lines: renderCategoryLines(catKey, grouped) });\n }\n\n if (diff) {\n const diffLines = buildBaselineDiffLines(diff);\n if (diffLines.length > 0) { sections.push({ header: 'Baseline Comparison', lines: diffLines }); }\n }\n\n let totalPassed = 0;\n let totalFailed = 0;\n for (const catKey of categoryKeys) {\n totalPassed += grouped.categories[catKey]!.summary.passed;\n totalFailed += grouped.categories[catKey]!.summary.failed;\n }\n sections.push({\n header: 'Totals',\n lines: [`Total: ${totalPassed} passed, ${totalFailed} failed (${categoryKeys.length} categories)`],\n });\n\n return sections;\n}\n","import type {\n QAResults,\n WorkspacePackage,\n QAPluginConfig,\n PackageStatus,\n GroupedResults,\n GroupSummary,\n} from '@kb-labs/qa-contracts';\n\nfunction emptyGroupSummary(checkTypes: string[]): GroupSummary {\n const checks = {} as GroupSummary['checks'];\n for (const ct of checkTypes) {\n checks[ct] = { passed: 0, failed: 0, skipped: 0 };\n }\n return { total: 0, passed: 0, failed: 0, checks };\n}\n\nfunction resolveCheckStatus(\n pkgName: string,\n ct: string,\n results: QAResults,\n): 'passed' | 'failed' | 'skipped' {\n const r = results[ct];\n if (!r) {return 'skipped';}\n if (r.failed.includes(pkgName)) {return 'failed';}\n if (r.passed.includes(pkgName)) {return 'passed';}\n return 'skipped';\n}\n\n/**\n * Build per-package status from QA results.\n */\nfunction buildPackageStatus(\n pkg: WorkspacePackage,\n results: QAResults,\n category: string,\n): PackageStatus {\n const checks = {} as PackageStatus['checks'];\n const errors: Record<string, string> = {};\n\n for (const ct of Object.keys(results)) {\n checks[ct] = resolveCheckStatus(pkg.name, ct, results);\n if (checks[ct] === 'failed' && results[ct]?.errors[pkg.name]) {\n errors[ct] = results[ct]!.errors[pkg.name]!;\n }\n }\n\n return {\n name: pkg.name,\n repo: pkg.repo,\n category,\n checks,\n errors,\n };\n}\n\n/**\n * Add a PackageStatus to a GroupSummary.\n */\nfunction addToSummary(summary: GroupSummary, status: PackageStatus): void {\n summary.total++;\n\n const hasFail = Object.values(status.checks).some((v) => v === 'failed');\n if (hasFail) {\n summary.failed++;\n } else {\n summary.passed++;\n }\n\n for (const ct of Object.keys(status.checks)) {\n const s = status.checks[ct];\n if (!summary.checks[ct]) {\n summary.checks[ct] = { passed: 0, failed: 0, skipped: 0 };\n }\n if (s === 'passed') {summary.checks[ct].passed++;}\n else if (s === 'failed') {summary.checks[ct].failed++;}\n else {summary.checks[ct].skipped++;}\n }\n}\n\n/**\n * Group QA results by category → repo → packages.\n *\n * A package can appear in multiple categories if its repo is listed\n * in multiple category configs (e.g., kb-labs-cli in both \"core\" and \"hosts\").\n */\nexport function groupResults(\n results: QAResults,\n packages: WorkspacePackage[],\n categoryMap: Map<string, string[]>,\n config?: QAPluginConfig,\n): GroupedResults {\n const checkTypes = Object.keys(results);\n const grouped: GroupedResults = { categories: {} };\n\n for (const pkg of packages) {\n const categoryKeys = categoryMap.get(pkg.name) ?? ['uncategorized'];\n\n for (const categoryKey of categoryKeys) {\n const status = buildPackageStatus(pkg, results, categoryKey);\n\n // Ensure category exists\n if (!grouped.categories[categoryKey]) {\n const label =\n categoryKey === 'uncategorized'\n ? 'Uncategorized'\n : config?.categories?.[categoryKey]?.label ?? categoryKey;\n\n grouped.categories[categoryKey] = {\n label,\n repos: {},\n summary: emptyGroupSummary(checkTypes),\n };\n }\n\n const categoryGroup = grouped.categories[categoryKey]!;\n\n // Ensure repo exists within category\n if (!categoryGroup.repos[pkg.repo]) {\n categoryGroup.repos[pkg.repo] = {\n packages: [],\n summary: emptyGroupSummary(checkTypes),\n };\n }\n\n const repoGroup = categoryGroup.repos[pkg.repo]!;\n\n repoGroup.packages.push(status);\n addToSummary(repoGroup.summary, status);\n addToSummary(categoryGroup.summary, status);\n }\n }\n\n return grouped;\n}\n","import type { QAResults } from '@kb-labs/qa-contracts';\nimport type { ErrorGroup, QAErrorGroupsResponse } from '@kb-labs/qa-contracts';\n\n/**\n * Extract an error pattern from raw error text.\n * Tries to identify ESLint rules, TS error codes, or common patterns.\n */\nfunction extractPattern(errorText: string, checkType: string): string {\n if (checkType === 'lint') {\n // ESLint: look for rule names like \"@typescript-eslint/no-explicit-any\"\n const ruleMatch = errorText.match(/(\\S+\\/[\\w-]+|no-[\\w-]+)/);\n if (ruleMatch?.[1]) {return ruleMatch[1];}\n }\n\n if (checkType === 'typeCheck') {\n // TypeScript: look for error codes like \"TS2345\" or \"error TS2345\"\n const tsMatch = errorText.match(/TS(\\d{4,5})/);\n if (tsMatch) {return `TS${tsMatch[1]}`;}\n }\n\n if (checkType === 'test') {\n // Test failures: look for \"FAIL\" + test file pattern\n const failMatch = errorText.match(/FAIL\\s+(\\S+)/);\n if (failMatch) {return `FAIL: ${failMatch[1]}`;}\n }\n\n if (checkType === 'build') {\n // Build: \"Module not found\", \"Cannot find module\"\n if (errorText.includes('Cannot find module')) {return 'Cannot find module';}\n if (errorText.includes('Module not found')) {return 'Module not found';}\n }\n\n // Fallback: first meaningful line (skip empty lines, trim)\n const firstLine = errorText.split('\\n').find((l) => l.trim().length > 0)?.trim() ?? '';\n return firstLine.slice(0, 100) || 'Unknown error';\n}\n\n/**\n * Group errors from QA results by error pattern.\n * Packages with the same error pattern (e.g., same ESLint rule) are grouped together.\n */\nexport function groupErrors(results: QAResults): QAErrorGroupsResponse {\n const groupMap = new Map<string, ErrorGroup>();\n let ungrouped = 0;\n\n for (const ct of Object.keys(results)) {\n const check = results[ct]!;\n if (!check.errors) {continue;}\n\n for (const [pkgName, errorText] of Object.entries(check.errors)) {\n const pattern = extractPattern(errorText, ct);\n const key = `${ct}::${pattern}`;\n\n const existing = groupMap.get(key);\n if (existing) {\n existing.count++;\n existing.packages.push(pkgName);\n } else {\n groupMap.set(key, {\n pattern,\n count: 1,\n packages: [pkgName],\n checkType: ct,\n example: errorText.slice(0, 200),\n });\n }\n }\n }\n\n // Groups with count=1 are \"ungrouped\" (unique errors)\n const groups: ErrorGroup[] = [];\n for (const group of groupMap.values()) {\n if (group.count === 1) {\n ungrouped++;\n } else {\n groups.push(group);\n }\n }\n\n // Sort by count descending\n groups.sort((a, b) => b.count - a.count);\n\n return { groups, ungrouped };\n}\n"]}
|
package/dist/runner/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { L as LastRunData, c as collectSubmoduleInfo, g as getSubmoduleInfo, a as getWorkspacePackages, l as loadLastRun, r as
|
|
1
|
+
export { L as LastRunData, c as collectSubmoduleInfo, g as getSubmoduleInfo, a as getWorkspacePackages, l as loadLastRun, r as runCustomChecks, b as runLintCheck, d as runQA, e as runTestCheck, f as runTypeCheck, s as saveLastRun } from '../last-run-store-C1AkskWI.js';
|
|
2
2
|
import { WorkspacePackage, CheckResult } from '@kb-labs/qa-contracts';
|
|
3
3
|
|
|
4
4
|
interface CacheEntry {
|
package/dist/runner/index.js
CHANGED
|
@@ -279,21 +279,39 @@ var ID_MAP = {
|
|
|
279
279
|
tests: "test"
|
|
280
280
|
};
|
|
281
281
|
function emptyResult() {
|
|
282
|
-
return { passed: [], failed: [], skipped: [], errors: {} };
|
|
282
|
+
return { passed: [], failed: [], skipped: [], errors: {}, details: {} };
|
|
283
283
|
}
|
|
284
|
-
function runCommand(command, args, cwd, timeoutMs) {
|
|
284
|
+
function runCommand(command, args, cwd, timeoutMs, extraEnv) {
|
|
285
285
|
try {
|
|
286
|
-
const
|
|
286
|
+
const env = extraEnv ? { ...process.env, ...extraEnv } : void 0;
|
|
287
|
+
const result = spawnSync(command, args, { cwd, timeout: timeoutMs, encoding: "utf-8", shell: false, env });
|
|
287
288
|
const stdout = result.stdout ?? "";
|
|
288
289
|
const stderr = result.stderr ?? "";
|
|
289
290
|
const exitCode = result.status ?? 1;
|
|
290
291
|
return { ok: exitCode === 0, stdout, stderr, exitCode };
|
|
291
292
|
} catch (e) {
|
|
292
|
-
return { ok: false, stdout: "", stderr: e.message
|
|
293
|
+
return { ok: false, stdout: "", stderr: e instanceof Error ? e.message : String(e), exitCode: 1 };
|
|
293
294
|
}
|
|
294
295
|
}
|
|
296
|
+
function parseTypedOutput(stdout) {
|
|
297
|
+
try {
|
|
298
|
+
const parsed = JSON.parse(stdout);
|
|
299
|
+
if (typeof parsed === "object" && parsed !== null && "ok" in parsed) {
|
|
300
|
+
return {
|
|
301
|
+
ok: parsed.ok === true,
|
|
302
|
+
items: Array.isArray(parsed.items) ? parsed.items : []
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
} catch {
|
|
306
|
+
}
|
|
307
|
+
return null;
|
|
308
|
+
}
|
|
295
309
|
function evaluate(check, stdout, stderr, exitCode) {
|
|
296
310
|
if ((check.parser ?? "exitcode") === "json") {
|
|
311
|
+
const typed = parseTypedOutput(stdout);
|
|
312
|
+
if (typed !== null) {
|
|
313
|
+
return typed.ok;
|
|
314
|
+
}
|
|
297
315
|
try {
|
|
298
316
|
const parsed = JSON.parse(stdout);
|
|
299
317
|
return parsed.ok === true || parsed.success === true || parsed.status === "ok";
|
|
@@ -303,23 +321,54 @@ function evaluate(check, stdout, stderr, exitCode) {
|
|
|
303
321
|
}
|
|
304
322
|
return exitCode === 0;
|
|
305
323
|
}
|
|
306
|
-
function recordResult(bucket, key, passed, stdout, stderr, exitCode, canonicalId, onProgress, durationMs) {
|
|
324
|
+
function recordResult(bucket, key, passed, stdout, stderr, exitCode, check, canonicalId, onProgress, durationMs) {
|
|
307
325
|
if (passed) {
|
|
308
326
|
bucket.passed.push(key);
|
|
309
327
|
onProgress?.(canonicalId, key, "pass", durationMs);
|
|
310
328
|
} else {
|
|
311
329
|
bucket.failed.push(key);
|
|
312
330
|
bucket.errors[key] = stderr || stdout || `Exit code ${exitCode}`;
|
|
331
|
+
if ((check.parser ?? "exitcode") === "json") {
|
|
332
|
+
const typed = parseTypedOutput(stdout);
|
|
333
|
+
if (typed && typed.items.length > 0) {
|
|
334
|
+
bucket.details[key] = typed.items;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
313
337
|
onProgress?.(canonicalId, key, "fail", durationMs);
|
|
314
338
|
}
|
|
315
339
|
}
|
|
316
|
-
function
|
|
340
|
+
function getDiffPackageDirs(rootDir, base, diffFilter) {
|
|
341
|
+
try {
|
|
342
|
+
const filter = diffFilter ? `--diff-filter=${diffFilter}` : "";
|
|
343
|
+
const args = ["diff", filter, `${base}...HEAD`, "--name-only"].filter(Boolean);
|
|
344
|
+
const output = execSync(`git ${args.join(" ")}`, { cwd: rootDir, encoding: "utf-8" }).trim();
|
|
345
|
+
if (!output) {
|
|
346
|
+
return /* @__PURE__ */ new Set();
|
|
347
|
+
}
|
|
348
|
+
return new Set(output.split("\n").map((f) => f.split("/")[0]).filter((s) => Boolean(s)));
|
|
349
|
+
} catch {
|
|
350
|
+
return /* @__PURE__ */ new Set();
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
function filterPackagesByDiff(packages, rootDir, diffFilter, base) {
|
|
354
|
+
const touchedDirs = getDiffPackageDirs(rootDir, base, diffFilter);
|
|
355
|
+
if (touchedDirs.size === 0) {
|
|
356
|
+
return [];
|
|
357
|
+
}
|
|
358
|
+
return packages.filter((pkg) => {
|
|
359
|
+
const relParts = pkg.relativePath.split("/");
|
|
360
|
+
return relParts.some((_, i) => touchedDirs.has(relParts.slice(0, i + 1).join("/")));
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
function runInRepoRoot(check, canonicalId, resolvedArgs, rootDir, bucket, onProgress, diffBase) {
|
|
317
364
|
const startMs = Date.now();
|
|
318
|
-
const
|
|
319
|
-
|
|
365
|
+
const env = diffBase ? { KB_QA_BASE: diffBase } : void 0;
|
|
366
|
+
const { stderr, exitCode, stdout } = runCommand(check.command, resolvedArgs, rootDir, check.timeoutMs ?? 12e4, env);
|
|
367
|
+
recordResult(bucket, rootDir, evaluate(check, stdout, stderr, exitCode), stdout, stderr, exitCode, check, canonicalId, onProgress, Date.now() - startMs);
|
|
320
368
|
}
|
|
321
|
-
function runInScopePath(check, canonicalId, resolvedArgs, packages, rootDir, bucket, onProgress) {
|
|
369
|
+
function runInScopePath(check, canonicalId, resolvedArgs, packages, rootDir, bucket, onProgress, diffBase) {
|
|
322
370
|
const seen = /* @__PURE__ */ new Set();
|
|
371
|
+
const env = diffBase ? { KB_QA_BASE: diffBase } : void 0;
|
|
323
372
|
for (const pkg of packages) {
|
|
324
373
|
if (seen.has(pkg.repo)) {
|
|
325
374
|
continue;
|
|
@@ -330,8 +379,8 @@ function runInScopePath(check, canonicalId, resolvedArgs, packages, rootDir, buc
|
|
|
330
379
|
continue;
|
|
331
380
|
}
|
|
332
381
|
const startMs = Date.now();
|
|
333
|
-
const { stderr, exitCode, stdout } = runCommand(check.command, resolvedArgs, scopeDir, check.timeoutMs ?? 12e4);
|
|
334
|
-
recordResult(bucket, pkg.repo, evaluate(check, stdout, stderr, exitCode), stdout, stderr, exitCode, canonicalId, onProgress, Date.now() - startMs);
|
|
382
|
+
const { stderr, exitCode, stdout } = runCommand(check.command, resolvedArgs, scopeDir, check.timeoutMs ?? 12e4, env);
|
|
383
|
+
recordResult(bucket, pkg.repo, evaluate(check, stdout, stderr, exitCode), stdout, stderr, exitCode, check, canonicalId, onProgress, Date.now() - startMs);
|
|
335
384
|
}
|
|
336
385
|
}
|
|
337
386
|
function getPnpmScriptName(check) {
|
|
@@ -352,9 +401,10 @@ function hasNpmScript(pkgDir, scriptName) {
|
|
|
352
401
|
return false;
|
|
353
402
|
}
|
|
354
403
|
}
|
|
355
|
-
function runPerPackage(check, canonicalId, resolvedArgs, packages, bucket, onProgress) {
|
|
404
|
+
function runPerPackage(check, canonicalId, resolvedArgs, packages, bucket, onProgress, diffBase) {
|
|
356
405
|
const sortedPackages = check.ordered ? sortByBuildLayers(packages) : packages;
|
|
357
406
|
const scriptName = getPnpmScriptName(check);
|
|
407
|
+
const env = diffBase ? { KB_QA_BASE: diffBase } : void 0;
|
|
358
408
|
for (const pkg of sortedPackages) {
|
|
359
409
|
if (scriptName && !hasNpmScript(pkg.dir, scriptName)) {
|
|
360
410
|
bucket.skipped.push(pkg.name);
|
|
@@ -362,11 +412,11 @@ function runPerPackage(check, canonicalId, resolvedArgs, packages, bucket, onPro
|
|
|
362
412
|
continue;
|
|
363
413
|
}
|
|
364
414
|
const startMs = Date.now();
|
|
365
|
-
const { stderr, exitCode, stdout } = runCommand(check.command, resolvedArgs, pkg.dir, check.timeoutMs ?? 12e4);
|
|
366
|
-
recordResult(bucket, pkg.name, evaluate(check, stdout, stderr, exitCode), stdout, stderr, exitCode, canonicalId, onProgress, Date.now() - startMs);
|
|
415
|
+
const { stderr, exitCode, stdout } = runCommand(check.command, resolvedArgs, pkg.dir, check.timeoutMs ?? 12e4, env);
|
|
416
|
+
recordResult(bucket, pkg.name, evaluate(check, stdout, stderr, exitCode), stdout, stderr, exitCode, check, canonicalId, onProgress, Date.now() - startMs);
|
|
367
417
|
}
|
|
368
418
|
}
|
|
369
|
-
function runCustomChecks(checks, packages, rootDir, onProgress) {
|
|
419
|
+
function runCustomChecks(checks, packages, rootDir, onProgress, diffBase) {
|
|
370
420
|
const results = {};
|
|
371
421
|
for (const check of checks) {
|
|
372
422
|
const canonicalId = ID_MAP[check.id.toLowerCase()] ?? check.id;
|
|
@@ -380,12 +430,34 @@ function runCustomChecks(checks, packages, rootDir, onProgress) {
|
|
|
380
430
|
);
|
|
381
431
|
const runIn = check.runIn ?? "perPackage";
|
|
382
432
|
if (runIn === "repoRoot") {
|
|
383
|
-
runInRepoRoot(check, canonicalId, resolvedArgs, rootDir, bucket, onProgress);
|
|
433
|
+
runInRepoRoot(check, canonicalId, resolvedArgs, rootDir, bucket, onProgress, diffBase);
|
|
384
434
|
} else if (runIn === "scopePath") {
|
|
385
|
-
runInScopePath(check, canonicalId, resolvedArgs, packages, rootDir, bucket, onProgress);
|
|
435
|
+
runInScopePath(check, canonicalId, resolvedArgs, packages, rootDir, bucket, onProgress, diffBase);
|
|
436
|
+
} else if (runIn === "diffOnly" || runIn === "newFiles") {
|
|
437
|
+
const base = diffBase ?? "main";
|
|
438
|
+
const diffFilter = runIn === "newFiles" ? "A" : "";
|
|
439
|
+
const filteredPackages = filterPackagesByDiff(packages, rootDir, diffFilter, base);
|
|
440
|
+
if (filteredPackages.length === 0) {
|
|
441
|
+
bucket.skipped.push(...packages.map((p) => p.name));
|
|
442
|
+
for (const pkg of packages) {
|
|
443
|
+
onProgress?.(canonicalId, pkg.name, "skip");
|
|
444
|
+
}
|
|
445
|
+
} else {
|
|
446
|
+
const filteredNames = new Set(filteredPackages.map((p) => p.name));
|
|
447
|
+
for (const pkg of packages) {
|
|
448
|
+
if (!filteredNames.has(pkg.name)) {
|
|
449
|
+
bucket.skipped.push(pkg.name);
|
|
450
|
+
onProgress?.(canonicalId, pkg.name, "skip");
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
runPerPackage(check, canonicalId, resolvedArgs, filteredPackages, bucket, onProgress, base);
|
|
454
|
+
}
|
|
386
455
|
} else {
|
|
387
456
|
runPerPackage(check, canonicalId, resolvedArgs, packages, bucket, onProgress);
|
|
388
457
|
}
|
|
458
|
+
if (Object.keys(bucket.details).length > 0) {
|
|
459
|
+
results[canonicalId].details = bucket.details;
|
|
460
|
+
}
|
|
389
461
|
}
|
|
390
462
|
return results;
|
|
391
463
|
}
|
|
@@ -501,8 +573,9 @@ function runBuildCheck(options) {
|
|
|
501
573
|
} catch (err) {
|
|
502
574
|
const durationMs = Date.now() - startMs;
|
|
503
575
|
result.failed.push(pkg.name);
|
|
504
|
-
const
|
|
505
|
-
|
|
576
|
+
const spawnErr = err;
|
|
577
|
+
const rawErr = (spawnErr.stderr || spawnErr.stdout || spawnErr.message || "").trim();
|
|
578
|
+
result.errors[pkg.name] = rawErr.slice(0, 2e3) || `Build failed (exit code ${spawnErr.status ?? 1})`;
|
|
506
579
|
onProgress?.(pkg.name, "fail", durationMs);
|
|
507
580
|
}
|
|
508
581
|
}
|
|
@@ -530,8 +603,9 @@ function runLintCheck(options) {
|
|
|
530
603
|
onProgress?.(pkg.name, "pass", Date.now() - startMs);
|
|
531
604
|
} catch (err) {
|
|
532
605
|
result.failed.push(pkg.name);
|
|
533
|
-
const
|
|
534
|
-
|
|
606
|
+
const spawnErr = err;
|
|
607
|
+
const rawErr = (spawnErr.stdout || spawnErr.stderr || spawnErr.message || "").trim();
|
|
608
|
+
result.errors[pkg.name] = rawErr.slice(0, 2e3) || `Lint failed (exit code ${spawnErr.status ?? 1})`;
|
|
535
609
|
onProgress?.(pkg.name, "fail", Date.now() - startMs);
|
|
536
610
|
}
|
|
537
611
|
}
|
|
@@ -559,8 +633,9 @@ function runTypeCheck(options) {
|
|
|
559
633
|
onProgress?.(pkg.name, "pass", Date.now() - startMs);
|
|
560
634
|
} catch (err) {
|
|
561
635
|
result.failed.push(pkg.name);
|
|
562
|
-
const
|
|
563
|
-
|
|
636
|
+
const spawnErr = err;
|
|
637
|
+
const rawErr = (spawnErr.stdout || spawnErr.stderr || spawnErr.message || "").trim();
|
|
638
|
+
result.errors[pkg.name] = rawErr.slice(0, 2e3) || `Type check failed (exit code ${spawnErr.status ?? 1})`;
|
|
564
639
|
onProgress?.(pkg.name, "fail", Date.now() - startMs);
|
|
565
640
|
}
|
|
566
641
|
}
|
|
@@ -597,8 +672,9 @@ function runTestCheck(options) {
|
|
|
597
672
|
onProgress?.(pkg.name, "pass", Date.now() - startMs);
|
|
598
673
|
} catch (err) {
|
|
599
674
|
result.failed.push(pkg.name);
|
|
600
|
-
const
|
|
601
|
-
|
|
675
|
+
const spawnErr = err;
|
|
676
|
+
const rawErr = (spawnErr.stdout || spawnErr.stderr || spawnErr.message || "").trim();
|
|
677
|
+
result.errors[pkg.name] = rawErr.slice(0, 2e3) || `Test failed (exit code ${spawnErr.status ?? 1})`;
|
|
602
678
|
onProgress?.(pkg.name, "fail", Date.now() - startMs);
|
|
603
679
|
}
|
|
604
680
|
}
|
|
@@ -708,6 +784,6 @@ async function runQA(options) {
|
|
|
708
784
|
return { results, packages };
|
|
709
785
|
}
|
|
710
786
|
|
|
711
|
-
export { collectSubmoduleInfo, computePackageHash, getSubmoduleInfo, getWorkspacePackages, hasPackageChanged, loadCache, loadLastRun, runBuildCheck, runLintCheck, runQA, runTestCheck, runTypeCheck, saveCache, saveLastRun, updateCacheEntry };
|
|
787
|
+
export { collectSubmoduleInfo, computePackageHash, getSubmoduleInfo, getWorkspacePackages, hasPackageChanged, loadCache, loadLastRun, runBuildCheck, runCustomChecks, runLintCheck, runQA, runTestCheck, runTypeCheck, saveCache, saveLastRun, updateCacheEntry };
|
|
712
788
|
//# sourceMappingURL=index.js.map
|
|
713
789
|
//# sourceMappingURL=index.js.map
|