@kb-labs/qa-core 2.98.0 → 2.100.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/index.d.ts +9 -2
- package/dist/index.js +171 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ShellAPI } from '@kb-labs/sdk';
|
|
2
|
-
import { DevkitRunOutput, DevkitCheckOutput, DevkitStatsOutput, DevkitStatusOutput, DevkitGateOutput, SnapshotGit, RunSnapshot, CheckSnapshot, StatsSnapshot, GateSnapshot, BaselineData, TrendAnalysis, RegressionDetection, BaselineCheckDiff, PackageTimeline } from '@kb-labs/qa-contracts';
|
|
2
|
+
import { DevkitRunOutput, DevkitCheckOutput, DevkitStatsOutput, DevkitStatusOutput, DevkitGateOutput, SnapshotGit, RunSnapshot, CheckSnapshot, StatsSnapshot, GateSnapshot, E2eFlakySnapshot, E2eCaseResult, BaselineData, TrendAnalysis, RegressionDetection, BaselineCheckDiff, PackageTimeline, FlakyOverview, CaseTimeline } from '@kb-labs/qa-contracts';
|
|
3
3
|
export { ReportSection, buildBaselineDiffReport, buildBaselineReport, buildCheckJsonReport, buildCheckReport, buildHistoryTable, buildRegressionsReport, buildRunJsonReport, buildRunReport, buildStatsJsonReport, buildStatsReport, buildTrendsReport, formatTaskName } from './report/index.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -57,6 +57,9 @@ declare class SnapshotStore {
|
|
|
57
57
|
latestStats(): StatsSnapshot | null;
|
|
58
58
|
loadGateHistory(): GateSnapshot[];
|
|
59
59
|
saveGate(raw: DevkitGateOutput, durationMs: number, git?: SnapshotGit, runContext?: Record<string, unknown>): GateSnapshot;
|
|
60
|
+
loadE2eFlakyHistory(): E2eFlakySnapshot[];
|
|
61
|
+
saveE2eFlaky(cases: E2eCaseResult[], durationMs: number, git?: SnapshotGit, runContext?: Record<string, unknown>): E2eFlakySnapshot;
|
|
62
|
+
latestE2eFlaky(): E2eFlakySnapshot | null;
|
|
60
63
|
loadBaseline(): BaselineData | null;
|
|
61
64
|
saveBaseline(check: DevkitCheckOutput, stats: DevkitStatsOutput, git?: SnapshotGit): BaselineData;
|
|
62
65
|
}
|
|
@@ -69,4 +72,8 @@ declare function compareWithBaseline(currentCheck: DevkitCheckOutput, currentSta
|
|
|
69
72
|
|
|
70
73
|
declare function buildPackageTimeline(history: RunSnapshot[], packageName: string): PackageTimeline;
|
|
71
74
|
|
|
72
|
-
|
|
75
|
+
declare function caseKeyOf(caseResult: Pick<E2eCaseResult, 'suite' | 'spec' | 'testId'>): string;
|
|
76
|
+
declare function buildCaseTimeline(history: E2eFlakySnapshot[], caseKey: string): CaseTimeline | null;
|
|
77
|
+
declare function analyzeFlakyCases(history: E2eFlakySnapshot[], window?: number): FlakyOverview;
|
|
78
|
+
|
|
79
|
+
export { DevkitAdapter, type DevkitAdapterOptions, SnapshotStore, analyzeFlakyCases, analyzeTrends, buildCaseTimeline, buildPackageTimeline, captureGit, caseKeyOf, compareWithBaseline, detectRegressions, resolveDevkitBin };
|
package/dist/index.js
CHANGED
|
@@ -221,6 +221,28 @@ var SnapshotStore = class {
|
|
|
221
221
|
writeJson(join(this.rootDir, PATHS.SNAPSHOTS_GATE), history);
|
|
222
222
|
return snap;
|
|
223
223
|
}
|
|
224
|
+
// ── E2E flaky snapshots ───────────────────────────────────────────────────────
|
|
225
|
+
loadE2eFlakyHistory() {
|
|
226
|
+
return readJson(join(this.rootDir, PATHS.SNAPSHOTS_E2E_FLAKY));
|
|
227
|
+
}
|
|
228
|
+
saveE2eFlaky(cases, durationMs, git, runContext) {
|
|
229
|
+
const snap = {
|
|
230
|
+
...buildMeta(durationMs, git, runContext),
|
|
231
|
+
kind: "e2e-flaky",
|
|
232
|
+
cases
|
|
233
|
+
};
|
|
234
|
+
const history = this.loadE2eFlakyHistory();
|
|
235
|
+
history.push(snap);
|
|
236
|
+
while (history.length > this.maxEntries) {
|
|
237
|
+
history.shift();
|
|
238
|
+
}
|
|
239
|
+
writeJson(join(this.rootDir, PATHS.SNAPSHOTS_E2E_FLAKY), history);
|
|
240
|
+
return snap;
|
|
241
|
+
}
|
|
242
|
+
latestE2eFlaky() {
|
|
243
|
+
const h = this.loadE2eFlakyHistory();
|
|
244
|
+
return h.length > 0 ? h[h.length - 1] : null;
|
|
245
|
+
}
|
|
224
246
|
// ── Baseline ───────────────────────────────────────────────────────────────
|
|
225
247
|
loadBaseline() {
|
|
226
248
|
const p = join(this.rootDir, PATHS.BASELINE);
|
|
@@ -476,6 +498,154 @@ function buildPackageTimeline(history, packageName) {
|
|
|
476
498
|
firstFailure
|
|
477
499
|
};
|
|
478
500
|
}
|
|
501
|
+
function caseKeyOf(caseResult) {
|
|
502
|
+
return `${caseResult.suite}/${caseResult.spec}#${caseResult.testId}`;
|
|
503
|
+
}
|
|
504
|
+
function lastErrorOf(caseResult) {
|
|
505
|
+
const failedAttempt = [...caseResult.attempts].reverse().find((a) => a.status === "failed");
|
|
506
|
+
return { category: failedAttempt?.errorCategory, message: failedAttempt?.errorMessage };
|
|
507
|
+
}
|
|
508
|
+
function buildCaseTimeline(history, caseKey) {
|
|
509
|
+
const entries = [];
|
|
510
|
+
let suite = "";
|
|
511
|
+
let spec = "";
|
|
512
|
+
let testId = "";
|
|
513
|
+
let title = "";
|
|
514
|
+
for (const snap of [...history].reverse()) {
|
|
515
|
+
const match = snap.cases.find((c) => caseKeyOf(c) === caseKey);
|
|
516
|
+
if (!match) {
|
|
517
|
+
continue;
|
|
518
|
+
}
|
|
519
|
+
suite = match.suite;
|
|
520
|
+
spec = match.spec;
|
|
521
|
+
testId = match.testId;
|
|
522
|
+
title = match.title;
|
|
523
|
+
const { category, message } = lastErrorOf(match);
|
|
524
|
+
entries.push({
|
|
525
|
+
timestamp: snap.timestamp,
|
|
526
|
+
gitCommit: snap.git?.commit ?? "unknown",
|
|
527
|
+
status: match.outcome,
|
|
528
|
+
retries: match.attempts.length > 0 ? match.attempts.length - 1 : 0,
|
|
529
|
+
errorCategory: category,
|
|
530
|
+
errorMessage: message
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
if (entries.length === 0) {
|
|
534
|
+
return null;
|
|
535
|
+
}
|
|
536
|
+
const nonSkipped = entries.filter((e) => e.status !== "skipped");
|
|
537
|
+
let flips = 0;
|
|
538
|
+
for (let i = 1; i < nonSkipped.length; i++) {
|
|
539
|
+
if (nonSkipped[i].status !== nonSkipped[i - 1].status) {
|
|
540
|
+
flips++;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
const flakyScore = nonSkipped.length > 1 ? Math.round(flips / (nonSkipped.length - 1) * 100) / 100 : 0;
|
|
544
|
+
const latest = nonSkipped[0];
|
|
545
|
+
let streakStatus = "passing";
|
|
546
|
+
let streakCount = 0;
|
|
547
|
+
if (latest) {
|
|
548
|
+
streakStatus = latest.status === "failed" ? "failing" : "passing";
|
|
549
|
+
streakCount = 1;
|
|
550
|
+
for (let i = 1; i < nonSkipped.length; i++) {
|
|
551
|
+
const s = nonSkipped[i].status === "failed" ? "failing" : "passing";
|
|
552
|
+
if (s !== streakStatus) {
|
|
553
|
+
break;
|
|
554
|
+
}
|
|
555
|
+
streakCount++;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
let firstFailure;
|
|
559
|
+
for (const e of [...entries].reverse()) {
|
|
560
|
+
if (e.status === "failed" || e.status === "flaky") {
|
|
561
|
+
firstFailure = e.timestamp;
|
|
562
|
+
break;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
return {
|
|
566
|
+
caseKey,
|
|
567
|
+
suite,
|
|
568
|
+
spec,
|
|
569
|
+
testId,
|
|
570
|
+
title,
|
|
571
|
+
history: entries,
|
|
572
|
+
flakyScore,
|
|
573
|
+
currentStreak: { status: streakStatus, count: streakCount },
|
|
574
|
+
firstFailure
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
function analyzeFlakyCases(history, window = TRENDS_WINDOW) {
|
|
578
|
+
const windowSnaps = history.slice(-window);
|
|
579
|
+
if (windowSnaps.length === 0) {
|
|
580
|
+
return {
|
|
581
|
+
window,
|
|
582
|
+
runsAnalyzed: 0,
|
|
583
|
+
totalCases: 0,
|
|
584
|
+
flakyCases: 0,
|
|
585
|
+
delta: { new: [], fixed: [], unchanged: [] },
|
|
586
|
+
byCategory: { "infra-timeout": 0, "assertion-race": 0, "ws-flake": 0, unknown: 0 },
|
|
587
|
+
top: []
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
const caseKeys = /* @__PURE__ */ new Set();
|
|
591
|
+
for (const snap of windowSnaps) {
|
|
592
|
+
for (const c of snap.cases) {
|
|
593
|
+
caseKeys.add(caseKeyOf(c));
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
const byCategory = {
|
|
597
|
+
"infra-timeout": 0,
|
|
598
|
+
"assertion-race": 0,
|
|
599
|
+
"ws-flake": 0,
|
|
600
|
+
unknown: 0
|
|
601
|
+
};
|
|
602
|
+
const flakyEntries = [];
|
|
603
|
+
const flakyNowKeys = /* @__PURE__ */ new Set();
|
|
604
|
+
for (const key of caseKeys) {
|
|
605
|
+
const timeline = buildCaseTimeline(windowSnaps, key);
|
|
606
|
+
if (!timeline || timeline.flakyScore === 0) {
|
|
607
|
+
continue;
|
|
608
|
+
}
|
|
609
|
+
flakyNowKeys.add(key);
|
|
610
|
+
const category = timeline.history[0]?.errorCategory ?? "unknown";
|
|
611
|
+
byCategory[category]++;
|
|
612
|
+
flakyEntries.push({
|
|
613
|
+
case: key,
|
|
614
|
+
flakyScore: timeline.flakyScore,
|
|
615
|
+
streak: `${timeline.currentStreak.status} x${timeline.currentStreak.count}`,
|
|
616
|
+
category
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
flakyEntries.sort((a, b) => b.flakyScore - a.flakyScore);
|
|
620
|
+
const previousSnaps = history.slice(-2 * window, -window);
|
|
621
|
+
const previousCaseKeys = /* @__PURE__ */ new Set();
|
|
622
|
+
for (const snap of previousSnaps) {
|
|
623
|
+
for (const c of snap.cases) {
|
|
624
|
+
previousCaseKeys.add(caseKeyOf(c));
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
const flakyPreviousKeys = /* @__PURE__ */ new Set();
|
|
628
|
+
for (const key of previousCaseKeys) {
|
|
629
|
+
const timeline = buildCaseTimeline(previousSnaps, key);
|
|
630
|
+
if (timeline && timeline.flakyScore > 0) {
|
|
631
|
+
flakyPreviousKeys.add(key);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
const delta = {
|
|
635
|
+
new: [...flakyNowKeys].filter((k) => !flakyPreviousKeys.has(k)),
|
|
636
|
+
fixed: [...flakyPreviousKeys].filter((k) => !flakyNowKeys.has(k)),
|
|
637
|
+
unchanged: [...flakyNowKeys].filter((k) => flakyPreviousKeys.has(k))
|
|
638
|
+
};
|
|
639
|
+
return {
|
|
640
|
+
window,
|
|
641
|
+
runsAnalyzed: windowSnaps.length,
|
|
642
|
+
totalCases: caseKeys.size,
|
|
643
|
+
flakyCases: flakyNowKeys.size,
|
|
644
|
+
delta,
|
|
645
|
+
byCategory,
|
|
646
|
+
top: flakyEntries.slice(0, 5)
|
|
647
|
+
};
|
|
648
|
+
}
|
|
479
649
|
|
|
480
650
|
// src/report/text-reporter.ts
|
|
481
651
|
function formatTaskName(task) {
|
|
@@ -696,6 +866,6 @@ function buildStatsJsonReport(snap) {
|
|
|
696
866
|
};
|
|
697
867
|
}
|
|
698
868
|
|
|
699
|
-
export { DevkitAdapter, SnapshotStore, analyzeTrends, buildBaselineDiffReport, buildBaselineReport, buildCheckJsonReport, buildCheckReport, buildHistoryTable, buildPackageTimeline, buildRegressionsReport, buildRunJsonReport, buildRunReport, buildStatsJsonReport, buildStatsReport, buildTrendsReport, captureGit, compareWithBaseline, detectRegressions, formatTaskName, resolveDevkitBin };
|
|
869
|
+
export { DevkitAdapter, SnapshotStore, analyzeFlakyCases, analyzeTrends, buildBaselineDiffReport, buildBaselineReport, buildCaseTimeline, buildCheckJsonReport, buildCheckReport, buildHistoryTable, buildPackageTimeline, buildRegressionsReport, buildRunJsonReport, buildRunReport, buildStatsJsonReport, buildStatsReport, buildTrendsReport, captureGit, caseKeyOf, compareWithBaseline, detectRegressions, formatTaskName, resolveDevkitBin };
|
|
700
870
|
//# sourceMappingURL=index.js.map
|
|
701
871
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/devkit/devkit-discovery.ts","../src/devkit/devkit-adapter.ts","../src/devkit/git-capture.ts","../src/snapshot/snapshot-store.ts","../src/analysis/trend-analyzer.ts","../src/analysis/regression-detector.ts","../src/analysis/baseline-comparator.ts","../src/analysis/package-timeline.ts","../src/report/text-reporter.ts","../src/report/json-reporter.ts"],"names":["existsSync","join","r","p"],"mappings":"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","file":"index.js","sourcesContent":["import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/**\n * Resolve the kb-devkit binary path.\n *\n * Resolution order:\n * 1. configPath (from QAPluginConfig.devkitPath) — absolute or relative to rootDir\n * 2. tools/kb-devkit/kb-devkit relative to rootDir (workspace-local copy)\n * 3. \"kb-devkit\" — resolved from PATH at spawn time\n *\n * The shell permission whitelist matches by basename, so passing a full path\n * to shell.exec() works correctly when allow: ['kb-devkit'] is declared.\n */\nexport function resolveDevkitBin(rootDir: string, configPath?: string): string {\n if (configPath) {\n const full = configPath.startsWith('/') ? configPath : join(rootDir, configPath);\n if (!existsSync(full)) {\n throw new Error(`devkitPath \"${configPath}\" not found at ${full}`);\n }\n return full;\n }\n\n const local = join(rootDir, 'tools', 'kb-devkit', 'kb-devkit');\n if (existsSync(local)) {return local;}\n\n return 'kb-devkit';\n}\n","import type { ShellAPI } from '@kb-labs/sdk';\nimport type {\n DevkitRunOutput,\n DevkitCheckOutput,\n DevkitStatsOutput,\n DevkitStatusOutput,\n DevkitGateOutput,\n} from '@kb-labs/qa-contracts';\n\nexport interface DevkitAdapterOptions {\n binaryPath: string;\n cwd: string;\n shell: ShellAPI;\n timeoutMs?: number;\n}\n\nexport class DevkitAdapter {\n private readonly bin: string;\n private readonly cwd: string;\n private readonly shell: ShellAPI;\n private readonly timeout: number;\n\n constructor(opts: DevkitAdapterOptions) {\n this.bin = opts.binaryPath;\n this.cwd = opts.cwd;\n this.shell = opts.shell;\n this.timeout = opts.timeoutMs ?? 600_000;\n }\n\n async run(tasks: string[]): Promise<DevkitRunOutput> {\n if (tasks.length === 0) {throw new Error('DevkitAdapter.run: tasks must not be empty');}\n return this.invoke<DevkitRunOutput>(['run', ...tasks]);\n }\n\n async check(): Promise<DevkitCheckOutput> {\n return this.invoke<DevkitCheckOutput>(['check']);\n }\n\n async stats(): Promise<DevkitStatsOutput> {\n return this.invoke<DevkitStatsOutput>(['stats']);\n }\n\n async status(): Promise<DevkitStatusOutput> {\n return this.invoke<DevkitStatusOutput>(['status']);\n }\n\n async gate(): Promise<DevkitGateOutput> {\n return this.invoke<DevkitGateOutput>(['gate']);\n }\n\n async version(): Promise<string> {\n const result = await this.shell.exec(this.bin, ['--version'], {\n cwd: this.cwd,\n timeout: 5_000,\n throwOnError: false,\n });\n if (!result.ok) {\n throw new Error(\n `kb-devkit not found or not executable at \"${this.bin}\". ` +\n `Set QAPluginConfig.devkitPath or ensure kb-devkit is on PATH.`\n );\n }\n return result.stdout.trim();\n }\n\n private async invoke<T>(args: string[]): Promise<T> {\n const result = await this.shell.exec(this.bin, [...args, '--json'], {\n cwd: this.cwd,\n timeout: this.timeout,\n throwOnError: false,\n });\n\n if (result.code !== 0 && !result.stdout.trim()) {\n throw new Error(\n `kb-devkit ${args[0]} failed (exit ${result.code}): ${result.stderr.slice(0, 500)}`\n );\n }\n\n try {\n return JSON.parse(result.stdout) as T;\n } catch {\n throw new Error(\n `kb-devkit ${args[0]} produced non-JSON output (exit ${result.code}). ` +\n `stderr: ${result.stderr.slice(0, 300)}`\n );\n }\n }\n}\n","import type { ShellAPI } from '@kb-labs/sdk';\nimport type { SnapshotGit } from '@kb-labs/qa-contracts';\n\n/**\n * Capture current git context using ctx.api.shell.\n * Returns undefined if the directory is not a git repo or git is unavailable.\n */\nexport async function captureGit(shell: ShellAPI, cwd: string): Promise<SnapshotGit | undefined> {\n try {\n const [commitRes, branchRes, messageRes] = await Promise.all([\n shell.exec('git', ['rev-parse', '--short', 'HEAD'], { cwd, throwOnError: false }),\n shell.exec('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd, throwOnError: false }),\n shell.exec('git', ['log', '-1', '--format=%s'], { cwd, throwOnError: false }),\n ]);\n\n if (!commitRes.ok) {return undefined;}\n\n return {\n commit: commitRes.stdout.trim(),\n branch: branchRes.stdout.trim() || 'HEAD',\n message: messageRes.stdout.trim(),\n };\n } catch {\n return undefined;\n }\n}\n","import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport {\n PATHS,\n HISTORY_MAX_ENTRIES,\n} from '@kb-labs/qa-contracts';\nimport type {\n RunSnapshot,\n CheckSnapshot,\n StatsSnapshot,\n GateSnapshot,\n SnapshotMeta,\n SnapshotGit,\n BaselineData,\n DevkitRunOutput,\n DevkitCheckOutput,\n DevkitStatsOutput,\n DevkitGateOutput,\n} from '@kb-labs/qa-contracts';\n\nfunction readJson<T>(filePath: string): T[] {\n if (!existsSync(filePath)) {return [];}\n try {\n return JSON.parse(readFileSync(filePath, 'utf-8')) as T[];\n } catch {\n return [];\n }\n}\n\nfunction writeJson(filePath: string, data: unknown): void {\n const dir = dirname(filePath);\n if (!existsSync(dir)) {mkdirSync(dir, { recursive: true });}\n writeFileSync(filePath, JSON.stringify(data, null, 2));\n}\n\nfunction buildMeta(\n durationMs: number,\n git?: SnapshotGit,\n runContext?: Record<string, unknown>,\n): SnapshotMeta {\n return {\n id: randomUUID(),\n timestamp: new Date().toISOString(),\n durationMs,\n ...(git ? { git } : {}),\n ...(runContext ? { runContext } : {}),\n };\n}\n\nexport class SnapshotStore {\n private readonly rootDir: string;\n private readonly maxEntries: number;\n\n constructor(rootDir: string, maxEntries = HISTORY_MAX_ENTRIES) {\n this.rootDir = rootDir;\n this.maxEntries = maxEntries;\n }\n\n // ── Run snapshots ──────────────────────────────────────────────────────────\n\n loadRunHistory(): RunSnapshot[] {\n return readJson<RunSnapshot>(join(this.rootDir, PATHS.SNAPSHOTS_RUN));\n }\n\n saveRun(\n raw: DevkitRunOutput,\n tasks: string[],\n durationMs: number,\n git?: SnapshotGit,\n runContext?: Record<string, unknown>,\n ): RunSnapshot {\n const snap: RunSnapshot = {\n ...buildMeta(durationMs, git, runContext),\n kind: 'run',\n tasks,\n raw,\n };\n const history = this.loadRunHistory();\n history.push(snap);\n while (history.length > this.maxEntries) {history.shift();}\n writeJson(join(this.rootDir, PATHS.SNAPSHOTS_RUN), history);\n return snap;\n }\n\n latestRun(): RunSnapshot | null {\n const h = this.loadRunHistory();\n return h.length > 0 ? h[h.length - 1]! : null;\n }\n\n // ── Check snapshots ────────────────────────────────────────────────────────\n\n loadCheckHistory(): CheckSnapshot[] {\n return readJson<CheckSnapshot>(join(this.rootDir, PATHS.SNAPSHOTS_CHECK));\n }\n\n saveCheck(\n raw: DevkitCheckOutput,\n durationMs: number,\n git?: SnapshotGit,\n runContext?: Record<string, unknown>,\n ): CheckSnapshot {\n const snap: CheckSnapshot = {\n ...buildMeta(durationMs, git, runContext),\n kind: 'check',\n raw,\n };\n const history = this.loadCheckHistory();\n history.push(snap);\n while (history.length > this.maxEntries) {history.shift();}\n writeJson(join(this.rootDir, PATHS.SNAPSHOTS_CHECK), history);\n return snap;\n }\n\n latestCheck(): CheckSnapshot | null {\n const h = this.loadCheckHistory();\n return h.length > 0 ? h[h.length - 1]! : null;\n }\n\n // ── Stats snapshots ────────────────────────────────────────────────────────\n\n loadStatsHistory(): StatsSnapshot[] {\n return readJson<StatsSnapshot>(join(this.rootDir, PATHS.SNAPSHOTS_STATS));\n }\n\n saveStats(\n raw: DevkitStatsOutput,\n durationMs: number,\n git?: SnapshotGit,\n runContext?: Record<string, unknown>,\n ): StatsSnapshot {\n const snap: StatsSnapshot = {\n ...buildMeta(durationMs, git, runContext),\n kind: 'stats',\n raw,\n };\n const history = this.loadStatsHistory();\n history.push(snap);\n while (history.length > this.maxEntries) {history.shift();}\n writeJson(join(this.rootDir, PATHS.SNAPSHOTS_STATS), history);\n return snap;\n }\n\n latestStats(): StatsSnapshot | null {\n const h = this.loadStatsHistory();\n return h.length > 0 ? h[h.length - 1]! : null;\n }\n\n // ── Gate snapshots ─────────────────────────────────────────────────────────\n\n loadGateHistory(): GateSnapshot[] {\n return readJson<GateSnapshot>(join(this.rootDir, PATHS.SNAPSHOTS_GATE));\n }\n\n saveGate(\n raw: DevkitGateOutput,\n durationMs: number,\n git?: SnapshotGit,\n runContext?: Record<string, unknown>,\n ): GateSnapshot {\n const snap: GateSnapshot = {\n ...buildMeta(durationMs, git, runContext),\n kind: 'gate',\n raw,\n };\n const history = this.loadGateHistory();\n history.push(snap);\n while (history.length > this.maxEntries) {history.shift();}\n writeJson(join(this.rootDir, PATHS.SNAPSHOTS_GATE), history);\n return snap;\n }\n\n // ── Baseline ───────────────────────────────────────────────────────────────\n\n loadBaseline(): BaselineData | null {\n const p = join(this.rootDir, PATHS.BASELINE);\n if (!existsSync(p)) {return null;}\n try {\n return JSON.parse(readFileSync(p, 'utf-8')) as BaselineData;\n } catch {\n return null;\n }\n }\n\n saveBaseline(\n check: DevkitCheckOutput,\n stats: DevkitStatsOutput,\n git?: SnapshotGit,\n ): BaselineData {\n const baseline: BaselineData = {\n timestamp: new Date().toISOString(),\n ...(git ? { git } : {}),\n check,\n stats,\n };\n writeJson(join(this.rootDir, PATHS.BASELINE), baseline);\n return baseline;\n }\n}\n","import type {\n RunSnapshot,\n TaskTrend,\n TaskTrendPoint,\n TaskTrendChangelog,\n TrendAnalysis,\n} from '@kb-labs/qa-contracts';\nimport { TRENDS_WINDOW } from '@kb-labs/qa-contracts';\n\nfunction extractFailed(snap: RunSnapshot, task: string): string[] {\n return snap.raw.results\n .filter(r => r.Task === task && !r.OK && !r.Cached)\n .map(r => r.Package);\n}\n\nfunction collectTasks(snapshots: RunSnapshot[]): string[] {\n const s = new Set<string>();\n for (const snap of snapshots) {\n for (const r of snap.raw.results) {s.add(r.Task);}\n }\n return [...s];\n}\n\nfunction buildTimeSeries(snapshots: RunSnapshot[], task: string): TaskTrendPoint[] {\n return snapshots.map(snap => {\n const results = snap.raw.results.filter(r => r.Task === task);\n const failed = results.filter(r => !r.OK && !r.Cached).length;\n const cached = results.filter(r => r.Cached).length;\n const passed = results.filter(r => r.OK && !r.Cached).length;\n return {\n timestamp: snap.timestamp,\n gitCommit: snap.git?.commit ?? 'unknown',\n gitBranch: snap.git?.branch ?? 'unknown',\n gitMessage: snap.git?.message ?? '',\n failed,\n cached,\n passed,\n total: results.length,\n };\n });\n}\n\nfunction buildChangelog(snapshots: RunSnapshot[], task: string): TaskTrendChangelog[] {\n const changelog: TaskTrendChangelog[] = [];\n for (let i = 1; i < snapshots.length; i++) {\n const prev = snapshots[i - 1]!;\n const curr = snapshots[i]!;\n const prevFailed = new Set(extractFailed(prev, task));\n const currFailed = extractFailed(curr, task);\n const currFailedSet = new Set(currFailed);\n const newFailures = currFailed.filter(p => !prevFailed.has(p));\n const fixed = [...prevFailed].filter(p => !currFailedSet.has(p));\n const delta = currFailed.length - prevFailed.size;\n if (newFailures.length > 0 || fixed.length > 0) {\n changelog.push({\n timestamp: curr.timestamp,\n gitCommit: curr.git?.commit ?? 'unknown',\n gitMessage: curr.git?.message ?? '',\n newFailures,\n fixed,\n delta,\n });\n }\n }\n return changelog;\n}\n\nexport function analyzeTrends(\n history: RunSnapshot[],\n window: number = TRENDS_WINDOW,\n): TrendAnalysis {\n if (history.length < 2) {\n return { window, historyCount: history.length, tasks: [] };\n }\n\n const windowSnaps = history.slice(-window);\n const first = windowSnaps[0]!;\n const last = windowSnaps[windowSnaps.length - 1]!;\n const tasks = collectTasks(windowSnaps);\n\n const taskTrends: TaskTrend[] = tasks.map(task => {\n const timeSeries = buildTimeSeries(windowSnaps, task);\n const changelog = buildChangelog(windowSnaps, task);\n const previous = extractFailed(first, task).length;\n const current = extractFailed(last, task).length;\n const delta = current - previous;\n const deltas = changelog.map(c => c.delta);\n const velocity = deltas.length > 0\n ? Math.round((deltas.reduce((s, d) => s + d, 0) / deltas.length) * 100) / 100\n : 0;\n const direction: TaskTrend['direction'] =\n delta > 0 ? 'regression' : delta < 0 ? 'improvement' : 'no-change';\n return { task, previous, current, delta, direction, velocity, timeSeries, changelog };\n });\n\n return { window, historyCount: history.length, tasks: taskTrends };\n}\n","import type { RunSnapshot, RegressionDetection, RunRegression } from '@kb-labs/qa-contracts';\n\nexport function detectRegressions(history: RunSnapshot[]): RegressionDetection {\n if (history.length < 2) {\n return {\n hasRegressions: false,\n regressions: [],\n comparedAt: { previous: '', current: '' },\n };\n }\n\n const prev = history[history.length - 2]!;\n const curr = history[history.length - 1]!;\n\n const allTasks = new Set([\n ...prev.raw.results.map(r => r.Task),\n ...curr.raw.results.map(r => r.Task),\n ]);\n\n const regressions: RunRegression[] = [];\n\n for (const task of allTasks) {\n const prevFailed = new Set(\n prev.raw.results.filter(r => r.Task === task && !r.OK && !r.Cached).map(r => r.Package)\n );\n const currFailed = curr.raw.results\n .filter(r => r.Task === task && !r.OK && !r.Cached)\n .map(r => r.Package);\n const newFailures = currFailed.filter(p => !prevFailed.has(p));\n if (newFailures.length > 0) {\n regressions.push({\n task,\n delta: currFailed.length - prevFailed.size,\n newFailures,\n });\n }\n }\n\n return {\n hasRegressions: regressions.length > 0,\n regressions,\n comparedAt: { previous: prev.timestamp, current: curr.timestamp },\n };\n}\n","import type {\n BaselineData,\n BaselineCheckDiff,\n CheckIssueDiff,\n DevkitCheckOutput,\n DevkitStatsOutput,\n} from '@kb-labs/qa-contracts';\n\nfunction issueKey(pkg: string, check: string, message: string): string {\n return `${pkg}::${check}::${message}`;\n}\n\nexport function compareWithBaseline(\n currentCheck: DevkitCheckOutput,\n currentStats: DevkitStatsOutput,\n baseline: BaselineData,\n): BaselineCheckDiff {\n const baselineIssues = new Map<string, CheckIssueDiff>();\n for (const [pkg, pkgData] of Object.entries(baseline.check.packages)) {\n for (const issue of pkgData.issues ?? []) {\n const key = issueKey(pkg, issue.check, issue.message);\n baselineIssues.set(key, {\n pkg, check: issue.check, status: 'fixed', severity: issue.severity, message: issue.message,\n });\n }\n }\n\n const currentIssues = new Map<string, CheckIssueDiff>();\n for (const [pkg, pkgData] of Object.entries(currentCheck.packages)) {\n for (const issue of pkgData.issues ?? []) {\n const key = issueKey(pkg, issue.check, issue.message);\n currentIssues.set(key, {\n pkg, check: issue.check, status: 'new', severity: issue.severity, message: issue.message,\n });\n }\n }\n\n const newIssues: CheckIssueDiff[] = [];\n const fixedIssues: CheckIssueDiff[] = [];\n const persistingIssues: CheckIssueDiff[] = [];\n\n for (const [key, issue] of currentIssues) {\n if (baselineIssues.has(key)) {\n persistingIssues.push({ ...issue, status: 'persisting' });\n } else {\n newIssues.push({ ...issue, status: 'new' });\n }\n }\n for (const [key, issue] of baselineIssues) {\n if (!currentIssues.has(key)) {\n fixedIssues.push({ ...issue, status: 'fixed' });\n }\n }\n\n return {\n newIssues,\n fixedIssues,\n persistingIssues,\n newIssueCount: newIssues.length,\n fixedIssueCount: fixedIssues.length,\n scoreDelta: currentStats.score - baseline.stats.score,\n gradeDelta: `${baseline.stats.grade} → ${currentStats.grade}`,\n };\n}\n","import type { RunSnapshot, PackageTimeline, PackageTaskHistory } from '@kb-labs/qa-contracts';\n\nexport function buildPackageTimeline(\n history: RunSnapshot[],\n packageName: string,\n): PackageTimeline {\n const entries: PackageTaskHistory[] = [];\n\n for (const snap of [...history].reverse()) {\n for (const r of snap.raw.results.filter(r => r.Package === packageName)) {\n entries.push({\n timestamp: snap.timestamp,\n gitCommit: snap.git?.commit ?? 'unknown',\n task: r.Task,\n status: r.Cached ? 'cached' : r.OK ? 'passed' : 'failed',\n });\n }\n }\n\n const taskNames = [...new Set(entries.map(e => e.task))];\n let totalFlips = 0;\n let totalTransitions = 0;\n const flakyTasks: string[] = [];\n\n for (const task of taskNames) {\n const taskEntries = entries.filter(e => e.task === task && e.status !== 'cached');\n let flips = 0;\n for (let i = 1; i < taskEntries.length; i++) {\n totalTransitions++;\n if (taskEntries[i]!.status !== taskEntries[i - 1]!.status) {\n flips++;\n totalFlips++;\n }\n }\n if (taskEntries.length > 1 && flips / (taskEntries.length - 1) > 0.3) {\n flakyTasks.push(task);\n }\n }\n\n const flakyScore = totalTransitions > 0\n ? Math.round((totalFlips / totalTransitions) * 100) / 100\n : 0;\n\n const latest = entries[0];\n let streakStatus: 'passing' | 'failing' = 'passing';\n let streakCount = 0;\n\n if (latest) {\n streakStatus = latest.status === 'failed' ? 'failing' : 'passing';\n streakCount = 1;\n for (let i = 1; i < entries.length; i++) {\n const s = entries[i]!.status === 'failed' ? 'failing' : 'passing';\n if (s !== streakStatus) {break;}\n streakCount++;\n }\n }\n\n let firstFailure: string | undefined;\n for (const e of [...entries].reverse()) {\n if (e.status === 'failed') {\n firstFailure = e.timestamp;\n break;\n }\n }\n\n return {\n packageName,\n history: entries,\n flakyScore,\n flakyTasks,\n currentStreak: { status: streakStatus, count: streakCount },\n firstFailure,\n };\n}\n","import type {\n RunSnapshot,\n CheckSnapshot,\n StatsSnapshot,\n TrendAnalysis,\n RegressionDetection,\n BaselineData,\n BaselineCheckDiff,\n} from '@kb-labs/qa-contracts';\n\nexport interface ReportSection {\n header: string;\n lines: string[];\n}\n\nexport function formatTaskName(task: string): string {\n return task\n .split(/[-_]/)\n .map(w => w.charAt(0).toUpperCase() + w.slice(1))\n .join(' ');\n}\n\nexport function buildRunReport(snap: RunSnapshot | null): ReportSection[] {\n if (!snap) {return [{ header: 'Run', lines: ['No run data available.'] }];}\n\n const sections: ReportSection[] = [];\n const tasks = [...new Set(snap.raw.results.map(r => r.Task))];\n\n for (const task of tasks) {\n const results = snap.raw.results.filter(r => r.Task === task);\n const passed = results.filter(r => r.OK && !r.Cached).length;\n const failed = results.filter(r => !r.OK && !r.Cached).length;\n const cached = results.filter(r => r.Cached).length;\n const failedPkgs = results.filter(r => !r.OK && !r.Cached).map(r => r.Package);\n\n const lines: string[] = [`pass ${passed} fail ${failed} cached ${cached}`];\n if (failedPkgs.length > 0) {\n const shown = failedPkgs.slice(0, 5);\n lines.push(...shown.map(p => ` ✗ ${p}`));\n if (failedPkgs.length > 5) {lines.push(` ... ${failedPkgs.length - 5} more`);}\n }\n\n sections.push({ header: formatTaskName(task), lines });\n }\n\n const status = snap.raw.ok ? 'passed' : 'failed';\n const { total, passed: p, failed: f, cached: c } = snap.raw.summary;\n sections.push({\n header: 'Summary',\n lines: [`${status.toUpperCase()} total ${total} pass ${p} fail ${f} cached ${c} (${snap.raw.elapsed})`],\n });\n\n return sections;\n}\n\nexport function buildCheckReport(snap: CheckSnapshot | null): ReportSection[] {\n if (!snap) {return [{ header: 'Check', lines: ['No check data available.'] }];}\n\n const sections: ReportSection[] = [];\n\n for (const [pkg, pkgData] of Object.entries(snap.raw.packages)) {\n const issues = pkgData.issues ?? [];\n if (issues.length === 0) {continue;}\n\n const errors = issues.filter(i => i.severity === 'error').length;\n const warnings = issues.filter(i => i.severity === 'warning').length;\n const infos = issues.filter(i => i.severity === 'info').length;\n\n const lines: string[] = [`errors ${errors} warnings ${warnings} info ${infos}`];\n for (const issue of issues.slice(0, 5)) {\n lines.push(` [${issue.severity}] ${issue.check}: ${issue.message}`);\n }\n if (issues.length > 5) {lines.push(` ... ${issues.length - 5} more`);}\n\n sections.push({ header: pkg, lines });\n }\n\n if (sections.length === 0) {\n sections.push({ header: 'Check', lines: ['All packages OK.'] });\n }\n\n return sections;\n}\n\nexport function buildStatsReport(snap: StatsSnapshot | null): ReportSection[] {\n if (!snap) {return [{ header: 'Stats', lines: ['No stats data available.'] }];}\n\n const { score, grade, summary, by_category, coverage } = snap.raw;\n\n const sections: ReportSection[] = [];\n\n sections.push({\n header: 'Score',\n lines: [`${score}/100 Grade: ${grade} (${summary.healthy} healthy / ${summary.warning} warning / ${summary.error} error)`],\n });\n\n const catLines = Object.entries(by_category).map(([cat, data]) => {\n const pct = data.total > 0 ? Math.round((data.healthy / data.total) * 100) : 0;\n return ` ${cat.padEnd(20)} ${data.grade} ${pct}% (${data.healthy}/${data.total})`;\n });\n sections.push({ header: 'By Category', lines: catLines });\n\n if (Object.keys(coverage).length > 0) {\n const covLines = Object.entries(coverage).map(([k, v]) => ` ${k.padEnd(20)} ${v.pct}% (${v.pass}/${v.total})`);\n sections.push({ header: 'Coverage', lines: covLines });\n }\n\n return sections;\n}\n\nexport function buildHistoryTable(history: RunSnapshot[], limit = 20): ReportSection[] {\n const rows = [...history].reverse().slice(0, limit);\n if (rows.length === 0) {return [{ header: 'History', lines: ['No history available.'] }];}\n\n const lines = rows.map(snap => {\n const status = snap.raw.ok ? 'pass' : 'fail';\n const tasks = snap.tasks.join(', ');\n const commit = snap.git?.commit ?? '-------';\n const date = new Date(snap.timestamp).toLocaleString();\n return ` ${date} ${commit} ${status} [${tasks}]`;\n });\n\n return [{ header: `History (last ${rows.length})`, lines }];\n}\n\nexport function buildTrendsReport(analysis: TrendAnalysis): ReportSection[] {\n if (analysis.tasks.length === 0) {\n return [{ header: 'Trends', lines: ['Not enough history for trend analysis.'] }];\n }\n\n const sections: ReportSection[] = [];\n\n for (const trend of analysis.tasks) {\n const arrow = trend.direction === 'regression' ? '↑' : trend.direction === 'improvement' ? '↓' : '→';\n const lines: string[] = [\n `${arrow} ${trend.direction} prev ${trend.previous} curr ${trend.current} delta ${trend.delta > 0 ? '+' : ''}${trend.delta} velocity ${trend.velocity}`,\n ];\n\n if (trend.changelog.length > 0) {\n const last = trend.changelog[trend.changelog.length - 1]!;\n if (last.newFailures.length > 0) {lines.push(` last regression: ${last.newFailures.slice(0, 3).join(', ')}`);}\n if (last.fixed.length > 0) {lines.push(` last fixed: ${last.fixed.slice(0, 3).join(', ')}`);}\n }\n\n sections.push({ header: formatTaskName(trend.task), lines });\n }\n\n return sections;\n}\n\nexport function buildRegressionsReport(detection: RegressionDetection): ReportSection[] {\n if (!detection.hasRegressions) {\n return [{ header: 'Regressions', lines: ['No regressions detected.'] }];\n }\n\n const sections: ReportSection[] = [];\n\n for (const reg of detection.regressions) {\n const lines = [\n `delta +${reg.delta}`,\n ...reg.newFailures.slice(0, 5).map(p => ` ✗ ${p}`),\n ];\n if (reg.newFailures.length > 5) {lines.push(` ... ${reg.newFailures.length - 5} more`);}\n sections.push({ header: formatTaskName(reg.task), lines });\n }\n\n const prev = new Date(detection.comparedAt.previous).toLocaleString();\n const curr = new Date(detection.comparedAt.current).toLocaleString();\n sections.push({ header: 'Compared', lines: [`${prev} → ${curr}`] });\n\n return sections;\n}\n\nexport function buildBaselineReport(baseline: BaselineData | null): ReportSection[] {\n if (!baseline) {return [{ header: 'Baseline', lines: ['No baseline set. Run `qa baseline update` to set one.'] }];}\n\n const { score, grade } = baseline.stats;\n const totalIssues = Object.values(baseline.check.packages)\n .reduce((sum, pkg) => sum + (pkg.issues?.length ?? 0), 0);\n const commit = baseline.git?.commit ?? 'unknown';\n const date = new Date(baseline.timestamp).toLocaleString();\n\n return [{\n header: 'Baseline',\n lines: [`score ${score}/100 grade ${grade} issues ${totalIssues} commit ${commit} set ${date}`],\n }];\n}\n\nexport function buildBaselineDiffReport(diff: BaselineCheckDiff): ReportSection[] {\n const sections: ReportSection[] = [];\n\n const scoreDir = diff.scoreDelta > 0 ? '+' : '';\n sections.push({\n header: 'Score Delta',\n lines: [`${scoreDir}${diff.scoreDelta} ${diff.gradeDelta} new ${diff.newIssueCount} fixed ${diff.fixedIssueCount}`],\n });\n\n if (diff.newIssues.length > 0) {\n const lines = diff.newIssues.slice(0, 10).map(i => ` [${i.severity}] ${i.pkg} ${i.check}: ${i.message}`);\n if (diff.newIssues.length > 10) {lines.push(` ... ${diff.newIssues.length - 10} more`);}\n sections.push({ header: 'New Issues', lines });\n }\n\n if (diff.fixedIssues.length > 0) {\n const lines = diff.fixedIssues.slice(0, 10).map(i => ` [${i.severity}] ${i.pkg} ${i.check}: ${i.message}`);\n if (diff.fixedIssues.length > 10) {lines.push(` ... ${diff.fixedIssues.length - 10} more`);}\n sections.push({ header: 'Fixed Issues', lines });\n }\n\n if (diff.persistingIssues.length > 0) {\n sections.push({ header: 'Persisting Issues', lines: [`${diff.persistingIssues.length} issues unchanged`] });\n }\n\n return sections;\n}\n","import type { RunSnapshot, CheckSnapshot, StatsSnapshot } from '@kb-labs/qa-contracts';\n\nexport function buildRunJsonReport(snap: RunSnapshot): object {\n return {\n id: snap.id,\n timestamp: snap.timestamp,\n git: snap.git,\n durationMs: snap.durationMs,\n tasks: snap.tasks,\n ok: snap.raw.ok,\n elapsed: snap.raw.elapsed,\n summary: snap.raw.summary,\n results: snap.raw.results,\n };\n}\n\nexport function buildCheckJsonReport(snap: CheckSnapshot): object {\n return {\n id: snap.id,\n timestamp: snap.timestamp,\n git: snap.git,\n durationMs: snap.durationMs,\n ok: snap.raw.ok,\n packages: snap.raw.packages,\n };\n}\n\nexport function buildStatsJsonReport(snap: StatsSnapshot): object {\n return {\n id: snap.id,\n timestamp: snap.timestamp,\n git: snap.git,\n durationMs: snap.durationMs,\n ok: snap.raw.ok,\n score: snap.raw.score,\n grade: snap.raw.grade,\n summary: snap.raw.summary,\n by_category: snap.raw.by_category,\n issues_by_type: snap.raw.issues_by_type,\n coverage: snap.raw.coverage,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/devkit/devkit-discovery.ts","../src/devkit/devkit-adapter.ts","../src/devkit/git-capture.ts","../src/snapshot/snapshot-store.ts","../src/analysis/trend-analyzer.ts","../src/analysis/regression-detector.ts","../src/analysis/baseline-comparator.ts","../src/analysis/package-timeline.ts","../src/analysis/case-timeline.ts","../src/report/text-reporter.ts","../src/report/json-reporter.ts"],"names":["existsSync","join","r","TRENDS_WINDOW","p"],"mappings":"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","file":"index.js","sourcesContent":["import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/**\n * Resolve the kb-devkit binary path.\n *\n * Resolution order:\n * 1. configPath (from QAPluginConfig.devkitPath) — absolute or relative to rootDir\n * 2. tools/kb-devkit/kb-devkit relative to rootDir (workspace-local copy)\n * 3. \"kb-devkit\" — resolved from PATH at spawn time\n *\n * The shell permission whitelist matches by basename, so passing a full path\n * to shell.exec() works correctly when allow: ['kb-devkit'] is declared.\n */\nexport function resolveDevkitBin(rootDir: string, configPath?: string): string {\n if (configPath) {\n const full = configPath.startsWith('/') ? configPath : join(rootDir, configPath);\n if (!existsSync(full)) {\n throw new Error(`devkitPath \"${configPath}\" not found at ${full}`);\n }\n return full;\n }\n\n const local = join(rootDir, 'tools', 'kb-devkit', 'kb-devkit');\n if (existsSync(local)) {return local;}\n\n return 'kb-devkit';\n}\n","import type { ShellAPI } from '@kb-labs/sdk';\nimport type {\n DevkitRunOutput,\n DevkitCheckOutput,\n DevkitStatsOutput,\n DevkitStatusOutput,\n DevkitGateOutput,\n} from '@kb-labs/qa-contracts';\n\nexport interface DevkitAdapterOptions {\n binaryPath: string;\n cwd: string;\n shell: ShellAPI;\n timeoutMs?: number;\n}\n\nexport class DevkitAdapter {\n private readonly bin: string;\n private readonly cwd: string;\n private readonly shell: ShellAPI;\n private readonly timeout: number;\n\n constructor(opts: DevkitAdapterOptions) {\n this.bin = opts.binaryPath;\n this.cwd = opts.cwd;\n this.shell = opts.shell;\n this.timeout = opts.timeoutMs ?? 600_000;\n }\n\n async run(tasks: string[]): Promise<DevkitRunOutput> {\n if (tasks.length === 0) {throw new Error('DevkitAdapter.run: tasks must not be empty');}\n return this.invoke<DevkitRunOutput>(['run', ...tasks]);\n }\n\n async check(): Promise<DevkitCheckOutput> {\n return this.invoke<DevkitCheckOutput>(['check']);\n }\n\n async stats(): Promise<DevkitStatsOutput> {\n return this.invoke<DevkitStatsOutput>(['stats']);\n }\n\n async status(): Promise<DevkitStatusOutput> {\n return this.invoke<DevkitStatusOutput>(['status']);\n }\n\n async gate(): Promise<DevkitGateOutput> {\n return this.invoke<DevkitGateOutput>(['gate']);\n }\n\n async version(): Promise<string> {\n const result = await this.shell.exec(this.bin, ['--version'], {\n cwd: this.cwd,\n timeout: 5_000,\n throwOnError: false,\n });\n if (!result.ok) {\n throw new Error(\n `kb-devkit not found or not executable at \"${this.bin}\". ` +\n `Set QAPluginConfig.devkitPath or ensure kb-devkit is on PATH.`\n );\n }\n return result.stdout.trim();\n }\n\n private async invoke<T>(args: string[]): Promise<T> {\n const result = await this.shell.exec(this.bin, [...args, '--json'], {\n cwd: this.cwd,\n timeout: this.timeout,\n throwOnError: false,\n });\n\n if (result.code !== 0 && !result.stdout.trim()) {\n throw new Error(\n `kb-devkit ${args[0]} failed (exit ${result.code}): ${result.stderr.slice(0, 500)}`\n );\n }\n\n try {\n return JSON.parse(result.stdout) as T;\n } catch {\n throw new Error(\n `kb-devkit ${args[0]} produced non-JSON output (exit ${result.code}). ` +\n `stderr: ${result.stderr.slice(0, 300)}`\n );\n }\n }\n}\n","import type { ShellAPI } from '@kb-labs/sdk';\nimport type { SnapshotGit } from '@kb-labs/qa-contracts';\n\n/**\n * Capture current git context using ctx.api.shell.\n * Returns undefined if the directory is not a git repo or git is unavailable.\n */\nexport async function captureGit(shell: ShellAPI, cwd: string): Promise<SnapshotGit | undefined> {\n try {\n const [commitRes, branchRes, messageRes] = await Promise.all([\n shell.exec('git', ['rev-parse', '--short', 'HEAD'], { cwd, throwOnError: false }),\n shell.exec('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd, throwOnError: false }),\n shell.exec('git', ['log', '-1', '--format=%s'], { cwd, throwOnError: false }),\n ]);\n\n if (!commitRes.ok) {return undefined;}\n\n return {\n commit: commitRes.stdout.trim(),\n branch: branchRes.stdout.trim() || 'HEAD',\n message: messageRes.stdout.trim(),\n };\n } catch {\n return undefined;\n }\n}\n","import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport {\n PATHS,\n HISTORY_MAX_ENTRIES,\n} from '@kb-labs/qa-contracts';\nimport type {\n RunSnapshot,\n CheckSnapshot,\n StatsSnapshot,\n GateSnapshot,\n E2eFlakySnapshot,\n E2eCaseResult,\n SnapshotMeta,\n SnapshotGit,\n BaselineData,\n DevkitRunOutput,\n DevkitCheckOutput,\n DevkitStatsOutput,\n DevkitGateOutput,\n} from '@kb-labs/qa-contracts';\n\nfunction readJson<T>(filePath: string): T[] {\n if (!existsSync(filePath)) {return [];}\n try {\n return JSON.parse(readFileSync(filePath, 'utf-8')) as T[];\n } catch {\n return [];\n }\n}\n\nfunction writeJson(filePath: string, data: unknown): void {\n const dir = dirname(filePath);\n if (!existsSync(dir)) {mkdirSync(dir, { recursive: true });}\n writeFileSync(filePath, JSON.stringify(data, null, 2));\n}\n\nfunction buildMeta(\n durationMs: number,\n git?: SnapshotGit,\n runContext?: Record<string, unknown>,\n): SnapshotMeta {\n return {\n id: randomUUID(),\n timestamp: new Date().toISOString(),\n durationMs,\n ...(git ? { git } : {}),\n ...(runContext ? { runContext } : {}),\n };\n}\n\nexport class SnapshotStore {\n private readonly rootDir: string;\n private readonly maxEntries: number;\n\n constructor(rootDir: string, maxEntries = HISTORY_MAX_ENTRIES) {\n this.rootDir = rootDir;\n this.maxEntries = maxEntries;\n }\n\n // ── Run snapshots ──────────────────────────────────────────────────────────\n\n loadRunHistory(): RunSnapshot[] {\n return readJson<RunSnapshot>(join(this.rootDir, PATHS.SNAPSHOTS_RUN));\n }\n\n saveRun(\n raw: DevkitRunOutput,\n tasks: string[],\n durationMs: number,\n git?: SnapshotGit,\n runContext?: Record<string, unknown>,\n ): RunSnapshot {\n const snap: RunSnapshot = {\n ...buildMeta(durationMs, git, runContext),\n kind: 'run',\n tasks,\n raw,\n };\n const history = this.loadRunHistory();\n history.push(snap);\n while (history.length > this.maxEntries) {history.shift();}\n writeJson(join(this.rootDir, PATHS.SNAPSHOTS_RUN), history);\n return snap;\n }\n\n latestRun(): RunSnapshot | null {\n const h = this.loadRunHistory();\n return h.length > 0 ? h[h.length - 1]! : null;\n }\n\n // ── Check snapshots ────────────────────────────────────────────────────────\n\n loadCheckHistory(): CheckSnapshot[] {\n return readJson<CheckSnapshot>(join(this.rootDir, PATHS.SNAPSHOTS_CHECK));\n }\n\n saveCheck(\n raw: DevkitCheckOutput,\n durationMs: number,\n git?: SnapshotGit,\n runContext?: Record<string, unknown>,\n ): CheckSnapshot {\n const snap: CheckSnapshot = {\n ...buildMeta(durationMs, git, runContext),\n kind: 'check',\n raw,\n };\n const history = this.loadCheckHistory();\n history.push(snap);\n while (history.length > this.maxEntries) {history.shift();}\n writeJson(join(this.rootDir, PATHS.SNAPSHOTS_CHECK), history);\n return snap;\n }\n\n latestCheck(): CheckSnapshot | null {\n const h = this.loadCheckHistory();\n return h.length > 0 ? h[h.length - 1]! : null;\n }\n\n // ── Stats snapshots ────────────────────────────────────────────────────────\n\n loadStatsHistory(): StatsSnapshot[] {\n return readJson<StatsSnapshot>(join(this.rootDir, PATHS.SNAPSHOTS_STATS));\n }\n\n saveStats(\n raw: DevkitStatsOutput,\n durationMs: number,\n git?: SnapshotGit,\n runContext?: Record<string, unknown>,\n ): StatsSnapshot {\n const snap: StatsSnapshot = {\n ...buildMeta(durationMs, git, runContext),\n kind: 'stats',\n raw,\n };\n const history = this.loadStatsHistory();\n history.push(snap);\n while (history.length > this.maxEntries) {history.shift();}\n writeJson(join(this.rootDir, PATHS.SNAPSHOTS_STATS), history);\n return snap;\n }\n\n latestStats(): StatsSnapshot | null {\n const h = this.loadStatsHistory();\n return h.length > 0 ? h[h.length - 1]! : null;\n }\n\n // ── Gate snapshots ─────────────────────────────────────────────────────────\n\n loadGateHistory(): GateSnapshot[] {\n return readJson<GateSnapshot>(join(this.rootDir, PATHS.SNAPSHOTS_GATE));\n }\n\n saveGate(\n raw: DevkitGateOutput,\n durationMs: number,\n git?: SnapshotGit,\n runContext?: Record<string, unknown>,\n ): GateSnapshot {\n const snap: GateSnapshot = {\n ...buildMeta(durationMs, git, runContext),\n kind: 'gate',\n raw,\n };\n const history = this.loadGateHistory();\n history.push(snap);\n while (history.length > this.maxEntries) {history.shift();}\n writeJson(join(this.rootDir, PATHS.SNAPSHOTS_GATE), history);\n return snap;\n }\n\n // ── E2E flaky snapshots ───────────────────────────────────────────────────────\n\n loadE2eFlakyHistory(): E2eFlakySnapshot[] {\n return readJson<E2eFlakySnapshot>(join(this.rootDir, PATHS.SNAPSHOTS_E2E_FLAKY));\n }\n\n saveE2eFlaky(\n cases: E2eCaseResult[],\n durationMs: number,\n git?: SnapshotGit,\n runContext?: Record<string, unknown>,\n ): E2eFlakySnapshot {\n const snap: E2eFlakySnapshot = {\n ...buildMeta(durationMs, git, runContext),\n kind: 'e2e-flaky',\n cases,\n };\n const history = this.loadE2eFlakyHistory();\n history.push(snap);\n while (history.length > this.maxEntries) {history.shift();}\n writeJson(join(this.rootDir, PATHS.SNAPSHOTS_E2E_FLAKY), history);\n return snap;\n }\n\n latestE2eFlaky(): E2eFlakySnapshot | null {\n const h = this.loadE2eFlakyHistory();\n return h.length > 0 ? h[h.length - 1]! : null;\n }\n\n // ── Baseline ───────────────────────────────────────────────────────────────\n\n loadBaseline(): BaselineData | null {\n const p = join(this.rootDir, PATHS.BASELINE);\n if (!existsSync(p)) {return null;}\n try {\n return JSON.parse(readFileSync(p, 'utf-8')) as BaselineData;\n } catch {\n return null;\n }\n }\n\n saveBaseline(\n check: DevkitCheckOutput,\n stats: DevkitStatsOutput,\n git?: SnapshotGit,\n ): BaselineData {\n const baseline: BaselineData = {\n timestamp: new Date().toISOString(),\n ...(git ? { git } : {}),\n check,\n stats,\n };\n writeJson(join(this.rootDir, PATHS.BASELINE), baseline);\n return baseline;\n }\n}\n","import type {\n RunSnapshot,\n TaskTrend,\n TaskTrendPoint,\n TaskTrendChangelog,\n TrendAnalysis,\n} from '@kb-labs/qa-contracts';\nimport { TRENDS_WINDOW } from '@kb-labs/qa-contracts';\n\nfunction extractFailed(snap: RunSnapshot, task: string): string[] {\n return snap.raw.results\n .filter(r => r.Task === task && !r.OK && !r.Cached)\n .map(r => r.Package);\n}\n\nfunction collectTasks(snapshots: RunSnapshot[]): string[] {\n const s = new Set<string>();\n for (const snap of snapshots) {\n for (const r of snap.raw.results) {s.add(r.Task);}\n }\n return [...s];\n}\n\nfunction buildTimeSeries(snapshots: RunSnapshot[], task: string): TaskTrendPoint[] {\n return snapshots.map(snap => {\n const results = snap.raw.results.filter(r => r.Task === task);\n const failed = results.filter(r => !r.OK && !r.Cached).length;\n const cached = results.filter(r => r.Cached).length;\n const passed = results.filter(r => r.OK && !r.Cached).length;\n return {\n timestamp: snap.timestamp,\n gitCommit: snap.git?.commit ?? 'unknown',\n gitBranch: snap.git?.branch ?? 'unknown',\n gitMessage: snap.git?.message ?? '',\n failed,\n cached,\n passed,\n total: results.length,\n };\n });\n}\n\nfunction buildChangelog(snapshots: RunSnapshot[], task: string): TaskTrendChangelog[] {\n const changelog: TaskTrendChangelog[] = [];\n for (let i = 1; i < snapshots.length; i++) {\n const prev = snapshots[i - 1]!;\n const curr = snapshots[i]!;\n const prevFailed = new Set(extractFailed(prev, task));\n const currFailed = extractFailed(curr, task);\n const currFailedSet = new Set(currFailed);\n const newFailures = currFailed.filter(p => !prevFailed.has(p));\n const fixed = [...prevFailed].filter(p => !currFailedSet.has(p));\n const delta = currFailed.length - prevFailed.size;\n if (newFailures.length > 0 || fixed.length > 0) {\n changelog.push({\n timestamp: curr.timestamp,\n gitCommit: curr.git?.commit ?? 'unknown',\n gitMessage: curr.git?.message ?? '',\n newFailures,\n fixed,\n delta,\n });\n }\n }\n return changelog;\n}\n\nexport function analyzeTrends(\n history: RunSnapshot[],\n window: number = TRENDS_WINDOW,\n): TrendAnalysis {\n if (history.length < 2) {\n return { window, historyCount: history.length, tasks: [] };\n }\n\n const windowSnaps = history.slice(-window);\n const first = windowSnaps[0]!;\n const last = windowSnaps[windowSnaps.length - 1]!;\n const tasks = collectTasks(windowSnaps);\n\n const taskTrends: TaskTrend[] = tasks.map(task => {\n const timeSeries = buildTimeSeries(windowSnaps, task);\n const changelog = buildChangelog(windowSnaps, task);\n const previous = extractFailed(first, task).length;\n const current = extractFailed(last, task).length;\n const delta = current - previous;\n const deltas = changelog.map(c => c.delta);\n const velocity = deltas.length > 0\n ? Math.round((deltas.reduce((s, d) => s + d, 0) / deltas.length) * 100) / 100\n : 0;\n const direction: TaskTrend['direction'] =\n delta > 0 ? 'regression' : delta < 0 ? 'improvement' : 'no-change';\n return { task, previous, current, delta, direction, velocity, timeSeries, changelog };\n });\n\n return { window, historyCount: history.length, tasks: taskTrends };\n}\n","import type { RunSnapshot, RegressionDetection, RunRegression } from '@kb-labs/qa-contracts';\n\nexport function detectRegressions(history: RunSnapshot[]): RegressionDetection {\n if (history.length < 2) {\n return {\n hasRegressions: false,\n regressions: [],\n comparedAt: { previous: '', current: '' },\n };\n }\n\n const prev = history[history.length - 2]!;\n const curr = history[history.length - 1]!;\n\n const allTasks = new Set([\n ...prev.raw.results.map(r => r.Task),\n ...curr.raw.results.map(r => r.Task),\n ]);\n\n const regressions: RunRegression[] = [];\n\n for (const task of allTasks) {\n const prevFailed = new Set(\n prev.raw.results.filter(r => r.Task === task && !r.OK && !r.Cached).map(r => r.Package)\n );\n const currFailed = curr.raw.results\n .filter(r => r.Task === task && !r.OK && !r.Cached)\n .map(r => r.Package);\n const newFailures = currFailed.filter(p => !prevFailed.has(p));\n if (newFailures.length > 0) {\n regressions.push({\n task,\n delta: currFailed.length - prevFailed.size,\n newFailures,\n });\n }\n }\n\n return {\n hasRegressions: regressions.length > 0,\n regressions,\n comparedAt: { previous: prev.timestamp, current: curr.timestamp },\n };\n}\n","import type {\n BaselineData,\n BaselineCheckDiff,\n CheckIssueDiff,\n DevkitCheckOutput,\n DevkitStatsOutput,\n} from '@kb-labs/qa-contracts';\n\nfunction issueKey(pkg: string, check: string, message: string): string {\n return `${pkg}::${check}::${message}`;\n}\n\nexport function compareWithBaseline(\n currentCheck: DevkitCheckOutput,\n currentStats: DevkitStatsOutput,\n baseline: BaselineData,\n): BaselineCheckDiff {\n const baselineIssues = new Map<string, CheckIssueDiff>();\n for (const [pkg, pkgData] of Object.entries(baseline.check.packages)) {\n for (const issue of pkgData.issues ?? []) {\n const key = issueKey(pkg, issue.check, issue.message);\n baselineIssues.set(key, {\n pkg, check: issue.check, status: 'fixed', severity: issue.severity, message: issue.message,\n });\n }\n }\n\n const currentIssues = new Map<string, CheckIssueDiff>();\n for (const [pkg, pkgData] of Object.entries(currentCheck.packages)) {\n for (const issue of pkgData.issues ?? []) {\n const key = issueKey(pkg, issue.check, issue.message);\n currentIssues.set(key, {\n pkg, check: issue.check, status: 'new', severity: issue.severity, message: issue.message,\n });\n }\n }\n\n const newIssues: CheckIssueDiff[] = [];\n const fixedIssues: CheckIssueDiff[] = [];\n const persistingIssues: CheckIssueDiff[] = [];\n\n for (const [key, issue] of currentIssues) {\n if (baselineIssues.has(key)) {\n persistingIssues.push({ ...issue, status: 'persisting' });\n } else {\n newIssues.push({ ...issue, status: 'new' });\n }\n }\n for (const [key, issue] of baselineIssues) {\n if (!currentIssues.has(key)) {\n fixedIssues.push({ ...issue, status: 'fixed' });\n }\n }\n\n return {\n newIssues,\n fixedIssues,\n persistingIssues,\n newIssueCount: newIssues.length,\n fixedIssueCount: fixedIssues.length,\n scoreDelta: currentStats.score - baseline.stats.score,\n gradeDelta: `${baseline.stats.grade} → ${currentStats.grade}`,\n };\n}\n","import type { RunSnapshot, PackageTimeline, PackageTaskHistory } from '@kb-labs/qa-contracts';\n\nexport function buildPackageTimeline(\n history: RunSnapshot[],\n packageName: string,\n): PackageTimeline {\n const entries: PackageTaskHistory[] = [];\n\n for (const snap of [...history].reverse()) {\n for (const r of snap.raw.results.filter(r => r.Package === packageName)) {\n entries.push({\n timestamp: snap.timestamp,\n gitCommit: snap.git?.commit ?? 'unknown',\n task: r.Task,\n status: r.Cached ? 'cached' : r.OK ? 'passed' : 'failed',\n });\n }\n }\n\n const taskNames = [...new Set(entries.map(e => e.task))];\n let totalFlips = 0;\n let totalTransitions = 0;\n const flakyTasks: string[] = [];\n\n for (const task of taskNames) {\n const taskEntries = entries.filter(e => e.task === task && e.status !== 'cached');\n let flips = 0;\n for (let i = 1; i < taskEntries.length; i++) {\n totalTransitions++;\n if (taskEntries[i]!.status !== taskEntries[i - 1]!.status) {\n flips++;\n totalFlips++;\n }\n }\n if (taskEntries.length > 1 && flips / (taskEntries.length - 1) > 0.3) {\n flakyTasks.push(task);\n }\n }\n\n const flakyScore = totalTransitions > 0\n ? Math.round((totalFlips / totalTransitions) * 100) / 100\n : 0;\n\n const latest = entries[0];\n let streakStatus: 'passing' | 'failing' = 'passing';\n let streakCount = 0;\n\n if (latest) {\n streakStatus = latest.status === 'failed' ? 'failing' : 'passing';\n streakCount = 1;\n for (let i = 1; i < entries.length; i++) {\n const s = entries[i]!.status === 'failed' ? 'failing' : 'passing';\n if (s !== streakStatus) {break;}\n streakCount++;\n }\n }\n\n let firstFailure: string | undefined;\n for (const e of [...entries].reverse()) {\n if (e.status === 'failed') {\n firstFailure = e.timestamp;\n break;\n }\n }\n\n return {\n packageName,\n history: entries,\n flakyScore,\n flakyTasks,\n currentStreak: { status: streakStatus, count: streakCount },\n firstFailure,\n };\n}\n","import type {\n E2eFlakySnapshot,\n E2eCaseResult,\n E2eErrorCategory,\n CaseHistoryEntry,\n CaseTimeline,\n FlakyOverview,\n FlakyOverviewEntry,\n} from '@kb-labs/qa-contracts';\nimport { TRENDS_WINDOW } from '@kb-labs/qa-contracts';\n\nexport function caseKeyOf(caseResult: Pick<E2eCaseResult, 'suite' | 'spec' | 'testId'>): string {\n return `${caseResult.suite}/${caseResult.spec}#${caseResult.testId}`;\n}\n\nfunction lastErrorOf(caseResult: E2eCaseResult): { category?: E2eErrorCategory; message?: string } {\n const failedAttempt = [...caseResult.attempts].reverse().find(a => a.status === 'failed');\n return { category: failedAttempt?.errorCategory, message: failedAttempt?.errorMessage };\n}\n\nexport function buildCaseTimeline(\n history: E2eFlakySnapshot[],\n caseKey: string,\n): CaseTimeline | null {\n const entries: CaseHistoryEntry[] = [];\n let suite = '';\n let spec = '';\n let testId = '';\n let title = '';\n\n for (const snap of [...history].reverse()) {\n const match = snap.cases.find(c => caseKeyOf(c) === caseKey);\n if (!match) {continue;}\n suite = match.suite;\n spec = match.spec;\n testId = match.testId;\n title = match.title;\n const { category, message } = lastErrorOf(match);\n entries.push({\n timestamp: snap.timestamp,\n gitCommit: snap.git?.commit ?? 'unknown',\n status: match.outcome,\n retries: match.attempts.length > 0 ? match.attempts.length - 1 : 0,\n errorCategory: category,\n errorMessage: message,\n });\n }\n\n if (entries.length === 0) {return null;}\n\n const nonSkipped = entries.filter(e => e.status !== 'skipped');\n let flips = 0;\n for (let i = 1; i < nonSkipped.length; i++) {\n if (nonSkipped[i]!.status !== nonSkipped[i - 1]!.status) {flips++;}\n }\n const flakyScore = nonSkipped.length > 1\n ? Math.round((flips / (nonSkipped.length - 1)) * 100) / 100\n : 0;\n\n // Uses nonSkipped (not entries) so a run of 'skipped' outcomes doesn't\n // fabricate a passing streak — same exclusion flakyScore applies above.\n const latest = nonSkipped[0];\n let streakStatus: 'passing' | 'failing' = 'passing';\n let streakCount = 0;\n if (latest) {\n streakStatus = latest.status === 'failed' ? 'failing' : 'passing';\n streakCount = 1;\n for (let i = 1; i < nonSkipped.length; i++) {\n const s = nonSkipped[i]!.status === 'failed' ? 'failing' : 'passing';\n if (s !== streakStatus) {break;}\n streakCount++;\n }\n }\n\n let firstFailure: string | undefined;\n for (const e of [...entries].reverse()) {\n if (e.status === 'failed' || e.status === 'flaky') {\n firstFailure = e.timestamp;\n break;\n }\n }\n\n return {\n caseKey,\n suite,\n spec,\n testId,\n title,\n history: entries,\n flakyScore,\n currentStreak: { status: streakStatus, count: streakCount },\n firstFailure,\n };\n}\n\nexport function analyzeFlakyCases(\n history: E2eFlakySnapshot[],\n window: number = TRENDS_WINDOW,\n): FlakyOverview {\n const windowSnaps = history.slice(-window);\n if (windowSnaps.length === 0) {\n return {\n window,\n runsAnalyzed: 0,\n totalCases: 0,\n flakyCases: 0,\n delta: { new: [], fixed: [], unchanged: [] },\n byCategory: { 'infra-timeout': 0, 'assertion-race': 0, 'ws-flake': 0, unknown: 0 },\n top: [],\n };\n }\n\n const caseKeys = new Set<string>();\n for (const snap of windowSnaps) {\n for (const c of snap.cases) {caseKeys.add(caseKeyOf(c));}\n }\n\n const byCategory: Record<E2eErrorCategory, number> = {\n 'infra-timeout': 0,\n 'assertion-race': 0,\n 'ws-flake': 0,\n unknown: 0,\n };\n const flakyEntries: FlakyOverviewEntry[] = [];\n const flakyNowKeys = new Set<string>();\n\n for (const key of caseKeys) {\n const timeline = buildCaseTimeline(windowSnaps, key);\n if (!timeline || timeline.flakyScore === 0) {continue;}\n\n flakyNowKeys.add(key);\n const category = timeline.history[0]?.errorCategory ?? 'unknown';\n byCategory[category]++;\n flakyEntries.push({\n case: key,\n flakyScore: timeline.flakyScore,\n streak: `${timeline.currentStreak.status} x${timeline.currentStreak.count}`,\n category,\n });\n }\n\n flakyEntries.sort((a, b) => b.flakyScore - a.flakyScore);\n\n const previousSnaps = history.slice(-2 * window, -window);\n // Collect previous-window keys independently of `caseKeys` (current window)\n // — a case that was flaky before but has since disappeared entirely (spec\n // renamed/deleted) must still be checkable, or it can never show up as \"fixed\".\n const previousCaseKeys = new Set<string>();\n for (const snap of previousSnaps) {\n for (const c of snap.cases) {previousCaseKeys.add(caseKeyOf(c));}\n }\n const flakyPreviousKeys = new Set<string>();\n for (const key of previousCaseKeys) {\n const timeline = buildCaseTimeline(previousSnaps, key);\n if (timeline && timeline.flakyScore > 0) {flakyPreviousKeys.add(key);}\n }\n\n const delta = {\n new: [...flakyNowKeys].filter(k => !flakyPreviousKeys.has(k)),\n fixed: [...flakyPreviousKeys].filter(k => !flakyNowKeys.has(k)),\n unchanged: [...flakyNowKeys].filter(k => flakyPreviousKeys.has(k)),\n };\n\n return {\n window,\n runsAnalyzed: windowSnaps.length,\n totalCases: caseKeys.size,\n flakyCases: flakyNowKeys.size,\n delta,\n byCategory,\n top: flakyEntries.slice(0, 5),\n };\n}\n","import type {\n RunSnapshot,\n CheckSnapshot,\n StatsSnapshot,\n TrendAnalysis,\n RegressionDetection,\n BaselineData,\n BaselineCheckDiff,\n} from '@kb-labs/qa-contracts';\n\nexport interface ReportSection {\n header: string;\n lines: string[];\n}\n\nexport function formatTaskName(task: string): string {\n return task\n .split(/[-_]/)\n .map(w => w.charAt(0).toUpperCase() + w.slice(1))\n .join(' ');\n}\n\nexport function buildRunReport(snap: RunSnapshot | null): ReportSection[] {\n if (!snap) {return [{ header: 'Run', lines: ['No run data available.'] }];}\n\n const sections: ReportSection[] = [];\n const tasks = [...new Set(snap.raw.results.map(r => r.Task))];\n\n for (const task of tasks) {\n const results = snap.raw.results.filter(r => r.Task === task);\n const passed = results.filter(r => r.OK && !r.Cached).length;\n const failed = results.filter(r => !r.OK && !r.Cached).length;\n const cached = results.filter(r => r.Cached).length;\n const failedPkgs = results.filter(r => !r.OK && !r.Cached).map(r => r.Package);\n\n const lines: string[] = [`pass ${passed} fail ${failed} cached ${cached}`];\n if (failedPkgs.length > 0) {\n const shown = failedPkgs.slice(0, 5);\n lines.push(...shown.map(p => ` ✗ ${p}`));\n if (failedPkgs.length > 5) {lines.push(` ... ${failedPkgs.length - 5} more`);}\n }\n\n sections.push({ header: formatTaskName(task), lines });\n }\n\n const status = snap.raw.ok ? 'passed' : 'failed';\n const { total, passed: p, failed: f, cached: c } = snap.raw.summary;\n sections.push({\n header: 'Summary',\n lines: [`${status.toUpperCase()} total ${total} pass ${p} fail ${f} cached ${c} (${snap.raw.elapsed})`],\n });\n\n return sections;\n}\n\nexport function buildCheckReport(snap: CheckSnapshot | null): ReportSection[] {\n if (!snap) {return [{ header: 'Check', lines: ['No check data available.'] }];}\n\n const sections: ReportSection[] = [];\n\n for (const [pkg, pkgData] of Object.entries(snap.raw.packages)) {\n const issues = pkgData.issues ?? [];\n if (issues.length === 0) {continue;}\n\n const errors = issues.filter(i => i.severity === 'error').length;\n const warnings = issues.filter(i => i.severity === 'warning').length;\n const infos = issues.filter(i => i.severity === 'info').length;\n\n const lines: string[] = [`errors ${errors} warnings ${warnings} info ${infos}`];\n for (const issue of issues.slice(0, 5)) {\n lines.push(` [${issue.severity}] ${issue.check}: ${issue.message}`);\n }\n if (issues.length > 5) {lines.push(` ... ${issues.length - 5} more`);}\n\n sections.push({ header: pkg, lines });\n }\n\n if (sections.length === 0) {\n sections.push({ header: 'Check', lines: ['All packages OK.'] });\n }\n\n return sections;\n}\n\nexport function buildStatsReport(snap: StatsSnapshot | null): ReportSection[] {\n if (!snap) {return [{ header: 'Stats', lines: ['No stats data available.'] }];}\n\n const { score, grade, summary, by_category, coverage } = snap.raw;\n\n const sections: ReportSection[] = [];\n\n sections.push({\n header: 'Score',\n lines: [`${score}/100 Grade: ${grade} (${summary.healthy} healthy / ${summary.warning} warning / ${summary.error} error)`],\n });\n\n const catLines = Object.entries(by_category).map(([cat, data]) => {\n const pct = data.total > 0 ? Math.round((data.healthy / data.total) * 100) : 0;\n return ` ${cat.padEnd(20)} ${data.grade} ${pct}% (${data.healthy}/${data.total})`;\n });\n sections.push({ header: 'By Category', lines: catLines });\n\n if (Object.keys(coverage).length > 0) {\n const covLines = Object.entries(coverage).map(([k, v]) => ` ${k.padEnd(20)} ${v.pct}% (${v.pass}/${v.total})`);\n sections.push({ header: 'Coverage', lines: covLines });\n }\n\n return sections;\n}\n\nexport function buildHistoryTable(history: RunSnapshot[], limit = 20): ReportSection[] {\n const rows = [...history].reverse().slice(0, limit);\n if (rows.length === 0) {return [{ header: 'History', lines: ['No history available.'] }];}\n\n const lines = rows.map(snap => {\n const status = snap.raw.ok ? 'pass' : 'fail';\n const tasks = snap.tasks.join(', ');\n const commit = snap.git?.commit ?? '-------';\n const date = new Date(snap.timestamp).toLocaleString();\n return ` ${date} ${commit} ${status} [${tasks}]`;\n });\n\n return [{ header: `History (last ${rows.length})`, lines }];\n}\n\nexport function buildTrendsReport(analysis: TrendAnalysis): ReportSection[] {\n if (analysis.tasks.length === 0) {\n return [{ header: 'Trends', lines: ['Not enough history for trend analysis.'] }];\n }\n\n const sections: ReportSection[] = [];\n\n for (const trend of analysis.tasks) {\n const arrow = trend.direction === 'regression' ? '↑' : trend.direction === 'improvement' ? '↓' : '→';\n const lines: string[] = [\n `${arrow} ${trend.direction} prev ${trend.previous} curr ${trend.current} delta ${trend.delta > 0 ? '+' : ''}${trend.delta} velocity ${trend.velocity}`,\n ];\n\n if (trend.changelog.length > 0) {\n const last = trend.changelog[trend.changelog.length - 1]!;\n if (last.newFailures.length > 0) {lines.push(` last regression: ${last.newFailures.slice(0, 3).join(', ')}`);}\n if (last.fixed.length > 0) {lines.push(` last fixed: ${last.fixed.slice(0, 3).join(', ')}`);}\n }\n\n sections.push({ header: formatTaskName(trend.task), lines });\n }\n\n return sections;\n}\n\nexport function buildRegressionsReport(detection: RegressionDetection): ReportSection[] {\n if (!detection.hasRegressions) {\n return [{ header: 'Regressions', lines: ['No regressions detected.'] }];\n }\n\n const sections: ReportSection[] = [];\n\n for (const reg of detection.regressions) {\n const lines = [\n `delta +${reg.delta}`,\n ...reg.newFailures.slice(0, 5).map(p => ` ✗ ${p}`),\n ];\n if (reg.newFailures.length > 5) {lines.push(` ... ${reg.newFailures.length - 5} more`);}\n sections.push({ header: formatTaskName(reg.task), lines });\n }\n\n const prev = new Date(detection.comparedAt.previous).toLocaleString();\n const curr = new Date(detection.comparedAt.current).toLocaleString();\n sections.push({ header: 'Compared', lines: [`${prev} → ${curr}`] });\n\n return sections;\n}\n\nexport function buildBaselineReport(baseline: BaselineData | null): ReportSection[] {\n if (!baseline) {return [{ header: 'Baseline', lines: ['No baseline set. Run `qa baseline update` to set one.'] }];}\n\n const { score, grade } = baseline.stats;\n const totalIssues = Object.values(baseline.check.packages)\n .reduce((sum, pkg) => sum + (pkg.issues?.length ?? 0), 0);\n const commit = baseline.git?.commit ?? 'unknown';\n const date = new Date(baseline.timestamp).toLocaleString();\n\n return [{\n header: 'Baseline',\n lines: [`score ${score}/100 grade ${grade} issues ${totalIssues} commit ${commit} set ${date}`],\n }];\n}\n\nexport function buildBaselineDiffReport(diff: BaselineCheckDiff): ReportSection[] {\n const sections: ReportSection[] = [];\n\n const scoreDir = diff.scoreDelta > 0 ? '+' : '';\n sections.push({\n header: 'Score Delta',\n lines: [`${scoreDir}${diff.scoreDelta} ${diff.gradeDelta} new ${diff.newIssueCount} fixed ${diff.fixedIssueCount}`],\n });\n\n if (diff.newIssues.length > 0) {\n const lines = diff.newIssues.slice(0, 10).map(i => ` [${i.severity}] ${i.pkg} ${i.check}: ${i.message}`);\n if (diff.newIssues.length > 10) {lines.push(` ... ${diff.newIssues.length - 10} more`);}\n sections.push({ header: 'New Issues', lines });\n }\n\n if (diff.fixedIssues.length > 0) {\n const lines = diff.fixedIssues.slice(0, 10).map(i => ` [${i.severity}] ${i.pkg} ${i.check}: ${i.message}`);\n if (diff.fixedIssues.length > 10) {lines.push(` ... ${diff.fixedIssues.length - 10} more`);}\n sections.push({ header: 'Fixed Issues', lines });\n }\n\n if (diff.persistingIssues.length > 0) {\n sections.push({ header: 'Persisting Issues', lines: [`${diff.persistingIssues.length} issues unchanged`] });\n }\n\n return sections;\n}\n","import type { RunSnapshot, CheckSnapshot, StatsSnapshot } from '@kb-labs/qa-contracts';\n\nexport function buildRunJsonReport(snap: RunSnapshot): object {\n return {\n id: snap.id,\n timestamp: snap.timestamp,\n git: snap.git,\n durationMs: snap.durationMs,\n tasks: snap.tasks,\n ok: snap.raw.ok,\n elapsed: snap.raw.elapsed,\n summary: snap.raw.summary,\n results: snap.raw.results,\n };\n}\n\nexport function buildCheckJsonReport(snap: CheckSnapshot): object {\n return {\n id: snap.id,\n timestamp: snap.timestamp,\n git: snap.git,\n durationMs: snap.durationMs,\n ok: snap.raw.ok,\n packages: snap.raw.packages,\n };\n}\n\nexport function buildStatsJsonReport(snap: StatsSnapshot): object {\n return {\n id: snap.id,\n timestamp: snap.timestamp,\n git: snap.git,\n durationMs: snap.durationMs,\n ok: snap.raw.ok,\n score: snap.raw.score,\n grade: snap.raw.grade,\n summary: snap.raw.summary,\n by_category: snap.raw.by_category,\n issues_by_type: snap.raw.issues_by_type,\n coverage: snap.raw.coverage,\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kb-labs/qa-core",
|
|
3
3
|
"description": "Core business logic for KB Labs QA Plugin — runner, baseline, history, and reporting.",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.100.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@kb-labs/sdk": "2.22.0",
|
|
26
|
-
"@kb-labs/qa-contracts": "2.
|
|
26
|
+
"@kb-labs/qa-contracts": "2.100.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/node": "^24.3.3",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"tsup": "^8.5.0",
|
|
33
33
|
"typescript": "^5.6.3",
|
|
34
34
|
"vitest": "^3.2.6",
|
|
35
|
-
"@kb-labs/devkit": "2.
|
|
35
|
+
"@kb-labs/devkit": "2.100.0"
|
|
36
36
|
},
|
|
37
37
|
"engines": {
|
|
38
38
|
"node": ">=20.0.0",
|