@kb-labs/qa-entry 2.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/cli/commands/baseline-status.d.ts +10 -0
- package/dist/cli/commands/baseline-status.js +32 -0
- package/dist/cli/commands/baseline-status.js.map +1 -0
- package/dist/cli/commands/baseline-update.d.ts +10 -0
- package/dist/cli/commands/baseline-update.js +33 -0
- package/dist/cli/commands/baseline-update.js.map +1 -0
- package/dist/cli/commands/flags.d.ts +106 -0
- package/dist/cli/commands/flags.js +99 -0
- package/dist/cli/commands/flags.js.map +1 -0
- package/dist/cli/commands/qa-history.d.ts +10 -0
- package/dist/cli/commands/qa-history.js +41 -0
- package/dist/cli/commands/qa-history.js.map +1 -0
- package/dist/cli/commands/qa-regressions.d.ts +10 -0
- package/dist/cli/commands/qa-regressions.js +33 -0
- package/dist/cli/commands/qa-regressions.js.map +1 -0
- package/dist/cli/commands/qa-run.d.ts +16 -0
- package/dist/cli/commands/qa-run.js +159 -0
- package/dist/cli/commands/qa-run.js.map +1 -0
- package/dist/cli/commands/qa-save.d.ts +10 -0
- package/dist/cli/commands/qa-save.js +69 -0
- package/dist/cli/commands/qa-save.js.map +1 -0
- package/dist/cli/commands/qa-trends.d.ts +10 -0
- package/dist/cli/commands/qa-trends.js +35 -0
- package/dist/cli/commands/qa-trends.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +390 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.d.ts +198 -0
- package/dist/manifest.js +391 -0
- package/dist/manifest.js.map +1 -0
- package/dist/rest/handlers/baseline-diff-handler.d.ts +33 -0
- package/dist/rest/handlers/baseline-diff-handler.js +51 -0
- package/dist/rest/handlers/baseline-diff-handler.js.map +1 -0
- package/dist/rest/handlers/baseline-handler.d.ts +19 -0
- package/dist/rest/handlers/baseline-handler.js +14 -0
- package/dist/rest/handlers/baseline-handler.js.map +1 -0
- package/dist/rest/handlers/baseline-update-handler.d.ts +20 -0
- package/dist/rest/handlers/baseline-update-handler.js +23 -0
- package/dist/rest/handlers/baseline-update-handler.js.map +1 -0
- package/dist/rest/handlers/details-handler.d.ts +61 -0
- package/dist/rest/handlers/details-handler.js +70 -0
- package/dist/rest/handlers/details-handler.js.map +1 -0
- package/dist/rest/handlers/error-groups-handler.d.ts +15 -0
- package/dist/rest/handlers/error-groups-handler.js +17 -0
- package/dist/rest/handlers/error-groups-handler.js.map +1 -0
- package/dist/rest/handlers/history-handler.d.ts +25 -0
- package/dist/rest/handlers/history-handler.js +22 -0
- package/dist/rest/handlers/history-handler.js.map +1 -0
- package/dist/rest/handlers/latest-handler.d.ts +22 -0
- package/dist/rest/handlers/latest-handler.js +17 -0
- package/dist/rest/handlers/latest-handler.js.map +1 -0
- package/dist/rest/handlers/package-timeline-handler.d.ts +26 -0
- package/dist/rest/handlers/package-timeline-handler.js +18 -0
- package/dist/rest/handlers/package-timeline-handler.js.map +1 -0
- package/dist/rest/handlers/regressions-handler.d.ts +16 -0
- package/dist/rest/handlers/regressions-handler.js +14 -0
- package/dist/rest/handlers/regressions-handler.js.map +1 -0
- package/dist/rest/handlers/run-check-handler.d.ts +20 -0
- package/dist/rest/handlers/run-check-handler.js +58 -0
- package/dist/rest/handlers/run-check-handler.js.map +1 -0
- package/dist/rest/handlers/run-handler.d.ts +33 -0
- package/dist/rest/handlers/run-handler.js +75 -0
- package/dist/rest/handlers/run-handler.js.map +1 -0
- package/dist/rest/handlers/summary-handler.d.ts +26 -0
- package/dist/rest/handlers/summary-handler.js +35 -0
- package/dist/rest/handlers/summary-handler.js.map +1 -0
- package/dist/rest/handlers/trends-handler.d.ts +48 -0
- package/dist/rest/handlers/trends-handler.js +30 -0
- package/dist/rest/handlers/trends-handler.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
+
import { RestInput } from '@kb-labs/sdk';
|
|
3
|
+
|
|
4
|
+
declare const _default: _kb_labs_shared_command_kit.Handler<unknown, RestInput<unknown, {
|
|
5
|
+
skipChecks?: string[] | undefined;
|
|
6
|
+
saveToHistory?: boolean | undefined;
|
|
7
|
+
}, unknown>, {
|
|
8
|
+
status: "passed" | "failed";
|
|
9
|
+
entry: {
|
|
10
|
+
status: "passed" | "failed";
|
|
11
|
+
git: {
|
|
12
|
+
commit: string;
|
|
13
|
+
branch: string;
|
|
14
|
+
message: string;
|
|
15
|
+
};
|
|
16
|
+
timestamp: string;
|
|
17
|
+
summary: Record<string, {
|
|
18
|
+
passed: number;
|
|
19
|
+
failed: number;
|
|
20
|
+
skipped: number;
|
|
21
|
+
}>;
|
|
22
|
+
failedPackages: Record<string, string[]>;
|
|
23
|
+
} | null;
|
|
24
|
+
results: Record<string, {
|
|
25
|
+
passed: string[];
|
|
26
|
+
failed: string[];
|
|
27
|
+
skipped: string[];
|
|
28
|
+
errors: Record<string, string>;
|
|
29
|
+
}>;
|
|
30
|
+
durationMs: number;
|
|
31
|
+
}>;
|
|
32
|
+
|
|
33
|
+
export { _default as default };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { defineHandler, useConfig } from '@kb-labs/sdk';
|
|
2
|
+
import { runQA, createHistoryEntry, appendEntry } from '@kb-labs/qa-core';
|
|
3
|
+
|
|
4
|
+
// src/rest/handlers/run-handler.ts
|
|
5
|
+
var run_handler_default = defineHandler({
|
|
6
|
+
async execute(ctx, input) {
|
|
7
|
+
const rootDir = ctx.cwd;
|
|
8
|
+
const startTime = Date.now();
|
|
9
|
+
const body = input.body;
|
|
10
|
+
let config;
|
|
11
|
+
try {
|
|
12
|
+
config = await Promise.race([
|
|
13
|
+
useConfig(),
|
|
14
|
+
new Promise((resolve) => {
|
|
15
|
+
setTimeout(() => resolve(void 0), 3e3);
|
|
16
|
+
})
|
|
17
|
+
]);
|
|
18
|
+
} catch {
|
|
19
|
+
}
|
|
20
|
+
const checks = config?.checks;
|
|
21
|
+
const { results } = await runQA({
|
|
22
|
+
rootDir,
|
|
23
|
+
skipChecks: body?.skipChecks,
|
|
24
|
+
packagesConfig: config?.packages,
|
|
25
|
+
checks
|
|
26
|
+
});
|
|
27
|
+
const hasFailed = Object.values(results).some((r) => r.failed.length > 0);
|
|
28
|
+
const status = hasFailed ? "failed" : "passed";
|
|
29
|
+
let entry = null;
|
|
30
|
+
if (body?.saveToHistory !== false) {
|
|
31
|
+
entry = createHistoryEntry(results, rootDir);
|
|
32
|
+
appendEntry(rootDir, entry);
|
|
33
|
+
}
|
|
34
|
+
const durationMs = Date.now() - startTime;
|
|
35
|
+
const analytics = ctx.platform.analytics;
|
|
36
|
+
if (analytics) {
|
|
37
|
+
for (const ct of Object.keys(results)) {
|
|
38
|
+
const r = results[ct];
|
|
39
|
+
await analytics.track("qa.check.completed", {
|
|
40
|
+
checkType: ct,
|
|
41
|
+
status: r.failed.length > 0 ? "failed" : "passed",
|
|
42
|
+
passed: r.passed.length,
|
|
43
|
+
failed: r.failed.length,
|
|
44
|
+
skipped: r.skipped.length,
|
|
45
|
+
gitCommit: entry?.git.commit,
|
|
46
|
+
gitBranch: entry?.git.branch
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
const checkKeys = Object.keys(results);
|
|
50
|
+
await analytics.track("qa.run.completed", {
|
|
51
|
+
status,
|
|
52
|
+
...Object.fromEntries(checkKeys.flatMap((ct) => [
|
|
53
|
+
[`${ct}Passed`, results[ct].passed.length],
|
|
54
|
+
[`${ct}Failed`, results[ct].failed.length]
|
|
55
|
+
])),
|
|
56
|
+
totalPassed: checkKeys.reduce((s, ct) => s + results[ct].passed.length, 0),
|
|
57
|
+
totalFailed: checkKeys.reduce((s, ct) => s + results[ct].failed.length, 0),
|
|
58
|
+
totalSkipped: checkKeys.reduce((s, ct) => s + results[ct].skipped.length, 0),
|
|
59
|
+
gitCommit: entry?.git.commit,
|
|
60
|
+
gitBranch: entry?.git.branch,
|
|
61
|
+
durationMs
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
status,
|
|
66
|
+
results,
|
|
67
|
+
entry,
|
|
68
|
+
durationMs
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
export { run_handler_default as default };
|
|
74
|
+
//# sourceMappingURL=run-handler.js.map
|
|
75
|
+
//# sourceMappingURL=run-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/run-handler.ts"],"names":[],"mappings":"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","file":"run-handler.js","sourcesContent":["/**\n * POST /run handler\n *\n * Runs QA checks (build, lint, types, tests) and optionally saves to history.\n */\n\nimport { defineHandler, useConfig, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { runQA, createHistoryEntry, appendEntry } from '@kb-labs/qa-core';\nimport type { QARunRequest, QARunResponse, QAPluginConfig } from '@kb-labs/qa-contracts';\n\nexport default defineHandler({\n async execute(\n ctx: PluginContextV3,\n input: RestInput<unknown, QARunRequest>,\n ): Promise<QARunResponse> {\n const rootDir = ctx.cwd;\n const startTime = Date.now();\n const body = input.body;\n\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 { /* no platform context */ }\n\n const checks = config?.checks;\n\n const { results } = await runQA({\n rootDir,\n skipChecks: body?.skipChecks,\n packagesConfig: config?.packages,\n checks,\n });\n\n // Determine overall status\n const hasFailed = Object.values(results).some((r) => r.failed.length > 0);\n const status = hasFailed ? 'failed' : 'passed';\n\n // Save to history unless explicitly disabled\n let entry = null;\n if (body?.saveToHistory !== false) {\n entry = createHistoryEntry(results, rootDir);\n appendEntry(rootDir, entry);\n }\n\n const durationMs = Date.now() - startTime;\n\n // Track analytics events\n const analytics = ctx.platform.analytics;\n if (analytics) {\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 gitCommit: entry?.git.commit, gitBranch: entry?.git.branch,\n });\n }\n const checkKeys = Object.keys(results);\n await analytics.track('qa.run.completed', {\n status,\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 gitCommit: entry?.git.commit, gitBranch: entry?.git.branch,\n durationMs,\n });\n }\n\n return {\n status,\n results,\n entry,\n durationMs,\n };\n },\n});\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
+
import { RestInput } from '@kb-labs/sdk';
|
|
3
|
+
|
|
4
|
+
declare const _default: _kb_labs_shared_command_kit.Handler<unknown, RestInput<{}, unknown, unknown>, {
|
|
5
|
+
status: string;
|
|
6
|
+
lastRunAt: string | null;
|
|
7
|
+
git: {
|
|
8
|
+
commit: string;
|
|
9
|
+
branch: string;
|
|
10
|
+
message: string;
|
|
11
|
+
} | null;
|
|
12
|
+
checks: {
|
|
13
|
+
passed: number;
|
|
14
|
+
failed: number;
|
|
15
|
+
skipped: number;
|
|
16
|
+
checkType: string;
|
|
17
|
+
label: string;
|
|
18
|
+
total: number;
|
|
19
|
+
icon?: string | undefined;
|
|
20
|
+
}[];
|
|
21
|
+
hasBaseline: boolean;
|
|
22
|
+
baselineTimestamp: string | null;
|
|
23
|
+
historyCount: number;
|
|
24
|
+
}>;
|
|
25
|
+
|
|
26
|
+
export { _default as default };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { defineHandler } from '@kb-labs/sdk';
|
|
2
|
+
import { loadBaseline, loadHistory } from '@kb-labs/qa-core';
|
|
3
|
+
import { getCheckIcon, getCheckLabel } from '@kb-labs/qa-contracts';
|
|
4
|
+
|
|
5
|
+
// src/rest/handlers/summary-handler.ts
|
|
6
|
+
var summary_handler_default = defineHandler({
|
|
7
|
+
async execute(ctx, _input) {
|
|
8
|
+
const baseline = loadBaseline(ctx.cwd);
|
|
9
|
+
const history = loadHistory(ctx.cwd);
|
|
10
|
+
const latest = history.length > 0 ? history[history.length - 1] : null;
|
|
11
|
+
const checkKeys = latest ? Object.keys(latest.summary) : [];
|
|
12
|
+
const checks = checkKeys.map((ct) => ({
|
|
13
|
+
checkType: ct,
|
|
14
|
+
label: getCheckLabel(ct),
|
|
15
|
+
icon: getCheckIcon(ct),
|
|
16
|
+
passed: latest?.summary[ct]?.passed ?? 0,
|
|
17
|
+
failed: latest?.summary[ct]?.failed ?? 0,
|
|
18
|
+
skipped: latest?.summary[ct]?.skipped ?? 0,
|
|
19
|
+
total: (latest?.summary[ct]?.passed ?? 0) + (latest?.summary[ct]?.failed ?? 0) + (latest?.summary[ct]?.skipped ?? 0)
|
|
20
|
+
}));
|
|
21
|
+
return {
|
|
22
|
+
status: latest?.status ?? "unknown",
|
|
23
|
+
lastRunAt: latest?.timestamp ?? null,
|
|
24
|
+
git: latest?.git ?? null,
|
|
25
|
+
checks,
|
|
26
|
+
hasBaseline: baseline !== null,
|
|
27
|
+
baselineTimestamp: baseline?.timestamp ?? null,
|
|
28
|
+
historyCount: history.length
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export { summary_handler_default as default };
|
|
34
|
+
//# sourceMappingURL=summary-handler.js.map
|
|
35
|
+
//# sourceMappingURL=summary-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/summary-handler.ts"],"names":[],"mappings":";;;;;AAWA,IAAO,0BAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,GAAA,EACA,MAAA,EAC4B;AAC5B,IAAA,MAAM,QAAA,GAAW,YAAA,CAAa,GAAA,CAAI,GAAG,CAAA;AACrC,IAAA,MAAM,OAAA,GAAU,WAAA,CAAY,GAAA,CAAI,GAAG,CAAA;AACnC,IAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,GAAS,CAAA,GAAI,QAAQ,OAAA,CAAQ,MAAA,GAAS,CAAC,CAAA,GAAI,IAAA;AAElE,IAAA,MAAM,YAAY,MAAA,GAAS,MAAA,CAAO,KAAK,MAAA,CAAO,OAAO,IAAI,EAAC;AAC1D,IAAA,MAAM,MAAA,GAAS,SAAA,CAAU,GAAA,CAAI,CAAC,EAAA,MAAQ;AAAA,MACpC,SAAA,EAAW,EAAA;AAAA,MACX,KAAA,EAAO,cAAc,EAAE,CAAA;AAAA,MACvB,IAAA,EAAM,aAAa,EAAE,CAAA;AAAA,MACrB,MAAA,EAAQ,MAAA,EAAQ,OAAA,CAAQ,EAAE,GAAG,MAAA,IAAU,CAAA;AAAA,MACvC,MAAA,EAAQ,MAAA,EAAQ,OAAA,CAAQ,EAAE,GAAG,MAAA,IAAU,CAAA;AAAA,MACvC,OAAA,EAAS,MAAA,EAAQ,OAAA,CAAQ,EAAE,GAAG,OAAA,IAAW,CAAA;AAAA,MACzC,QACG,MAAA,EAAQ,OAAA,CAAQ,EAAE,CAAA,EAAG,UAAU,CAAA,KAC/B,MAAA,EAAQ,OAAA,CAAQ,EAAE,GAAG,MAAA,IAAU,CAAA,CAAA,IAC/B,QAAQ,OAAA,CAAQ,EAAE,GAAG,OAAA,IAAW,CAAA;AAAA,KACrC,CAAE,CAAA;AAEF,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,QAAQ,MAAA,IAAU,SAAA;AAAA,MAC1B,SAAA,EAAW,QAAQ,SAAA,IAAa,IAAA;AAAA,MAChC,GAAA,EAAK,QAAQ,GAAA,IAAO,IAAA;AAAA,MACpB,MAAA;AAAA,MACA,aAAa,QAAA,KAAa,IAAA;AAAA,MAC1B,iBAAA,EAAmB,UAAU,SAAA,IAAa,IAAA;AAAA,MAC1C,cAAc,OAAA,CAAQ;AAAA,KACxB;AAAA,EACF;AACF,CAAC","file":"summary-handler.js","sourcesContent":["/**\n * GET /summary handler\n *\n * Aggregated QA overview: per-check pass rates, baseline info, last run status.\n */\n\nimport { defineHandler, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { loadBaseline, loadHistory } from '@kb-labs/qa-core';\nimport { getCheckLabel, getCheckIcon } from '@kb-labs/qa-contracts';\nimport type { QASummaryRequest, QASummaryResponse } from '@kb-labs/qa-contracts';\n\nexport default defineHandler({\n async execute(\n ctx: PluginContextV3,\n _input: RestInput<QASummaryRequest, unknown>,\n ): Promise<QASummaryResponse> {\n const baseline = loadBaseline(ctx.cwd);\n const history = loadHistory(ctx.cwd);\n const latest = history.length > 0 ? history[history.length - 1] : null;\n\n const checkKeys = latest ? Object.keys(latest.summary) : [];\n const checks = checkKeys.map((ct) => ({\n checkType: ct,\n label: getCheckLabel(ct),\n icon: getCheckIcon(ct),\n passed: latest?.summary[ct]?.passed ?? 0,\n failed: latest?.summary[ct]?.failed ?? 0,\n skipped: latest?.summary[ct]?.skipped ?? 0,\n total:\n (latest?.summary[ct]?.passed ?? 0) +\n (latest?.summary[ct]?.failed ?? 0) +\n (latest?.summary[ct]?.skipped ?? 0),\n }));\n\n return {\n status: latest?.status ?? 'unknown',\n lastRunAt: latest?.timestamp ?? null,\n git: latest?.git ?? null,\n checks,\n hasBaseline: baseline !== null,\n baselineTimestamp: baseline?.timestamp ?? null,\n historyCount: history.length,\n };\n },\n});\n"]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
+
import { RestInput } from '@kb-labs/sdk';
|
|
3
|
+
|
|
4
|
+
declare const _default: _kb_labs_shared_command_kit.Handler<unknown, RestInput<Record<string, string>, unknown, unknown>, {
|
|
5
|
+
historyCount: number;
|
|
6
|
+
window: number;
|
|
7
|
+
trends: {
|
|
8
|
+
checkType: string;
|
|
9
|
+
previous: number;
|
|
10
|
+
current: number;
|
|
11
|
+
delta: number;
|
|
12
|
+
trend: "regression" | "improvement" | "no-change";
|
|
13
|
+
label?: string | undefined;
|
|
14
|
+
icon?: string | undefined;
|
|
15
|
+
}[];
|
|
16
|
+
} | {
|
|
17
|
+
historyCount: number;
|
|
18
|
+
window: number;
|
|
19
|
+
trends: {
|
|
20
|
+
checkType: string;
|
|
21
|
+
previous: number;
|
|
22
|
+
current: number;
|
|
23
|
+
delta: number;
|
|
24
|
+
trend: "regression" | "improvement" | "no-change";
|
|
25
|
+
timeSeries: {
|
|
26
|
+
passed: number;
|
|
27
|
+
failed: number;
|
|
28
|
+
skipped: number;
|
|
29
|
+
timestamp: string;
|
|
30
|
+
gitCommit: string;
|
|
31
|
+
gitBranch: string;
|
|
32
|
+
gitMessage: string;
|
|
33
|
+
}[];
|
|
34
|
+
changelog: {
|
|
35
|
+
timestamp: string;
|
|
36
|
+
delta: number;
|
|
37
|
+
gitCommit: string;
|
|
38
|
+
gitMessage: string;
|
|
39
|
+
newFailures: string[];
|
|
40
|
+
fixed: string[];
|
|
41
|
+
}[];
|
|
42
|
+
velocity: number;
|
|
43
|
+
label?: string | undefined;
|
|
44
|
+
icon?: string | undefined;
|
|
45
|
+
}[];
|
|
46
|
+
}>;
|
|
47
|
+
|
|
48
|
+
export { _default as default };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { defineHandler } from '@kb-labs/sdk';
|
|
2
|
+
import { loadHistory, analyzeEnrichedTrends, analyzeTrends } from '@kb-labs/qa-core';
|
|
3
|
+
import { TRENDS_WINDOW } from '@kb-labs/qa-contracts';
|
|
4
|
+
|
|
5
|
+
// src/rest/handlers/trends-handler.ts
|
|
6
|
+
var trends_handler_default = defineHandler({
|
|
7
|
+
async execute(ctx, input) {
|
|
8
|
+
const window = input.query?.window ? Number(input.query.window) : TRENDS_WINDOW;
|
|
9
|
+
const enriched = String(input.query?.enriched) === "true";
|
|
10
|
+
const history = loadHistory(ctx.cwd);
|
|
11
|
+
if (enriched) {
|
|
12
|
+
const trends2 = analyzeEnrichedTrends(history, window);
|
|
13
|
+
return {
|
|
14
|
+
trends: trends2,
|
|
15
|
+
historyCount: history.length,
|
|
16
|
+
window
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const trends = analyzeTrends(history, window);
|
|
20
|
+
return {
|
|
21
|
+
trends,
|
|
22
|
+
historyCount: history.length,
|
|
23
|
+
window
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export { trends_handler_default as default };
|
|
29
|
+
//# sourceMappingURL=trends-handler.js.map
|
|
30
|
+
//# sourceMappingURL=trends-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/trends-handler.ts"],"names":["trends"],"mappings":";;;;;AAYA,IAAO,yBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,GAAA,EACA,KAAA,EACsD;AACtD,IAAA,MAAM,MAAA,GAAS,MAAM,KAAA,EAAO,MAAA,GAAS,OAAO,KAAA,CAAM,KAAA,CAAM,MAAM,CAAA,GAAI,aAAA;AAClE,IAAA,MAAM,QAAA,GAAW,MAAA,CAAO,KAAA,CAAM,KAAA,EAAO,QAAQ,CAAA,KAAM,MAAA;AACnD,IAAA,MAAM,OAAA,GAAU,WAAA,CAAY,GAAA,CAAI,GAAG,CAAA;AAEnC,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,MAAMA,OAAAA,GAAS,qBAAA,CAAsB,OAAA,EAAS,MAAM,CAAA;AACpD,MAAA,OAAO;AAAA,QACL,MAAA,EAAAA,OAAAA;AAAA,QACA,cAAc,OAAA,CAAQ,MAAA;AAAA,QACtB;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAS,aAAA,CAAc,OAAA,EAAS,MAAM,CAAA;AAC5C,IAAA,OAAO;AAAA,MACL,MAAA;AAAA,MACA,cAAc,OAAA,CAAQ,MAAA;AAAA,MACtB;AAAA,KACF;AAAA,EACF;AACF,CAAC","file":"trends-handler.js","sourcesContent":["/**\n * GET /trends handler\n *\n * Analyzes QA quality trends over a sliding window.\n * Supports ?window=N and ?enriched=true for full time-series + changelog.\n */\n\nimport { defineHandler, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { loadHistory, analyzeTrends, analyzeEnrichedTrends } from '@kb-labs/qa-core';\nimport { TRENDS_WINDOW } from '@kb-labs/qa-contracts';\nimport type { QATrendsResponse, QAEnrichedTrendsResponse } from '@kb-labs/qa-contracts';\n\nexport default defineHandler({\n async execute(\n ctx: PluginContextV3,\n input: RestInput<Record<string, string>, unknown>,\n ): Promise<QATrendsResponse | QAEnrichedTrendsResponse> {\n const window = input.query?.window ? Number(input.query.window) : TRENDS_WINDOW;\n const enriched = String(input.query?.enriched) === 'true';\n const history = loadHistory(ctx.cwd);\n\n if (enriched) {\n const trends = analyzeEnrichedTrends(history, window);\n return {\n trends,\n historyCount: history.length,\n window,\n };\n }\n\n const trends = analyzeTrends(history, window);\n return {\n trends,\n historyCount: history.length,\n window,\n };\n },\n});\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kb-labs/qa-entry",
|
|
3
|
+
"version": "2.14.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "CLI commands for KB Labs QA Plugin — qa:run, qa:save, qa:history, qa:trends, qa:regressions, baseline:update, baseline:status.",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./plugin-manifest": {
|
|
14
|
+
"import": "./dist/manifest.js",
|
|
15
|
+
"types": "./dist/manifest.d.ts"
|
|
16
|
+
},
|
|
17
|
+
"./dist/*": "./dist/*"
|
|
18
|
+
},
|
|
19
|
+
"kb": {
|
|
20
|
+
"manifest": "./dist/manifest.js"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist",
|
|
24
|
+
"README.md",
|
|
25
|
+
"LICENSE"
|
|
26
|
+
],
|
|
27
|
+
"sideEffects": false,
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"zod": "latest",
|
|
30
|
+
"@kb-labs/qa-core": "2.14.0",
|
|
31
|
+
"@kb-labs/qa-contracts": "2.14.0",
|
|
32
|
+
"@kb-labs/plugin-contracts": "2.14.0",
|
|
33
|
+
"@kb-labs/sdk": "1.6.6"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"react": ">=18.0.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@rspack/cli": "latest",
|
|
40
|
+
"@rspack/core": "latest",
|
|
41
|
+
"@types/node": "^24.3.3",
|
|
42
|
+
"@types/react": "^18.3.18",
|
|
43
|
+
"@types/react-dom": "^18.3.5",
|
|
44
|
+
"react": "^18.3.1",
|
|
45
|
+
"react-dom": "^18.3.1",
|
|
46
|
+
"rimraf": "^6.0.1",
|
|
47
|
+
"tsup": "^8.5.0",
|
|
48
|
+
"typescript": "^5.6.3",
|
|
49
|
+
"vitest": "^3.2.4",
|
|
50
|
+
"@kb-labs/devkit": "2.14.0",
|
|
51
|
+
"@kb-labs/plugin-runtime": "2.14.0",
|
|
52
|
+
"@kb-labs/studio-plugin-tools": "2.14.0"
|
|
53
|
+
},
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=20.0.0",
|
|
56
|
+
"pnpm": ">=9.0.0"
|
|
57
|
+
},
|
|
58
|
+
"scripts": {
|
|
59
|
+
"pretype-check": "pnpm --filter @kb-labs/qa-entry build",
|
|
60
|
+
"clean": "rimraf dist",
|
|
61
|
+
"build": "tsup --config tsup.config.ts && pnpm build:studio",
|
|
62
|
+
"build:studio": "rspack build --config rspack.studio.config.mjs",
|
|
63
|
+
"dev": "tsup --config tsup.config.ts --watch",
|
|
64
|
+
"dev:studio": "rspack build --config rspack.studio.config.mjs --watch",
|
|
65
|
+
"lint": "eslint src --ext .ts",
|
|
66
|
+
"lint:fix": "eslint . --fix",
|
|
67
|
+
"type-check": "tsc --noEmit",
|
|
68
|
+
"test": "vitest run --passWithNoTests",
|
|
69
|
+
"test:watch": "vitest"
|
|
70
|
+
}
|
|
71
|
+
}
|