@kb-labs/qa-entry 2.93.0 → 2.96.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) 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/{919.js → 215.js} +1 -1
  81. package/dist/widgets/370.js +1 -1
  82. package/dist/widgets/{805.js → 46.js} +92 -92
  83. package/dist/widgets/50.js +1 -1
  84. package/dist/widgets/62.js +96 -0
  85. package/dist/widgets/648.js +1 -0
  86. package/dist/widgets/669.js +1 -1
  87. package/dist/widgets/775.js +1 -1
  88. package/dist/widgets/78.js +1 -0
  89. package/dist/widgets/823.js +1 -0
  90. package/dist/widgets/968.js +2 -2
  91. package/dist/widgets/__federation_expose_QADashboard.js +1 -1
  92. package/dist/widgets/mf-manifest.json +32 -31
  93. package/dist/widgets/mf-stats.json +32 -31
  94. package/dist/widgets/remoteEntry.js +2 -2
  95. package/package.json +12 -9
  96. package/dist/cli/commands/qa-save.d.ts +0 -10
  97. package/dist/cli/commands/qa-save.js +0 -69
  98. package/dist/cli/commands/qa-save.js.map +0 -1
  99. package/dist/rest/handlers/details-handler.d.ts +0 -61
  100. package/dist/rest/handlers/details-handler.js +0 -70
  101. package/dist/rest/handlers/details-handler.js.map +0 -1
  102. package/dist/rest/handlers/error-groups-handler.js +0 -17
  103. package/dist/rest/handlers/error-groups-handler.js.map +0 -1
  104. package/dist/rest/handlers/latest-handler.d.ts +0 -22
  105. package/dist/rest/handlers/latest-handler.js +0 -17
  106. package/dist/rest/handlers/latest-handler.js.map +0 -1
  107. package/dist/rest/handlers/run-check-handler.d.ts +0 -20
  108. package/dist/rest/handlers/run-check-handler.js +0 -58
  109. package/dist/rest/handlers/run-check-handler.js.map +0 -1
  110. package/dist/widgets/418.js +0 -38
  111. package/dist/widgets/451.js +0 -1
  112. package/dist/widgets/694.js +0 -1
@@ -1,125 +1,111 @@
1
+ import { defineFlags } from '@kb-labs/sdk';
2
+
1
3
  // 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)"
4
+ var qaRunFlags = defineFlags({
5
+ tasks: {
6
+ type: "string",
7
+ description: "Comma-separated tasks to run (default: build,lint,type-check,test)"
12
8
  },
13
- "no-cache": {
9
+ save: {
14
10
  type: "boolean",
15
- description: "Disable caching (force full run)",
16
- default: false
11
+ description: "Save snapshot to history",
12
+ default: true
17
13
  },
18
- all: {
14
+ json: {
19
15
  type: "boolean",
20
- description: "Run all packages, ignoring affected analysis",
16
+ description: "Output JSON",
21
17
  default: false
18
+ }
19
+ });
20
+ var qaCheckFlags = defineFlags({
21
+ save: {
22
+ type: "boolean",
23
+ description: "Save snapshot to history",
24
+ default: true
22
25
  },
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: {
26
+ json: {
39
27
  type: "boolean",
40
- description: "Show summary-only report (legacy flat format)",
28
+ description: "Output JSON",
41
29
  default: false
42
30
  }
43
- };
44
- var qaSaveFlags = {
31
+ });
32
+ var qaStatsFlags = defineFlags({
33
+ save: {
34
+ type: "boolean",
35
+ description: "Save snapshot to history",
36
+ default: true
37
+ },
45
38
  json: {
46
39
  type: "boolean",
47
- description: JSON_FLAG_DESCRIPTION,
40
+ description: "Output JSON",
48
41
  default: false
49
42
  }
50
- };
51
- var qaHistoryFlags = {
52
- json: {
43
+ });
44
+ var qaGateFlags = defineFlags({
45
+ save: {
53
46
  type: "boolean",
54
- description: JSON_FLAG_DESCRIPTION,
47
+ description: "Save snapshot to history",
55
48
  default: false
56
49
  },
50
+ json: {
51
+ type: "boolean",
52
+ description: "Output JSON",
53
+ default: false
54
+ }
55
+ });
56
+ var qaHistoryFlags = defineFlags({
57
57
  limit: {
58
58
  type: "number",
59
- description: "Number of entries to show",
59
+ description: "Max entries to show",
60
60
  default: 20
61
- }
62
- };
63
- var qaTrendsFlags = {
61
+ },
64
62
  json: {
65
63
  type: "boolean",
66
- description: JSON_FLAG_DESCRIPTION,
64
+ description: "Output JSON",
67
65
  default: false
68
- },
66
+ }
67
+ });
68
+ var qaTrendsFlags = defineFlags({
69
69
  window: {
70
70
  type: "number",
71
- description: "Number of entries for trend window",
71
+ description: "Number of history entries to analyze",
72
72
  default: 10
73
- }
74
- };
75
- var qaRegressionsFlags = {
73
+ },
76
74
  json: {
77
75
  type: "boolean",
78
- description: JSON_FLAG_DESCRIPTION,
76
+ description: "Output JSON",
79
77
  default: false
80
78
  }
81
- };
82
- var baselineUpdateFlags = {
79
+ });
80
+ var qaRegressionsFlags = defineFlags({
83
81
  json: {
84
82
  type: "boolean",
85
- description: JSON_FLAG_DESCRIPTION,
83
+ description: "Output JSON",
86
84
  default: false
87
85
  }
88
- };
89
- var baselineStatusFlags = {
86
+ });
87
+ var baselineUpdateFlags = defineFlags({
90
88
  json: {
91
89
  type: "boolean",
92
- description: JSON_FLAG_DESCRIPTION,
90
+ description: "Output JSON",
93
91
  default: false
94
92
  }
95
- };
96
- var qaCheckFlags = {
97
- id: {
98
- type: "string",
99
- description: "Check ID to run (must match a check in qa.checks config)",
100
- demandOption: true
101
- },
102
- base: {
103
- type: "string",
104
- description: "Base branch/commit for diff strategies (diffOnly, newFiles). Default: main",
105
- default: "main"
106
- },
107
- context: {
108
- type: "string",
109
- description: 'JSON context to attach to history entry (e.g. {"taskId":"123"})'
110
- },
93
+ });
94
+ var baselineStatusFlags = defineFlags({
111
95
  json: {
112
96
  type: "boolean",
113
- description: JSON_FLAG_DESCRIPTION,
97
+ description: "Output JSON",
114
98
  default: false
115
- },
116
- save: {
99
+ }
100
+ });
101
+ var baselineDiffFlags = defineFlags({
102
+ json: {
117
103
  type: "boolean",
118
- description: "Save result to history after running (default: true)",
119
- default: true
104
+ description: "Output JSON",
105
+ default: false
120
106
  }
121
- };
107
+ });
122
108
 
123
- export { baselineStatusFlags, baselineUpdateFlags, qaCheckFlags, qaHistoryFlags, qaRegressionsFlags, qaRunFlags, qaSaveFlags, qaTrendsFlags };
109
+ export { baselineDiffFlags, baselineStatusFlags, baselineUpdateFlags, qaCheckFlags, qaGateFlags, qaHistoryFlags, qaRegressionsFlags, qaRunFlags, qaStatsFlags, qaTrendsFlags };
124
110
  //# sourceMappingURL=flags.js.map
125
111
  //# sourceMappingURL=flags.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/cli/commands/flags.ts"],"names":[],"mappings":"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","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\nexport const qaCheckFlags = {\n id: {\n type: 'string',\n description: 'Check ID to run (must match a check in qa.checks config)',\n demandOption: true,\n },\n base: {\n type: 'string',\n description: 'Base branch/commit for diff strategies (diffOnly, newFiles). Default: main',\n default: 'main',\n },\n context: {\n type: 'string',\n description: 'JSON context to attach to history entry (e.g. {\"taskId\":\"123\"})',\n },\n json: {\n type: 'boolean',\n description: JSON_FLAG_DESCRIPTION,\n default: false,\n },\n save: {\n type: 'boolean',\n description: 'Save result to history after running (default: true)',\n default: true,\n },\n} as const;\n\nexport type QACheckFlags = typeof qaCheckFlags;\n"]}
1
+ {"version":3,"sources":["../../../src/cli/commands/flags.ts"],"names":[],"mappings":"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","file":"flags.js","sourcesContent":["import { defineFlags } from '@kb-labs/sdk';\n\nexport const qaRunFlags = defineFlags({\n tasks: {\n type: 'string',\n description: 'Comma-separated tasks to run (default: build,lint,type-check,test)',\n },\n save: {\n type: 'boolean',\n description: 'Save snapshot to history',\n default: true,\n },\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n});\nexport type QaRunFlags = typeof qaRunFlags.infer;\n\nexport const qaCheckFlags = defineFlags({\n save: {\n type: 'boolean',\n description: 'Save snapshot to history',\n default: true,\n },\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n});\nexport type QaCheckFlags = typeof qaCheckFlags.infer;\n\nexport const qaStatsFlags = defineFlags({\n save: {\n type: 'boolean',\n description: 'Save snapshot to history',\n default: true,\n },\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n});\nexport type QaStatsFlags = typeof qaStatsFlags.infer;\n\nexport const qaGateFlags = defineFlags({\n save: {\n type: 'boolean',\n description: 'Save snapshot to history',\n default: false,\n },\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n});\nexport type QaGateFlags = typeof qaGateFlags.infer;\n\nexport const qaHistoryFlags = defineFlags({\n limit: {\n type: 'number',\n description: 'Max entries to show',\n default: 20,\n },\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n});\nexport type QaHistoryFlags = typeof qaHistoryFlags.infer;\n\nexport const qaTrendsFlags = defineFlags({\n window: {\n type: 'number',\n description: 'Number of history entries to analyze',\n default: 10,\n },\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n});\nexport type QaTrendsFlags = typeof qaTrendsFlags.infer;\n\nexport const qaRegressionsFlags = defineFlags({\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n});\nexport type QaRegressionsFlags = typeof qaRegressionsFlags.infer;\n\nexport const baselineUpdateFlags = defineFlags({\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n});\nexport type BaselineUpdateFlags = typeof baselineUpdateFlags.infer;\n\nexport const baselineStatusFlags = defineFlags({\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n});\nexport type BaselineStatusFlags = typeof baselineStatusFlags.infer;\n\nexport const baselineDiffFlags = defineFlags({\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n});\nexport type BaselineDiffFlags = typeof baselineDiffFlags.infer;\n"]}
@@ -1,40 +1,19 @@
1
1
  import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
2
  import { CLIInput } from '@kb-labs/sdk';
3
3
 
4
- interface QACheckFlags {
5
- id: string;
6
- base?: string;
7
- context?: string;
8
- json?: boolean;
9
- save?: boolean;
10
- }
11
- declare const qaCheckFlags: {
12
- readonly id: {
13
- readonly type: "string";
14
- readonly description: "Check ID to run (must match a check in qa.checks config)";
15
- readonly demandOption: true;
4
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<_kb_labs_shared_command_kit.InferFlags<{
5
+ save: {
6
+ type: "boolean";
7
+ description: string;
8
+ default: true;
16
9
  };
17
- readonly base: {
18
- readonly type: "string";
19
- readonly description: "Base branch/commit for diff strategies (diffOnly, newFiles). Default: main";
20
- readonly default: "main";
10
+ json: {
11
+ type: "boolean";
12
+ description: string;
13
+ default: false;
21
14
  };
22
- readonly context: {
23
- readonly type: "string";
24
- readonly description: "JSON context to attach to the history entry (e.g. {\"taskId\":\"123\",\"agentId\":\"claude\"})";
25
- };
26
- readonly json: {
27
- readonly type: "boolean";
28
- readonly description: "Output structured JSON report";
29
- readonly default: false;
30
- };
31
- readonly save: {
32
- readonly type: "boolean";
33
- readonly description: "Save result to history after running";
34
- readonly default: true;
35
- };
36
- };
37
- type QACheckFlagsType = typeof qaCheckFlags;
38
- declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<QACheckFlags>, unknown>;
15
+ }>>, {
16
+ exitCode: number;
17
+ }>;
39
18
 
40
- export { type QACheckFlagsType, _default as default, qaCheckFlags };
19
+ export { _default as default };
@@ -1,123 +1,43 @@
1
1
  import { defineCommand, useConfig } from '@kb-labs/sdk';
2
- import { getWorkspacePackages, runCustomChecks, createHistoryEntry, appendEntry, buildJsonReport } from '@kb-labs/qa-core';
2
+ import { resolveDevkitBin, DevkitAdapter, SnapshotStore, captureGit, buildCheckJsonReport, buildCheckReport } from '@kb-labs/qa-core';
3
3
 
4
4
  // src/cli/commands/qa-check.ts
5
- var qaCheckFlags = {
6
- id: {
7
- type: "string",
8
- description: "Check ID to run (must match a check in qa.checks config)",
9
- demandOption: true
10
- },
11
- base: {
12
- type: "string",
13
- description: "Base branch/commit for diff strategies (diffOnly, newFiles). Default: main",
14
- default: "main"
15
- },
16
- context: {
17
- type: "string",
18
- description: 'JSON context to attach to the history entry (e.g. {"taskId":"123","agentId":"claude"})'
19
- },
20
- json: {
21
- type: "boolean",
22
- description: "Output structured JSON report",
23
- default: false
24
- },
25
- save: {
26
- type: "boolean",
27
- description: "Save result to history after running",
28
- default: true
29
- }
30
- };
31
5
  var qa_check_default = defineCommand({
32
6
  id: "qa:check",
33
- description: "Run a single QA check atomically and optionally save to history",
7
+ description: "Run devkit structural checks",
34
8
  handler: {
35
9
  async execute(ctx, input) {
36
- const { ui } = ctx;
37
10
  const { flags } = input;
38
- const rootDir = ctx.cwd;
39
- const checkId = flags.id;
40
- const base = flags.base ?? "main";
41
- const isJson = !!flags.json;
42
- const shouldSave = flags.save !== false;
43
- let config;
44
- try {
45
- config = await Promise.race([
46
- useConfig(),
47
- new Promise((resolve) => {
48
- setTimeout(() => resolve(void 0), 3e3);
49
- })
50
- ]);
51
- } catch {
52
- }
53
- const allChecks = config?.checks ?? [];
54
- const checkConfig = allChecks.find((c) => c.id === checkId);
55
- if (!checkConfig) {
56
- const msg = `Check "${checkId}" not found in qa.checks config`;
57
- if (isJson) {
58
- ui?.json?.({ status: "error", message: msg });
59
- } else {
60
- ui?.error?.(msg, { title: "QA Check Error" });
61
- }
62
- return { exitCode: 1 };
63
- }
64
- let runContext;
65
- if (flags.context) {
66
- try {
67
- runContext = JSON.parse(flags.context);
68
- } catch {
69
- const msg = `Invalid JSON in --context: ${flags.context}`;
70
- if (isJson) {
71
- ui?.json?.({ status: "error", message: msg });
72
- } else {
73
- ui?.error?.(msg, { title: "QA Check Error" });
74
- }
75
- return { exitCode: 1 };
76
- }
77
- }
78
- const packages = getWorkspacePackages(rootDir, {}, config?.packages);
79
- const results = runCustomChecks(
80
- [checkConfig],
81
- packages,
82
- rootDir,
83
- void 0,
84
- base
85
- );
86
- const checkResult = results[checkId];
87
- const hasFailed = checkResult ? checkResult.failed.length > 0 : false;
88
- if (shouldSave) {
89
- const entry = createHistoryEntry(results, rootDir, packages, runContext);
90
- appendEntry(rootDir, entry, allChecks);
91
- }
92
- const severity = checkConfig.severity ?? "blocker";
93
- const report = buildJsonReport(results, null, [checkConfig]);
94
- if (isJson) {
95
- ui?.json?.(report);
11
+ const config = await useConfig();
12
+ const cwd = ctx.cwd ?? process.cwd();
13
+ const binaryPath = resolveDevkitBin(cwd, config?.devkitPath);
14
+ const adapter = new DevkitAdapter({ binaryPath, cwd, shell: ctx.api.shell });
15
+ const store = new SnapshotStore(cwd, config?.historyMaxEntries);
16
+ const save = flags.save !== false;
17
+ const git = await captureGit(ctx.api.shell, cwd);
18
+ const start = Date.now();
19
+ const raw = await adapter.check();
20
+ const durationMs = Date.now() - start;
21
+ const snap = save ? store.saveCheck(raw, durationMs, git) : null;
22
+ const effective = snap ?? {
23
+ kind: "check",
24
+ id: "",
25
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
26
+ durationMs,
27
+ raw
28
+ };
29
+ if (flags.json) {
30
+ ctx.ui?.json?.(buildCheckJsonReport(effective));
96
31
  } else {
97
- if (hasFailed) {
98
- const findings = severity === "warning" ? report.warnings : report.blockers;
99
- const checkFindings = findings.find((f) => f.check === checkId);
100
- if (checkFindings) {
101
- ui?.error?.(`Check "${checkId}" failed`, {
102
- title: `${severity === "warning" ? "\u26A0" : "\u2717"} ${checkId}`,
103
- sections: [{
104
- header: "",
105
- items: checkFindings.items.map(
106
- (item) => ` ${item.target}: ${item.message}${item.fix ? ` \u2192 ${item.fix}` : ""}`
107
- )
108
- }]
109
- });
110
- }
111
- } else {
112
- ui?.success?.(`Check "${checkId}" passed`, { title: `\u2713 ${checkId}` });
32
+ for (const section of buildCheckReport(effective)) {
33
+ ctx.ui?.success?.(`${section.header}`, { sections: [{ items: section.lines }] });
113
34
  }
114
35
  }
115
- const shouldFail = hasFailed && severity === "blocker";
116
- return { exitCode: shouldFail ? 1 : 0 };
36
+ return { exitCode: raw.ok ? 0 : 1 };
117
37
  }
118
38
  }
119
39
  });
120
40
 
121
- export { qa_check_default as default, qaCheckFlags };
41
+ export { qa_check_default as default };
122
42
  //# sourceMappingURL=qa-check.js.map
123
43
  //# sourceMappingURL=qa-check.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/cli/commands/qa-check.ts"],"names":[],"mappings":"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","file":"qa-check.js","sourcesContent":["import { defineCommand, type CLIInput, useConfig, type PluginContextV3 } from '@kb-labs/sdk';\nimport type { QAPluginConfig, QACheckConfig } from '@kb-labs/qa-contracts';\nimport {\n getWorkspacePackages,\n runCustomChecks,\n createHistoryEntry,\n appendEntry,\n buildJsonReport,\n} from '@kb-labs/qa-core';\n\ninterface QACheckFlags {\n id: string;\n base?: string;\n context?: string;\n json?: boolean;\n save?: boolean;\n}\n\nexport const qaCheckFlags = {\n id: {\n type: 'string',\n description: 'Check ID to run (must match a check in qa.checks config)',\n demandOption: true,\n },\n base: {\n type: 'string',\n description: 'Base branch/commit for diff strategies (diffOnly, newFiles). Default: main',\n default: 'main',\n },\n context: {\n type: 'string',\n description: 'JSON context to attach to the history entry (e.g. {\"taskId\":\"123\",\"agentId\":\"claude\"})',\n },\n json: {\n type: 'boolean',\n description: 'Output structured JSON report',\n default: false,\n },\n save: {\n type: 'boolean',\n description: 'Save result to history after running',\n default: true,\n },\n} as const;\n\nexport type QACheckFlagsType = typeof qaCheckFlags;\n\nexport default defineCommand({\n id: 'qa:check',\n description: 'Run a single QA check atomically and optionally save to history',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<QACheckFlags>) {\n const { ui } = ctx;\n const { flags } = input;\n const rootDir = ctx.cwd;\n const checkId = flags.id as string;\n const base = (flags.base as string | undefined) ?? 'main';\n const isJson = !!flags.json;\n const shouldSave = flags.save !== false;\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 {\n // config not available\n }\n\n // Find the check config by id\n const allChecks: QACheckConfig[] = config?.checks ?? [];\n const checkConfig = allChecks.find(c => c.id === checkId);\n\n if (!checkConfig) {\n const msg = `Check \"${checkId}\" not found in qa.checks config`;\n if (isJson) {\n ui?.json?.({ status: 'error', message: msg });\n } else {\n ui?.error?.(msg, { title: 'QA Check Error' });\n }\n return { exitCode: 1 };\n }\n\n // Parse runContext from --context flag\n let runContext: Record<string, unknown> | undefined;\n if (flags.context) {\n try {\n runContext = JSON.parse(flags.context as string);\n } catch {\n const msg = `Invalid JSON in --context: ${flags.context}`;\n if (isJson) {\n ui?.json?.({ status: 'error', message: msg });\n } else {\n ui?.error?.(msg, { title: 'QA Check Error' });\n }\n return { exitCode: 1 };\n }\n }\n\n const packages = getWorkspacePackages(rootDir, {}, config?.packages);\n\n const results = runCustomChecks(\n [checkConfig],\n packages,\n rootDir,\n undefined,\n base,\n );\n\n const checkResult = results[checkId];\n const hasFailed = checkResult ? checkResult.failed.length > 0 : false;\n\n // Save to history if requested\n if (shouldSave) {\n const entry = createHistoryEntry(results, rootDir, packages, runContext);\n appendEntry(rootDir, entry, allChecks);\n }\n\n const severity = checkConfig.severity ?? 'blocker';\n const report = buildJsonReport(results, null, [checkConfig]);\n\n if (isJson) {\n ui?.json?.(report);\n } else {\n if (hasFailed) {\n const findings = severity === 'warning' ? report.warnings : report.blockers;\n const checkFindings = findings.find(f => f.check === checkId);\n if (checkFindings) {\n ui?.error?.(`Check \"${checkId}\" failed`, {\n title: `${severity === 'warning' ? '⚠' : '✗'} ${checkId}`,\n sections: [{\n header: '',\n items: checkFindings.items.map(item =>\n ` ${item.target}: ${item.message}${item.fix ? ` → ${item.fix}` : ''}`\n ),\n }],\n });\n }\n } else {\n ui?.success?.(`Check \"${checkId}\" passed`, { title: `✓ ${checkId}` });\n }\n }\n\n // Exit code: blockers fail, warnings pass, info always pass\n const shouldFail = hasFailed && severity === 'blocker';\n return { exitCode: shouldFail ? 1 : 0 };\n },\n },\n});\n"]}
1
+ {"version":3,"sources":["../../../src/cli/commands/qa-check.ts"],"names":[],"mappings":";;;;AAiBA,IAAO,mBAAQ,aAAA,CAAqE;AAAA,EAClF,EAAA,EAAI,UAAA;AAAA,EACJ,WAAA,EAAa,8BAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAA8D;AAChG,MAAA,MAAM,EAAE,OAAM,GAAI,KAAA;AAClB,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAA0B;AAC/C,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AAEnC,MAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,GAAA,EAAK,MAAA,EAAQ,UAAU,CAAA;AAC3D,MAAA,MAAM,OAAA,GAAU,IAAI,aAAA,CAAc,EAAE,UAAA,EAAY,KAAK,KAAA,EAAO,GAAA,CAAI,GAAA,CAAI,KAAA,EAAO,CAAA;AAC3E,MAAA,MAAM,KAAA,GAAQ,IAAI,aAAA,CAAc,GAAA,EAAK,QAAQ,iBAAiB,CAAA;AAE9D,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,KAAS,KAAA;AAC5B,MAAA,MAAM,MAAM,MAAM,UAAA,CAAW,GAAA,CAAI,GAAA,CAAI,OAAO,GAAG,CAAA;AAE/C,MAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,EAAI;AACvB,MAAA,MAAM,GAAA,GAAM,MAAM,OAAA,CAAQ,KAAA,EAAM;AAChC,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAI,KAAA;AAEhC,MAAA,MAAM,OAAO,IAAA,GAAO,KAAA,CAAM,UAAU,GAAA,EAAK,UAAA,EAAY,GAAG,CAAA,GAAI,IAAA;AAC5D,MAAA,MAAM,YAA2D,IAAA,IAAQ;AAAA,QACvE,IAAA,EAAM,OAAA;AAAA,QAAS,EAAA,EAAI,EAAA;AAAA,QAAI,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,QAAG,UAAA;AAAA,QAAY;AAAA,OAC1E;AAEA,MAAA,IAAI,MAAM,IAAA,EAAM;AACd,QAAA,GAAA,CAAI,EAAA,EAAI,IAAA,GAAO,oBAAA,CAAqB,SAAS,CAAC,CAAA;AAAA,MAChD,CAAA,MAAO;AACL,QAAA,KAAA,MAAW,OAAA,IAAW,gBAAA,CAAiB,SAAS,CAAA,EAAG;AACjD,UAAA,GAAA,CAAI,EAAA,EAAI,OAAA,GAAU,CAAA,EAAG,OAAA,CAAQ,MAAM,CAAA,CAAA,EAAI,EAAE,QAAA,EAAU,CAAC,EAAE,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA;AAAA,QACjF;AAAA,MACF;AAEA,MAAA,OAAO,EAAE,QAAA,EAAU,GAAA,CAAI,EAAA,GAAK,IAAI,CAAA,EAAE;AAAA,IACpC;AAAA;AAEJ,CAAC","file":"qa-check.js","sourcesContent":["import {\n defineCommand,\n useConfig,\n type CLIInput,\n type PluginContextV3,\n} from '@kb-labs/sdk';\nimport {\n DevkitAdapter,\n SnapshotStore,\n resolveDevkitBin,\n captureGit,\n buildCheckReport,\n buildCheckJsonReport,\n} from '@kb-labs/qa-core';\nimport { type QAPluginConfig } from '@kb-labs/qa-contracts';\nimport type { QaCheckFlags } from './flags.js';\n\nexport default defineCommand<unknown, CLIInput<QaCheckFlags>, { exitCode: number }>({\n id: 'qa:check',\n description: 'Run devkit structural checks',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<QaCheckFlags>): Promise<{ exitCode: number }> {\n const { flags } = input;\n const config = await useConfig<QAPluginConfig>();\n const cwd = ctx.cwd ?? process.cwd();\n\n const binaryPath = resolveDevkitBin(cwd, config?.devkitPath);\n const adapter = new DevkitAdapter({ binaryPath, cwd, shell: ctx.api.shell });\n const store = new SnapshotStore(cwd, config?.historyMaxEntries);\n\n const save = flags.save !== false;\n const git = await captureGit(ctx.api.shell, cwd);\n\n const start = Date.now();\n const raw = await adapter.check();\n const durationMs = Date.now() - start;\n\n const snap = save ? store.saveCheck(raw, durationMs, git) : null;\n const effective: import('@kb-labs/qa-contracts').CheckSnapshot = snap ?? {\n kind: 'check', id: '', timestamp: new Date().toISOString(), durationMs, raw,\n };\n\n if (flags.json) {\n ctx.ui?.json?.(buildCheckJsonReport(effective));\n } else {\n for (const section of buildCheckReport(effective)) {\n ctx.ui?.success?.(`${section.header}`, { sections: [{ items: section.lines }] });\n }\n }\n\n return { exitCode: raw.ok ? 0 : 1 };\n },\n },\n});\n"]}
@@ -0,0 +1,19 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import { CLIInput } from '@kb-labs/sdk';
3
+
4
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<_kb_labs_shared_command_kit.InferFlags<{
5
+ save: {
6
+ type: "boolean";
7
+ description: string;
8
+ default: false;
9
+ };
10
+ json: {
11
+ type: "boolean";
12
+ description: string;
13
+ default: false;
14
+ };
15
+ }>>, {
16
+ exitCode: number;
17
+ }>;
18
+
19
+ export { _default as default };
@@ -0,0 +1,36 @@
1
+ import { defineCommand, useConfig } from '@kb-labs/sdk';
2
+ import { resolveDevkitBin, DevkitAdapter, SnapshotStore, captureGit } from '@kb-labs/qa-core';
3
+
4
+ // src/cli/commands/qa-gate.ts
5
+ var qa_gate_default = defineCommand({
6
+ id: "qa:gate",
7
+ description: "Run pre-commit gate check (exits 1 if violations found)",
8
+ handler: {
9
+ async execute(ctx, input) {
10
+ const { flags } = input;
11
+ const config = await useConfig();
12
+ const cwd = ctx.cwd ?? process.cwd();
13
+ const binaryPath = resolveDevkitBin(cwd, config?.devkitPath);
14
+ const adapter = new DevkitAdapter({ binaryPath, cwd, shell: ctx.api.shell });
15
+ const store = new SnapshotStore(cwd, config?.historyMaxEntries);
16
+ const git = await captureGit(ctx.api.shell, cwd);
17
+ const start = Date.now();
18
+ const raw = await adapter.gate();
19
+ const durationMs = Date.now() - start;
20
+ if (flags.save) store.saveGate(raw, durationMs, git);
21
+ if (flags.json) {
22
+ ctx.ui?.json?.(raw);
23
+ } else if (raw.ok) {
24
+ ctx.ui?.success?.(`Gate passed. ${raw.staged_files} staged file(s), no violations.`);
25
+ } else {
26
+ const items = raw.violations.map((v) => `[${v.severity}] ${v.package} ${v.check}: ${v.message}`);
27
+ ctx.ui?.error?.("Gate failed", { sections: [{ header: "Violations", items }] });
28
+ }
29
+ return { exitCode: raw.ok ? 0 : 1 };
30
+ }
31
+ }
32
+ });
33
+
34
+ export { qa_gate_default as default };
35
+ //# sourceMappingURL=qa-gate.js.map
36
+ //# sourceMappingURL=qa-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/commands/qa-gate.ts"],"names":[],"mappings":";;;;AAeA,IAAO,kBAAQ,aAAA,CAAoE;AAAA,EACjF,EAAA,EAAI,SAAA;AAAA,EACJ,WAAA,EAAa,yDAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAA6D;AAC/F,MAAA,MAAM,EAAE,OAAM,GAAI,KAAA;AAClB,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAA0B;AAC/C,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AAEnC,MAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,GAAA,EAAK,MAAA,EAAQ,UAAU,CAAA;AAC3D,MAAA,MAAM,OAAA,GAAU,IAAI,aAAA,CAAc,EAAE,UAAA,EAAY,KAAK,KAAA,EAAO,GAAA,CAAI,GAAA,CAAI,KAAA,EAAO,CAAA;AAC3E,MAAA,MAAM,KAAA,GAAQ,IAAI,aAAA,CAAc,GAAA,EAAK,QAAQ,iBAAiB,CAAA;AAE9D,MAAA,MAAM,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,IAAA,EAAK;AAC/B,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAI,KAAA;AAEhC,MAAA,IAAI,MAAM,IAAA,EAAM,KAAA,CAAM,QAAA,CAAS,GAAA,EAAK,YAAY,GAAG,CAAA;AAEnD,MAAA,IAAI,MAAM,IAAA,EAAM;AACd,QAAA,GAAA,CAAI,EAAA,EAAI,OAAO,GAAG,CAAA;AAAA,MACpB,CAAA,MAAA,IAAW,IAAI,EAAA,EAAI;AACjB,QAAA,GAAA,CAAI,EAAA,EAAI,OAAA,GAAU,CAAA,aAAA,EAAgB,GAAA,CAAI,YAAY,CAAA,+BAAA,CAAiC,CAAA;AAAA,MACrF,CAAA,MAAO;AACL,QAAA,MAAM,QAAQ,GAAA,CAAI,UAAA,CAAW,GAAA,CAAI,CAAA,CAAA,KAAK,IAAI,CAAA,CAAE,QAAQ,CAAA,EAAA,EAAK,CAAA,CAAE,OAAO,CAAA,EAAA,EAAK,CAAA,CAAE,KAAK,CAAA,EAAA,EAAK,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA;AAC9F,QAAA,GAAA,CAAI,EAAA,EAAI,KAAA,GAAQ,aAAA,EAAe,EAAE,QAAA,EAAU,CAAC,EAAE,MAAA,EAAQ,YAAA,EAAc,KAAA,EAAO,CAAA,EAAG,CAAA;AAAA,MAChF;AAEA,MAAA,OAAO,EAAE,QAAA,EAAU,GAAA,CAAI,EAAA,GAAK,IAAI,CAAA,EAAE;AAAA,IACpC;AAAA;AAEJ,CAAC","file":"qa-gate.js","sourcesContent":["import {\n defineCommand,\n useConfig,\n type CLIInput,\n type PluginContextV3,\n} from '@kb-labs/sdk';\nimport {\n DevkitAdapter,\n SnapshotStore,\n resolveDevkitBin,\n captureGit,\n} from '@kb-labs/qa-core';\nimport { type QAPluginConfig } from '@kb-labs/qa-contracts';\nimport type { QaGateFlags } from './flags.js';\n\nexport default defineCommand<unknown, CLIInput<QaGateFlags>, { exitCode: number }>({\n id: 'qa:gate',\n description: 'Run pre-commit gate check (exits 1 if violations found)',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<QaGateFlags>): Promise<{ exitCode: number }> {\n const { flags } = input;\n const config = await useConfig<QAPluginConfig>();\n const cwd = ctx.cwd ?? process.cwd();\n\n const binaryPath = resolveDevkitBin(cwd, config?.devkitPath);\n const adapter = new DevkitAdapter({ binaryPath, cwd, shell: ctx.api.shell });\n const store = new SnapshotStore(cwd, config?.historyMaxEntries);\n\n const git = await captureGit(ctx.api.shell, cwd);\n\n const start = Date.now();\n const raw = await adapter.gate();\n const durationMs = Date.now() - start;\n\n if (flags.save) store.saveGate(raw, durationMs, git);\n\n if (flags.json) {\n ctx.ui?.json?.(raw);\n } else if (raw.ok) {\n ctx.ui?.success?.(`Gate passed. ${raw.staged_files} staged file(s), no violations.`);\n } else {\n const items = raw.violations.map(v => `[${v.severity}] ${v.package} ${v.check}: ${v.message}`);\n ctx.ui?.error?.('Gate failed', { sections: [{ header: 'Violations', items }] });\n }\n\n return { exitCode: raw.ok ? 0 : 1 };\n },\n },\n});\n"]}
@@ -1,9 +1,19 @@
1
1
  import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
- import { QAHistoryFlags } from './flags.js';
2
+ import { CLIInput } from '@kb-labs/sdk';
3
3
 
4
- type QAHistoryInput = QAHistoryFlags & {
5
- argv?: string[];
6
- };
7
- declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, QAHistoryInput, unknown>;
4
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<_kb_labs_shared_command_kit.InferFlags<{
5
+ limit: {
6
+ type: "number";
7
+ description: string;
8
+ default: number;
9
+ };
10
+ json: {
11
+ type: "boolean";
12
+ description: string;
13
+ default: false;
14
+ };
15
+ }>>, {
16
+ exitCode: number;
17
+ }>;
8
18
 
9
19
  export { _default as default };
@@ -1,5 +1,5 @@
1
- import { defineCommand } from '@kb-labs/sdk';
2
- import { loadHistory, buildHistoryTable } from '@kb-labs/qa-core';
1
+ import { defineCommand, useConfig } from '@kb-labs/sdk';
2
+ import { SnapshotStore, buildHistoryTable } from '@kb-labs/qa-core';
3
3
 
4
4
  // src/cli/commands/qa-history.ts
5
5
  var qa_history_default = defineCommand({
@@ -7,29 +7,18 @@ var qa_history_default = defineCommand({
7
7
  description: "Show QA run history",
8
8
  handler: {
9
9
  async execute(ctx, input) {
10
- const { ui } = ctx;
11
- const flags = "flags" in input && typeof input.flags === "object" && input.flags !== null ? 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;
10
+ const { flags } = input;
11
+ const config = await useConfig();
12
+ const cwd = ctx.cwd ?? process.cwd();
13
+ const store = new SnapshotStore(cwd, config?.historyMaxEntries);
14
+ const limit = flags.limit ?? 20;
15
+ const history = store.loadRunHistory();
23
16
  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
- });
17
+ ctx.ui?.json?.([...history].reverse().slice(0, limit));
18
+ } else {
19
+ for (const section of buildHistoryTable(history, limit)) {
20
+ ctx.ui?.success?.(`${section.header}`, { sections: [{ items: section.lines }] });
21
+ }
33
22
  }
34
23
  return { exitCode: 0 };
35
24
  }
@@ -1 +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,OAAA,IAAW,KAAA,IAAS,OAAQ,KAAA,CAA8B,KAAA,KAAU,QAAA,IAAa,KAAA,CAA8B,KAAA,KAAU,IAAA,GACnI,KAAA,CAAoC,KAAA,GACrC,KAAA;AACJ,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[] };\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 = ('flags' in input && typeof (input as { flags?: unknown }).flags === 'object' && (input as { flags?: unknown }).flags !== null)\n ? (input as { flags: QAHistoryInput }).flags\n : 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"]}
1
+ {"version":3,"sources":["../../../src/cli/commands/qa-history.ts"],"names":[],"mappings":";;;;AAaA,IAAO,qBAAQ,aAAA,CAAuE;AAAA,EACpF,EAAA,EAAI,YAAA;AAAA,EACJ,WAAA,EAAa,qBAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAgE;AAClG,MAAA,MAAM,EAAE,OAAM,GAAI,KAAA;AAClB,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAA0B;AAC/C,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AAEnC,MAAA,MAAM,KAAA,GAAQ,IAAI,aAAA,CAAc,GAAA,EAAK,QAAQ,iBAAiB,CAAA;AAC9D,MAAA,MAAM,KAAA,GAAQ,MAAM,KAAA,IAAS,EAAA;AAC7B,MAAA,MAAM,OAAA,GAAU,MAAM,cAAA,EAAe;AAErC,MAAA,IAAI,MAAM,IAAA,EAAM;AACd,QAAA,GAAA,CAAI,EAAA,EAAI,IAAA,GAAO,CAAC,GAAG,OAAO,CAAA,CAAE,OAAA,EAAQ,CAAE,KAAA,CAAM,CAAA,EAAG,KAAK,CAAC,CAAA;AAAA,MACvD,CAAA,MAAO;AACL,QAAA,KAAA,MAAW,OAAA,IAAW,iBAAA,CAAkB,OAAA,EAAS,KAAK,CAAA,EAAG;AACvD,UAAA,GAAA,CAAI,EAAA,EAAI,OAAA,GAAU,CAAA,EAAG,OAAA,CAAQ,MAAM,CAAA,CAAA,EAAI,EAAE,QAAA,EAAU,CAAC,EAAE,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA;AAAA,QACjF;AAAA,MACF;AAEA,MAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,IACvB;AAAA;AAEJ,CAAC","file":"qa-history.js","sourcesContent":["import {\n defineCommand,\n useConfig,\n type CLIInput,\n type PluginContextV3,\n} from '@kb-labs/sdk';\nimport {\n SnapshotStore,\n buildHistoryTable,\n} from '@kb-labs/qa-core';\nimport { type QAPluginConfig } from '@kb-labs/qa-contracts';\nimport type { QaHistoryFlags } from './flags.js';\n\nexport default defineCommand<unknown, CLIInput<QaHistoryFlags>, { exitCode: number }>({\n id: 'qa:history',\n description: 'Show QA run history',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<QaHistoryFlags>): Promise<{ exitCode: number }> {\n const { flags } = input;\n const config = await useConfig<QAPluginConfig>();\n const cwd = ctx.cwd ?? process.cwd();\n\n const store = new SnapshotStore(cwd, config?.historyMaxEntries);\n const limit = flags.limit ?? 20;\n const history = store.loadRunHistory();\n\n if (flags.json) {\n ctx.ui?.json?.([...history].reverse().slice(0, limit));\n } else {\n for (const section of buildHistoryTable(history, limit)) {\n ctx.ui?.success?.(`${section.header}`, { sections: [{ items: section.lines }] });\n }\n }\n\n return { exitCode: 0 };\n },\n },\n});\n"]}