@kb-labs/qa-entry 2.93.0 → 2.96.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/cli/commands/baseline-diff.d.ts +14 -0
- package/dist/cli/commands/baseline-diff.js +40 -0
- package/dist/cli/commands/baseline-diff.js.map +1 -0
- package/dist/cli/commands/baseline-status.d.ts +10 -5
- package/dist/cli/commands/baseline-status.js +14 -17
- package/dist/cli/commands/baseline-status.js.map +1 -1
- package/dist/cli/commands/baseline-update.d.ts +10 -5
- package/dist/cli/commands/baseline-update.js +26 -18
- package/dist/cli/commands/baseline-update.js.map +1 -1
- package/dist/cli/commands/flags.d.ts +117 -132
- package/dist/cli/commands/flags.js +65 -79
- package/dist/cli/commands/flags.js.map +1 -1
- package/dist/cli/commands/qa-check.d.ts +13 -34
- package/dist/cli/commands/qa-check.js +26 -106
- package/dist/cli/commands/qa-check.js.map +1 -1
- package/dist/cli/commands/qa-gate.d.ts +19 -0
- package/dist/cli/commands/qa-gate.js +36 -0
- package/dist/cli/commands/qa-gate.js.map +1 -0
- package/dist/cli/commands/qa-history.d.ts +15 -5
- package/dist/cli/commands/qa-history.js +13 -24
- package/dist/cli/commands/qa-history.js.map +1 -1
- package/dist/cli/commands/qa-regressions.d.ts +10 -5
- package/dist/cli/commands/qa-regressions.js +15 -18
- package/dist/cli/commands/qa-regressions.js.map +1 -1
- package/dist/cli/commands/qa-run.d.ts +18 -11
- package/dist/cli/commands/qa-run.js +28 -141
- package/dist/cli/commands/qa-run.js.map +1 -1
- package/dist/cli/commands/qa-stats.d.ts +19 -0
- package/dist/cli/commands/qa-stats.js +43 -0
- package/dist/cli/commands/qa-stats.js.map +1 -0
- package/dist/cli/commands/qa-trends.d.ts +15 -5
- package/dist/cli/commands/qa-trends.js +15 -18
- package/dist/cli/commands/qa-trends.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +143 -291
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +74 -106
- package/dist/manifest.js +143 -291
- package/dist/manifest.js.map +1 -1
- package/dist/rest/handlers/baseline-diff-handler.d.ts +7 -27
- package/dist/rest/handlers/baseline-diff-handler.js +15 -41
- package/dist/rest/handlers/baseline-diff-handler.js.map +1 -1
- package/dist/rest/handlers/baseline-handler.d.ts +3 -13
- package/dist/rest/handlers/baseline-handler.js +10 -5
- package/dist/rest/handlers/baseline-handler.js.map +1 -1
- package/dist/rest/handlers/baseline-update-handler.d.ts +4 -14
- package/dist/rest/handlers/baseline-update-handler.js +15 -13
- package/dist/rest/handlers/baseline-update-handler.js.map +1 -1
- package/dist/rest/handlers/check-handler.d.ts +15 -0
- package/dist/rest/handlers/check-handler.js +28 -0
- package/dist/rest/handlers/check-handler.js.map +1 -0
- package/dist/rest/handlers/gate-handler.d.ts +13 -0
- package/dist/rest/handlers/gate-handler.js +28 -0
- package/dist/rest/handlers/gate-handler.js.map +1 -0
- package/dist/rest/handlers/history-handler.d.ts +3 -16
- package/dist/rest/handlers/history-handler.js +10 -11
- package/dist/rest/handlers/history-handler.js.map +1 -1
- package/dist/rest/handlers/package-timeline-handler.d.ts +5 -20
- package/dist/rest/handlers/package-timeline-handler.js +11 -7
- package/dist/rest/handlers/package-timeline-handler.js.map +1 -1
- package/dist/rest/handlers/regressions-handler.d.ts +2 -11
- package/dist/rest/handlers/regressions-handler.js +11 -5
- package/dist/rest/handlers/regressions-handler.js.map +1 -1
- package/dist/rest/handlers/run-handler.d.ts +10 -27
- package/dist/rest/handlers/run-handler.js +18 -63
- package/dist/rest/handlers/run-handler.js.map +1 -1
- package/dist/rest/handlers/{error-groups-handler.d.ts → stats-handler.d.ts} +5 -9
- package/dist/rest/handlers/stats-handler.js +21 -0
- package/dist/rest/handlers/stats-handler.js.map +1 -0
- package/dist/rest/handlers/summary-handler.d.ts +7 -20
- package/dist/rest/handlers/summary-handler.js +16 -26
- package/dist/rest/handlers/summary-handler.js.map +1 -1
- package/dist/rest/handlers/tasks-handler.d.ts +9 -0
- package/dist/rest/handlers/tasks-handler.js +38 -0
- package/dist/rest/handlers/tasks-handler.js.map +1 -0
- package/dist/rest/handlers/trends-handler.d.ts +4 -43
- package/dist/rest/handlers/trends-handler.js +11 -18
- package/dist/rest/handlers/trends-handler.js.map +1 -1
- package/dist/widgets/117.js +24 -1
- package/dist/widgets/{919.js → 215.js} +1 -1
- package/dist/widgets/370.js +1 -1
- package/dist/widgets/{805.js → 46.js} +92 -92
- package/dist/widgets/50.js +1 -1
- package/dist/widgets/62.js +96 -0
- package/dist/widgets/648.js +1 -0
- package/dist/widgets/669.js +1 -1
- package/dist/widgets/775.js +1 -1
- package/dist/widgets/78.js +1 -0
- package/dist/widgets/823.js +1 -0
- package/dist/widgets/968.js +2 -2
- package/dist/widgets/__federation_expose_QADashboard.js +1 -1
- package/dist/widgets/mf-manifest.json +32 -31
- package/dist/widgets/mf-stats.json +32 -31
- package/dist/widgets/remoteEntry.js +2 -2
- package/package.json +12 -9
- package/dist/cli/commands/qa-save.d.ts +0 -10
- package/dist/cli/commands/qa-save.js +0 -69
- package/dist/cli/commands/qa-save.js.map +0 -1
- package/dist/rest/handlers/details-handler.d.ts +0 -61
- package/dist/rest/handlers/details-handler.js +0 -70
- package/dist/rest/handlers/details-handler.js.map +0 -1
- package/dist/rest/handlers/error-groups-handler.js +0 -17
- package/dist/rest/handlers/error-groups-handler.js.map +0 -1
- package/dist/rest/handlers/latest-handler.d.ts +0 -22
- package/dist/rest/handlers/latest-handler.js +0 -17
- package/dist/rest/handlers/latest-handler.js.map +0 -1
- package/dist/rest/handlers/run-check-handler.d.ts +0 -20
- package/dist/rest/handlers/run-check-handler.js +0 -58
- package/dist/rest/handlers/run-check-handler.js.map +0 -1
- package/dist/widgets/418.js +0 -38
- package/dist/widgets/451.js +0 -1
- package/dist/widgets/694.js +0 -1
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
-
import {
|
|
2
|
+
import { CLIInput } from '@kb-labs/sdk';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<_kb_labs_shared_command_kit.InferFlags<{
|
|
5
|
+
json: {
|
|
6
|
+
type: "boolean";
|
|
7
|
+
description: string;
|
|
8
|
+
default: false;
|
|
9
|
+
};
|
|
10
|
+
}>>, {
|
|
11
|
+
exitCode: number;
|
|
12
|
+
}>;
|
|
8
13
|
|
|
9
14
|
export { _default as default };
|
|
@@ -1,29 +1,26 @@
|
|
|
1
|
-
import { defineCommand } from '@kb-labs/sdk';
|
|
2
|
-
import {
|
|
1
|
+
import { defineCommand, useConfig } from '@kb-labs/sdk';
|
|
2
|
+
import { SnapshotStore, detectRegressions, buildRegressionsReport } from '@kb-labs/qa-core';
|
|
3
3
|
|
|
4
4
|
// src/cli/commands/qa-regressions.ts
|
|
5
5
|
var qa_regressions_default = defineCommand({
|
|
6
6
|
id: "qa:regressions",
|
|
7
|
-
description: "Detect regressions since last
|
|
7
|
+
description: "Detect regressions since last run",
|
|
8
8
|
handler: {
|
|
9
9
|
async execute(ctx, input) {
|
|
10
|
-
const {
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
10
|
+
const { flags } = input;
|
|
11
|
+
const config = await useConfig();
|
|
12
|
+
const cwd = ctx.cwd ?? process.cwd();
|
|
13
|
+
const store = new SnapshotStore(cwd, config?.historyMaxEntries);
|
|
14
|
+
const history = store.loadRunHistory();
|
|
15
|
+
const detection = detectRegressions(history);
|
|
15
16
|
if (flags.json) {
|
|
16
|
-
ui?.json?.(
|
|
17
|
-
|
|
17
|
+
ctx.ui?.json?.(detection);
|
|
18
|
+
} else {
|
|
19
|
+
for (const section of buildRegressionsReport(detection)) {
|
|
20
|
+
ctx.ui?.success?.(`${section.header}`, { sections: [{ items: section.lines }] });
|
|
21
|
+
}
|
|
18
22
|
}
|
|
19
|
-
|
|
20
|
-
for (const section of sections) {
|
|
21
|
-
ui?.success?.(section.header, {
|
|
22
|
-
title: section.header,
|
|
23
|
-
sections: [{ header: "", items: section.lines }]
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
return { exitCode: result.hasRegressions ? 1 : 0 };
|
|
23
|
+
return { exitCode: detection.hasRegressions ? 1 : 0 };
|
|
27
24
|
}
|
|
28
25
|
}
|
|
29
26
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/qa-regressions.ts"],"names":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/qa-regressions.ts"],"names":[],"mappings":";;;;AAcA,IAAO,yBAAQ,aAAA,CAA2E;AAAA,EACxF,EAAA,EAAI,gBAAA;AAAA,EACJ,WAAA,EAAa,mCAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAoE;AACtG,MAAA,MAAM,EAAE,OAAM,GAAI,KAAA;AAClB,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAA0B;AAC/C,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AAEnC,MAAA,MAAM,KAAA,GAAQ,IAAI,aAAA,CAAc,GAAA,EAAK,QAAQ,iBAAiB,CAAA;AAC9D,MAAA,MAAM,OAAA,GAAU,MAAM,cAAA,EAAe;AACrC,MAAA,MAAM,SAAA,GAAY,kBAAkB,OAAO,CAAA;AAE3C,MAAA,IAAI,MAAM,IAAA,EAAM;AACd,QAAA,GAAA,CAAI,EAAA,EAAI,OAAO,SAAS,CAAA;AAAA,MAC1B,CAAA,MAAO;AACL,QAAA,KAAA,MAAW,OAAA,IAAW,sBAAA,CAAuB,SAAS,CAAA,EAAG;AACvD,UAAA,GAAA,CAAI,EAAA,EAAI,OAAA,GAAU,CAAA,EAAG,OAAA,CAAQ,MAAM,CAAA,CAAA,EAAI,EAAE,QAAA,EAAU,CAAC,EAAE,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA;AAAA,QACjF;AAAA,MACF;AAEA,MAAA,OAAO,EAAE,QAAA,EAAU,SAAA,CAAU,cAAA,GAAiB,IAAI,CAAA,EAAE;AAAA,IACtD;AAAA;AAEJ,CAAC","file":"qa-regressions.js","sourcesContent":["import {\n defineCommand,\n useConfig,\n type CLIInput,\n type PluginContextV3,\n} from '@kb-labs/sdk';\nimport {\n SnapshotStore,\n detectRegressions,\n buildRegressionsReport,\n} from '@kb-labs/qa-core';\nimport { type QAPluginConfig } from '@kb-labs/qa-contracts';\nimport type { QaRegressionsFlags } from './flags.js';\n\nexport default defineCommand<unknown, CLIInput<QaRegressionsFlags>, { exitCode: number }>({\n id: 'qa:regressions',\n description: 'Detect regressions since last run',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<QaRegressionsFlags>): Promise<{ exitCode: number }> {\n const { flags } = input;\n const config = await useConfig<QAPluginConfig>();\n const cwd = ctx.cwd ?? process.cwd();\n\n const store = new SnapshotStore(cwd, config?.historyMaxEntries);\n const history = store.loadRunHistory();\n const detection = detectRegressions(history);\n\n if (flags.json) {\n ctx.ui?.json?.(detection);\n } else {\n for (const section of buildRegressionsReport(detection)) {\n ctx.ui?.success?.(`${section.header}`, { sections: [{ items: section.lines }] });\n }\n }\n\n return { exitCode: detection.hasRegressions ? 1 : 0 };\n },\n },\n});\n"]}
|
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
2
|
import { CLIInput } from '@kb-labs/sdk';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
4
|
+
declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<_kb_labs_shared_command_kit.InferFlags<{
|
|
5
|
+
tasks: {
|
|
6
|
+
type: "string";
|
|
7
|
+
description: string;
|
|
8
|
+
};
|
|
9
|
+
save: {
|
|
10
|
+
type: "boolean";
|
|
11
|
+
description: string;
|
|
12
|
+
default: true;
|
|
13
|
+
};
|
|
14
|
+
json: {
|
|
15
|
+
type: "boolean";
|
|
16
|
+
description: string;
|
|
17
|
+
default: false;
|
|
18
|
+
};
|
|
19
|
+
}>>, {
|
|
20
|
+
exitCode: number;
|
|
21
|
+
}>;
|
|
15
22
|
|
|
16
23
|
export { _default as default };
|
|
@@ -1,155 +1,42 @@
|
|
|
1
1
|
import { defineCommand, useConfig } from '@kb-labs/sdk';
|
|
2
|
-
import {
|
|
2
|
+
import { resolveDevkitBin, DevkitAdapter, SnapshotStore, captureGit, buildRunJsonReport, buildRunReport } from '@kb-labs/qa-core';
|
|
3
|
+
import { DEFAULT_TASKS } from '@kb-labs/qa-contracts';
|
|
3
4
|
|
|
4
5
|
// src/cli/commands/qa-run.ts
|
|
5
|
-
var CHECK_ICONS = {
|
|
6
|
-
build: "\u{1F528}",
|
|
7
|
-
lint: "\u{1F50D}",
|
|
8
|
-
typeCheck: "\u{1F4D8}",
|
|
9
|
-
test: "\u{1F9EA}"
|
|
10
|
-
};
|
|
11
|
-
var STATUS_MARKS = {
|
|
12
|
-
pass: "\u2713",
|
|
13
|
-
fail: "\u2717",
|
|
14
|
-
skip: "\u2212"
|
|
15
|
-
};
|
|
16
6
|
var qa_run_default = defineCommand({
|
|
17
7
|
id: "qa:run",
|
|
18
|
-
description: "Run
|
|
8
|
+
description: "Run devkit tasks and record results",
|
|
19
9
|
handler: {
|
|
20
10
|
async execute(ctx, input) {
|
|
21
|
-
const { ui } = ctx;
|
|
22
11
|
const { flags } = input;
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
scope: scopeKey
|
|
46
|
-
}, config?.packages);
|
|
47
|
-
totalPkgs = pkgs.length;
|
|
48
|
-
} catch {
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
const counters = {};
|
|
52
|
-
let currentPhase = "";
|
|
53
|
-
const startTime = Date.now();
|
|
54
|
-
const { results, packages } = await runQA({
|
|
55
|
-
rootDir,
|
|
56
|
-
skipChecks,
|
|
57
|
-
noCache: !!flags["no-cache"],
|
|
58
|
-
package: flags.package,
|
|
59
|
-
repo: flags.repo,
|
|
60
|
-
scope: scopeKey,
|
|
61
|
-
packagesConfig: config?.packages,
|
|
62
|
-
checks,
|
|
63
|
-
onProgress: (phase, pkg, status, durationMs2) => {
|
|
64
|
-
if (isJson) {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
if (phase !== currentPhase) {
|
|
68
|
-
currentPhase = phase;
|
|
69
|
-
counters[phase] = 0;
|
|
70
|
-
const phaseIcon = CHECK_ICONS[phase] ?? "\u25B8";
|
|
71
|
-
const elapsed = ((Date.now() - startTime) / 1e3).toFixed(0);
|
|
72
|
-
process.stdout.write(`
|
|
73
|
-
${phaseIcon} ${phase} (${elapsed}s elapsed)
|
|
74
|
-
`);
|
|
75
|
-
}
|
|
76
|
-
counters[phase] = (counters[phase] ?? 0) + 1;
|
|
77
|
-
const count = counters[phase];
|
|
78
|
-
const total = totalPkgs || "?";
|
|
79
|
-
const mark = STATUS_MARKS[status] ?? status;
|
|
80
|
-
const time = durationMs2 != null ? ` (${(durationMs2 / 1e3).toFixed(1)}s)` : "";
|
|
81
|
-
process.stdout.write(` [${count}/${total}] ${pkg} ${mark}${time}
|
|
82
|
-
`);
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
const durationMs = Date.now() - startTime;
|
|
86
|
-
if (!isJson) {
|
|
87
|
-
const elapsed = (durationMs / 1e3).toFixed(1);
|
|
88
|
-
process.stdout.write(`
|
|
89
|
-
Completed in ${elapsed}s
|
|
90
|
-
|
|
91
|
-
`);
|
|
92
|
-
}
|
|
93
|
-
const analytics = ctx.platform.analytics;
|
|
94
|
-
if (analytics) {
|
|
95
|
-
const hasFails2 = Object.values(results).some((r) => r.failed.length > 0);
|
|
96
|
-
for (const ct of Object.keys(results)) {
|
|
97
|
-
const r = results[ct];
|
|
98
|
-
await analytics.track("qa.check.completed", {
|
|
99
|
-
checkType: ct,
|
|
100
|
-
status: r.failed.length > 0 ? "failed" : "passed",
|
|
101
|
-
passed: r.passed.length,
|
|
102
|
-
failed: r.failed.length,
|
|
103
|
-
skipped: r.skipped.length
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
const checkKeys = Object.keys(results);
|
|
107
|
-
await analytics.track("qa.run.completed", {
|
|
108
|
-
status: hasFails2 ? "failed" : "passed",
|
|
109
|
-
...Object.fromEntries(checkKeys.flatMap((ct) => [
|
|
110
|
-
[`${ct}Passed`, results[ct].passed.length],
|
|
111
|
-
[`${ct}Failed`, results[ct].failed.length]
|
|
112
|
-
])),
|
|
113
|
-
totalPassed: checkKeys.reduce((s, ct) => s + results[ct].passed.length, 0),
|
|
114
|
-
totalFailed: checkKeys.reduce((s, ct) => s + results[ct].failed.length, 0),
|
|
115
|
-
totalSkipped: checkKeys.reduce((s, ct) => s + results[ct].skipped.length, 0),
|
|
116
|
-
durationMs
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
const baseline = loadBaseline(rootDir);
|
|
120
|
-
const diff = baseline ? compareWithBaseline(results, baseline) : null;
|
|
121
|
-
const categoryMap = resolveCategories(packages, config);
|
|
122
|
-
const grouped = groupResults(results, packages, categoryMap, config);
|
|
123
|
-
if (isJson) {
|
|
124
|
-
const report = buildDetailedJsonReport(results, grouped, diff);
|
|
125
|
-
ui?.json?.({ ...report, skippedChecks: skipChecks });
|
|
126
|
-
return { exitCode: report.status === "failed" ? 1 : 0 };
|
|
127
|
-
}
|
|
128
|
-
if (skipChecks.length > 0) {
|
|
129
|
-
ui?.success?.("Skipped checks", {
|
|
130
|
-
title: "Skipped checks",
|
|
131
|
-
sections: [{ header: "", items: skipChecks.map((c) => ` - ${c}`) }]
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
if (flags.summary) {
|
|
135
|
-
const sections = buildRunReport(results, diff);
|
|
136
|
-
for (const section of sections) {
|
|
137
|
-
ui?.success?.(section.header, {
|
|
138
|
-
title: section.header,
|
|
139
|
-
sections: [{ header: "", items: section.lines }]
|
|
140
|
-
});
|
|
141
|
-
}
|
|
12
|
+
const config = await useConfig();
|
|
13
|
+
const cwd = ctx.cwd ?? process.cwd();
|
|
14
|
+
const binaryPath = resolveDevkitBin(cwd, config?.devkitPath);
|
|
15
|
+
const adapter = new DevkitAdapter({ binaryPath, cwd, shell: ctx.api.shell });
|
|
16
|
+
const store = new SnapshotStore(cwd, config?.historyMaxEntries);
|
|
17
|
+
const tasks = flags.tasks ? flags.tasks.split(",").map((s) => s.trim()).filter(Boolean) : config?.defaultTasks?.slice() ?? [...DEFAULT_TASKS];
|
|
18
|
+
const save = flags.save !== false;
|
|
19
|
+
const git = await captureGit(ctx.api.shell, cwd);
|
|
20
|
+
const start = Date.now();
|
|
21
|
+
const raw = await adapter.run(tasks);
|
|
22
|
+
const durationMs = Date.now() - start;
|
|
23
|
+
const snap = save ? store.saveRun(raw, tasks, durationMs, git) : null;
|
|
24
|
+
const effective = snap ?? {
|
|
25
|
+
kind: "run",
|
|
26
|
+
id: "",
|
|
27
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
28
|
+
durationMs,
|
|
29
|
+
tasks,
|
|
30
|
+
raw
|
|
31
|
+
};
|
|
32
|
+
if (flags.json) {
|
|
33
|
+
ctx.ui?.json?.(buildRunJsonReport(effective));
|
|
142
34
|
} else {
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
ui?.success?.(section.header, {
|
|
146
|
-
title: section.header,
|
|
147
|
-
sections: [{ header: "", items: section.lines }]
|
|
148
|
-
});
|
|
35
|
+
for (const section of buildRunReport(effective)) {
|
|
36
|
+
ctx.ui?.success?.(`${section.header}`, { sections: [{ items: section.lines }] });
|
|
149
37
|
}
|
|
150
38
|
}
|
|
151
|
-
|
|
152
|
-
return { exitCode: hasFails ? 1 : 0 };
|
|
39
|
+
return { exitCode: raw.ok ? 0 : 1 };
|
|
153
40
|
}
|
|
154
41
|
}
|
|
155
42
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/qa-run.ts"],"names":["durationMs","hasFails"],"mappings":"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","file":"qa-run.js","sourcesContent":["import { defineCommand, type CLIInput, useConfig, type PluginContextV3 } from '@kb-labs/sdk';\nimport type { QAPluginConfig } from '@kb-labs/qa-contracts';\nimport {\n runQA,\n getWorkspacePackages,\n compareWithBaseline,\n loadBaseline,\n buildDetailedJsonReport,\n buildRunReport,\n buildDetailedRunReport,\n resolveCategories,\n groupResults,\n} from '@kb-labs/qa-core';\n\ninterface QARunFlags {\n json?: boolean;\n 'skip-check'?: string | string[];\n 'no-cache'?: boolean;\n all?: boolean;\n package?: string;\n repo?: string;\n scope?: string;\n summary?: boolean;\n}\n\nconst CHECK_ICONS: Record<string, string> = {\n build: '🔨',\n lint: '🔍',\n typeCheck: '📘',\n test: '🧪',\n};\n\nconst STATUS_MARKS: Record<string, string> = {\n pass: '✓',\n fail: '✗',\n skip: '−',\n};\n\nexport default defineCommand({\n id: 'qa:run',\n description: 'Run all QA checks (build, lint, types, tests)',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<QARunFlags>) {\n const { ui } = ctx;\n const { flags } = input;\n const rootDir = ctx.cwd;\n\n // Load plugin config — needed for package discovery and checks.\n // useConfig() can hang if platform IPC is unavailable, so race with a timeout.\n let config: QAPluginConfig | undefined;\n try {\n config = await Promise.race([\n useConfig<QAPluginConfig>(),\n new Promise<undefined>((resolve) => { setTimeout(() => resolve(undefined), 3000); }),\n ]);\n } catch {\n // Config not available (no platform context) — proceed without config\n }\n\n // Select checks: per-scope override → global checks → built-in runners\n const scopeKey = flags.scope as string | undefined;\n const checks = (scopeKey ? config?.scopes?.[scopeKey]?.checks : undefined)\n ?? config?.checks;\n\n const rawSkip = flags['skip-check'];\n const skipChecks: string[] = Array.isArray(rawSkip)\n ? rawSkip as string[]\n : rawSkip ? [rawSkip as string] : [];\n\n const isJson = !!flags.json;\n\n // Pre-discover packages to get total count for progress display\n let totalPkgs = 0;\n if (!isJson) {\n try {\n const pkgs = getWorkspacePackages(rootDir, {\n package: flags.package as string | undefined,\n repo: flags.repo as string | undefined,\n scope: scopeKey,\n }, config?.packages);\n totalPkgs = pkgs.length;\n } catch {\n // Will be discovered again inside runQA\n }\n }\n\n // Progress tracking for live UI\n const counters: Record<string, number> = {};\n let currentPhase = '';\n\n const startTime = Date.now();\n const { results, packages } = await runQA({\n rootDir,\n skipChecks,\n noCache: !!flags['no-cache'],\n package: flags.package as string | undefined,\n repo: flags.repo as string | undefined,\n scope: scopeKey,\n packagesConfig: config?.packages,\n checks,\n onProgress: (phase, pkg, status, durationMs) => {\n if (isJson) {return;}\n\n // Print phase header on phase change\n if (phase !== currentPhase) {\n currentPhase = phase;\n counters[phase] = 0;\n const phaseIcon = CHECK_ICONS[phase] ?? '▸';\n const elapsed = ((Date.now() - startTime) / 1000).toFixed(0);\n process.stdout.write(`\\n${phaseIcon} ${phase} (${elapsed}s elapsed)\\n`);\n }\n\n counters[phase] = (counters[phase] ?? 0) + 1;\n const count = counters[phase];\n const total = totalPkgs || '?';\n const mark = STATUS_MARKS[status] ?? status;\n const time = durationMs != null ? ` (${(durationMs / 1000).toFixed(1)}s)` : '';\n\n process.stdout.write(` [${count}/${total}] ${pkg} ${mark}${time}\\n`);\n },\n });\n const durationMs = Date.now() - startTime;\n\n if (!isJson) {\n const elapsed = (durationMs / 1000).toFixed(1);\n process.stdout.write(`\\nCompleted in ${elapsed}s\\n\\n`);\n }\n\n // Track analytics events\n const analytics = ctx.platform.analytics;\n if (analytics) {\n const hasFails = Object.values(results).some((r) => r.failed.length > 0);\n for (const ct of Object.keys(results)) {\n const r = results[ct]!;\n await analytics.track('qa.check.completed', {\n checkType: ct,\n status: r.failed.length > 0 ? 'failed' : 'passed',\n passed: r.passed.length,\n failed: r.failed.length,\n skipped: r.skipped.length,\n });\n }\n const checkKeys = Object.keys(results);\n await analytics.track('qa.run.completed', {\n status: hasFails ? 'failed' : 'passed',\n ...Object.fromEntries(checkKeys.flatMap((ct) => [\n [`${ct}Passed`, results[ct]!.passed.length],\n [`${ct}Failed`, results[ct]!.failed.length],\n ])),\n totalPassed: checkKeys.reduce((s, ct) => s + results[ct]!.passed.length, 0),\n totalFailed: checkKeys.reduce((s, ct) => s + results[ct]!.failed.length, 0),\n totalSkipped: checkKeys.reduce((s, ct) => s + results[ct]!.skipped.length, 0),\n durationMs,\n });\n }\n\n // Compare with baseline if available\n const baseline = loadBaseline(rootDir);\n const diff = baseline ? compareWithBaseline(results, baseline) : null;\n\n const categoryMap = resolveCategories(packages, config);\n const grouped = groupResults(results, packages, categoryMap, config);\n\n if (isJson) {\n const report = buildDetailedJsonReport(results, grouped, diff);\n ui?.json?.({ ...report, skippedChecks: skipChecks });\n return { exitCode: report.status === 'failed' ? 1 : 0 };\n }\n\n // Show skipped checks section for easier debugging\n if (skipChecks.length > 0) {\n ui?.success?.('Skipped checks', {\n title: 'Skipped checks',\n sections: [{ header: '', items: skipChecks.map(c => ` - ${c}`) }],\n });\n }\n\n if (flags.summary) {\n // Legacy summary format\n const sections = buildRunReport(results, diff);\n for (const section of sections) {\n ui?.success?.(section.header, {\n title: section.header,\n sections: [{ header: '', items: section.lines }],\n });\n }\n } else {\n // Detailed report grouped by category → repo\n const sections = buildDetailedRunReport(grouped, diff);\n for (const section of sections) {\n ui?.success?.(section.header, {\n title: section.header,\n sections: [{ header: '', items: section.lines }],\n });\n }\n }\n\n const hasFails = Object.values(results).some((r) => r.failed.length > 0);\n return { exitCode: hasFails ? 1 : 0 };\n },\n },\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/qa-run.ts"],"names":[],"mappings":";;;;;AAiBA,IAAO,iBAAQ,aAAA,CAAmE;AAAA,EAChF,EAAA,EAAI,QAAA;AAAA,EACJ,WAAA,EAAa,qCAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAA4D;AAC9F,MAAA,MAAM,EAAE,OAAM,GAAI,KAAA;AAClB,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAA0B;AAC/C,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AAEnC,MAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,GAAA,EAAK,MAAA,EAAQ,UAAU,CAAA;AAC3D,MAAA,MAAM,OAAA,GAAU,IAAI,aAAA,CAAc,EAAE,UAAA,EAAY,KAAK,KAAA,EAAO,GAAA,CAAI,GAAA,CAAI,KAAA,EAAO,CAAA;AAC3E,MAAA,MAAM,KAAA,GAAQ,IAAI,aAAA,CAAc,GAAA,EAAK,QAAQ,iBAAiB,CAAA;AAE9D,MAAA,MAAM,KAAA,GAAkB,MAAM,KAAA,GAC1B,KAAA,CAAM,MAAM,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,MAAM,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,GACxD,MAAA,EAAQ,cAAc,KAAA,EAAM,IAAK,CAAC,GAAG,aAAa,CAAA;AACtD,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,KAAS,KAAA;AAE5B,MAAA,MAAM,MAAM,MAAM,UAAA,CAAW,GAAA,CAAI,GAAA,CAAI,OAAO,GAAG,CAAA;AAE/C,MAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,EAAI;AACvB,MAAA,MAAM,GAAA,GAAM,MAAM,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA;AACnC,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAI,KAAA;AAEhC,MAAA,MAAM,IAAA,GAAO,OAAO,KAAA,CAAM,OAAA,CAAQ,KAAK,KAAA,EAAO,UAAA,EAAY,GAAG,CAAA,GAAI,IAAA;AACjE,MAAA,MAAM,YAAyD,IAAA,IAAQ;AAAA,QACrE,IAAA,EAAM,KAAA;AAAA,QAAO,EAAA,EAAI,EAAA;AAAA,QAAI,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,QAAG,UAAA;AAAA,QAAY,KAAA;AAAA,QAAO;AAAA,OAC/E;AAEA,MAAA,IAAI,MAAM,IAAA,EAAM;AACd,QAAA,GAAA,CAAI,EAAA,EAAI,IAAA,GAAO,kBAAA,CAAmB,SAAS,CAAC,CAAA;AAAA,MAC9C,CAAA,MAAO;AACL,QAAA,KAAA,MAAW,OAAA,IAAW,cAAA,CAAe,SAAS,CAAA,EAAG;AAC/C,UAAA,GAAA,CAAI,EAAA,EAAI,OAAA,GAAU,CAAA,EAAG,OAAA,CAAQ,MAAM,CAAA,CAAA,EAAI,EAAE,QAAA,EAAU,CAAC,EAAE,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA;AAAA,QACjF;AAAA,MACF;AAEA,MAAA,OAAO,EAAE,QAAA,EAAU,GAAA,CAAI,EAAA,GAAK,IAAI,CAAA,EAAE;AAAA,IACpC;AAAA;AAEJ,CAAC","file":"qa-run.js","sourcesContent":["import {\n defineCommand,\n useConfig,\n type CLIInput,\n type PluginContextV3,\n} from '@kb-labs/sdk';\nimport {\n DevkitAdapter,\n SnapshotStore,\n resolveDevkitBin,\n captureGit,\n buildRunReport,\n buildRunJsonReport,\n} from '@kb-labs/qa-core';\nimport { DEFAULT_TASKS, type QAPluginConfig } from '@kb-labs/qa-contracts';\nimport type { QaRunFlags } from './flags.js';\n\nexport default defineCommand<unknown, CLIInput<QaRunFlags>, { exitCode: number }>({\n id: 'qa:run',\n description: 'Run devkit tasks and record results',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<QaRunFlags>): Promise<{ exitCode: number }> {\n const { flags } = input;\n const config = await useConfig<QAPluginConfig>();\n const cwd = ctx.cwd ?? process.cwd();\n\n const binaryPath = resolveDevkitBin(cwd, config?.devkitPath);\n const adapter = new DevkitAdapter({ binaryPath, cwd, shell: ctx.api.shell });\n const store = new SnapshotStore(cwd, config?.historyMaxEntries);\n\n const tasks: string[] = flags.tasks\n ? flags.tasks.split(',').map(s => s.trim()).filter(Boolean)\n : config?.defaultTasks?.slice() ?? [...DEFAULT_TASKS];\n const save = flags.save !== false;\n\n const git = await captureGit(ctx.api.shell, cwd);\n\n const start = Date.now();\n const raw = await adapter.run(tasks);\n const durationMs = Date.now() - start;\n\n const snap = save ? store.saveRun(raw, tasks, durationMs, git) : null;\n const effective: import('@kb-labs/qa-contracts').RunSnapshot = snap ?? {\n kind: 'run', id: '', timestamp: new Date().toISOString(), durationMs, tasks, raw,\n };\n\n if (flags.json) {\n ctx.ui?.json?.(buildRunJsonReport(effective));\n } else {\n for (const section of buildRunReport(effective)) {\n ctx.ui?.success?.(`${section.header}`, { sections: [{ items: section.lines }] });\n }\n }\n\n return { exitCode: raw.ok ? 0 : 1 };\n },\n },\n});\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
+
import { CLIInput } from '@kb-labs/sdk';
|
|
3
|
+
|
|
4
|
+
declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<_kb_labs_shared_command_kit.InferFlags<{
|
|
5
|
+
save: {
|
|
6
|
+
type: "boolean";
|
|
7
|
+
description: string;
|
|
8
|
+
default: true;
|
|
9
|
+
};
|
|
10
|
+
json: {
|
|
11
|
+
type: "boolean";
|
|
12
|
+
description: string;
|
|
13
|
+
default: false;
|
|
14
|
+
};
|
|
15
|
+
}>>, {
|
|
16
|
+
exitCode: number;
|
|
17
|
+
}>;
|
|
18
|
+
|
|
19
|
+
export { _default as default };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { defineCommand, useConfig } from '@kb-labs/sdk';
|
|
2
|
+
import { resolveDevkitBin, DevkitAdapter, SnapshotStore, captureGit, buildStatsJsonReport, buildStatsReport } from '@kb-labs/qa-core';
|
|
3
|
+
|
|
4
|
+
// src/cli/commands/qa-stats.ts
|
|
5
|
+
var qa_stats_default = defineCommand({
|
|
6
|
+
id: "qa:stats",
|
|
7
|
+
description: "Show devkit health score and category breakdown",
|
|
8
|
+
handler: {
|
|
9
|
+
async execute(ctx, input) {
|
|
10
|
+
const { flags } = input;
|
|
11
|
+
const config = await useConfig();
|
|
12
|
+
const cwd = ctx.cwd ?? process.cwd();
|
|
13
|
+
const binaryPath = resolveDevkitBin(cwd, config?.devkitPath);
|
|
14
|
+
const adapter = new DevkitAdapter({ binaryPath, cwd, shell: ctx.api.shell });
|
|
15
|
+
const store = new SnapshotStore(cwd, config?.historyMaxEntries);
|
|
16
|
+
const save = flags.save !== false;
|
|
17
|
+
const git = await captureGit(ctx.api.shell, cwd);
|
|
18
|
+
const start = Date.now();
|
|
19
|
+
const raw = await adapter.stats();
|
|
20
|
+
const durationMs = Date.now() - start;
|
|
21
|
+
const snap = save ? store.saveStats(raw, durationMs, git) : null;
|
|
22
|
+
const effective = snap ?? {
|
|
23
|
+
kind: "stats",
|
|
24
|
+
id: "",
|
|
25
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
26
|
+
durationMs,
|
|
27
|
+
raw
|
|
28
|
+
};
|
|
29
|
+
if (flags.json) {
|
|
30
|
+
ctx.ui?.json?.(buildStatsJsonReport(effective));
|
|
31
|
+
} else {
|
|
32
|
+
for (const section of buildStatsReport(effective)) {
|
|
33
|
+
ctx.ui?.success?.(`${section.header}`, { sections: [{ items: section.lines }] });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return { exitCode: 0 };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export { qa_stats_default as default };
|
|
42
|
+
//# sourceMappingURL=qa-stats.js.map
|
|
43
|
+
//# sourceMappingURL=qa-stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/qa-stats.ts"],"names":[],"mappings":";;;;AAiBA,IAAO,mBAAQ,aAAA,CAAqE;AAAA,EAClF,EAAA,EAAI,UAAA;AAAA,EACJ,WAAA,EAAa,iDAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAA8D;AAChG,MAAA,MAAM,EAAE,OAAM,GAAI,KAAA;AAClB,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAA0B;AAC/C,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AAEnC,MAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,GAAA,EAAK,MAAA,EAAQ,UAAU,CAAA;AAC3D,MAAA,MAAM,OAAA,GAAU,IAAI,aAAA,CAAc,EAAE,UAAA,EAAY,KAAK,KAAA,EAAO,GAAA,CAAI,GAAA,CAAI,KAAA,EAAO,CAAA;AAC3E,MAAA,MAAM,KAAA,GAAQ,IAAI,aAAA,CAAc,GAAA,EAAK,QAAQ,iBAAiB,CAAA;AAE9D,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,KAAS,KAAA;AAC5B,MAAA,MAAM,MAAM,MAAM,UAAA,CAAW,GAAA,CAAI,GAAA,CAAI,OAAO,GAAG,CAAA;AAE/C,MAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,EAAI;AACvB,MAAA,MAAM,GAAA,GAAM,MAAM,OAAA,CAAQ,KAAA,EAAM;AAChC,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAI,KAAA;AAEhC,MAAA,MAAM,OAAO,IAAA,GAAO,KAAA,CAAM,UAAU,GAAA,EAAK,UAAA,EAAY,GAAG,CAAA,GAAI,IAAA;AAC5D,MAAA,MAAM,YAA2D,IAAA,IAAQ;AAAA,QACvE,IAAA,EAAM,OAAA;AAAA,QAAS,EAAA,EAAI,EAAA;AAAA,QAAI,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,QAAG,UAAA;AAAA,QAAY;AAAA,OAC1E;AAEA,MAAA,IAAI,MAAM,IAAA,EAAM;AACd,QAAA,GAAA,CAAI,EAAA,EAAI,IAAA,GAAO,oBAAA,CAAqB,SAAS,CAAC,CAAA;AAAA,MAChD,CAAA,MAAO;AACL,QAAA,KAAA,MAAW,OAAA,IAAW,gBAAA,CAAiB,SAAS,CAAA,EAAG;AACjD,UAAA,GAAA,CAAI,EAAA,EAAI,OAAA,GAAU,CAAA,EAAG,OAAA,CAAQ,MAAM,CAAA,CAAA,EAAI,EAAE,QAAA,EAAU,CAAC,EAAE,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA;AAAA,QACjF;AAAA,MACF;AAEA,MAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,IACvB;AAAA;AAEJ,CAAC","file":"qa-stats.js","sourcesContent":["import {\n defineCommand,\n useConfig,\n type CLIInput,\n type PluginContextV3,\n} from '@kb-labs/sdk';\nimport {\n DevkitAdapter,\n SnapshotStore,\n resolveDevkitBin,\n captureGit,\n buildStatsReport,\n buildStatsJsonReport,\n} from '@kb-labs/qa-core';\nimport { type QAPluginConfig } from '@kb-labs/qa-contracts';\nimport type { QaStatsFlags } from './flags.js';\n\nexport default defineCommand<unknown, CLIInput<QaStatsFlags>, { exitCode: number }>({\n id: 'qa:stats',\n description: 'Show devkit health score and category breakdown',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<QaStatsFlags>): Promise<{ exitCode: number }> {\n const { flags } = input;\n const config = await useConfig<QAPluginConfig>();\n const cwd = ctx.cwd ?? process.cwd();\n\n const binaryPath = resolveDevkitBin(cwd, config?.devkitPath);\n const adapter = new DevkitAdapter({ binaryPath, cwd, shell: ctx.api.shell });\n const store = new SnapshotStore(cwd, config?.historyMaxEntries);\n\n const save = flags.save !== false;\n const git = await captureGit(ctx.api.shell, cwd);\n\n const start = Date.now();\n const raw = await adapter.stats();\n const durationMs = Date.now() - start;\n\n const snap = save ? store.saveStats(raw, durationMs, git) : null;\n const effective: import('@kb-labs/qa-contracts').StatsSnapshot = snap ?? {\n kind: 'stats', id: '', timestamp: new Date().toISOString(), durationMs, raw,\n };\n\n if (flags.json) {\n ctx.ui?.json?.(buildStatsJsonReport(effective));\n } else {\n for (const section of buildStatsReport(effective)) {\n ctx.ui?.success?.(`${section.header}`, { sections: [{ items: section.lines }] });\n }\n }\n\n return { exitCode: 0 };\n },\n },\n});\n"]}
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
-
import {
|
|
2
|
+
import { CLIInput } from '@kb-labs/sdk';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<_kb_labs_shared_command_kit.InferFlags<{
|
|
5
|
+
window: {
|
|
6
|
+
type: "number";
|
|
7
|
+
description: string;
|
|
8
|
+
default: number;
|
|
9
|
+
};
|
|
10
|
+
json: {
|
|
11
|
+
type: "boolean";
|
|
12
|
+
description: string;
|
|
13
|
+
default: false;
|
|
14
|
+
};
|
|
15
|
+
}>>, {
|
|
16
|
+
exitCode: number;
|
|
17
|
+
}>;
|
|
8
18
|
|
|
9
19
|
export { _default as default };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { defineCommand } from '@kb-labs/sdk';
|
|
2
|
-
import {
|
|
1
|
+
import { defineCommand, useConfig } from '@kb-labs/sdk';
|
|
2
|
+
import { SnapshotStore, analyzeTrends, buildTrendsReport } from '@kb-labs/qa-core';
|
|
3
|
+
import { TRENDS_WINDOW } from '@kb-labs/qa-contracts';
|
|
3
4
|
|
|
4
5
|
// src/cli/commands/qa-trends.ts
|
|
5
6
|
var qa_trends_default = defineCommand({
|
|
@@ -7,23 +8,19 @@ var qa_trends_default = defineCommand({
|
|
|
7
8
|
description: "Show QA quality trends over time",
|
|
8
9
|
handler: {
|
|
9
10
|
async execute(ctx, input) {
|
|
10
|
-
const {
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const window =
|
|
15
|
-
const
|
|
11
|
+
const { flags } = input;
|
|
12
|
+
const config = await useConfig();
|
|
13
|
+
const cwd = ctx.cwd ?? process.cwd();
|
|
14
|
+
const store = new SnapshotStore(cwd, config?.historyMaxEntries);
|
|
15
|
+
const window = flags.window ?? TRENDS_WINDOW;
|
|
16
|
+
const history = store.loadRunHistory();
|
|
17
|
+
const analysis = analyzeTrends(history, window);
|
|
16
18
|
if (flags.json) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
for (const section of sections) {
|
|
23
|
-
ui?.success?.(section.header, {
|
|
24
|
-
title: section.header,
|
|
25
|
-
sections: [{ header: "", items: section.lines }]
|
|
26
|
-
});
|
|
19
|
+
ctx.ui?.json?.(analysis);
|
|
20
|
+
} else {
|
|
21
|
+
for (const section of buildTrendsReport(analysis)) {
|
|
22
|
+
ctx.ui?.success?.(`${section.header}`, { sections: [{ items: section.lines }] });
|
|
23
|
+
}
|
|
27
24
|
}
|
|
28
25
|
return { exitCode: 0 };
|
|
29
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/qa-trends.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/qa-trends.ts"],"names":[],"mappings":";;;;;AAcA,IAAO,oBAAQ,aAAA,CAAsE;AAAA,EACnF,EAAA,EAAI,WAAA;AAAA,EACJ,WAAA,EAAa,kCAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAA+D;AACjG,MAAA,MAAM,EAAE,OAAM,GAAI,KAAA;AAClB,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAA0B;AAC/C,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AAEnC,MAAA,MAAM,KAAA,GAAQ,IAAI,aAAA,CAAc,GAAA,EAAK,QAAQ,iBAAiB,CAAA;AAC9D,MAAA,MAAM,MAAA,GAAS,MAAM,MAAA,IAAU,aAAA;AAC/B,MAAA,MAAM,OAAA,GAAU,MAAM,cAAA,EAAe;AACrC,MAAA,MAAM,QAAA,GAAW,aAAA,CAAc,OAAA,EAAS,MAAM,CAAA;AAE9C,MAAA,IAAI,MAAM,IAAA,EAAM;AACd,QAAA,GAAA,CAAI,EAAA,EAAI,OAAO,QAAQ,CAAA;AAAA,MACzB,CAAA,MAAO;AACL,QAAA,KAAA,MAAW,OAAA,IAAW,iBAAA,CAAkB,QAAQ,CAAA,EAAG;AACjD,UAAA,GAAA,CAAI,EAAA,EAAI,OAAA,GAAU,CAAA,EAAG,OAAA,CAAQ,MAAM,CAAA,CAAA,EAAI,EAAE,QAAA,EAAU,CAAC,EAAE,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA;AAAA,QACjF;AAAA,MACF;AAEA,MAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,IACvB;AAAA;AAEJ,CAAC","file":"qa-trends.js","sourcesContent":["import {\n defineCommand,\n useConfig,\n type CLIInput,\n type PluginContextV3,\n} from '@kb-labs/sdk';\nimport {\n SnapshotStore,\n analyzeTrends,\n buildTrendsReport,\n} from '@kb-labs/qa-core';\nimport { TRENDS_WINDOW, type QAPluginConfig } from '@kb-labs/qa-contracts';\nimport type { QaTrendsFlags } from './flags.js';\n\nexport default defineCommand<unknown, CLIInput<QaTrendsFlags>, { exitCode: number }>({\n id: 'qa:trends',\n description: 'Show QA quality trends over time',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<QaTrendsFlags>): Promise<{ exitCode: number }> {\n const { flags } = input;\n const config = await useConfig<QAPluginConfig>();\n const cwd = ctx.cwd ?? process.cwd();\n\n const store = new SnapshotStore(cwd, config?.historyMaxEntries);\n const window = flags.window ?? TRENDS_WINDOW;\n const history = store.loadRunHistory();\n const analysis = analyzeTrends(history, window);\n\n if (flags.json) {\n ctx.ui?.json?.(analysis);\n } else {\n for (const section of buildTrendsReport(analysis)) {\n ctx.ui?.success?.(`${section.header}`, { sections: [{ items: section.lines }] });\n }\n }\n\n return { exitCode: 0 };\n },\n },\n});\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { default as manifest } from './manifest.js';
|
|
2
|
-
import '@kb-labs/
|
|
2
|
+
import '@kb-labs/plugin-contracts';
|