@kb-labs/qa-contracts 0.6.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/LICENSE +4 -0
- package/README.md +90 -0
- package/dist/index.d.ts +2191 -0
- package/dist/index.js +319 -0
- package/dist/index.js.map +1 -0
- package/package.json +47 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
// src/types/rest-api.ts
|
|
4
|
+
var CheckTypeSchema = z.string();
|
|
5
|
+
var GitInfoSchema = z.object({
|
|
6
|
+
commit: z.string(),
|
|
7
|
+
branch: z.string()
|
|
8
|
+
});
|
|
9
|
+
var GitInfoWithMessageSchema = GitInfoSchema.extend({
|
|
10
|
+
message: z.string()
|
|
11
|
+
});
|
|
12
|
+
var CheckSummarySchema = z.object({
|
|
13
|
+
passed: z.number(),
|
|
14
|
+
failed: z.number(),
|
|
15
|
+
skipped: z.number()
|
|
16
|
+
});
|
|
17
|
+
var QASummaryRequestSchema = z.object({});
|
|
18
|
+
var QASummaryCheckSchema = z.object({
|
|
19
|
+
checkType: z.string(),
|
|
20
|
+
label: z.string(),
|
|
21
|
+
icon: z.string().optional(),
|
|
22
|
+
passed: z.number(),
|
|
23
|
+
failed: z.number(),
|
|
24
|
+
skipped: z.number(),
|
|
25
|
+
total: z.number()
|
|
26
|
+
});
|
|
27
|
+
var QASummaryResponseSchema = z.object({
|
|
28
|
+
status: z.string(),
|
|
29
|
+
lastRunAt: z.string().nullable(),
|
|
30
|
+
git: GitInfoWithMessageSchema.nullable(),
|
|
31
|
+
checks: z.array(QASummaryCheckSchema),
|
|
32
|
+
hasBaseline: z.boolean(),
|
|
33
|
+
baselineTimestamp: z.string().nullable(),
|
|
34
|
+
historyCount: z.number()
|
|
35
|
+
});
|
|
36
|
+
var QALatestRequestSchema = z.object({});
|
|
37
|
+
var HistoryEntrySchema = z.object({
|
|
38
|
+
timestamp: z.string(),
|
|
39
|
+
git: GitInfoWithMessageSchema,
|
|
40
|
+
status: z.enum(["passed", "failed"]),
|
|
41
|
+
summary: z.record(CheckTypeSchema, CheckSummarySchema),
|
|
42
|
+
failedPackages: z.record(CheckTypeSchema, z.array(z.string()))
|
|
43
|
+
});
|
|
44
|
+
var QALatestResponseSchema = z.object({
|
|
45
|
+
entry: HistoryEntrySchema.nullable()
|
|
46
|
+
});
|
|
47
|
+
var QAHistoryRequestSchema = z.object({
|
|
48
|
+
limit: z.number().optional()
|
|
49
|
+
});
|
|
50
|
+
var QAHistoryResponseSchema = z.object({
|
|
51
|
+
entries: z.array(HistoryEntrySchema),
|
|
52
|
+
total: z.number()
|
|
53
|
+
});
|
|
54
|
+
var QATrendsRequestSchema = z.object({
|
|
55
|
+
window: z.number().optional(),
|
|
56
|
+
enriched: z.boolean().optional()
|
|
57
|
+
});
|
|
58
|
+
var TrendResultSchema = z.object({
|
|
59
|
+
checkType: CheckTypeSchema,
|
|
60
|
+
label: z.string().optional(),
|
|
61
|
+
icon: z.string().optional(),
|
|
62
|
+
previous: z.number(),
|
|
63
|
+
current: z.number(),
|
|
64
|
+
delta: z.number(),
|
|
65
|
+
trend: z.enum(["regression", "improvement", "no-change"])
|
|
66
|
+
});
|
|
67
|
+
var QATrendsResponseSchema = z.object({
|
|
68
|
+
trends: z.array(TrendResultSchema),
|
|
69
|
+
historyCount: z.number(),
|
|
70
|
+
window: z.number()
|
|
71
|
+
});
|
|
72
|
+
var TrendTimeSeriesPointSchema = z.object({
|
|
73
|
+
timestamp: z.string(),
|
|
74
|
+
gitCommit: z.string(),
|
|
75
|
+
gitBranch: z.string(),
|
|
76
|
+
gitMessage: z.string(),
|
|
77
|
+
passed: z.number(),
|
|
78
|
+
failed: z.number(),
|
|
79
|
+
skipped: z.number()
|
|
80
|
+
});
|
|
81
|
+
var TrendChangelogEntrySchema = z.object({
|
|
82
|
+
timestamp: z.string(),
|
|
83
|
+
gitCommit: z.string(),
|
|
84
|
+
gitMessage: z.string(),
|
|
85
|
+
newFailures: z.array(z.string()),
|
|
86
|
+
fixed: z.array(z.string()),
|
|
87
|
+
delta: z.number()
|
|
88
|
+
});
|
|
89
|
+
var EnrichedTrendResultSchema = z.object({
|
|
90
|
+
checkType: CheckTypeSchema,
|
|
91
|
+
label: z.string().optional(),
|
|
92
|
+
icon: z.string().optional(),
|
|
93
|
+
timeSeries: z.array(TrendTimeSeriesPointSchema),
|
|
94
|
+
changelog: z.array(TrendChangelogEntrySchema),
|
|
95
|
+
current: z.number(),
|
|
96
|
+
previous: z.number(),
|
|
97
|
+
delta: z.number(),
|
|
98
|
+
trend: z.enum(["regression", "improvement", "no-change"]),
|
|
99
|
+
velocity: z.number()
|
|
100
|
+
});
|
|
101
|
+
var QAEnrichedTrendsResponseSchema = z.object({
|
|
102
|
+
trends: z.array(EnrichedTrendResultSchema),
|
|
103
|
+
historyCount: z.number(),
|
|
104
|
+
window: z.number()
|
|
105
|
+
});
|
|
106
|
+
var QARegressionsRequestSchema = z.object({
|
|
107
|
+
scope: z.string().optional()
|
|
108
|
+
});
|
|
109
|
+
var RegressionEntrySchema = z.object({
|
|
110
|
+
checkType: z.string(),
|
|
111
|
+
delta: z.number(),
|
|
112
|
+
newFailures: z.array(z.string())
|
|
113
|
+
});
|
|
114
|
+
var QARegressionsResponseSchema = z.object({
|
|
115
|
+
hasRegressions: z.boolean(),
|
|
116
|
+
regressions: z.array(RegressionEntrySchema),
|
|
117
|
+
scope: z.string().optional()
|
|
118
|
+
});
|
|
119
|
+
var QABaselineRequestSchema = z.object({});
|
|
120
|
+
var BaselineCheckSnapshotSchema = z.object({
|
|
121
|
+
passed: z.number(),
|
|
122
|
+
failed: z.number(),
|
|
123
|
+
failedPackages: z.array(z.string())
|
|
124
|
+
});
|
|
125
|
+
var BaselineSnapshotSchema = z.object({
|
|
126
|
+
timestamp: z.string(),
|
|
127
|
+
git: GitInfoSchema,
|
|
128
|
+
results: z.record(CheckTypeSchema, BaselineCheckSnapshotSchema)
|
|
129
|
+
});
|
|
130
|
+
var QABaselineResponseSchema = z.object({
|
|
131
|
+
baseline: BaselineSnapshotSchema.nullable()
|
|
132
|
+
});
|
|
133
|
+
var CheckResultSchema = z.object({
|
|
134
|
+
passed: z.array(z.string()),
|
|
135
|
+
failed: z.array(z.string()),
|
|
136
|
+
skipped: z.array(z.string()),
|
|
137
|
+
errors: z.record(z.string(), z.string())
|
|
138
|
+
});
|
|
139
|
+
var QARunRequestSchema = z.object({
|
|
140
|
+
skipChecks: z.array(z.string()).optional(),
|
|
141
|
+
saveToHistory: z.boolean().optional()
|
|
142
|
+
});
|
|
143
|
+
var QARunResponseSchema = z.object({
|
|
144
|
+
status: z.enum(["passed", "failed"]),
|
|
145
|
+
results: z.record(CheckTypeSchema, CheckResultSchema),
|
|
146
|
+
entry: HistoryEntrySchema.nullable(),
|
|
147
|
+
durationMs: z.number()
|
|
148
|
+
});
|
|
149
|
+
var SubmoduleInfoSchema = z.object({
|
|
150
|
+
name: z.string(),
|
|
151
|
+
commit: z.string(),
|
|
152
|
+
branch: z.string(),
|
|
153
|
+
dirty: z.boolean(),
|
|
154
|
+
message: z.string()
|
|
155
|
+
});
|
|
156
|
+
var PackageCheckDetailSchema = z.object({
|
|
157
|
+
name: z.string(),
|
|
158
|
+
repo: z.string(),
|
|
159
|
+
status: z.enum(["passed", "failed", "skipped"]),
|
|
160
|
+
error: z.string().optional(),
|
|
161
|
+
submodule: SubmoduleInfoSchema.optional()
|
|
162
|
+
});
|
|
163
|
+
var CheckDetailsSchema = z.object({
|
|
164
|
+
passed: z.array(PackageCheckDetailSchema),
|
|
165
|
+
failed: z.array(PackageCheckDetailSchema),
|
|
166
|
+
skipped: z.array(PackageCheckDetailSchema)
|
|
167
|
+
});
|
|
168
|
+
var QADetailsRequestSchema = z.object({});
|
|
169
|
+
var QADetailsResponseSchema = z.object({
|
|
170
|
+
timestamp: z.string().nullable(),
|
|
171
|
+
git: GitInfoWithMessageSchema.nullable(),
|
|
172
|
+
submodules: z.record(z.string(), SubmoduleInfoSchema).optional(),
|
|
173
|
+
checks: z.record(CheckTypeSchema, CheckDetailsSchema)
|
|
174
|
+
});
|
|
175
|
+
var QARunCheckRequestSchema = z.object({
|
|
176
|
+
checkType: z.string(),
|
|
177
|
+
repo: z.string().optional(),
|
|
178
|
+
package: z.string().optional()
|
|
179
|
+
});
|
|
180
|
+
var QARunCheckResponseSchema = z.object({
|
|
181
|
+
checkType: CheckTypeSchema,
|
|
182
|
+
status: z.enum(["passed", "failed"]),
|
|
183
|
+
result: CheckResultSchema,
|
|
184
|
+
durationMs: z.number()
|
|
185
|
+
});
|
|
186
|
+
var QABaselineUpdateRequestSchema = z.object({});
|
|
187
|
+
var QABaselineUpdateResponseSchema = z.object({
|
|
188
|
+
success: z.boolean(),
|
|
189
|
+
baseline: BaselineSnapshotSchema
|
|
190
|
+
});
|
|
191
|
+
var CheckDiffSchema = z.object({
|
|
192
|
+
newFailures: z.array(z.string()),
|
|
193
|
+
fixed: z.array(z.string()),
|
|
194
|
+
stillFailing: z.array(z.string()),
|
|
195
|
+
delta: z.number()
|
|
196
|
+
});
|
|
197
|
+
var QABaselineDiffRequestSchema = z.object({});
|
|
198
|
+
var QABaselineDiffResponseSchema = z.object({
|
|
199
|
+
hasDiff: z.boolean(),
|
|
200
|
+
diff: z.record(CheckTypeSchema, CheckDiffSchema),
|
|
201
|
+
baseline: BaselineSnapshotSchema.nullable(),
|
|
202
|
+
current: z.object({
|
|
203
|
+
timestamp: z.string(),
|
|
204
|
+
summary: z.record(CheckTypeSchema, z.object({
|
|
205
|
+
passed: z.number(),
|
|
206
|
+
failed: z.number()
|
|
207
|
+
}))
|
|
208
|
+
}).nullable()
|
|
209
|
+
});
|
|
210
|
+
var PackageTimelineEntrySchema = z.object({
|
|
211
|
+
timestamp: z.string(),
|
|
212
|
+
git: GitInfoWithMessageSchema,
|
|
213
|
+
submoduleCommit: z.string().optional(),
|
|
214
|
+
checks: z.record(CheckTypeSchema, z.enum(["passed", "failed", "skipped"]))
|
|
215
|
+
});
|
|
216
|
+
var QAPackageTimelineRequestSchema = z.object({});
|
|
217
|
+
var QAPackageTimelineResponseSchema = z.object({
|
|
218
|
+
packageName: z.string(),
|
|
219
|
+
repo: z.string(),
|
|
220
|
+
entries: z.array(PackageTimelineEntrySchema),
|
|
221
|
+
flakyScore: z.number(),
|
|
222
|
+
flakyChecks: z.array(CheckTypeSchema),
|
|
223
|
+
firstFailure: z.string().optional(),
|
|
224
|
+
currentStreak: z.object({
|
|
225
|
+
status: z.enum(["passing", "failing"]),
|
|
226
|
+
count: z.number()
|
|
227
|
+
})
|
|
228
|
+
});
|
|
229
|
+
var ErrorGroupSchema = z.object({
|
|
230
|
+
pattern: z.string(),
|
|
231
|
+
count: z.number(),
|
|
232
|
+
packages: z.array(z.string()),
|
|
233
|
+
checkType: CheckTypeSchema,
|
|
234
|
+
example: z.string()
|
|
235
|
+
});
|
|
236
|
+
var QAErrorGroupsRequestSchema = z.object({});
|
|
237
|
+
var QAErrorGroupsResponseSchema = z.object({
|
|
238
|
+
groups: z.array(ErrorGroupSchema),
|
|
239
|
+
ungrouped: z.number()
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
// src/constants.ts
|
|
243
|
+
var QA_DATA_DIR = ".kb/qa";
|
|
244
|
+
var PATHS = {
|
|
245
|
+
BASELINE: ".kb/qa/baseline.json",
|
|
246
|
+
HISTORY: ".kb/qa/history.json",
|
|
247
|
+
CACHE: ".kb/qa/cache.json",
|
|
248
|
+
LAST_RUN: ".kb/qa/last-run.json"
|
|
249
|
+
};
|
|
250
|
+
var HISTORY_MAX_ENTRIES = 50;
|
|
251
|
+
var TRENDS_WINDOW = 10;
|
|
252
|
+
var DEFAULT_LABELS = {
|
|
253
|
+
build: "Build",
|
|
254
|
+
lint: "Lint",
|
|
255
|
+
typeCheck: "Type Check",
|
|
256
|
+
test: "Tests"
|
|
257
|
+
};
|
|
258
|
+
var DEFAULT_ICONS = {
|
|
259
|
+
build: "\u{1F528}",
|
|
260
|
+
lint: "\u{1F50D}",
|
|
261
|
+
typeCheck: "\u{1F4D8}",
|
|
262
|
+
test: "\u{1F9EA}"
|
|
263
|
+
};
|
|
264
|
+
function getCheckLabel(id, configName) {
|
|
265
|
+
return configName ?? DEFAULT_LABELS[id] ?? id;
|
|
266
|
+
}
|
|
267
|
+
function getCheckIcon(id, configIcon) {
|
|
268
|
+
return configIcon ?? DEFAULT_ICONS[id] ?? "\u2611\uFE0F";
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// src/routes.ts
|
|
272
|
+
var QA_BASE_PATH = "/v1/plugins/qa";
|
|
273
|
+
var QA_ROUTES = {
|
|
274
|
+
/** GET /summary - Aggregated QA overview */
|
|
275
|
+
SUMMARY: "/summary",
|
|
276
|
+
/** GET /latest - Last QA run result */
|
|
277
|
+
LATEST: "/latest",
|
|
278
|
+
/** GET /history - QA run history */
|
|
279
|
+
HISTORY: "/history",
|
|
280
|
+
/** GET /trends - Trend analysis */
|
|
281
|
+
TRENDS: "/trends",
|
|
282
|
+
/** GET /regressions - Regression detection */
|
|
283
|
+
REGRESSIONS: "/regressions",
|
|
284
|
+
/** GET /baseline - Current baseline snapshot */
|
|
285
|
+
BASELINE: "/baseline",
|
|
286
|
+
/** POST /run - Run QA checks */
|
|
287
|
+
RUN: "/run",
|
|
288
|
+
/** GET /details - Per-package details with errors from last run */
|
|
289
|
+
DETAILS: "/details",
|
|
290
|
+
/** POST /run/check - Run a single check type */
|
|
291
|
+
RUN_CHECK: "/run/check",
|
|
292
|
+
/** POST /baseline/update - Update baseline from last run */
|
|
293
|
+
BASELINE_UPDATE: "/baseline/update",
|
|
294
|
+
/** GET /baseline/diff - Diff current state vs baseline */
|
|
295
|
+
BASELINE_DIFF: "/baseline/diff",
|
|
296
|
+
/** GET /packages/:name/timeline - Per-package QA history timeline */
|
|
297
|
+
PACKAGE_TIMELINE: "/packages/:name/timeline",
|
|
298
|
+
/** GET /errors/groups - Grouped errors by pattern */
|
|
299
|
+
ERROR_GROUPS: "/errors/groups"
|
|
300
|
+
};
|
|
301
|
+
var QA_FULL_ROUTES = {
|
|
302
|
+
SUMMARY: `${QA_BASE_PATH}${QA_ROUTES.SUMMARY}`,
|
|
303
|
+
LATEST: `${QA_BASE_PATH}${QA_ROUTES.LATEST}`,
|
|
304
|
+
HISTORY: `${QA_BASE_PATH}${QA_ROUTES.HISTORY}`,
|
|
305
|
+
TRENDS: `${QA_BASE_PATH}${QA_ROUTES.TRENDS}`,
|
|
306
|
+
REGRESSIONS: `${QA_BASE_PATH}${QA_ROUTES.REGRESSIONS}`,
|
|
307
|
+
BASELINE: `${QA_BASE_PATH}${QA_ROUTES.BASELINE}`,
|
|
308
|
+
RUN: `${QA_BASE_PATH}${QA_ROUTES.RUN}`,
|
|
309
|
+
DETAILS: `${QA_BASE_PATH}${QA_ROUTES.DETAILS}`,
|
|
310
|
+
RUN_CHECK: `${QA_BASE_PATH}${QA_ROUTES.RUN_CHECK}`,
|
|
311
|
+
BASELINE_UPDATE: `${QA_BASE_PATH}${QA_ROUTES.BASELINE_UPDATE}`,
|
|
312
|
+
BASELINE_DIFF: `${QA_BASE_PATH}${QA_ROUTES.BASELINE_DIFF}`,
|
|
313
|
+
PACKAGE_TIMELINE: `${QA_BASE_PATH}${QA_ROUTES.PACKAGE_TIMELINE}`,
|
|
314
|
+
ERROR_GROUPS: `${QA_BASE_PATH}${QA_ROUTES.ERROR_GROUPS}`
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
export { HISTORY_MAX_ENTRIES, PATHS, QABaselineDiffRequestSchema, QABaselineDiffResponseSchema, QABaselineRequestSchema, QABaselineResponseSchema, QABaselineUpdateRequestSchema, QABaselineUpdateResponseSchema, QADetailsRequestSchema, QADetailsResponseSchema, QAEnrichedTrendsResponseSchema, QAErrorGroupsRequestSchema, QAErrorGroupsResponseSchema, QAHistoryRequestSchema, QAHistoryResponseSchema, QALatestRequestSchema, QALatestResponseSchema, QAPackageTimelineRequestSchema, QAPackageTimelineResponseSchema, QARegressionsRequestSchema, QARegressionsResponseSchema, QARunCheckRequestSchema, QARunCheckResponseSchema, QARunRequestSchema, QARunResponseSchema, QASummaryCheckSchema, QASummaryRequestSchema, QASummaryResponseSchema, QATrendsRequestSchema, QATrendsResponseSchema, QA_BASE_PATH, QA_DATA_DIR, QA_FULL_ROUTES, QA_ROUTES, TRENDS_WINDOW, getCheckIcon, getCheckLabel };
|
|
318
|
+
//# sourceMappingURL=index.js.map
|
|
319
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types/rest-api.ts","../src/constants.ts","../src/routes.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * REST API Request/Response Types and Zod Schemas for QA Plugin\n */\n\nimport { z } from 'zod';\n\n// ============================================================================\n// Common schemas\n// ============================================================================\n\nconst CheckTypeSchema = z.string();\n\nconst GitInfoSchema = z.object({\n commit: z.string(),\n branch: z.string(),\n});\n\nconst GitInfoWithMessageSchema = GitInfoSchema.extend({\n message: z.string(),\n});\n\nconst CheckSummarySchema = z.object({\n passed: z.number(),\n failed: z.number(),\n skipped: z.number(),\n});\n\n// ============================================================================\n// Summary API\n// ============================================================================\n\nexport const QASummaryRequestSchema = z.object({});\n\nexport type QASummaryRequest = z.infer<typeof QASummaryRequestSchema>;\n\nexport const QASummaryCheckSchema = z.object({\n checkType: z.string(),\n label: z.string(),\n icon: z.string().optional(),\n passed: z.number(),\n failed: z.number(),\n skipped: z.number(),\n total: z.number(),\n});\n\nexport const QASummaryResponseSchema = z.object({\n status: z.string(),\n lastRunAt: z.string().nullable(),\n git: GitInfoWithMessageSchema.nullable(),\n checks: z.array(QASummaryCheckSchema),\n hasBaseline: z.boolean(),\n baselineTimestamp: z.string().nullable(),\n historyCount: z.number(),\n});\n\nexport type QASummaryResponse = z.infer<typeof QASummaryResponseSchema>;\n\n// ============================================================================\n// Latest API\n// ============================================================================\n\nexport const QALatestRequestSchema = z.object({});\n\nexport type QALatestRequest = z.infer<typeof QALatestRequestSchema>;\n\nconst HistoryEntrySchema = z.object({\n timestamp: z.string(),\n git: GitInfoWithMessageSchema,\n status: z.enum(['passed', 'failed']),\n summary: z.record(CheckTypeSchema, CheckSummarySchema),\n failedPackages: z.record(CheckTypeSchema, z.array(z.string())),\n});\n\nexport const QALatestResponseSchema = z.object({\n entry: HistoryEntrySchema.nullable(),\n});\n\nexport type QALatestResponse = z.infer<typeof QALatestResponseSchema>;\n\n// ============================================================================\n// History API\n// ============================================================================\n\nexport const QAHistoryRequestSchema = z.object({\n limit: z.number().optional(),\n});\n\nexport type QAHistoryRequest = z.infer<typeof QAHistoryRequestSchema>;\n\nexport const QAHistoryResponseSchema = z.object({\n entries: z.array(HistoryEntrySchema),\n total: z.number(),\n});\n\nexport type QAHistoryResponse = z.infer<typeof QAHistoryResponseSchema>;\n\n// ============================================================================\n// Trends API\n// ============================================================================\n\nexport const QATrendsRequestSchema = z.object({\n window: z.number().optional(),\n enriched: z.boolean().optional(),\n});\n\nexport type QATrendsRequest = z.infer<typeof QATrendsRequestSchema>;\n\nconst TrendResultSchema = z.object({\n checkType: CheckTypeSchema,\n label: z.string().optional(),\n icon: z.string().optional(),\n previous: z.number(),\n current: z.number(),\n delta: z.number(),\n trend: z.enum(['regression', 'improvement', 'no-change']),\n});\n\nexport const QATrendsResponseSchema = z.object({\n trends: z.array(TrendResultSchema),\n historyCount: z.number(),\n window: z.number(),\n});\n\nexport type QATrendsResponse = z.infer<typeof QATrendsResponseSchema>;\n\n// --- Enriched Trends ---\n\nconst TrendTimeSeriesPointSchema = z.object({\n timestamp: z.string(),\n gitCommit: z.string(),\n gitBranch: z.string(),\n gitMessage: z.string(),\n passed: z.number(),\n failed: z.number(),\n skipped: z.number(),\n});\n\nconst TrendChangelogEntrySchema = z.object({\n timestamp: z.string(),\n gitCommit: z.string(),\n gitMessage: z.string(),\n newFailures: z.array(z.string()),\n fixed: z.array(z.string()),\n delta: z.number(),\n});\n\nconst EnrichedTrendResultSchema = z.object({\n checkType: CheckTypeSchema,\n label: z.string().optional(),\n icon: z.string().optional(),\n timeSeries: z.array(TrendTimeSeriesPointSchema),\n changelog: z.array(TrendChangelogEntrySchema),\n current: z.number(),\n previous: z.number(),\n delta: z.number(),\n trend: z.enum(['regression', 'improvement', 'no-change']),\n velocity: z.number(),\n});\n\nexport const QAEnrichedTrendsResponseSchema = z.object({\n trends: z.array(EnrichedTrendResultSchema),\n historyCount: z.number(),\n window: z.number(),\n});\n\nexport type QAEnrichedTrendsResponse = z.infer<typeof QAEnrichedTrendsResponseSchema>;\n\n// ============================================================================\n// Regressions API\n// ============================================================================\n\nexport const QARegressionsRequestSchema = z.object({\n scope: z.string().optional(),\n});\n\nexport type QARegressionsRequest = z.infer<typeof QARegressionsRequestSchema>;\n\nconst RegressionEntrySchema = z.object({\n checkType: z.string(),\n delta: z.number(),\n newFailures: z.array(z.string()),\n});\n\nexport type RegressionEntry = z.infer<typeof RegressionEntrySchema>;\n\nexport const QARegressionsResponseSchema = z.object({\n hasRegressions: z.boolean(),\n regressions: z.array(RegressionEntrySchema),\n scope: z.string().optional(),\n});\n\n\nexport type QARegressionsResponse = z.infer<typeof QARegressionsResponseSchema>;\n\n// ============================================================================\n// Baseline API\n// ============================================================================\n\nexport const QABaselineRequestSchema = z.object({});\n\nexport type QABaselineRequest = z.infer<typeof QABaselineRequestSchema>;\n\nconst BaselineCheckSnapshotSchema = z.object({\n passed: z.number(),\n failed: z.number(),\n failedPackages: z.array(z.string()),\n});\n\nconst BaselineSnapshotSchema = z.object({\n timestamp: z.string(),\n git: GitInfoSchema,\n results: z.record(CheckTypeSchema, BaselineCheckSnapshotSchema),\n});\n\nexport const QABaselineResponseSchema = z.object({\n baseline: BaselineSnapshotSchema.nullable(),\n});\n\nexport type QABaselineResponse = z.infer<typeof QABaselineResponseSchema>;\n\n// ============================================================================\n// Run API (POST)\n// ============================================================================\n\nconst CheckResultSchema = z.object({\n passed: z.array(z.string()),\n failed: z.array(z.string()),\n skipped: z.array(z.string()),\n errors: z.record(z.string(), z.string()),\n});\n\nexport const QARunRequestSchema = z.object({\n skipChecks: z.array(z.string()).optional(),\n saveToHistory: z.boolean().optional(),\n});\n\nexport type QARunRequest = z.infer<typeof QARunRequestSchema>;\n\nexport const QARunResponseSchema = z.object({\n status: z.enum(['passed', 'failed']),\n results: z.record(CheckTypeSchema, CheckResultSchema),\n entry: HistoryEntrySchema.nullable(),\n durationMs: z.number(),\n});\n\nexport type QARunResponse = z.infer<typeof QARunResponseSchema>;\n\n// ============================================================================\n// Details API (GET /details)\n// ============================================================================\n\nconst SubmoduleInfoSchema = z.object({\n name: z.string(),\n commit: z.string(),\n branch: z.string(),\n dirty: z.boolean(),\n message: z.string(),\n});\n\nconst PackageCheckDetailSchema = z.object({\n name: z.string(),\n repo: z.string(),\n status: z.enum(['passed', 'failed', 'skipped']),\n error: z.string().optional(),\n submodule: SubmoduleInfoSchema.optional(),\n});\n\nconst CheckDetailsSchema = z.object({\n passed: z.array(PackageCheckDetailSchema),\n failed: z.array(PackageCheckDetailSchema),\n skipped: z.array(PackageCheckDetailSchema),\n});\n\nexport const QADetailsRequestSchema = z.object({});\n\nexport type QADetailsRequest = z.infer<typeof QADetailsRequestSchema>;\n\nexport const QADetailsResponseSchema = z.object({\n timestamp: z.string().nullable(),\n git: GitInfoWithMessageSchema.nullable(),\n submodules: z.record(z.string(), SubmoduleInfoSchema).optional(),\n checks: z.record(CheckTypeSchema, CheckDetailsSchema),\n});\n\nexport type QADetailsResponse = z.infer<typeof QADetailsResponseSchema>;\n\n// ============================================================================\n// Run Check API (POST /run/check)\n// ============================================================================\n\nexport const QARunCheckRequestSchema = z.object({\n checkType: z.string(),\n repo: z.string().optional(),\n package: z.string().optional(),\n});\n\nexport type QARunCheckRequest = z.infer<typeof QARunCheckRequestSchema>;\n\nexport const QARunCheckResponseSchema = z.object({\n checkType: CheckTypeSchema,\n status: z.enum(['passed', 'failed']),\n result: CheckResultSchema,\n durationMs: z.number(),\n});\n\nexport type QARunCheckResponse = z.infer<typeof QARunCheckResponseSchema>;\n\n// ============================================================================\n// Baseline Update API (POST /baseline/update)\n// ============================================================================\n\nexport const QABaselineUpdateRequestSchema = z.object({});\n\nexport type QABaselineUpdateRequest = z.infer<typeof QABaselineUpdateRequestSchema>;\n\nexport const QABaselineUpdateResponseSchema = z.object({\n success: z.boolean(),\n baseline: BaselineSnapshotSchema,\n});\n\nexport type QABaselineUpdateResponse = z.infer<typeof QABaselineUpdateResponseSchema>;\n\n// ============================================================================\n// Baseline Diff API (GET /baseline/diff)\n// ============================================================================\n\nconst CheckDiffSchema = z.object({\n newFailures: z.array(z.string()),\n fixed: z.array(z.string()),\n stillFailing: z.array(z.string()),\n delta: z.number(),\n});\n\nexport const QABaselineDiffRequestSchema = z.object({});\n\nexport type QABaselineDiffRequest = z.infer<typeof QABaselineDiffRequestSchema>;\n\nexport const QABaselineDiffResponseSchema = z.object({\n hasDiff: z.boolean(),\n diff: z.record(CheckTypeSchema, CheckDiffSchema),\n baseline: BaselineSnapshotSchema.nullable(),\n current: z.object({\n timestamp: z.string(),\n summary: z.record(CheckTypeSchema, z.object({\n passed: z.number(),\n failed: z.number(),\n })),\n }).nullable(),\n});\n\nexport type QABaselineDiffResponse = z.infer<typeof QABaselineDiffResponseSchema>;\n\n// ============================================================================\n// Package Timeline API (GET /packages/:name/timeline)\n// ============================================================================\n\nconst PackageTimelineEntrySchema = z.object({\n timestamp: z.string(),\n git: GitInfoWithMessageSchema,\n submoduleCommit: z.string().optional(),\n checks: z.record(CheckTypeSchema, z.enum(['passed', 'failed', 'skipped'])),\n});\n\nexport const QAPackageTimelineRequestSchema = z.object({});\n\nexport type QAPackageTimelineRequest = z.infer<typeof QAPackageTimelineRequestSchema>;\n\nexport const QAPackageTimelineResponseSchema = z.object({\n packageName: z.string(),\n repo: z.string(),\n entries: z.array(PackageTimelineEntrySchema),\n flakyScore: z.number(),\n flakyChecks: z.array(CheckTypeSchema),\n firstFailure: z.string().optional(),\n currentStreak: z.object({\n status: z.enum(['passing', 'failing']),\n count: z.number(),\n }),\n});\n\nexport type QAPackageTimelineResponse = z.infer<typeof QAPackageTimelineResponseSchema>;\n\n// ============================================================================\n// Error Groups API (GET /errors/groups)\n// ============================================================================\n\nconst ErrorGroupSchema = z.object({\n pattern: z.string(),\n count: z.number(),\n packages: z.array(z.string()),\n checkType: CheckTypeSchema,\n example: z.string(),\n});\n\nexport const QAErrorGroupsRequestSchema = z.object({});\n\nexport type QAErrorGroupsRequest = z.infer<typeof QAErrorGroupsRequestSchema>;\n\nexport const QAErrorGroupsResponseSchema = z.object({\n groups: z.array(ErrorGroupSchema),\n ungrouped: z.number(),\n});\n\nexport type QAErrorGroupsResponse = z.infer<typeof QAErrorGroupsResponseSchema>;\n","/**\n * Data directory for the QA plugin, relative to monorepo root.\n */\nexport const QA_DATA_DIR = '.kb/qa';\n\n/**\n * File paths for QA plugin data storage (relative to monorepo root).\n */\nexport const PATHS = {\n BASELINE: '.kb/qa/baseline.json',\n HISTORY: '.kb/qa/history.json',\n CACHE: '.kb/qa/cache.json',\n LAST_RUN: '.kb/qa/last-run.json',\n} as const;\n\n/**\n * Maximum number of history entries to keep.\n */\nexport const HISTORY_MAX_ENTRIES = 50;\n\n/**\n * Default number of entries for trend analysis window.\n */\nexport const TRENDS_WINDOW = 10;\n\n/**\n * Default labels for built-in check types.\n */\nconst DEFAULT_LABELS: Record<string, string> = {\n build: 'Build',\n lint: 'Lint',\n typeCheck: 'Type Check',\n test: 'Tests',\n};\n\n/**\n * Default icons (emoji) for built-in check types.\n */\nconst DEFAULT_ICONS: Record<string, string> = {\n build: '๐จ',\n lint: '๐',\n typeCheck: '๐',\n test: '๐งช',\n};\n\n/**\n * Get display label for a check type. Priority: configName > known default > id.\n */\nexport function getCheckLabel(id: string, configName?: string): string {\n return configName ?? DEFAULT_LABELS[id] ?? id;\n}\n\n/**\n * Get display icon (emoji) for a check type. Priority: configIcon > known default > generic.\n */\nexport function getCheckIcon(id: string, configIcon?: string): string {\n return configIcon ?? DEFAULT_ICONS[id] ?? 'โ๏ธ';\n}\n","/**\n * @module @kb-labs/qa-contracts/routes\n * REST API route constants for QA plugin\n */\n\n/**\n * REST API base path for QA plugin\n */\nexport const QA_BASE_PATH = '/v1/plugins/qa' as const;\n\n/**\n * REST API route paths (relative to basePath)\n */\nexport const QA_ROUTES = {\n /** GET /summary - Aggregated QA overview */\n SUMMARY: '/summary',\n\n /** GET /latest - Last QA run result */\n LATEST: '/latest',\n\n /** GET /history - QA run history */\n HISTORY: '/history',\n\n /** GET /trends - Trend analysis */\n TRENDS: '/trends',\n\n /** GET /regressions - Regression detection */\n REGRESSIONS: '/regressions',\n\n /** GET /baseline - Current baseline snapshot */\n BASELINE: '/baseline',\n\n /** POST /run - Run QA checks */\n RUN: '/run',\n\n /** GET /details - Per-package details with errors from last run */\n DETAILS: '/details',\n\n /** POST /run/check - Run a single check type */\n RUN_CHECK: '/run/check',\n\n /** POST /baseline/update - Update baseline from last run */\n BASELINE_UPDATE: '/baseline/update',\n\n /** GET /baseline/diff - Diff current state vs baseline */\n BASELINE_DIFF: '/baseline/diff',\n\n /** GET /packages/:name/timeline - Per-package QA history timeline */\n PACKAGE_TIMELINE: '/packages/:name/timeline',\n\n /** GET /errors/groups - Grouped errors by pattern */\n ERROR_GROUPS: '/errors/groups',\n} as const;\n\n/**\n * Full REST API URLs (basePath + route)\n * Useful for testing and documentation\n */\nexport const QA_FULL_ROUTES = {\n SUMMARY: `${QA_BASE_PATH}${QA_ROUTES.SUMMARY}`,\n LATEST: `${QA_BASE_PATH}${QA_ROUTES.LATEST}`,\n HISTORY: `${QA_BASE_PATH}${QA_ROUTES.HISTORY}`,\n TRENDS: `${QA_BASE_PATH}${QA_ROUTES.TRENDS}`,\n REGRESSIONS: `${QA_BASE_PATH}${QA_ROUTES.REGRESSIONS}`,\n BASELINE: `${QA_BASE_PATH}${QA_ROUTES.BASELINE}`,\n RUN: `${QA_BASE_PATH}${QA_ROUTES.RUN}`,\n DETAILS: `${QA_BASE_PATH}${QA_ROUTES.DETAILS}`,\n RUN_CHECK: `${QA_BASE_PATH}${QA_ROUTES.RUN_CHECK}`,\n BASELINE_UPDATE: `${QA_BASE_PATH}${QA_ROUTES.BASELINE_UPDATE}`,\n BASELINE_DIFF: `${QA_BASE_PATH}${QA_ROUTES.BASELINE_DIFF}`,\n PACKAGE_TIMELINE: `${QA_BASE_PATH}${QA_ROUTES.PACKAGE_TIMELINE}`,\n ERROR_GROUPS: `${QA_BASE_PATH}${QA_ROUTES.ERROR_GROUPS}`,\n} as const;\n\nexport type QARoute = typeof QA_ROUTES[keyof typeof QA_ROUTES];\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kb-labs/qa-contracts",
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Contracts for KB Labs QA Plugin โ types, interfaces, and constants for QA checks, baselines, and history tracking.",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./dist/*": "./dist/*"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md",
|
|
18
|
+
"LICENSE"
|
|
19
|
+
],
|
|
20
|
+
"sideEffects": false,
|
|
21
|
+
"scripts": {
|
|
22
|
+
"pretype-check": "pnpm --filter @kb-labs/qa-contracts build",
|
|
23
|
+
"clean": "rimraf dist",
|
|
24
|
+
"build": "tsup --config tsup.config.ts",
|
|
25
|
+
"dev": "tsup --config tsup.config.ts --watch",
|
|
26
|
+
"lint": "eslint src --ext .ts",
|
|
27
|
+
"lint:fix": "eslint . --fix",
|
|
28
|
+
"type-check": "tsc --noEmit",
|
|
29
|
+
"test": "vitest run --passWithNoTests",
|
|
30
|
+
"test:watch": "vitest"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"zod": "^3.23.8"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@kb-labs/devkit": "link:../../../../infra/kb-labs-devkit",
|
|
37
|
+
"@types/node": "^24.3.3",
|
|
38
|
+
"rimraf": "^6.0.1",
|
|
39
|
+
"tsup": "^8.5.0",
|
|
40
|
+
"typescript": "^5.6.3",
|
|
41
|
+
"vitest": "^3.2.4"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=20.0.0",
|
|
45
|
+
"pnpm": ">=9.0.0"
|
|
46
|
+
}
|
|
47
|
+
}
|