@kb-labs/qa-entry 2.94.0 → 2.98.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.
Files changed (116) hide show
  1. package/dist/cli/commands/baseline-diff.d.ts +14 -0
  2. package/dist/cli/commands/baseline-diff.js +40 -0
  3. package/dist/cli/commands/baseline-diff.js.map +1 -0
  4. package/dist/cli/commands/baseline-status.d.ts +10 -5
  5. package/dist/cli/commands/baseline-status.js +14 -17
  6. package/dist/cli/commands/baseline-status.js.map +1 -1
  7. package/dist/cli/commands/baseline-update.d.ts +10 -5
  8. package/dist/cli/commands/baseline-update.js +26 -18
  9. package/dist/cli/commands/baseline-update.js.map +1 -1
  10. package/dist/cli/commands/flags.d.ts +117 -132
  11. package/dist/cli/commands/flags.js +65 -79
  12. package/dist/cli/commands/flags.js.map +1 -1
  13. package/dist/cli/commands/qa-check.d.ts +13 -34
  14. package/dist/cli/commands/qa-check.js +26 -106
  15. package/dist/cli/commands/qa-check.js.map +1 -1
  16. package/dist/cli/commands/qa-gate.d.ts +19 -0
  17. package/dist/cli/commands/qa-gate.js +36 -0
  18. package/dist/cli/commands/qa-gate.js.map +1 -0
  19. package/dist/cli/commands/qa-history.d.ts +15 -5
  20. package/dist/cli/commands/qa-history.js +13 -24
  21. package/dist/cli/commands/qa-history.js.map +1 -1
  22. package/dist/cli/commands/qa-regressions.d.ts +10 -5
  23. package/dist/cli/commands/qa-regressions.js +15 -18
  24. package/dist/cli/commands/qa-regressions.js.map +1 -1
  25. package/dist/cli/commands/qa-run.d.ts +18 -11
  26. package/dist/cli/commands/qa-run.js +28 -141
  27. package/dist/cli/commands/qa-run.js.map +1 -1
  28. package/dist/cli/commands/qa-stats.d.ts +19 -0
  29. package/dist/cli/commands/qa-stats.js +43 -0
  30. package/dist/cli/commands/qa-stats.js.map +1 -0
  31. package/dist/cli/commands/qa-trends.d.ts +15 -5
  32. package/dist/cli/commands/qa-trends.js +15 -18
  33. package/dist/cli/commands/qa-trends.js.map +1 -1
  34. package/dist/index.d.ts +1 -1
  35. package/dist/index.js +143 -291
  36. package/dist/index.js.map +1 -1
  37. package/dist/manifest.d.ts +74 -106
  38. package/dist/manifest.js +143 -291
  39. package/dist/manifest.js.map +1 -1
  40. package/dist/rest/handlers/baseline-diff-handler.d.ts +7 -27
  41. package/dist/rest/handlers/baseline-diff-handler.js +15 -41
  42. package/dist/rest/handlers/baseline-diff-handler.js.map +1 -1
  43. package/dist/rest/handlers/baseline-handler.d.ts +3 -13
  44. package/dist/rest/handlers/baseline-handler.js +10 -5
  45. package/dist/rest/handlers/baseline-handler.js.map +1 -1
  46. package/dist/rest/handlers/baseline-update-handler.d.ts +4 -14
  47. package/dist/rest/handlers/baseline-update-handler.js +15 -13
  48. package/dist/rest/handlers/baseline-update-handler.js.map +1 -1
  49. package/dist/rest/handlers/check-handler.d.ts +15 -0
  50. package/dist/rest/handlers/check-handler.js +28 -0
  51. package/dist/rest/handlers/check-handler.js.map +1 -0
  52. package/dist/rest/handlers/gate-handler.d.ts +13 -0
  53. package/dist/rest/handlers/gate-handler.js +28 -0
  54. package/dist/rest/handlers/gate-handler.js.map +1 -0
  55. package/dist/rest/handlers/history-handler.d.ts +3 -16
  56. package/dist/rest/handlers/history-handler.js +10 -11
  57. package/dist/rest/handlers/history-handler.js.map +1 -1
  58. package/dist/rest/handlers/package-timeline-handler.d.ts +5 -20
  59. package/dist/rest/handlers/package-timeline-handler.js +11 -7
  60. package/dist/rest/handlers/package-timeline-handler.js.map +1 -1
  61. package/dist/rest/handlers/regressions-handler.d.ts +2 -11
  62. package/dist/rest/handlers/regressions-handler.js +11 -5
  63. package/dist/rest/handlers/regressions-handler.js.map +1 -1
  64. package/dist/rest/handlers/run-handler.d.ts +10 -27
  65. package/dist/rest/handlers/run-handler.js +18 -63
  66. package/dist/rest/handlers/run-handler.js.map +1 -1
  67. package/dist/rest/handlers/{error-groups-handler.d.ts → stats-handler.d.ts} +5 -9
  68. package/dist/rest/handlers/stats-handler.js +21 -0
  69. package/dist/rest/handlers/stats-handler.js.map +1 -0
  70. package/dist/rest/handlers/summary-handler.d.ts +7 -20
  71. package/dist/rest/handlers/summary-handler.js +16 -26
  72. package/dist/rest/handlers/summary-handler.js.map +1 -1
  73. package/dist/rest/handlers/tasks-handler.d.ts +9 -0
  74. package/dist/rest/handlers/tasks-handler.js +38 -0
  75. package/dist/rest/handlers/tasks-handler.js.map +1 -0
  76. package/dist/rest/handlers/trends-handler.d.ts +4 -43
  77. package/dist/rest/handlers/trends-handler.js +11 -18
  78. package/dist/rest/handlers/trends-handler.js.map +1 -1
  79. package/dist/widgets/117.js +24 -1
  80. package/dist/widgets/165.js +1 -1
  81. package/dist/widgets/370.js +1 -1
  82. package/dist/widgets/405.js +1 -1
  83. package/dist/widgets/{805.js → 46.js} +92 -92
  84. package/dist/widgets/50.js +1 -1
  85. package/dist/widgets/546.js +1 -1
  86. package/dist/widgets/62.js +96 -0
  87. package/dist/widgets/648.js +1 -0
  88. package/dist/widgets/669.js +1 -1
  89. package/dist/widgets/733.js +34 -0
  90. package/dist/widgets/775.js +1 -1
  91. package/dist/widgets/78.js +1 -0
  92. package/dist/widgets/823.js +1 -0
  93. package/dist/widgets/968.js +2 -2
  94. package/dist/widgets/__federation_expose_QADashboard.js +1 -1
  95. package/dist/widgets/mf-manifest.json +32 -31
  96. package/dist/widgets/mf-stats.json +32 -31
  97. package/dist/widgets/remoteEntry.js +3 -3
  98. package/package.json +12 -9
  99. package/dist/cli/commands/qa-save.d.ts +0 -10
  100. package/dist/cli/commands/qa-save.js +0 -69
  101. package/dist/cli/commands/qa-save.js.map +0 -1
  102. package/dist/rest/handlers/details-handler.d.ts +0 -61
  103. package/dist/rest/handlers/details-handler.js +0 -70
  104. package/dist/rest/handlers/details-handler.js.map +0 -1
  105. package/dist/rest/handlers/error-groups-handler.js +0 -17
  106. package/dist/rest/handlers/error-groups-handler.js.map +0 -1
  107. package/dist/rest/handlers/latest-handler.d.ts +0 -22
  108. package/dist/rest/handlers/latest-handler.js +0 -17
  109. package/dist/rest/handlers/latest-handler.js.map +0 -1
  110. package/dist/rest/handlers/run-check-handler.d.ts +0 -20
  111. package/dist/rest/handlers/run-check-handler.js +0 -58
  112. package/dist/rest/handlers/run-check-handler.js.map +0 -1
  113. package/dist/widgets/418.js +0 -38
  114. package/dist/widgets/451.js +0 -1
  115. package/dist/widgets/694.js +0 -1
  116. package/dist/widgets/919.js +0 -34
@@ -1,72 +1,27 @@
1
- import { defineHandler, useConfig } from '@kb-labs/sdk';
2
- import { runQA, createHistoryEntry, appendEntry } from '@kb-labs/qa-core';
1
+ import { defineHandler, useConfig, rethrowForRest } from '@kb-labs/sdk';
2
+ import { resolveDevkitBin, DevkitAdapter, SnapshotStore, captureGit } from '@kb-labs/qa-core';
3
+ import { DEFAULT_TASKS } from '@kb-labs/qa-contracts';
3
4
 
4
5
  // src/rest/handlers/run-handler.ts
5
6
  var run_handler_default = defineHandler({
6
7
  async execute(ctx, input) {
7
- const rootDir = ctx.cwd;
8
- const startTime = Date.now();
9
- const body = input.body;
10
- let config;
11
8
  try {
12
- config = await Promise.race([
13
- useConfig(),
14
- new Promise((resolve) => {
15
- setTimeout(() => resolve(void 0), 3e3);
16
- })
17
- ]);
18
- } catch {
9
+ const { tasks, save = true, runContext } = input.body ?? {};
10
+ const config = await useConfig();
11
+ const cwd = ctx.cwd;
12
+ const binaryPath = resolveDevkitBin(cwd, config?.devkitPath);
13
+ const adapter = new DevkitAdapter({ binaryPath, cwd, shell: ctx.api.shell });
14
+ const store = new SnapshotStore(cwd, config?.historyMaxEntries);
15
+ const effectiveTasks = tasks ?? config?.defaultTasks ?? [...DEFAULT_TASKS];
16
+ const git = await captureGit(ctx.api.shell, cwd);
17
+ const start = Date.now();
18
+ const raw = await adapter.run(effectiveTasks);
19
+ const durationMs = Date.now() - start;
20
+ const snap = save ? store.saveRun(raw, effectiveTasks, durationMs, git, runContext) : null;
21
+ return { snapshot: snap, raw, ok: raw.ok };
22
+ } catch (error) {
23
+ rethrowForRest(error);
19
24
  }
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
25
  }
71
26
  });
72
27
 
@@ -1 +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"]}
1
+ {"version":3,"sources":["../../../src/rest/handlers/run-handler.ts"],"names":[],"mappings":";;;;;AAUA,IAAO,sBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAoC;AACtE,IAAA,IAAI;AACF,MAAA,MAAM,EAAE,OAAO,IAAA,GAAO,IAAA,EAAM,YAAW,GAAI,KAAA,CAAM,QAAQ,EAAC;AAC1D,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAA0B;AAC/C,MAAA,MAAM,MAAM,GAAA,CAAI,GAAA;AAEhB,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,iBAAiB,KAAA,IAAS,MAAA,EAAQ,YAAA,IAAgB,CAAC,GAAG,aAAa,CAAA;AACzE,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,cAAc,CAAA;AAC5C,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAI,KAAA;AAEhC,MAAA,MAAM,IAAA,GAAO,OAAO,KAAA,CAAM,OAAA,CAAQ,KAAK,cAAA,EAAgB,UAAA,EAAY,GAAA,EAAK,UAAU,CAAA,GAAI,IAAA;AACtF,MAAA,OAAO,EAAE,QAAA,EAAU,IAAA,EAAM,GAAA,EAAK,EAAA,EAAI,IAAI,EAAA,EAAG;AAAA,IAC3C,SAAS,KAAA,EAAO;AACd,MAAA,cAAA,CAAe,KAAK,CAAA;AAAA,IACtB;AAAA,EACF;AACF,CAAC","file":"run-handler.js","sourcesContent":["import { defineHandler, useConfig, rethrowForRest, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { DevkitAdapter, SnapshotStore, resolveDevkitBin, captureGit } from '@kb-labs/qa-core';\nimport { DEFAULT_TASKS, type QAPluginConfig } from '@kb-labs/qa-contracts';\n\ninterface RunBody {\n tasks?: string[];\n save?: boolean;\n runContext?: Record<string, unknown>;\n}\n\nexport default defineHandler({\n async execute(ctx: PluginContextV3, input: RestInput<unknown, RunBody>) {\n try {\n const { tasks, save = true, runContext } = input.body ?? {};\n const config = await useConfig<QAPluginConfig>();\n const cwd = ctx.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 effectiveTasks = tasks ?? config?.defaultTasks ?? [...DEFAULT_TASKS];\n const git = await captureGit(ctx.api.shell, cwd);\n\n const start = Date.now();\n const raw = await adapter.run(effectiveTasks);\n const durationMs = Date.now() - start;\n\n const snap = save ? store.saveRun(raw, effectiveTasks, durationMs, git, runContext) : null;\n return { snapshot: snap, raw, ok: raw.ok };\n } catch (error) {\n rethrowForRest(error);\n }\n },\n});\n"]}
@@ -1,15 +1,11 @@
1
1
  import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import * as _kb_labs_qa_contracts from '@kb-labs/qa-contracts';
2
3
  import { RestInput } from '@kb-labs/sdk';
3
4
 
4
- declare const _default: _kb_labs_shared_command_kit.Handler<unknown, RestInput<{}, unknown, unknown>, {
5
- groups: {
6
- checkType: string;
7
- count: number;
8
- pattern: string;
9
- packages: string[];
10
- example: string;
11
- }[];
12
- ungrouped: number;
5
+ declare const _default: _kb_labs_shared_command_kit.Handler<unknown, RestInput<unknown, unknown, unknown>, {
6
+ snapshot: null;
7
+ } | {
8
+ snapshot: _kb_labs_qa_contracts.StatsSnapshot;
13
9
  }>;
14
10
 
15
11
  export { _default as default };
@@ -0,0 +1,21 @@
1
+ import { defineHandler, useConfig, rethrowForRest } from '@kb-labs/sdk';
2
+ import { SnapshotStore } from '@kb-labs/qa-core';
3
+
4
+ // src/rest/handlers/stats-handler.ts
5
+ var stats_handler_default = defineHandler({
6
+ async execute(ctx, input) {
7
+ try {
8
+ const config = await useConfig();
9
+ const store = new SnapshotStore(ctx.cwd, config?.historyMaxEntries);
10
+ const snap = store.latestStats();
11
+ if (!snap) return { snapshot: null };
12
+ return { snapshot: snap };
13
+ } catch (error) {
14
+ rethrowForRest(error);
15
+ }
16
+ }
17
+ });
18
+
19
+ export { stats_handler_default as default };
20
+ //# sourceMappingURL=stats-handler.js.map
21
+ //# sourceMappingURL=stats-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/rest/handlers/stats-handler.ts"],"names":[],"mappings":";;;;AAIA,IAAO,wBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAkB;AACpD,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAA0B;AAC/C,MAAA,MAAM,QAAQ,IAAI,aAAA,CAAc,GAAA,CAAI,GAAA,EAAK,QAAQ,iBAAiB,CAAA;AAClE,MAAA,MAAM,IAAA,GAAO,MAAM,WAAA,EAAY;AAE/B,MAAA,IAAI,CAAC,IAAA,EAAM,OAAO,EAAE,UAAU,IAAA,EAAK;AACnC,MAAA,OAAO,EAAE,UAAU,IAAA,EAAK;AAAA,IAC1B,SAAS,KAAA,EAAO;AACd,MAAA,cAAA,CAAe,KAAK,CAAA;AAAA,IACtB;AAAA,EACF;AACF,CAAC","file":"stats-handler.js","sourcesContent":["import { defineHandler, useConfig, rethrowForRest, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { SnapshotStore } from '@kb-labs/qa-core';\nimport { type QAPluginConfig } from '@kb-labs/qa-contracts';\n\nexport default defineHandler({\n async execute(ctx: PluginContextV3, input: RestInput) {\n try {\n const config = await useConfig<QAPluginConfig>();\n const store = new SnapshotStore(ctx.cwd, config?.historyMaxEntries);\n const snap = store.latestStats();\n\n if (!snap) return { snapshot: null };\n return { snapshot: snap };\n } catch (error) {\n rethrowForRest(error);\n }\n },\n});\n"]}
@@ -1,26 +1,13 @@
1
1
  import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import * as _kb_labs_qa_contracts from '@kb-labs/qa-contracts';
2
3
  import { RestInput } from '@kb-labs/sdk';
3
4
 
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;
5
+ declare const _default: _kb_labs_shared_command_kit.Handler<unknown, RestInput<unknown, unknown, unknown>, {
6
+ latestRun: _kb_labs_qa_contracts.RunSnapshot | null;
7
+ latestCheck: _kb_labs_qa_contracts.CheckSnapshot | null;
8
+ latestStats: _kb_labs_qa_contracts.StatsSnapshot | null;
9
+ baseline: _kb_labs_qa_contracts.BaselineData | null;
10
+ defaultTasks: string[] | null;
24
11
  }>;
25
12
 
26
13
  export { _default as default };
@@ -1,32 +1,22 @@
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';
1
+ import { defineHandler, useConfig, rethrowForRest } from '@kb-labs/sdk';
2
+ import { SnapshotStore } from '@kb-labs/qa-core';
4
3
 
5
4
  // src/rest/handlers/summary-handler.ts
6
5
  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
- };
6
+ async execute(ctx, input) {
7
+ try {
8
+ const config = await useConfig();
9
+ const store = new SnapshotStore(ctx.cwd, config?.historyMaxEntries);
10
+ return {
11
+ latestRun: store.latestRun(),
12
+ latestCheck: store.latestCheck(),
13
+ latestStats: store.latestStats(),
14
+ baseline: store.loadBaseline(),
15
+ defaultTasks: config?.defaultTasks ?? null
16
+ };
17
+ } catch (error) {
18
+ rethrowForRest(error);
19
+ }
30
20
  }
31
21
  });
32
22
 
@@ -1 +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"]}
1
+ {"version":3,"sources":["../../../src/rest/handlers/summary-handler.ts"],"names":[],"mappings":";;;;AAIA,IAAO,0BAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAkB;AACpD,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAA0B;AAC/C,MAAA,MAAM,QAAQ,IAAI,aAAA,CAAc,GAAA,CAAI,GAAA,EAAK,QAAQ,iBAAiB,CAAA;AAElE,MAAA,OAAO;AAAA,QACL,SAAA,EAAW,MAAM,SAAA,EAAU;AAAA,QAC3B,WAAA,EAAa,MAAM,WAAA,EAAY;AAAA,QAC/B,WAAA,EAAa,MAAM,WAAA,EAAY;AAAA,QAC/B,QAAA,EAAU,MAAM,YAAA,EAAa;AAAA,QAC7B,YAAA,EAAc,QAAQ,YAAA,IAAgB;AAAA,OACxC;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,cAAA,CAAe,KAAK,CAAA;AAAA,IACtB;AAAA,EACF;AACF,CAAC","file":"summary-handler.js","sourcesContent":["import { defineHandler, useConfig, rethrowForRest, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { SnapshotStore } from '@kb-labs/qa-core';\nimport { type QAPluginConfig } from '@kb-labs/qa-contracts';\n\nexport default defineHandler({\n async execute(ctx: PluginContextV3, input: RestInput) {\n try {\n const config = await useConfig<QAPluginConfig>();\n const store = new SnapshotStore(ctx.cwd, config?.historyMaxEntries);\n\n return {\n latestRun: store.latestRun(),\n latestCheck: store.latestCheck(),\n latestStats: store.latestStats(),\n baseline: store.loadBaseline(),\n defaultTasks: config?.defaultTasks ?? null,\n };\n } catch (error) {\n rethrowForRest(error);\n }\n },\n});\n"]}
@@ -0,0 +1,9 @@
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, unknown>, {
5
+ tasks: string[];
6
+ defaultTasks: string[] | null;
7
+ }>;
8
+
9
+ export { _default as default };
@@ -0,0 +1,38 @@
1
+ import { defineHandler, useConfig, rethrowForRest } from '@kb-labs/sdk';
2
+ import { existsSync, readFileSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { load } from 'js-yaml';
5
+
6
+ // src/rest/handlers/tasks-handler.ts
7
+ function readDevkitTasks(cwd) {
8
+ const configFile = join(cwd, "devkit.yaml");
9
+ if (!existsSync(configFile)) return [];
10
+ try {
11
+ const raw = load(readFileSync(configFile, "utf-8"));
12
+ const tasks = raw?.tasks;
13
+ if (tasks && typeof tasks === "object" && !Array.isArray(tasks)) {
14
+ return Object.keys(tasks);
15
+ }
16
+ } catch {
17
+ }
18
+ return [];
19
+ }
20
+ var tasks_handler_default = defineHandler({
21
+ async execute(ctx, input) {
22
+ try {
23
+ const config = await useConfig();
24
+ const devkitTasks = readDevkitTasks(ctx.cwd);
25
+ const defaultTasks = config?.defaultTasks ?? null;
26
+ return {
27
+ tasks: devkitTasks,
28
+ defaultTasks
29
+ };
30
+ } catch (error) {
31
+ rethrowForRest(error);
32
+ }
33
+ }
34
+ });
35
+
36
+ export { tasks_handler_default as default };
37
+ //# sourceMappingURL=tasks-handler.js.map
38
+ //# sourceMappingURL=tasks-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/rest/handlers/tasks-handler.ts"],"names":[],"mappings":";;;;;;AAMA,SAAS,gBAAgB,GAAA,EAAuB;AAC9C,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAK,aAAa,CAAA;AAC1C,EAAA,IAAI,CAAC,UAAA,CAAW,UAAU,CAAA,SAAU,EAAC;AAErC,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,YAAA,CAAa,UAAA,EAAY,OAAO,CAAC,CAAA;AAClD,IAAA,MAAM,QAAQ,GAAA,EAAK,KAAA;AACnB,IAAA,IAAI,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,IAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AAC/D,MAAA,OAAO,MAAA,CAAO,KAAK,KAAK,CAAA;AAAA,IAC1B;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,EAAC;AACV;AAEA,IAAO,wBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAkB;AACpD,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAA0B;AAC/C,MAAA,MAAM,WAAA,GAAc,eAAA,CAAgB,GAAA,CAAI,GAAG,CAAA;AAC3C,MAAA,MAAM,YAAA,GAAe,QAAQ,YAAA,IAAgB,IAAA;AAE7C,MAAA,OAAO;AAAA,QACL,KAAA,EAAO,WAAA;AAAA,QACP;AAAA,OACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,cAAA,CAAe,KAAK,CAAA;AAAA,IACtB;AAAA,EACF;AACF,CAAC","file":"tasks-handler.js","sourcesContent":["import { defineHandler, useConfig, rethrowForRest, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { load } from 'js-yaml';\nimport { type QAPluginConfig } from '@kb-labs/qa-contracts';\n\nfunction readDevkitTasks(cwd: string): string[] {\n const configFile = join(cwd, 'devkit.yaml');\n if (!existsSync(configFile)) return [];\n\n try {\n const raw = load(readFileSync(configFile, 'utf-8')) as Record<string, unknown>;\n const tasks = raw?.tasks;\n if (tasks && typeof tasks === 'object' && !Array.isArray(tasks)) {\n return Object.keys(tasks);\n }\n } catch {\n // malformed yaml — fall through\n }\n return [];\n}\n\nexport default defineHandler({\n async execute(ctx: PluginContextV3, input: RestInput) {\n try {\n const config = await useConfig<QAPluginConfig>();\n const devkitTasks = readDevkitTasks(ctx.cwd);\n const defaultTasks = config?.defaultTasks ?? null;\n\n return {\n tasks: devkitTasks,\n defaultTasks,\n };\n } catch (error) {\n rethrowForRest(error);\n }\n },\n});\n"]}
@@ -1,48 +1,9 @@
1
1
  import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import * as _kb_labs_qa_contracts from '@kb-labs/qa-contracts';
2
3
  import { RestInput } from '@kb-labs/sdk';
3
4
 
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
- }>;
5
+ declare const _default: _kb_labs_shared_command_kit.Handler<unknown, RestInput<{
6
+ window?: string;
7
+ }, unknown, unknown>, _kb_labs_qa_contracts.TrendAnalysis>;
47
8
 
48
9
  export { _default as default };
@@ -1,27 +1,20 @@
1
- import { defineHandler } from '@kb-labs/sdk';
2
- import { loadHistory, analyzeEnrichedTrends, analyzeTrends } from '@kb-labs/qa-core';
1
+ import { defineHandler, useConfig, rethrowForRest } from '@kb-labs/sdk';
2
+ import { SnapshotStore, analyzeTrends } from '@kb-labs/qa-core';
3
3
  import { TRENDS_WINDOW } from '@kb-labs/qa-contracts';
4
4
 
5
5
  // src/rest/handlers/trends-handler.ts
6
6
  var trends_handler_default = defineHandler({
7
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
- };
8
+ try {
9
+ const config = await useConfig();
10
+ const store = new SnapshotStore(ctx.cwd, config?.historyMaxEntries);
11
+ const window = Number(input.query?.window) || TRENDS_WINDOW;
12
+ const history = store.loadRunHistory();
13
+ const analysis = analyzeTrends(history, window);
14
+ return analysis;
15
+ } catch (error) {
16
+ rethrowForRest(error);
18
17
  }
19
- const trends = analyzeTrends(history, window);
20
- return {
21
- trends,
22
- historyCount: history.length,
23
- window
24
- };
25
18
  }
26
19
  });
27
20
 
@@ -1 +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"]}
1
+ {"version":3,"sources":["../../../src/rest/handlers/trends-handler.ts"],"names":[],"mappings":";;;;;AAIA,IAAO,yBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAuC;AACzE,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAA0B;AAC/C,MAAA,MAAM,QAAQ,IAAI,aAAA,CAAc,GAAA,CAAI,GAAA,EAAK,QAAQ,iBAAiB,CAAA;AAElE,MAAA,MAAM,MAAA,GAAS,MAAA,CAAO,KAAA,CAAM,KAAA,EAAO,MAAM,CAAA,IAAK,aAAA;AAC9C,MAAA,MAAM,OAAA,GAAU,MAAM,cAAA,EAAe;AACrC,MAAA,MAAM,QAAA,GAAW,aAAA,CAAc,OAAA,EAAS,MAAM,CAAA;AAE9C,MAAA,OAAO,QAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,cAAA,CAAe,KAAK,CAAA;AAAA,IACtB;AAAA,EACF;AACF,CAAC","file":"trends-handler.js","sourcesContent":["import { defineHandler, useConfig, rethrowForRest, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { SnapshotStore, analyzeTrends } from '@kb-labs/qa-core';\nimport { TRENDS_WINDOW, type QAPluginConfig } from '@kb-labs/qa-contracts';\n\nexport default defineHandler({\n async execute(ctx: PluginContextV3, input: RestInput<{ window?: string }>) {\n try {\n const config = await useConfig<QAPluginConfig>();\n const store = new SnapshotStore(ctx.cwd, config?.historyMaxEntries);\n\n const window = Number(input.query?.window) || TRENDS_WINDOW;\n const history = store.loadRunHistory();\n const analysis = analyzeTrends(history, window);\n\n return analysis;\n } catch (error) {\n rethrowForRest(error);\n }\n },\n});\n"]}