@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.
Files changed (71) hide show
  1. package/README.md +1 -0
  2. package/dist/cli/commands/baseline-status.d.ts +10 -0
  3. package/dist/cli/commands/baseline-status.js +32 -0
  4. package/dist/cli/commands/baseline-status.js.map +1 -0
  5. package/dist/cli/commands/baseline-update.d.ts +10 -0
  6. package/dist/cli/commands/baseline-update.js +33 -0
  7. package/dist/cli/commands/baseline-update.js.map +1 -0
  8. package/dist/cli/commands/flags.d.ts +106 -0
  9. package/dist/cli/commands/flags.js +99 -0
  10. package/dist/cli/commands/flags.js.map +1 -0
  11. package/dist/cli/commands/qa-history.d.ts +10 -0
  12. package/dist/cli/commands/qa-history.js +41 -0
  13. package/dist/cli/commands/qa-history.js.map +1 -0
  14. package/dist/cli/commands/qa-regressions.d.ts +10 -0
  15. package/dist/cli/commands/qa-regressions.js +33 -0
  16. package/dist/cli/commands/qa-regressions.js.map +1 -0
  17. package/dist/cli/commands/qa-run.d.ts +16 -0
  18. package/dist/cli/commands/qa-run.js +159 -0
  19. package/dist/cli/commands/qa-run.js.map +1 -0
  20. package/dist/cli/commands/qa-save.d.ts +10 -0
  21. package/dist/cli/commands/qa-save.js +69 -0
  22. package/dist/cli/commands/qa-save.js.map +1 -0
  23. package/dist/cli/commands/qa-trends.d.ts +10 -0
  24. package/dist/cli/commands/qa-trends.js +35 -0
  25. package/dist/cli/commands/qa-trends.js.map +1 -0
  26. package/dist/index.d.ts +2 -0
  27. package/dist/index.js +390 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/manifest.d.ts +198 -0
  30. package/dist/manifest.js +391 -0
  31. package/dist/manifest.js.map +1 -0
  32. package/dist/rest/handlers/baseline-diff-handler.d.ts +33 -0
  33. package/dist/rest/handlers/baseline-diff-handler.js +51 -0
  34. package/dist/rest/handlers/baseline-diff-handler.js.map +1 -0
  35. package/dist/rest/handlers/baseline-handler.d.ts +19 -0
  36. package/dist/rest/handlers/baseline-handler.js +14 -0
  37. package/dist/rest/handlers/baseline-handler.js.map +1 -0
  38. package/dist/rest/handlers/baseline-update-handler.d.ts +20 -0
  39. package/dist/rest/handlers/baseline-update-handler.js +23 -0
  40. package/dist/rest/handlers/baseline-update-handler.js.map +1 -0
  41. package/dist/rest/handlers/details-handler.d.ts +61 -0
  42. package/dist/rest/handlers/details-handler.js +70 -0
  43. package/dist/rest/handlers/details-handler.js.map +1 -0
  44. package/dist/rest/handlers/error-groups-handler.d.ts +15 -0
  45. package/dist/rest/handlers/error-groups-handler.js +17 -0
  46. package/dist/rest/handlers/error-groups-handler.js.map +1 -0
  47. package/dist/rest/handlers/history-handler.d.ts +25 -0
  48. package/dist/rest/handlers/history-handler.js +22 -0
  49. package/dist/rest/handlers/history-handler.js.map +1 -0
  50. package/dist/rest/handlers/latest-handler.d.ts +22 -0
  51. package/dist/rest/handlers/latest-handler.js +17 -0
  52. package/dist/rest/handlers/latest-handler.js.map +1 -0
  53. package/dist/rest/handlers/package-timeline-handler.d.ts +26 -0
  54. package/dist/rest/handlers/package-timeline-handler.js +18 -0
  55. package/dist/rest/handlers/package-timeline-handler.js.map +1 -0
  56. package/dist/rest/handlers/regressions-handler.d.ts +16 -0
  57. package/dist/rest/handlers/regressions-handler.js +14 -0
  58. package/dist/rest/handlers/regressions-handler.js.map +1 -0
  59. package/dist/rest/handlers/run-check-handler.d.ts +20 -0
  60. package/dist/rest/handlers/run-check-handler.js +58 -0
  61. package/dist/rest/handlers/run-check-handler.js.map +1 -0
  62. package/dist/rest/handlers/run-handler.d.ts +33 -0
  63. package/dist/rest/handlers/run-handler.js +75 -0
  64. package/dist/rest/handlers/run-handler.js.map +1 -0
  65. package/dist/rest/handlers/summary-handler.d.ts +26 -0
  66. package/dist/rest/handlers/summary-handler.js +35 -0
  67. package/dist/rest/handlers/summary-handler.js.map +1 -0
  68. package/dist/rest/handlers/trends-handler.d.ts +48 -0
  69. package/dist/rest/handlers/trends-handler.js +30 -0
  70. package/dist/rest/handlers/trends-handler.js.map +1 -0
  71. package/package.json +71 -0
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # TODO
@@ -0,0 +1,10 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import { BaselineStatusFlags } from './flags.js';
3
+
4
+ type BaselineStatusInput = BaselineStatusFlags & {
5
+ argv?: string[];
6
+ flags?: any;
7
+ };
8
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, BaselineStatusInput, unknown>;
9
+
10
+ export { _default as default };
@@ -0,0 +1,32 @@
1
+ import { defineCommand } from '@kb-labs/sdk';
2
+ import { loadBaseline, buildBaselineReport } from '@kb-labs/qa-core';
3
+
4
+ // src/cli/commands/baseline-status.ts
5
+ var baseline_status_default = defineCommand({
6
+ id: "baseline:status",
7
+ description: "Show current baseline status",
8
+ handler: {
9
+ async execute(ctx, input) {
10
+ const { ui } = ctx;
11
+ const flags = input.flags ?? input;
12
+ const rootDir = ctx.cwd;
13
+ const baseline = loadBaseline(rootDir);
14
+ if (flags.json) {
15
+ ui?.json?.(baseline ?? { status: "no-baseline" });
16
+ return { exitCode: 0 };
17
+ }
18
+ const sections = buildBaselineReport(baseline);
19
+ for (const section of sections) {
20
+ ui?.success?.(section.header, {
21
+ title: section.header,
22
+ sections: [{ header: "", items: section.lines }]
23
+ });
24
+ }
25
+ return { exitCode: 0 };
26
+ }
27
+ }
28
+ });
29
+
30
+ export { baseline_status_default as default };
31
+ //# sourceMappingURL=baseline-status.js.map
32
+ //# sourceMappingURL=baseline-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/commands/baseline-status.ts"],"names":[],"mappings":";;;;AAMA,IAAO,0BAAQ,aAAA,CAAc;AAAA,EAC3B,EAAA,EAAI,iBAAA;AAAA,EACJ,WAAA,EAAa,8BAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAA4B;AAC9D,MAAA,MAAM,EAAE,IAAG,GAAI,GAAA;AACf,MAAA,MAAM,KAAA,GAAS,MAAc,KAAA,IAAS,KAAA;AACtC,MAAA,MAAM,UAAU,GAAA,CAAI,GAAA;AAEpB,MAAA,MAAM,QAAA,GAAW,aAAa,OAAO,CAAA;AAErC,MAAA,IAAI,MAAM,IAAA,EAAM;AACd,QAAA,EAAA,EAAI,IAAA,GAAO,QAAA,IAAY,EAAE,MAAA,EAAQ,eAAe,CAAA;AAChD,QAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,MACvB;AAEA,MAAA,MAAM,QAAA,GAAW,oBAAoB,QAAQ,CAAA;AAC7C,MAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,QAAA,EAAA,EAAI,OAAA,GAAU,QAAQ,MAAA,EAAQ;AAAA,UAC5B,OAAO,OAAA,CAAQ,MAAA;AAAA,UACf,QAAA,EAAU,CAAC,EAAE,MAAA,EAAQ,IAAI,KAAA,EAAO,OAAA,CAAQ,OAAO;AAAA,SAChD,CAAA;AAAA,MACH;AAEA,MAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,IACvB;AAAA;AAEJ,CAAC","file":"baseline-status.js","sourcesContent":["import { defineCommand, type PluginContextV3 } from '@kb-labs/sdk';\nimport { loadBaseline, buildBaselineReport } from '@kb-labs/qa-core';\nimport type { BaselineStatusFlags } from './flags.js';\n\ntype BaselineStatusInput = BaselineStatusFlags & { argv?: string[]; flags?: any };\n\nexport default defineCommand({\n id: 'baseline:status',\n description: 'Show current baseline status',\n\n handler: {\n async execute(ctx: PluginContextV3, input: BaselineStatusInput) {\n const { ui } = ctx;\n const flags = (input as any).flags ?? input;\n const rootDir = ctx.cwd;\n\n const baseline = loadBaseline(rootDir);\n\n if (flags.json) {\n ui?.json?.(baseline ?? { status: 'no-baseline' });\n return { exitCode: 0 };\n }\n\n const sections = buildBaselineReport(baseline);\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 return { exitCode: 0 };\n },\n },\n});\n"]}
@@ -0,0 +1,10 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import { BaselineUpdateFlags } from './flags.js';
3
+
4
+ type BaselineUpdateInput = BaselineUpdateFlags & {
5
+ argv?: string[];
6
+ flags?: any;
7
+ };
8
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, BaselineUpdateInput, unknown>;
9
+
10
+ export { _default as default };
@@ -0,0 +1,33 @@
1
+ import { defineCommand } from '@kb-labs/sdk';
2
+ import { captureBaseline, buildBaselineReport } from '@kb-labs/qa-core';
3
+
4
+ // src/cli/commands/baseline-update.ts
5
+ var baseline_update_default = defineCommand({
6
+ id: "baseline:update",
7
+ description: "Run full QA and save as new baseline",
8
+ handler: {
9
+ async execute(ctx, input) {
10
+ const { ui } = ctx;
11
+ const flags = input.flags ?? input;
12
+ const rootDir = ctx.cwd;
13
+ const snapshot = await captureBaseline(rootDir);
14
+ if (flags.json) {
15
+ ui?.json?.(snapshot);
16
+ return { exitCode: 0 };
17
+ }
18
+ const sections = buildBaselineReport(snapshot);
19
+ for (const section of sections) {
20
+ ui?.success?.(section.header, {
21
+ title: section.header,
22
+ sections: [{ header: "", items: section.lines }]
23
+ });
24
+ }
25
+ ui?.success?.("Baseline captured successfully", {});
26
+ return { exitCode: 0 };
27
+ }
28
+ }
29
+ });
30
+
31
+ export { baseline_update_default as default };
32
+ //# sourceMappingURL=baseline-update.js.map
33
+ //# sourceMappingURL=baseline-update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/commands/baseline-update.ts"],"names":[],"mappings":";;;;AAMA,IAAO,0BAAQ,aAAA,CAAc;AAAA,EAC3B,EAAA,EAAI,iBAAA;AAAA,EACJ,WAAA,EAAa,sCAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAA4B;AAC9D,MAAA,MAAM,EAAE,IAAG,GAAI,GAAA;AACf,MAAA,MAAM,KAAA,GAAS,MAAc,KAAA,IAAS,KAAA;AACtC,MAAA,MAAM,UAAU,GAAA,CAAI,GAAA;AAEpB,MAAA,MAAM,QAAA,GAAW,MAAM,eAAA,CAAgB,OAAO,CAAA;AAE9C,MAAA,IAAI,MAAM,IAAA,EAAM;AACd,QAAA,EAAA,EAAI,OAAO,QAAQ,CAAA;AACnB,QAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,MACvB;AAEA,MAAA,MAAM,QAAA,GAAW,oBAAoB,QAAQ,CAAA;AAC7C,MAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,QAAA,EAAA,EAAI,OAAA,GAAU,QAAQ,MAAA,EAAQ;AAAA,UAC5B,OAAO,OAAA,CAAQ,MAAA;AAAA,UACf,QAAA,EAAU,CAAC,EAAE,MAAA,EAAQ,IAAI,KAAA,EAAO,OAAA,CAAQ,OAAO;AAAA,SAChD,CAAA;AAAA,MACH;AAEA,MAAA,EAAA,EAAI,OAAA,GAAU,gCAAA,EAAkC,EAAE,CAAA;AAClD,MAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,IACvB;AAAA;AAEJ,CAAC","file":"baseline-update.js","sourcesContent":["import { defineCommand, type PluginContextV3 } from '@kb-labs/sdk';\nimport { captureBaseline, buildBaselineReport } from '@kb-labs/qa-core';\nimport type { BaselineUpdateFlags } from './flags.js';\n\ntype BaselineUpdateInput = BaselineUpdateFlags & { argv?: string[]; flags?: any };\n\nexport default defineCommand({\n id: 'baseline:update',\n description: 'Run full QA and save as new baseline',\n\n handler: {\n async execute(ctx: PluginContextV3, input: BaselineUpdateInput) {\n const { ui } = ctx;\n const flags = (input as any).flags ?? input;\n const rootDir = ctx.cwd;\n\n const snapshot = await captureBaseline(rootDir);\n\n if (flags.json) {\n ui?.json?.(snapshot);\n return { exitCode: 0 };\n }\n\n const sections = buildBaselineReport(snapshot);\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 ui?.success?.('Baseline captured successfully', {});\n return { exitCode: 0 };\n },\n },\n});\n"]}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * QA Plugin CLI flag definitions.
3
+ * DRY: Define once, use in manifest and command handlers.
4
+ */
5
+ declare const qaRunFlags: {
6
+ readonly json: {
7
+ readonly type: "boolean";
8
+ readonly description: "Output JSON format";
9
+ readonly default: false;
10
+ };
11
+ readonly 'skip-check': {
12
+ readonly type: "array";
13
+ readonly description: "Skip specific check IDs (e.g. --skip-check build --skip-check lint)";
14
+ };
15
+ readonly 'no-cache': {
16
+ readonly type: "boolean";
17
+ readonly description: "Disable caching (force full run)";
18
+ readonly default: false;
19
+ };
20
+ readonly all: {
21
+ readonly type: "boolean";
22
+ readonly description: "Run all packages, ignoring affected analysis";
23
+ readonly default: false;
24
+ };
25
+ readonly package: {
26
+ readonly type: "string";
27
+ readonly description: "Filter by package name";
28
+ readonly alias: "p";
29
+ };
30
+ readonly repo: {
31
+ readonly type: "string";
32
+ readonly description: "Filter by repo name";
33
+ readonly alias: "r";
34
+ };
35
+ readonly scope: {
36
+ readonly type: "string";
37
+ readonly description: "Filter by npm scope";
38
+ readonly alias: "s";
39
+ };
40
+ readonly summary: {
41
+ readonly type: "boolean";
42
+ readonly description: "Show summary-only report (legacy flat format)";
43
+ readonly default: false;
44
+ };
45
+ };
46
+ type QARunFlags = typeof qaRunFlags;
47
+ declare const qaSaveFlags: {
48
+ readonly json: {
49
+ readonly type: "boolean";
50
+ readonly description: "Output JSON format";
51
+ readonly default: false;
52
+ };
53
+ };
54
+ type QASaveFlags = typeof qaSaveFlags;
55
+ declare const qaHistoryFlags: {
56
+ readonly json: {
57
+ readonly type: "boolean";
58
+ readonly description: "Output JSON format";
59
+ readonly default: false;
60
+ };
61
+ readonly limit: {
62
+ readonly type: "number";
63
+ readonly description: "Number of entries to show";
64
+ readonly default: 20;
65
+ };
66
+ };
67
+ type QAHistoryFlags = typeof qaHistoryFlags;
68
+ declare const qaTrendsFlags: {
69
+ readonly json: {
70
+ readonly type: "boolean";
71
+ readonly description: "Output JSON format";
72
+ readonly default: false;
73
+ };
74
+ readonly window: {
75
+ readonly type: "number";
76
+ readonly description: "Number of entries for trend window";
77
+ readonly default: 10;
78
+ };
79
+ };
80
+ type QATrendsFlags = typeof qaTrendsFlags;
81
+ declare const qaRegressionsFlags: {
82
+ readonly json: {
83
+ readonly type: "boolean";
84
+ readonly description: "Output JSON format";
85
+ readonly default: false;
86
+ };
87
+ };
88
+ type QARegressionsFlags = typeof qaRegressionsFlags;
89
+ declare const baselineUpdateFlags: {
90
+ readonly json: {
91
+ readonly type: "boolean";
92
+ readonly description: "Output JSON format";
93
+ readonly default: false;
94
+ };
95
+ };
96
+ type BaselineUpdateFlags = typeof baselineUpdateFlags;
97
+ declare const baselineStatusFlags: {
98
+ readonly json: {
99
+ readonly type: "boolean";
100
+ readonly description: "Output JSON format";
101
+ readonly default: false;
102
+ };
103
+ };
104
+ type BaselineStatusFlags = typeof baselineStatusFlags;
105
+
106
+ export { type BaselineStatusFlags, type BaselineUpdateFlags, type QAHistoryFlags, type QARegressionsFlags, type QARunFlags, type QASaveFlags, type QATrendsFlags, baselineStatusFlags, baselineUpdateFlags, qaHistoryFlags, qaRegressionsFlags, qaRunFlags, qaSaveFlags, qaTrendsFlags };
@@ -0,0 +1,99 @@
1
+ // src/cli/commands/flags.ts
2
+ var JSON_FLAG_DESCRIPTION = "Output JSON format";
3
+ var qaRunFlags = {
4
+ json: {
5
+ type: "boolean",
6
+ description: JSON_FLAG_DESCRIPTION,
7
+ default: false
8
+ },
9
+ "skip-check": {
10
+ type: "array",
11
+ description: "Skip specific check IDs (e.g. --skip-check build --skip-check lint)"
12
+ },
13
+ "no-cache": {
14
+ type: "boolean",
15
+ description: "Disable caching (force full run)",
16
+ default: false
17
+ },
18
+ all: {
19
+ type: "boolean",
20
+ description: "Run all packages, ignoring affected analysis",
21
+ default: false
22
+ },
23
+ package: {
24
+ type: "string",
25
+ description: "Filter by package name",
26
+ alias: "p"
27
+ },
28
+ repo: {
29
+ type: "string",
30
+ description: "Filter by repo name",
31
+ alias: "r"
32
+ },
33
+ scope: {
34
+ type: "string",
35
+ description: "Filter by npm scope",
36
+ alias: "s"
37
+ },
38
+ summary: {
39
+ type: "boolean",
40
+ description: "Show summary-only report (legacy flat format)",
41
+ default: false
42
+ }
43
+ };
44
+ var qaSaveFlags = {
45
+ json: {
46
+ type: "boolean",
47
+ description: JSON_FLAG_DESCRIPTION,
48
+ default: false
49
+ }
50
+ };
51
+ var qaHistoryFlags = {
52
+ json: {
53
+ type: "boolean",
54
+ description: JSON_FLAG_DESCRIPTION,
55
+ default: false
56
+ },
57
+ limit: {
58
+ type: "number",
59
+ description: "Number of entries to show",
60
+ default: 20
61
+ }
62
+ };
63
+ var qaTrendsFlags = {
64
+ json: {
65
+ type: "boolean",
66
+ description: JSON_FLAG_DESCRIPTION,
67
+ default: false
68
+ },
69
+ window: {
70
+ type: "number",
71
+ description: "Number of entries for trend window",
72
+ default: 10
73
+ }
74
+ };
75
+ var qaRegressionsFlags = {
76
+ json: {
77
+ type: "boolean",
78
+ description: JSON_FLAG_DESCRIPTION,
79
+ default: false
80
+ }
81
+ };
82
+ var baselineUpdateFlags = {
83
+ json: {
84
+ type: "boolean",
85
+ description: JSON_FLAG_DESCRIPTION,
86
+ default: false
87
+ }
88
+ };
89
+ var baselineStatusFlags = {
90
+ json: {
91
+ type: "boolean",
92
+ description: JSON_FLAG_DESCRIPTION,
93
+ default: false
94
+ }
95
+ };
96
+
97
+ export { baselineStatusFlags, baselineUpdateFlags, qaHistoryFlags, qaRegressionsFlags, qaRunFlags, qaSaveFlags, qaTrendsFlags };
98
+ //# sourceMappingURL=flags.js.map
99
+ //# sourceMappingURL=flags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/commands/flags.ts"],"names":[],"mappings":";AAKA,IAAM,qBAAA,GAAwB,oBAAA;AAEvB,IAAM,UAAA,GAAa;AAAA,EACxB,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,qBAAA;AAAA,IACb,OAAA,EAAS;AAAA,GACX;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,IAAA,EAAM,OAAA;AAAA,IACN,WAAA,EAAa;AAAA,GACf;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,kCAAA;AAAA,IACb,OAAA,EAAS;AAAA,GACX;AAAA,EACA,GAAA,EAAK;AAAA,IACH,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,8CAAA;AAAA,IACb,OAAA,EAAS;AAAA,GACX;AAAA,EACA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,EAAa,wBAAA;AAAA,IACb,KAAA,EAAO;AAAA,GACT;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,EAAa,qBAAA;AAAA,IACb,KAAA,EAAO;AAAA,GACT;AAAA,EACA,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,EAAa,qBAAA;AAAA,IACb,KAAA,EAAO;AAAA,GACT;AAAA,EACA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,+CAAA;AAAA,IACb,OAAA,EAAS;AAAA;AAEb;AAIO,IAAM,WAAA,GAAc;AAAA,EACzB,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,qBAAA;AAAA,IACb,OAAA,EAAS;AAAA;AAEb;AAIO,IAAM,cAAA,GAAiB;AAAA,EAC5B,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,qBAAA;AAAA,IACb,OAAA,EAAS;AAAA,GACX;AAAA,EACA,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,EAAa,2BAAA;AAAA,IACb,OAAA,EAAS;AAAA;AAEb;AAIO,IAAM,aAAA,GAAgB;AAAA,EAC3B,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,qBAAA;AAAA,IACb,OAAA,EAAS;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,EAAa,oCAAA;AAAA,IACb,OAAA,EAAS;AAAA;AAEb;AAIO,IAAM,kBAAA,GAAqB;AAAA,EAChC,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,qBAAA;AAAA,IACb,OAAA,EAAS;AAAA;AAEb;AAIO,IAAM,mBAAA,GAAsB;AAAA,EACjC,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,qBAAA;AAAA,IACb,OAAA,EAAS;AAAA;AAEb;AAIO,IAAM,mBAAA,GAAsB;AAAA,EACjC,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,qBAAA;AAAA,IACb,OAAA,EAAS;AAAA;AAEb","file":"flags.js","sourcesContent":["/**\n * QA Plugin CLI flag definitions.\n * DRY: Define once, use in manifest and command handlers.\n */\n\nconst JSON_FLAG_DESCRIPTION = 'Output JSON format';\n\nexport const qaRunFlags = {\n json: {\n type: 'boolean',\n description: JSON_FLAG_DESCRIPTION,\n default: false,\n },\n 'skip-check': {\n type: 'array',\n description: 'Skip specific check IDs (e.g. --skip-check build --skip-check lint)',\n },\n 'no-cache': {\n type: 'boolean',\n description: 'Disable caching (force full run)',\n default: false,\n },\n all: {\n type: 'boolean',\n description: 'Run all packages, ignoring affected analysis',\n default: false,\n },\n package: {\n type: 'string',\n description: 'Filter by package name',\n alias: 'p',\n },\n repo: {\n type: 'string',\n description: 'Filter by repo name',\n alias: 'r',\n },\n scope: {\n type: 'string',\n description: 'Filter by npm scope',\n alias: 's',\n },\n summary: {\n type: 'boolean',\n description: 'Show summary-only report (legacy flat format)',\n default: false,\n },\n} as const;\n\nexport type QARunFlags = typeof qaRunFlags;\n\nexport const qaSaveFlags = {\n json: {\n type: 'boolean',\n description: JSON_FLAG_DESCRIPTION,\n default: false,\n },\n} as const;\n\nexport type QASaveFlags = typeof qaSaveFlags;\n\nexport const qaHistoryFlags = {\n json: {\n type: 'boolean',\n description: JSON_FLAG_DESCRIPTION,\n default: false,\n },\n limit: {\n type: 'number',\n description: 'Number of entries to show',\n default: 20,\n },\n} as const;\n\nexport type QAHistoryFlags = typeof qaHistoryFlags;\n\nexport const qaTrendsFlags = {\n json: {\n type: 'boolean',\n description: JSON_FLAG_DESCRIPTION,\n default: false,\n },\n window: {\n type: 'number',\n description: 'Number of entries for trend window',\n default: 10,\n },\n} as const;\n\nexport type QATrendsFlags = typeof qaTrendsFlags;\n\nexport const qaRegressionsFlags = {\n json: {\n type: 'boolean',\n description: JSON_FLAG_DESCRIPTION,\n default: false,\n },\n} as const;\n\nexport type QARegressionsFlags = typeof qaRegressionsFlags;\n\nexport const baselineUpdateFlags = {\n json: {\n type: 'boolean',\n description: JSON_FLAG_DESCRIPTION,\n default: false,\n },\n} as const;\n\nexport type BaselineUpdateFlags = typeof baselineUpdateFlags;\n\nexport const baselineStatusFlags = {\n json: {\n type: 'boolean',\n description: JSON_FLAG_DESCRIPTION,\n default: false,\n },\n} as const;\n\nexport type BaselineStatusFlags = typeof baselineStatusFlags;\n"]}
@@ -0,0 +1,10 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import { QAHistoryFlags } from './flags.js';
3
+
4
+ type QAHistoryInput = QAHistoryFlags & {
5
+ argv?: string[];
6
+ flags?: any;
7
+ };
8
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, QAHistoryInput, unknown>;
9
+
10
+ export { _default as default };
@@ -0,0 +1,41 @@
1
+ import { defineCommand } from '@kb-labs/sdk';
2
+ import { loadHistory, buildHistoryTable } from '@kb-labs/qa-core';
3
+
4
+ // src/cli/commands/qa-history.ts
5
+ var qa_history_default = defineCommand({
6
+ id: "qa:history",
7
+ description: "Show QA run history",
8
+ handler: {
9
+ async execute(ctx, input) {
10
+ const { ui } = ctx;
11
+ const flags = input.flags ?? input;
12
+ const rootDir = ctx.cwd;
13
+ const history = loadHistory(rootDir);
14
+ if (history.length === 0) {
15
+ if (flags.json) {
16
+ ui?.json?.([]);
17
+ return { exitCode: 0 };
18
+ }
19
+ ui?.success?.("No QA history found. Run qa:save first.", {});
20
+ return { exitCode: 0 };
21
+ }
22
+ const limit = typeof flags.limit === "number" ? flags.limit : 20;
23
+ if (flags.json) {
24
+ ui?.json?.(history.slice(-limit));
25
+ return { exitCode: 0 };
26
+ }
27
+ const sections = buildHistoryTable(history, limit);
28
+ for (const section of sections) {
29
+ ui?.success?.(section.header, {
30
+ title: section.header,
31
+ sections: [{ header: "", items: section.lines }]
32
+ });
33
+ }
34
+ return { exitCode: 0 };
35
+ }
36
+ }
37
+ });
38
+
39
+ export { qa_history_default as default };
40
+ //# sourceMappingURL=qa-history.js.map
41
+ //# sourceMappingURL=qa-history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/commands/qa-history.ts"],"names":[],"mappings":";;;;AAMA,IAAO,qBAAQ,aAAA,CAAc;AAAA,EAC3B,EAAA,EAAI,YAAA;AAAA,EACJ,WAAA,EAAa,qBAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAuB;AACzD,MAAA,MAAM,EAAE,IAAG,GAAI,GAAA;AACf,MAAA,MAAM,KAAA,GAAS,MAAc,KAAA,IAAS,KAAA;AACtC,MAAA,MAAM,UAAU,GAAA,CAAI,GAAA;AAEpB,MAAA,MAAM,OAAA,GAAU,YAAY,OAAO,CAAA;AAEnC,MAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,QAAA,IAAI,MAAM,IAAA,EAAM;AACd,UAAA,EAAA,EAAI,IAAA,GAAO,EAAE,CAAA;AACb,UAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,QACvB;AACA,QAAA,EAAA,EAAI,OAAA,GAAU,yCAAA,EAA2C,EAAE,CAAA;AAC3D,QAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,MACvB;AAEA,MAAA,MAAM,QAAQ,OAAO,KAAA,CAAM,KAAA,KAAU,QAAA,GAAW,MAAM,KAAA,GAAQ,EAAA;AAE9D,MAAA,IAAI,MAAM,IAAA,EAAM;AACd,QAAA,EAAA,EAAI,IAAA,GAAO,OAAA,CAAQ,KAAA,CAAM,CAAC,KAAK,CAAC,CAAA;AAChC,QAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,MACvB;AAEA,MAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,OAAA,EAAS,KAAK,CAAA;AACjD,MAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,QAAA,EAAA,EAAI,OAAA,GAAU,QAAQ,MAAA,EAAQ;AAAA,UAC5B,OAAO,OAAA,CAAQ,MAAA;AAAA,UACf,QAAA,EAAU,CAAC,EAAE,MAAA,EAAQ,IAAI,KAAA,EAAO,OAAA,CAAQ,OAAO;AAAA,SAChD,CAAA;AAAA,MACH;AAEA,MAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,IACvB;AAAA;AAEJ,CAAC","file":"qa-history.js","sourcesContent":["import { defineCommand, type PluginContextV3 } from '@kb-labs/sdk';\nimport { loadHistory, buildHistoryTable } from '@kb-labs/qa-core';\nimport type { QAHistoryFlags } from './flags.js';\n\ntype QAHistoryInput = QAHistoryFlags & { argv?: string[]; flags?: any };\n\nexport default defineCommand({\n id: 'qa:history',\n description: 'Show QA run history',\n\n handler: {\n async execute(ctx: PluginContextV3, input: QAHistoryInput) {\n const { ui } = ctx;\n const flags = (input as any).flags ?? input;\n const rootDir = ctx.cwd;\n\n const history = loadHistory(rootDir);\n\n if (history.length === 0) {\n if (flags.json) {\n ui?.json?.([]);\n return { exitCode: 0 };\n }\n ui?.success?.('No QA history found. Run qa:save first.', {});\n return { exitCode: 0 };\n }\n\n const limit = typeof flags.limit === 'number' ? flags.limit : 20;\n\n if (flags.json) {\n ui?.json?.(history.slice(-limit));\n return { exitCode: 0 };\n }\n\n const sections = buildHistoryTable(history, limit);\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 return { exitCode: 0 };\n },\n },\n});\n"]}
@@ -0,0 +1,10 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import { QARegressionsFlags } from './flags.js';
3
+
4
+ type QARegressionsInput = QARegressionsFlags & {
5
+ argv?: string[];
6
+ flags?: any;
7
+ };
8
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, QARegressionsInput, unknown>;
9
+
10
+ export { _default as default };
@@ -0,0 +1,33 @@
1
+ import { defineCommand } from '@kb-labs/sdk';
2
+ import { loadHistory, detectRegressions, buildRegressionsReport } from '@kb-labs/qa-core';
3
+
4
+ // src/cli/commands/qa-regressions.ts
5
+ var qa_regressions_default = defineCommand({
6
+ id: "qa:regressions",
7
+ description: "Detect regressions since last QA save",
8
+ handler: {
9
+ async execute(ctx, input) {
10
+ const { ui } = ctx;
11
+ const flags = input.flags ?? input;
12
+ const rootDir = ctx.cwd;
13
+ const history = loadHistory(rootDir);
14
+ const result = detectRegressions(history);
15
+ if (flags.json) {
16
+ ui?.json?.(result);
17
+ return { exitCode: result.hasRegressions ? 1 : 0 };
18
+ }
19
+ const sections = buildRegressionsReport(result, history);
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 };
27
+ }
28
+ }
29
+ });
30
+
31
+ export { qa_regressions_default as default };
32
+ //# sourceMappingURL=qa-regressions.js.map
33
+ //# sourceMappingURL=qa-regressions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/commands/qa-regressions.ts"],"names":[],"mappings":";;;;AAMA,IAAO,yBAAQ,aAAA,CAAc;AAAA,EAC3B,EAAA,EAAI,gBAAA;AAAA,EACJ,WAAA,EAAa,uCAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAA2B;AAC7D,MAAA,MAAM,EAAE,IAAG,GAAI,GAAA;AACf,MAAA,MAAM,KAAA,GAAS,MAAc,KAAA,IAAS,KAAA;AACtC,MAAA,MAAM,UAAU,GAAA,CAAI,GAAA;AAEpB,MAAA,MAAM,OAAA,GAAU,YAAY,OAAO,CAAA;AACnC,MAAA,MAAM,MAAA,GAAS,kBAAkB,OAAO,CAAA;AAExC,MAAA,IAAI,MAAM,IAAA,EAAM;AACd,QAAA,EAAA,EAAI,OAAO,MAAM,CAAA;AACjB,QAAA,OAAO,EAAE,QAAA,EAAU,MAAA,CAAO,cAAA,GAAiB,IAAI,CAAA,EAAE;AAAA,MACnD;AAEA,MAAA,MAAM,QAAA,GAAW,sBAAA,CAAuB,MAAA,EAAQ,OAAO,CAAA;AACvD,MAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,QAAA,EAAA,EAAI,OAAA,GAAU,QAAQ,MAAA,EAAQ;AAAA,UAC5B,OAAO,OAAA,CAAQ,MAAA;AAAA,UACf,QAAA,EAAU,CAAC,EAAE,MAAA,EAAQ,IAAI,KAAA,EAAO,OAAA,CAAQ,OAAO;AAAA,SAChD,CAAA;AAAA,MACH;AAEA,MAAA,OAAO,EAAE,QAAA,EAAU,MAAA,CAAO,cAAA,GAAiB,IAAI,CAAA,EAAE;AAAA,IACnD;AAAA;AAEJ,CAAC","file":"qa-regressions.js","sourcesContent":["import { defineCommand, type PluginContextV3 } from '@kb-labs/sdk';\nimport { loadHistory, detectRegressions, buildRegressionsReport } from '@kb-labs/qa-core';\nimport type { QARegressionsFlags } from './flags.js';\n\ntype QARegressionsInput = QARegressionsFlags & { argv?: string[]; flags?: any };\n\nexport default defineCommand({\n id: 'qa:regressions',\n description: 'Detect regressions since last QA save',\n\n handler: {\n async execute(ctx: PluginContextV3, input: QARegressionsInput) {\n const { ui } = ctx;\n const flags = (input as any).flags ?? input;\n const rootDir = ctx.cwd;\n\n const history = loadHistory(rootDir);\n const result = detectRegressions(history);\n\n if (flags.json) {\n ui?.json?.(result);\n return { exitCode: result.hasRegressions ? 1 : 0 };\n }\n\n const sections = buildRegressionsReport(result, history);\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 return { exitCode: result.hasRegressions ? 1 : 0 };\n },\n },\n});\n"]}
@@ -0,0 +1,16 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import { CLIInput } from '@kb-labs/sdk';
3
+
4
+ interface QARunFlags {
5
+ json?: boolean;
6
+ 'skip-check'?: string | string[];
7
+ 'no-cache'?: boolean;
8
+ all?: boolean;
9
+ package?: string;
10
+ repo?: string;
11
+ scope?: string;
12
+ summary?: boolean;
13
+ }
14
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<QARunFlags>, unknown>;
15
+
16
+ export { _default as default };
@@ -0,0 +1,159 @@
1
+ import { defineCommand, useConfig } from '@kb-labs/sdk';
2
+ import { getWorkspacePackages, runQA, loadBaseline, compareWithBaseline, resolveCategories, groupResults, buildDetailedJsonReport, buildRunReport, buildDetailedRunReport } from '@kb-labs/qa-core';
3
+
4
+ // 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
+ var qa_run_default = defineCommand({
17
+ id: "qa:run",
18
+ description: "Run all QA checks (build, lint, types, tests)",
19
+ handler: {
20
+ async execute(ctx, input) {
21
+ const { ui } = ctx;
22
+ const { flags } = input;
23
+ const rootDir = ctx.cwd;
24
+ let config;
25
+ try {
26
+ config = await Promise.race([
27
+ useConfig(),
28
+ new Promise((resolve) => {
29
+ setTimeout(() => resolve(void 0), 3e3);
30
+ })
31
+ ]);
32
+ } catch {
33
+ }
34
+ const scopeKey = flags.scope;
35
+ const checks = (scopeKey ? config?.scopes?.[scopeKey]?.checks : void 0) ?? config?.checks;
36
+ const rawSkip = flags["skip-check"];
37
+ const skipChecks = Array.isArray(rawSkip) ? rawSkip : rawSkip ? [rawSkip] : [];
38
+ const isJson = !!flags.json;
39
+ let totalPkgs = 0;
40
+ if (!isJson) {
41
+ try {
42
+ const pkgs = getWorkspacePackages(rootDir, {
43
+ package: flags.package,
44
+ repo: flags.repo,
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
+ }
142
+ } else {
143
+ const sections = buildDetailedRunReport(grouped, diff);
144
+ for (const section of sections) {
145
+ ui?.success?.(section.header, {
146
+ title: section.header,
147
+ sections: [{ header: "", items: section.lines }]
148
+ });
149
+ }
150
+ }
151
+ const hasFails = Object.values(results).some((r) => r.failed.length > 0);
152
+ return { exitCode: hasFails ? 1 : 0 };
153
+ }
154
+ }
155
+ });
156
+
157
+ export { qa_run_default as default };
158
+ //# sourceMappingURL=qa-run.js.map
159
+ //# sourceMappingURL=qa-run.js.map
@@ -0,0 +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"]}
@@ -0,0 +1,10 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import { QASaveFlags } from './flags.js';
3
+
4
+ type QASaveInput = QASaveFlags & {
5
+ argv?: string[];
6
+ flags?: any;
7
+ };
8
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, QASaveInput, unknown>;
9
+
10
+ export { _default as default };