@kb-labs/qa-entry 2.88.0 → 2.93.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/baseline-status.d.ts +0 -1
- package/dist/cli/commands/baseline-status.js +1 -1
- package/dist/cli/commands/baseline-status.js.map +1 -1
- package/dist/cli/commands/baseline-update.d.ts +0 -1
- package/dist/cli/commands/baseline-update.js +1 -1
- package/dist/cli/commands/baseline-update.js.map +1 -1
- package/dist/cli/commands/flags.d.ts +28 -1
- package/dist/cli/commands/flags.js +27 -1
- package/dist/cli/commands/flags.js.map +1 -1
- package/dist/cli/commands/qa-check.d.ts +40 -0
- package/dist/cli/commands/qa-check.js +123 -0
- package/dist/cli/commands/qa-check.js.map +1 -0
- package/dist/cli/commands/qa-history.d.ts +0 -1
- package/dist/cli/commands/qa-history.js +1 -1
- package/dist/cli/commands/qa-history.js.map +1 -1
- package/dist/cli/commands/qa-regressions.d.ts +0 -1
- package/dist/cli/commands/qa-regressions.js +1 -1
- package/dist/cli/commands/qa-regressions.js.map +1 -1
- package/dist/cli/commands/qa-save.d.ts +1 -1
- package/dist/cli/commands/qa-save.js.map +1 -1
- package/dist/cli/commands/qa-trends.d.ts +0 -1
- package/dist/cli/commands/qa-trends.js +1 -1
- package/dist/cli/commands/qa-trends.js.map +1 -1
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -1
- package/dist/manifest.js +36 -0
- package/dist/manifest.js.map +1 -1
- package/dist/rest/handlers/package-timeline-handler.js.map +1 -1
- package/dist/widgets/mf-manifest.json +12 -12
- package/dist/widgets/mf-stats.json +12 -12
- package/dist/widgets/remoteEntry.js +2 -2
- package/package.json +8 -8
|
@@ -8,7 +8,7 @@ var baseline_status_default = defineCommand({
|
|
|
8
8
|
handler: {
|
|
9
9
|
async execute(ctx, input) {
|
|
10
10
|
const { ui } = ctx;
|
|
11
|
-
const flags = input.flags
|
|
11
|
+
const flags = "flags" in input && typeof input.flags === "object" && input.flags !== null ? input.flags : input;
|
|
12
12
|
const rootDir = ctx.cwd;
|
|
13
13
|
const baseline = loadBaseline(rootDir);
|
|
14
14
|
if (flags.json) {
|
|
@@ -1 +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,
|
|
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,OAAA,IAAW,KAAA,IAAS,OAAQ,KAAA,CAA8B,KAAA,KAAU,QAAA,IAAa,KAAA,CAA8B,KAAA,KAAU,IAAA,GACnI,KAAA,CAAyC,KAAA,GAC1C,KAAA;AACJ,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[] };\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 = ('flags' in input && typeof (input as { flags?: unknown }).flags === 'object' && (input as { flags?: unknown }).flags !== null)\n ? (input as { flags: BaselineStatusInput }).flags\n : 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"]}
|
|
@@ -8,7 +8,7 @@ var baseline_update_default = defineCommand({
|
|
|
8
8
|
handler: {
|
|
9
9
|
async execute(ctx, input) {
|
|
10
10
|
const { ui } = ctx;
|
|
11
|
-
const flags = input.flags
|
|
11
|
+
const flags = "flags" in input && typeof input.flags === "object" && input.flags !== null ? input.flags : input;
|
|
12
12
|
const rootDir = ctx.cwd;
|
|
13
13
|
const snapshot = await captureBaseline(rootDir);
|
|
14
14
|
if (flags.json) {
|
|
@@ -1 +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,
|
|
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,OAAA,IAAW,KAAA,IAAS,OAAQ,KAAA,CAA8B,KAAA,KAAU,QAAA,IAAa,KAAA,CAA8B,KAAA,KAAU,IAAA,GACnI,KAAA,CAAyC,KAAA,GAC1C,KAAA;AACJ,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[] };\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 = ('flags' in input && typeof (input as { flags?: unknown }).flags === 'object' && (input as { flags?: unknown }).flags !== null)\n ? (input as { flags: BaselineUpdateInput }).flags\n : 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"]}
|
|
@@ -102,5 +102,32 @@ declare const baselineStatusFlags: {
|
|
|
102
102
|
};
|
|
103
103
|
};
|
|
104
104
|
type BaselineStatusFlags = typeof baselineStatusFlags;
|
|
105
|
+
declare const qaCheckFlags: {
|
|
106
|
+
readonly id: {
|
|
107
|
+
readonly type: "string";
|
|
108
|
+
readonly description: "Check ID to run (must match a check in qa.checks config)";
|
|
109
|
+
readonly demandOption: true;
|
|
110
|
+
};
|
|
111
|
+
readonly base: {
|
|
112
|
+
readonly type: "string";
|
|
113
|
+
readonly description: "Base branch/commit for diff strategies (diffOnly, newFiles). Default: main";
|
|
114
|
+
readonly default: "main";
|
|
115
|
+
};
|
|
116
|
+
readonly context: {
|
|
117
|
+
readonly type: "string";
|
|
118
|
+
readonly description: "JSON context to attach to history entry (e.g. {\"taskId\":\"123\"})";
|
|
119
|
+
};
|
|
120
|
+
readonly json: {
|
|
121
|
+
readonly type: "boolean";
|
|
122
|
+
readonly description: "Output JSON format";
|
|
123
|
+
readonly default: false;
|
|
124
|
+
};
|
|
125
|
+
readonly save: {
|
|
126
|
+
readonly type: "boolean";
|
|
127
|
+
readonly description: "Save result to history after running (default: true)";
|
|
128
|
+
readonly default: true;
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
type QACheckFlags = typeof qaCheckFlags;
|
|
105
132
|
|
|
106
|
-
export { type BaselineStatusFlags, type BaselineUpdateFlags, type QAHistoryFlags, type QARegressionsFlags, type QARunFlags, type QASaveFlags, type QATrendsFlags, baselineStatusFlags, baselineUpdateFlags, qaHistoryFlags, qaRegressionsFlags, qaRunFlags, qaSaveFlags, qaTrendsFlags };
|
|
133
|
+
export { type BaselineStatusFlags, type BaselineUpdateFlags, type QACheckFlags, type QAHistoryFlags, type QARegressionsFlags, type QARunFlags, type QASaveFlags, type QATrendsFlags, baselineStatusFlags, baselineUpdateFlags, qaCheckFlags, qaHistoryFlags, qaRegressionsFlags, qaRunFlags, qaSaveFlags, qaTrendsFlags };
|
|
@@ -93,7 +93,33 @@ var baselineStatusFlags = {
|
|
|
93
93
|
default: false
|
|
94
94
|
}
|
|
95
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
|
+
},
|
|
111
|
+
json: {
|
|
112
|
+
type: "boolean",
|
|
113
|
+
description: JSON_FLAG_DESCRIPTION,
|
|
114
|
+
default: false
|
|
115
|
+
},
|
|
116
|
+
save: {
|
|
117
|
+
type: "boolean",
|
|
118
|
+
description: "Save result to history after running (default: true)",
|
|
119
|
+
default: true
|
|
120
|
+
}
|
|
121
|
+
};
|
|
96
122
|
|
|
97
|
-
export { baselineStatusFlags, baselineUpdateFlags, qaHistoryFlags, qaRegressionsFlags, qaRunFlags, qaSaveFlags, qaTrendsFlags };
|
|
123
|
+
export { baselineStatusFlags, baselineUpdateFlags, qaCheckFlags, qaHistoryFlags, qaRegressionsFlags, qaRunFlags, qaSaveFlags, qaTrendsFlags };
|
|
98
124
|
//# sourceMappingURL=flags.js.map
|
|
99
125
|
//# sourceMappingURL=flags.js.map
|
|
@@ -1 +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"]}
|
|
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;AAIO,IAAM,YAAA,GAAe;AAAA,EAC1B,EAAA,EAAI;AAAA,IACF,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,EAAa,0DAAA;AAAA,IACb,YAAA,EAAc;AAAA,GAChB;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,EAAa,4EAAA;AAAA,IACb,OAAA,EAAS;AAAA,GACX;AAAA,EACA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,EAAa;AAAA,GACf;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,qBAAA;AAAA,IACb,OAAA,EAAS;AAAA,GACX;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,sDAAA;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\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"]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
+
import { CLIInput } from '@kb-labs/sdk';
|
|
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;
|
|
16
|
+
};
|
|
17
|
+
readonly base: {
|
|
18
|
+
readonly type: "string";
|
|
19
|
+
readonly description: "Base branch/commit for diff strategies (diffOnly, newFiles). Default: main";
|
|
20
|
+
readonly default: "main";
|
|
21
|
+
};
|
|
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>;
|
|
39
|
+
|
|
40
|
+
export { type QACheckFlagsType, _default as default, qaCheckFlags };
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { defineCommand, useConfig } from '@kb-labs/sdk';
|
|
2
|
+
import { getWorkspacePackages, runCustomChecks, createHistoryEntry, appendEntry, buildJsonReport } from '@kb-labs/qa-core';
|
|
3
|
+
|
|
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
|
+
var qa_check_default = defineCommand({
|
|
32
|
+
id: "qa:check",
|
|
33
|
+
description: "Run a single QA check atomically and optionally save to history",
|
|
34
|
+
handler: {
|
|
35
|
+
async execute(ctx, input) {
|
|
36
|
+
const { ui } = ctx;
|
|
37
|
+
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);
|
|
96
|
+
} 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}` });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const shouldFail = hasFailed && severity === "blocker";
|
|
116
|
+
return { exitCode: shouldFail ? 1 : 0 };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
export { qa_check_default as default, qaCheckFlags };
|
|
122
|
+
//# sourceMappingURL=qa-check.js.map
|
|
123
|
+
//# sourceMappingURL=qa-check.js.map
|
|
@@ -0,0 +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"]}
|
|
@@ -8,7 +8,7 @@ var qa_history_default = defineCommand({
|
|
|
8
8
|
handler: {
|
|
9
9
|
async execute(ctx, input) {
|
|
10
10
|
const { ui } = ctx;
|
|
11
|
-
const flags = input.flags
|
|
11
|
+
const flags = "flags" in input && typeof input.flags === "object" && input.flags !== null ? input.flags : input;
|
|
12
12
|
const rootDir = ctx.cwd;
|
|
13
13
|
const history = loadHistory(rootDir);
|
|
14
14
|
if (history.length === 0) {
|
|
@@ -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,
|
|
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"]}
|
|
@@ -8,7 +8,7 @@ var qa_regressions_default = defineCommand({
|
|
|
8
8
|
handler: {
|
|
9
9
|
async execute(ctx, input) {
|
|
10
10
|
const { ui } = ctx;
|
|
11
|
-
const flags = input.flags
|
|
11
|
+
const flags = "flags" in input && typeof input.flags === "object" && input.flags !== null ? input.flags : input;
|
|
12
12
|
const rootDir = ctx.cwd;
|
|
13
13
|
const history = loadHistory(rootDir);
|
|
14
14
|
const result = detectRegressions(history);
|
|
@@ -1 +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,
|
|
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,OAAA,IAAW,KAAA,IAAS,OAAQ,KAAA,CAA8B,KAAA,KAAU,QAAA,IAAa,KAAA,CAA8B,KAAA,KAAU,IAAA,GACnI,KAAA,CAAwC,KAAA,GACzC,KAAA;AACJ,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[] };\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 = ('flags' in input && typeof (input as { flags?: unknown }).flags === 'object' && (input as { flags?: unknown }).flags !== null)\n ? (input as { flags: QARegressionsInput }).flags\n : 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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/qa-save.ts"],"names":[],"mappings":";;;;AAMA,IAAO,kBAAQ,aAAA,CAAc;AAAA,EAC3B,EAAA,EAAI,SAAA;AAAA,EACJ,WAAA,EAAa,2CAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAoB;AACtD,MAAA,MAAM,EAAE,IAAG,GAAI,GAAA;AACf,MAAA,MAAM,KAAA,
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/qa-save.ts"],"names":[],"mappings":"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","file":"qa-save.js","sourcesContent":["import { defineCommand, type PluginContextV3 } from '@kb-labs/sdk';\nimport { runQA, createHistoryEntry, appendEntry } from '@kb-labs/qa-core';\nimport type { QASaveFlags } from './flags.js';\n\ntype QASaveInput = QASaveFlags & { argv?: string[]; flags?: QASaveFlags };\n\nexport default defineCommand({\n id: 'qa:save',\n description: 'Run QA checks and save results to history',\n\n handler: {\n async execute(ctx: PluginContextV3, input: QASaveInput) {\n const { ui } = ctx;\n const flags = input.flags ?? input;\n const rootDir = ctx.cwd;\n\n const startTime = Date.now();\n const { results } = await runQA({ rootDir });\n const durationMs = Date.now() - startTime;\n const entry = createHistoryEntry(results, rootDir);\n appendEntry(rootDir, entry);\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,\n gitBranch: entry.git.branch,\n });\n }\n const checkKeys = Object.keys(results);\n await analytics.track('qa.run.completed', {\n status: entry.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 if (flags.json) {\n ui?.json?.(entry);\n return { exitCode: 0 };\n }\n\n ui?.success?.('QA state saved to history', {\n title: 'QA Save',\n sections: [{\n header: 'Saved Entry',\n items: [\n `Status: ${entry.status}`,\n `Git: ${entry.git.commit} (${entry.git.branch})`,\n `Message: ${entry.git.message}`,\n ],\n }],\n });\n\n return { exitCode: 0 };\n },\n },\n});\n"]}
|
|
@@ -8,7 +8,7 @@ var qa_trends_default = defineCommand({
|
|
|
8
8
|
handler: {
|
|
9
9
|
async execute(ctx, input) {
|
|
10
10
|
const { ui } = ctx;
|
|
11
|
-
const flags = input.flags
|
|
11
|
+
const flags = "flags" in input && typeof input.flags === "object" && input.flags !== null ? input.flags : input;
|
|
12
12
|
const rootDir = ctx.cwd;
|
|
13
13
|
const history = loadHistory(rootDir);
|
|
14
14
|
const window = typeof flags.window === "number" ? flags.window : 10;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/qa-trends.ts"],"names":[],"mappings":";;;;AAMA,IAAO,oBAAQ,aAAA,CAAc;AAAA,EAC3B,EAAA,EAAI,WAAA;AAAA,EACJ,WAAA,EAAa,kCAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAsB;AACxD,MAAA,MAAM,EAAE,IAAG,GAAI,GAAA;AACf,MAAA,MAAM,KAAA,GAAS,
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/qa-trends.ts"],"names":[],"mappings":";;;;AAMA,IAAO,oBAAQ,aAAA,CAAc;AAAA,EAC3B,EAAA,EAAI,WAAA;AAAA,EACJ,WAAA,EAAa,kCAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAsB;AACxD,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,CAAmC,KAAA,GACpC,KAAA;AACJ,MAAA,MAAM,UAAU,GAAA,CAAI,GAAA;AAEpB,MAAA,MAAM,OAAA,GAAU,YAAY,OAAO,CAAA;AACnC,MAAA,MAAM,SAAS,OAAO,KAAA,CAAM,MAAA,KAAW,QAAA,GAAW,MAAM,MAAA,GAAS,EAAA;AACjE,MAAA,MAAM,MAAA,GAAS,aAAA,CAAc,OAAA,EAAS,MAAM,CAAA;AAE5C,MAAA,IAAI,MAAM,IAAA,EAAM;AACd,QAAA,MAAM,cAAA,GAAiB,qBAAA,CAAsB,OAAA,EAAS,MAAM,CAAA;AAC5D,QAAA,EAAA,EAAI,IAAA,GAAO,EAAE,MAAA,EAAQ,cAAA,EAAgB,cAAc,OAAA,CAAQ,MAAA,EAAQ,QAAQ,CAAA;AAC3E,QAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,MACvB;AAEA,MAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,MAAA,EAAQ,OAAO,CAAA;AAClD,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-trends.js","sourcesContent":["import { defineCommand, type PluginContextV3 } from '@kb-labs/sdk';\nimport { loadHistory, analyzeTrends, analyzeEnrichedTrends, buildTrendsReport } from '@kb-labs/qa-core';\nimport type { QATrendsFlags } from './flags.js';\n\ntype QATrendsInput = QATrendsFlags & { argv?: string[] };\n\nexport default defineCommand({\n id: 'qa:trends',\n description: 'Show QA quality trends over time',\n\n handler: {\n async execute(ctx: PluginContextV3, input: QATrendsInput) {\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: QATrendsInput }).flags\n : input;\n const rootDir = ctx.cwd;\n\n const history = loadHistory(rootDir);\n const window = typeof flags.window === 'number' ? flags.window : 10;\n const trends = analyzeTrends(history, window);\n\n if (flags.json) {\n const enrichedTrends = analyzeEnrichedTrends(history, window);\n ui?.json?.({ trends: enrichedTrends, historyCount: history.length, window });\n return { exitCode: 0 };\n }\n\n const sections = buildTrendsReport(trends, 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: 0 };\n },\n },\n});\n"]}
|
package/dist/index.js
CHANGED
|
@@ -98,6 +98,32 @@ var baselineStatusFlags = {
|
|
|
98
98
|
default: false
|
|
99
99
|
}
|
|
100
100
|
};
|
|
101
|
+
var qaCheckFlags = {
|
|
102
|
+
id: {
|
|
103
|
+
type: "string",
|
|
104
|
+
description: "Check ID to run (must match a check in qa.checks config)",
|
|
105
|
+
demandOption: true
|
|
106
|
+
},
|
|
107
|
+
base: {
|
|
108
|
+
type: "string",
|
|
109
|
+
description: "Base branch/commit for diff strategies (diffOnly, newFiles). Default: main",
|
|
110
|
+
default: "main"
|
|
111
|
+
},
|
|
112
|
+
context: {
|
|
113
|
+
type: "string",
|
|
114
|
+
description: 'JSON context to attach to history entry (e.g. {"taskId":"123"})'
|
|
115
|
+
},
|
|
116
|
+
json: {
|
|
117
|
+
type: "boolean",
|
|
118
|
+
description: JSON_FLAG_DESCRIPTION,
|
|
119
|
+
default: false
|
|
120
|
+
},
|
|
121
|
+
save: {
|
|
122
|
+
type: "boolean",
|
|
123
|
+
description: "Save result to history after running (default: true)",
|
|
124
|
+
default: true
|
|
125
|
+
}
|
|
126
|
+
};
|
|
101
127
|
var pluginPermissions = combinePermissions().with(kbPlatformPreset).withFs({
|
|
102
128
|
mode: "readWrite",
|
|
103
129
|
allow: ["**"]
|
|
@@ -134,6 +160,16 @@ var manifest = {
|
|
|
134
160
|
flags: defineCommandFlags(qaRunFlags),
|
|
135
161
|
permissions: pluginPermissions
|
|
136
162
|
},
|
|
163
|
+
{
|
|
164
|
+
id: "check",
|
|
165
|
+
group: "qa",
|
|
166
|
+
describe: "Run a single QA check atomically",
|
|
167
|
+
longDescription: "Runs one check by ID, optionally saves to history with caller context. Designed for workflow steps: exit 0 = pass, exit 1 = blocker failed. Supports diffOnly/newFiles strategies and structured JSON output for agents.",
|
|
168
|
+
handler: "./cli/commands/qa-check.js#default",
|
|
169
|
+
handlerPath: "./cli/commands/qa-check.js",
|
|
170
|
+
flags: defineCommandFlags(qaCheckFlags),
|
|
171
|
+
permissions: pluginPermissions
|
|
172
|
+
},
|
|
137
173
|
{
|
|
138
174
|
id: "save",
|
|
139
175
|
group: "qa",
|