codmir 0.3.3 → 0.4.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/{chunk-LXEEBTWT.mjs → chunk-GU32P57R.mjs} +70 -0
- package/dist/cli/index.js +106 -14
- package/dist/cli/index.mjs +37 -15
- package/dist/index.d.mts +76 -1
- package/dist/index.d.ts +76 -1
- package/dist/index.js +70 -0
- package/dist/index.mjs +1 -1
- package/dist/voice-agent/index.d.mts +134 -0
- package/dist/voice-agent/index.d.ts +134 -0
- package/dist/voice-agent/index.js +220 -0
- package/dist/voice-agent/index.mjs +187 -0
- package/dist/voice-daemon/index.d.mts +354 -0
- package/dist/voice-daemon/index.d.ts +354 -0
- package/dist/voice-daemon/index.js +1089 -0
- package/dist/voice-daemon/index.mjs +1046 -0
- package/package.json +22 -4
|
@@ -9,6 +9,7 @@ var CodmirClient = class {
|
|
|
9
9
|
};
|
|
10
10
|
this.tickets = new TicketsAPI(this.config);
|
|
11
11
|
this.testCases = new TestCasesAPI(this.config);
|
|
12
|
+
this.testing = new TestingAPI(this.config);
|
|
12
13
|
}
|
|
13
14
|
/**
|
|
14
15
|
* Make an HTTP request to the codmir API
|
|
@@ -267,6 +268,75 @@ var TestCasesAPI = class {
|
|
|
267
268
|
);
|
|
268
269
|
}
|
|
269
270
|
};
|
|
271
|
+
var TestingAPI = class {
|
|
272
|
+
constructor(config) {
|
|
273
|
+
this.config = config;
|
|
274
|
+
}
|
|
275
|
+
async request(method, path, body) {
|
|
276
|
+
const url = `${this.config.baseUrl}${path}`;
|
|
277
|
+
const headers = {
|
|
278
|
+
"Content-Type": "application/json",
|
|
279
|
+
...this.config.headers
|
|
280
|
+
};
|
|
281
|
+
if (this.config.apiKey) {
|
|
282
|
+
headers["X-API-Key"] = this.config.apiKey;
|
|
283
|
+
}
|
|
284
|
+
const controller = new AbortController();
|
|
285
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
|
|
286
|
+
try {
|
|
287
|
+
const response = await fetch(url, {
|
|
288
|
+
method,
|
|
289
|
+
headers,
|
|
290
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
291
|
+
signal: controller.signal
|
|
292
|
+
});
|
|
293
|
+
clearTimeout(timeoutId);
|
|
294
|
+
if (!response.ok) {
|
|
295
|
+
const errorData = await response.json().catch(() => ({}));
|
|
296
|
+
const error = new Error(errorData.error || `HTTP ${response.status}`);
|
|
297
|
+
error.statusCode = response.status;
|
|
298
|
+
error.response = errorData;
|
|
299
|
+
throw error;
|
|
300
|
+
}
|
|
301
|
+
if (response.status === 204) {
|
|
302
|
+
return {};
|
|
303
|
+
}
|
|
304
|
+
return await response.json();
|
|
305
|
+
} catch (error) {
|
|
306
|
+
clearTimeout(timeoutId);
|
|
307
|
+
if (error.name === "AbortError") {
|
|
308
|
+
const timeoutError = new Error("Request timeout");
|
|
309
|
+
timeoutError.statusCode = 408;
|
|
310
|
+
throw timeoutError;
|
|
311
|
+
}
|
|
312
|
+
throw error;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
async submitTestRun(payload) {
|
|
316
|
+
return this.request("POST", "/api/testing/test-runs", payload);
|
|
317
|
+
}
|
|
318
|
+
async listTestRuns(projectId, options) {
|
|
319
|
+
const params = new URLSearchParams({ projectId });
|
|
320
|
+
if (options?.limit) params.set("limit", String(options.limit));
|
|
321
|
+
if (options?.suite) params.set("suite", options.suite);
|
|
322
|
+
const response = await this.request(
|
|
323
|
+
"GET",
|
|
324
|
+
`/api/testing/test-runs?${params.toString()}`
|
|
325
|
+
);
|
|
326
|
+
return response.runs || [];
|
|
327
|
+
}
|
|
328
|
+
async requestCoverageInsight(payload) {
|
|
329
|
+
return this.request("POST", "/api/testing/coverage-insight", payload);
|
|
330
|
+
}
|
|
331
|
+
async listCoverageInsights(projectId, limit = 5) {
|
|
332
|
+
const params = new URLSearchParams({ projectId, limit: String(limit) });
|
|
333
|
+
const response = await this.request(
|
|
334
|
+
"GET",
|
|
335
|
+
`/api/testing/coverage-insight?${params.toString()}`
|
|
336
|
+
);
|
|
337
|
+
return response.reports || [];
|
|
338
|
+
}
|
|
339
|
+
};
|
|
270
340
|
|
|
271
341
|
export {
|
|
272
342
|
CodmirClient
|
package/dist/cli/index.js
CHANGED
|
@@ -137,8 +137,8 @@ var require_package = __commonJS({
|
|
|
137
137
|
"package.json"(exports2, module2) {
|
|
138
138
|
module2.exports = {
|
|
139
139
|
name: "codmir",
|
|
140
|
-
version: "0.
|
|
141
|
-
description: "Official codmir SDK -
|
|
140
|
+
version: "0.4.0",
|
|
141
|
+
description: "Official codmir SDK - AI that prevents wasted engineering time. CLI, SDK, voice assistant, codebase analysis, and intelligent automation.",
|
|
142
142
|
main: "dist/index.js",
|
|
143
143
|
module: "dist/index.mjs",
|
|
144
144
|
types: "dist/index.d.ts",
|
|
@@ -150,6 +150,16 @@ var require_package = __commonJS({
|
|
|
150
150
|
types: "./dist/index.d.ts",
|
|
151
151
|
require: "./dist/index.js",
|
|
152
152
|
import: "./dist/index.mjs"
|
|
153
|
+
},
|
|
154
|
+
"./voice-agent": {
|
|
155
|
+
types: "./dist/voice-agent/index.d.ts",
|
|
156
|
+
require: "./dist/voice-agent/index.js",
|
|
157
|
+
import: "./dist/voice-agent/index.mjs"
|
|
158
|
+
},
|
|
159
|
+
"./voice-daemon": {
|
|
160
|
+
types: "./dist/voice-daemon/index.d.ts",
|
|
161
|
+
require: "./dist/voice-daemon/index.js",
|
|
162
|
+
import: "./dist/voice-daemon/index.mjs"
|
|
153
163
|
}
|
|
154
164
|
},
|
|
155
165
|
files: [
|
|
@@ -159,7 +169,7 @@ var require_package = __commonJS({
|
|
|
159
169
|
"runkit-example.js"
|
|
160
170
|
],
|
|
161
171
|
scripts: {
|
|
162
|
-
build: "tsup src/index.ts src/cli/index.ts --format cjs,esm --dts --clean",
|
|
172
|
+
build: "tsup src/index.ts src/cli/index.ts src/voice-agent/index.ts src/voice-daemon/index.ts --format cjs,esm --dts --clean",
|
|
163
173
|
dev: "tsup src/index.ts src/cli/index.ts --format cjs,esm --dts --watch",
|
|
164
174
|
prepublishOnly: "pnpm build",
|
|
165
175
|
test: "jest",
|
|
@@ -185,7 +195,11 @@ var require_package = __commonJS({
|
|
|
185
195
|
"tasks",
|
|
186
196
|
"automation",
|
|
187
197
|
"multi-agent",
|
|
188
|
-
"ai-assistant"
|
|
198
|
+
"ai-assistant",
|
|
199
|
+
"voice-assistant",
|
|
200
|
+
"speech-recognition",
|
|
201
|
+
"voice-daemon",
|
|
202
|
+
"wake-word"
|
|
189
203
|
],
|
|
190
204
|
author: "codmir",
|
|
191
205
|
license: "MIT",
|
|
@@ -210,12 +224,16 @@ var require_package = __commonJS({
|
|
|
210
224
|
"@semantic-release/release-notes-generator": "^14.0.0",
|
|
211
225
|
"@types/node": "^20.10.0",
|
|
212
226
|
"@types/prompts": "^2.4.9",
|
|
227
|
+
"@types/ws": "^8.18.1",
|
|
228
|
+
"@types/blessed": "^0.1.25",
|
|
213
229
|
"conventional-changelog-conventionalcommits": "^8.0.0",
|
|
214
230
|
"semantic-release": "^24.0.0",
|
|
215
231
|
tsup: "^8.0.1",
|
|
216
232
|
typescript: "^5.8.3"
|
|
217
233
|
},
|
|
218
234
|
dependencies: {
|
|
235
|
+
blessed: "^0.1.81",
|
|
236
|
+
"blessed-contrib": "^4.11.0",
|
|
219
237
|
chalk: "^5.3.0",
|
|
220
238
|
clipboardy: "^5.0.1",
|
|
221
239
|
commander: "^12.0.0",
|
|
@@ -1080,6 +1098,7 @@ var CodmirClient = class {
|
|
|
1080
1098
|
};
|
|
1081
1099
|
this.tickets = new TicketsAPI(this.config);
|
|
1082
1100
|
this.testCases = new TestCasesAPI(this.config);
|
|
1101
|
+
this.testing = new TestingAPI(this.config);
|
|
1083
1102
|
}
|
|
1084
1103
|
/**
|
|
1085
1104
|
* Make an HTTP request to the codmir API
|
|
@@ -1338,6 +1357,75 @@ var TestCasesAPI = class {
|
|
|
1338
1357
|
);
|
|
1339
1358
|
}
|
|
1340
1359
|
};
|
|
1360
|
+
var TestingAPI = class {
|
|
1361
|
+
constructor(config) {
|
|
1362
|
+
this.config = config;
|
|
1363
|
+
}
|
|
1364
|
+
async request(method, path8, body) {
|
|
1365
|
+
const url = `${this.config.baseUrl}${path8}`;
|
|
1366
|
+
const headers = {
|
|
1367
|
+
"Content-Type": "application/json",
|
|
1368
|
+
...this.config.headers
|
|
1369
|
+
};
|
|
1370
|
+
if (this.config.apiKey) {
|
|
1371
|
+
headers["X-API-Key"] = this.config.apiKey;
|
|
1372
|
+
}
|
|
1373
|
+
const controller = new AbortController();
|
|
1374
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
|
|
1375
|
+
try {
|
|
1376
|
+
const response = await fetch(url, {
|
|
1377
|
+
method,
|
|
1378
|
+
headers,
|
|
1379
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
1380
|
+
signal: controller.signal
|
|
1381
|
+
});
|
|
1382
|
+
clearTimeout(timeoutId);
|
|
1383
|
+
if (!response.ok) {
|
|
1384
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1385
|
+
const error = new Error(errorData.error || `HTTP ${response.status}`);
|
|
1386
|
+
error.statusCode = response.status;
|
|
1387
|
+
error.response = errorData;
|
|
1388
|
+
throw error;
|
|
1389
|
+
}
|
|
1390
|
+
if (response.status === 204) {
|
|
1391
|
+
return {};
|
|
1392
|
+
}
|
|
1393
|
+
return await response.json();
|
|
1394
|
+
} catch (error) {
|
|
1395
|
+
clearTimeout(timeoutId);
|
|
1396
|
+
if (error.name === "AbortError") {
|
|
1397
|
+
const timeoutError = new Error("Request timeout");
|
|
1398
|
+
timeoutError.statusCode = 408;
|
|
1399
|
+
throw timeoutError;
|
|
1400
|
+
}
|
|
1401
|
+
throw error;
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
async submitTestRun(payload) {
|
|
1405
|
+
return this.request("POST", "/api/testing/test-runs", payload);
|
|
1406
|
+
}
|
|
1407
|
+
async listTestRuns(projectId, options) {
|
|
1408
|
+
const params = new URLSearchParams({ projectId });
|
|
1409
|
+
if (options?.limit) params.set("limit", String(options.limit));
|
|
1410
|
+
if (options?.suite) params.set("suite", options.suite);
|
|
1411
|
+
const response = await this.request(
|
|
1412
|
+
"GET",
|
|
1413
|
+
`/api/testing/test-runs?${params.toString()}`
|
|
1414
|
+
);
|
|
1415
|
+
return response.runs || [];
|
|
1416
|
+
}
|
|
1417
|
+
async requestCoverageInsight(payload) {
|
|
1418
|
+
return this.request("POST", "/api/testing/coverage-insight", payload);
|
|
1419
|
+
}
|
|
1420
|
+
async listCoverageInsights(projectId, limit = 5) {
|
|
1421
|
+
const params = new URLSearchParams({ projectId, limit: String(limit) });
|
|
1422
|
+
const response = await this.request(
|
|
1423
|
+
"GET",
|
|
1424
|
+
`/api/testing/coverage-insight?${params.toString()}`
|
|
1425
|
+
);
|
|
1426
|
+
return response.reports || [];
|
|
1427
|
+
}
|
|
1428
|
+
};
|
|
1341
1429
|
|
|
1342
1430
|
// src/cli/commands/link.ts
|
|
1343
1431
|
var import_prompts2 = __toESM(require("prompts"));
|
|
@@ -2251,30 +2339,34 @@ function handleCouncilMessage(message, context) {
|
|
|
2251
2339
|
console.log("");
|
|
2252
2340
|
break;
|
|
2253
2341
|
case "round-start":
|
|
2254
|
-
printRoundHeader(message.round);
|
|
2342
|
+
printRoundHeader(message.round ?? 0);
|
|
2255
2343
|
roundResponses.length = 0;
|
|
2256
2344
|
break;
|
|
2257
|
-
case "member-thinking":
|
|
2345
|
+
case "member-thinking": {
|
|
2346
|
+
const role = message.role ?? "architect";
|
|
2258
2347
|
const thinkSpinner = (0, import_ora3.default)({
|
|
2259
|
-
text: `${ROLE_ICONS[
|
|
2348
|
+
text: `${ROLE_ICONS[role]} ${capitalize(role)} is analyzing...`,
|
|
2260
2349
|
color: "yellow"
|
|
2261
2350
|
}).start();
|
|
2262
2351
|
onSpinnerUpdate(thinkSpinner);
|
|
2263
2352
|
break;
|
|
2264
|
-
|
|
2353
|
+
}
|
|
2354
|
+
case "member-response": {
|
|
2265
2355
|
if (currentSpinner) currentSpinner.stop();
|
|
2266
|
-
const
|
|
2267
|
-
const
|
|
2356
|
+
const role = message.role ?? "architect";
|
|
2357
|
+
const roleColor = ROLE_COLORS[role] || import_chalk10.default.white;
|
|
2358
|
+
const icon = ROLE_ICONS[role] || "\u{1F916}";
|
|
2268
2359
|
console.log("");
|
|
2269
|
-
console.log(roleColor.bold(`${icon} ${capitalize(
|
|
2270
|
-
const formatted = formatResponse(message.content);
|
|
2360
|
+
console.log(roleColor.bold(`${icon} ${capitalize(role)}:`));
|
|
2361
|
+
const formatted = formatResponse(typeof message.content === "string" ? message.content : "");
|
|
2271
2362
|
console.log(import_chalk10.default.gray(` ${formatted}`));
|
|
2272
2363
|
console.log("");
|
|
2273
2364
|
roundResponses.push(message);
|
|
2274
2365
|
break;
|
|
2366
|
+
}
|
|
2275
2367
|
case "round-complete":
|
|
2276
|
-
const agreementCount = message.agreements
|
|
2277
|
-
const totalMembers = message.totalMembers
|
|
2368
|
+
const agreementCount = typeof message.agreements === "number" ? message.agreements : 0;
|
|
2369
|
+
const totalMembers = typeof message.totalMembers === "number" ? message.totalMembers : roundResponses.length;
|
|
2278
2370
|
const agreementPercent = Math.round(agreementCount / totalMembers * 100);
|
|
2279
2371
|
console.log(import_chalk10.default.gray(` Agreement: ${agreementCount}/${totalMembers} (${agreementPercent}%)`));
|
|
2280
2372
|
console.log("");
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
CodmirClient
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-GU32P57R.mjs";
|
|
5
5
|
import {
|
|
6
6
|
analyzeCommand,
|
|
7
7
|
clearConfig,
|
|
@@ -25,8 +25,8 @@ var require_package = __commonJS({
|
|
|
25
25
|
"package.json"(exports, module) {
|
|
26
26
|
module.exports = {
|
|
27
27
|
name: "codmir",
|
|
28
|
-
version: "0.
|
|
29
|
-
description: "Official codmir SDK -
|
|
28
|
+
version: "0.4.0",
|
|
29
|
+
description: "Official codmir SDK - AI that prevents wasted engineering time. CLI, SDK, voice assistant, codebase analysis, and intelligent automation.",
|
|
30
30
|
main: "dist/index.js",
|
|
31
31
|
module: "dist/index.mjs",
|
|
32
32
|
types: "dist/index.d.ts",
|
|
@@ -38,6 +38,16 @@ var require_package = __commonJS({
|
|
|
38
38
|
types: "./dist/index.d.ts",
|
|
39
39
|
require: "./dist/index.js",
|
|
40
40
|
import: "./dist/index.mjs"
|
|
41
|
+
},
|
|
42
|
+
"./voice-agent": {
|
|
43
|
+
types: "./dist/voice-agent/index.d.ts",
|
|
44
|
+
require: "./dist/voice-agent/index.js",
|
|
45
|
+
import: "./dist/voice-agent/index.mjs"
|
|
46
|
+
},
|
|
47
|
+
"./voice-daemon": {
|
|
48
|
+
types: "./dist/voice-daemon/index.d.ts",
|
|
49
|
+
require: "./dist/voice-daemon/index.js",
|
|
50
|
+
import: "./dist/voice-daemon/index.mjs"
|
|
41
51
|
}
|
|
42
52
|
},
|
|
43
53
|
files: [
|
|
@@ -47,7 +57,7 @@ var require_package = __commonJS({
|
|
|
47
57
|
"runkit-example.js"
|
|
48
58
|
],
|
|
49
59
|
scripts: {
|
|
50
|
-
build: "tsup src/index.ts src/cli/index.ts --format cjs,esm --dts --clean",
|
|
60
|
+
build: "tsup src/index.ts src/cli/index.ts src/voice-agent/index.ts src/voice-daemon/index.ts --format cjs,esm --dts --clean",
|
|
51
61
|
dev: "tsup src/index.ts src/cli/index.ts --format cjs,esm --dts --watch",
|
|
52
62
|
prepublishOnly: "pnpm build",
|
|
53
63
|
test: "jest",
|
|
@@ -73,7 +83,11 @@ var require_package = __commonJS({
|
|
|
73
83
|
"tasks",
|
|
74
84
|
"automation",
|
|
75
85
|
"multi-agent",
|
|
76
|
-
"ai-assistant"
|
|
86
|
+
"ai-assistant",
|
|
87
|
+
"voice-assistant",
|
|
88
|
+
"speech-recognition",
|
|
89
|
+
"voice-daemon",
|
|
90
|
+
"wake-word"
|
|
77
91
|
],
|
|
78
92
|
author: "codmir",
|
|
79
93
|
license: "MIT",
|
|
@@ -98,12 +112,16 @@ var require_package = __commonJS({
|
|
|
98
112
|
"@semantic-release/release-notes-generator": "^14.0.0",
|
|
99
113
|
"@types/node": "^20.10.0",
|
|
100
114
|
"@types/prompts": "^2.4.9",
|
|
115
|
+
"@types/ws": "^8.18.1",
|
|
116
|
+
"@types/blessed": "^0.1.25",
|
|
101
117
|
"conventional-changelog-conventionalcommits": "^8.0.0",
|
|
102
118
|
"semantic-release": "^24.0.0",
|
|
103
119
|
tsup: "^8.0.1",
|
|
104
120
|
typescript: "^5.8.3"
|
|
105
121
|
},
|
|
106
122
|
dependencies: {
|
|
123
|
+
blessed: "^0.1.81",
|
|
124
|
+
"blessed-contrib": "^4.11.0",
|
|
107
125
|
chalk: "^5.3.0",
|
|
108
126
|
clipboardy: "^5.0.1",
|
|
109
127
|
commander: "^12.0.0",
|
|
@@ -1190,30 +1208,34 @@ function handleCouncilMessage(message, context) {
|
|
|
1190
1208
|
console.log("");
|
|
1191
1209
|
break;
|
|
1192
1210
|
case "round-start":
|
|
1193
|
-
printRoundHeader(message.round);
|
|
1211
|
+
printRoundHeader(message.round ?? 0);
|
|
1194
1212
|
roundResponses.length = 0;
|
|
1195
1213
|
break;
|
|
1196
|
-
case "member-thinking":
|
|
1214
|
+
case "member-thinking": {
|
|
1215
|
+
const role = message.role ?? "architect";
|
|
1197
1216
|
const thinkSpinner = ora2({
|
|
1198
|
-
text: `${ROLE_ICONS[
|
|
1217
|
+
text: `${ROLE_ICONS[role]} ${capitalize(role)} is analyzing...`,
|
|
1199
1218
|
color: "yellow"
|
|
1200
1219
|
}).start();
|
|
1201
1220
|
onSpinnerUpdate(thinkSpinner);
|
|
1202
1221
|
break;
|
|
1203
|
-
|
|
1222
|
+
}
|
|
1223
|
+
case "member-response": {
|
|
1204
1224
|
if (currentSpinner) currentSpinner.stop();
|
|
1205
|
-
const
|
|
1206
|
-
const
|
|
1225
|
+
const role = message.role ?? "architect";
|
|
1226
|
+
const roleColor = ROLE_COLORS[role] || chalk9.white;
|
|
1227
|
+
const icon = ROLE_ICONS[role] || "\u{1F916}";
|
|
1207
1228
|
console.log("");
|
|
1208
|
-
console.log(roleColor.bold(`${icon} ${capitalize(
|
|
1209
|
-
const formatted = formatResponse(message.content);
|
|
1229
|
+
console.log(roleColor.bold(`${icon} ${capitalize(role)}:`));
|
|
1230
|
+
const formatted = formatResponse(typeof message.content === "string" ? message.content : "");
|
|
1210
1231
|
console.log(chalk9.gray(` ${formatted}`));
|
|
1211
1232
|
console.log("");
|
|
1212
1233
|
roundResponses.push(message);
|
|
1213
1234
|
break;
|
|
1235
|
+
}
|
|
1214
1236
|
case "round-complete":
|
|
1215
|
-
const agreementCount = message.agreements
|
|
1216
|
-
const totalMembers = message.totalMembers
|
|
1237
|
+
const agreementCount = typeof message.agreements === "number" ? message.agreements : 0;
|
|
1238
|
+
const totalMembers = typeof message.totalMembers === "number" ? message.totalMembers : roundResponses.length;
|
|
1217
1239
|
const agreementPercent = Math.round(agreementCount / totalMembers * 100);
|
|
1218
1240
|
console.log(chalk9.gray(` Agreement: ${agreementCount}/${totalMembers} (${agreementPercent}%)`));
|
|
1219
1241
|
console.log("");
|
package/dist/index.d.mts
CHANGED
|
@@ -88,6 +88,51 @@ interface CreateTestCaseInput {
|
|
|
88
88
|
interface UpdateTestCaseInput extends Partial<CreateTestCaseInput> {
|
|
89
89
|
status?: TestCaseStatus;
|
|
90
90
|
}
|
|
91
|
+
interface TestRunArtifact {
|
|
92
|
+
label?: string;
|
|
93
|
+
type?: string;
|
|
94
|
+
url: string;
|
|
95
|
+
}
|
|
96
|
+
interface TestRunSummaryInput {
|
|
97
|
+
projectId: string;
|
|
98
|
+
sprintId?: string;
|
|
99
|
+
suite: string;
|
|
100
|
+
framework?: string;
|
|
101
|
+
passCount: number;
|
|
102
|
+
failCount: number;
|
|
103
|
+
flakyCount?: number;
|
|
104
|
+
durationMs?: number;
|
|
105
|
+
commitSha?: string;
|
|
106
|
+
releaseTrainId?: string;
|
|
107
|
+
artifacts?: TestRunArtifact[];
|
|
108
|
+
}
|
|
109
|
+
interface TestRunRecord extends TestRunSummaryInput {
|
|
110
|
+
id: string;
|
|
111
|
+
createdAt: string;
|
|
112
|
+
}
|
|
113
|
+
interface CoverageFeatureBreakdown {
|
|
114
|
+
name: string;
|
|
115
|
+
coverage: number;
|
|
116
|
+
risk?: string;
|
|
117
|
+
}
|
|
118
|
+
interface CoverageInsightRequest {
|
|
119
|
+
projectId: string;
|
|
120
|
+
sprintId?: string;
|
|
121
|
+
linesPct: number;
|
|
122
|
+
branchesPct?: number;
|
|
123
|
+
statementsPct?: number;
|
|
124
|
+
functionsPct?: number;
|
|
125
|
+
features?: CoverageFeatureBreakdown[];
|
|
126
|
+
}
|
|
127
|
+
interface CoverageSuggestedTest {
|
|
128
|
+
title: string;
|
|
129
|
+
reason?: string;
|
|
130
|
+
}
|
|
131
|
+
interface CoverageInsight extends CoverageInsightRequest {
|
|
132
|
+
id: string;
|
|
133
|
+
createdAt: string;
|
|
134
|
+
suggestedTests?: CoverageSuggestedTest[] | null;
|
|
135
|
+
}
|
|
91
136
|
interface ApiResponse<T> {
|
|
92
137
|
data?: T;
|
|
93
138
|
error?: string;
|
|
@@ -132,6 +177,7 @@ declare class CodmirClient {
|
|
|
132
177
|
private readonly config;
|
|
133
178
|
readonly tickets: TicketsAPI;
|
|
134
179
|
readonly testCases: TestCasesAPI;
|
|
180
|
+
readonly testing: TestingAPI;
|
|
135
181
|
constructor(config: CodmirClientConfig);
|
|
136
182
|
/**
|
|
137
183
|
* Make an HTTP request to the codmir API
|
|
@@ -216,5 +262,34 @@ declare class TestCasesAPI {
|
|
|
216
262
|
*/
|
|
217
263
|
delete(projectId: string, testCaseId: string | number): Promise<void>;
|
|
218
264
|
}
|
|
265
|
+
declare class TestingAPI {
|
|
266
|
+
private config;
|
|
267
|
+
constructor(config: Required<CodmirClientConfig>);
|
|
268
|
+
private request;
|
|
269
|
+
submitTestRun(payload: TestRunSummaryInput): Promise<{
|
|
270
|
+
run: TestRunRecord;
|
|
271
|
+
summary: {
|
|
272
|
+
framework: string;
|
|
273
|
+
passRate: number;
|
|
274
|
+
totalDurationMs: number;
|
|
275
|
+
};
|
|
276
|
+
}>;
|
|
277
|
+
listTestRuns(projectId: string, options?: {
|
|
278
|
+
limit?: number;
|
|
279
|
+
suite?: string;
|
|
280
|
+
}): Promise<TestRunRecord[]>;
|
|
281
|
+
requestCoverageInsight(payload: CoverageInsightRequest): Promise<{
|
|
282
|
+
report: CoverageInsight;
|
|
283
|
+
insights: {
|
|
284
|
+
coverageGauge: number;
|
|
285
|
+
featureBreakdown?: CoverageInsightRequest['features'];
|
|
286
|
+
suggestedTests: {
|
|
287
|
+
title: string;
|
|
288
|
+
reason?: string;
|
|
289
|
+
}[];
|
|
290
|
+
};
|
|
291
|
+
}>;
|
|
292
|
+
listCoverageInsights(projectId: string, limit?: number): Promise<CoverageInsight[]>;
|
|
293
|
+
}
|
|
219
294
|
|
|
220
|
-
export { type ApiResponse, CodmirClient, type CodmirClientConfig, CodmirError, type CreateTestCaseInput, type CreateTicketInput, type PaginatedResponse, type TestCase, type TestCasePriority, type TestCaseStatus, type TestCaseStep, type TestCaseTemplate, type Ticket, type TicketPriority, type TicketStatus, type TicketType, type UpdateTestCaseInput, type UpdateTicketInput, type User };
|
|
295
|
+
export { type ApiResponse, CodmirClient, type CodmirClientConfig, CodmirError, type CoverageFeatureBreakdown, type CoverageInsight, type CoverageInsightRequest, type CoverageSuggestedTest, type CreateTestCaseInput, type CreateTicketInput, type PaginatedResponse, type TestCase, type TestCasePriority, type TestCaseStatus, type TestCaseStep, type TestCaseTemplate, type TestRunArtifact, type TestRunRecord, type TestRunSummaryInput, type Ticket, type TicketPriority, type TicketStatus, type TicketType, type UpdateTestCaseInput, type UpdateTicketInput, type User };
|
package/dist/index.d.ts
CHANGED
|
@@ -88,6 +88,51 @@ interface CreateTestCaseInput {
|
|
|
88
88
|
interface UpdateTestCaseInput extends Partial<CreateTestCaseInput> {
|
|
89
89
|
status?: TestCaseStatus;
|
|
90
90
|
}
|
|
91
|
+
interface TestRunArtifact {
|
|
92
|
+
label?: string;
|
|
93
|
+
type?: string;
|
|
94
|
+
url: string;
|
|
95
|
+
}
|
|
96
|
+
interface TestRunSummaryInput {
|
|
97
|
+
projectId: string;
|
|
98
|
+
sprintId?: string;
|
|
99
|
+
suite: string;
|
|
100
|
+
framework?: string;
|
|
101
|
+
passCount: number;
|
|
102
|
+
failCount: number;
|
|
103
|
+
flakyCount?: number;
|
|
104
|
+
durationMs?: number;
|
|
105
|
+
commitSha?: string;
|
|
106
|
+
releaseTrainId?: string;
|
|
107
|
+
artifacts?: TestRunArtifact[];
|
|
108
|
+
}
|
|
109
|
+
interface TestRunRecord extends TestRunSummaryInput {
|
|
110
|
+
id: string;
|
|
111
|
+
createdAt: string;
|
|
112
|
+
}
|
|
113
|
+
interface CoverageFeatureBreakdown {
|
|
114
|
+
name: string;
|
|
115
|
+
coverage: number;
|
|
116
|
+
risk?: string;
|
|
117
|
+
}
|
|
118
|
+
interface CoverageInsightRequest {
|
|
119
|
+
projectId: string;
|
|
120
|
+
sprintId?: string;
|
|
121
|
+
linesPct: number;
|
|
122
|
+
branchesPct?: number;
|
|
123
|
+
statementsPct?: number;
|
|
124
|
+
functionsPct?: number;
|
|
125
|
+
features?: CoverageFeatureBreakdown[];
|
|
126
|
+
}
|
|
127
|
+
interface CoverageSuggestedTest {
|
|
128
|
+
title: string;
|
|
129
|
+
reason?: string;
|
|
130
|
+
}
|
|
131
|
+
interface CoverageInsight extends CoverageInsightRequest {
|
|
132
|
+
id: string;
|
|
133
|
+
createdAt: string;
|
|
134
|
+
suggestedTests?: CoverageSuggestedTest[] | null;
|
|
135
|
+
}
|
|
91
136
|
interface ApiResponse<T> {
|
|
92
137
|
data?: T;
|
|
93
138
|
error?: string;
|
|
@@ -132,6 +177,7 @@ declare class CodmirClient {
|
|
|
132
177
|
private readonly config;
|
|
133
178
|
readonly tickets: TicketsAPI;
|
|
134
179
|
readonly testCases: TestCasesAPI;
|
|
180
|
+
readonly testing: TestingAPI;
|
|
135
181
|
constructor(config: CodmirClientConfig);
|
|
136
182
|
/**
|
|
137
183
|
* Make an HTTP request to the codmir API
|
|
@@ -216,5 +262,34 @@ declare class TestCasesAPI {
|
|
|
216
262
|
*/
|
|
217
263
|
delete(projectId: string, testCaseId: string | number): Promise<void>;
|
|
218
264
|
}
|
|
265
|
+
declare class TestingAPI {
|
|
266
|
+
private config;
|
|
267
|
+
constructor(config: Required<CodmirClientConfig>);
|
|
268
|
+
private request;
|
|
269
|
+
submitTestRun(payload: TestRunSummaryInput): Promise<{
|
|
270
|
+
run: TestRunRecord;
|
|
271
|
+
summary: {
|
|
272
|
+
framework: string;
|
|
273
|
+
passRate: number;
|
|
274
|
+
totalDurationMs: number;
|
|
275
|
+
};
|
|
276
|
+
}>;
|
|
277
|
+
listTestRuns(projectId: string, options?: {
|
|
278
|
+
limit?: number;
|
|
279
|
+
suite?: string;
|
|
280
|
+
}): Promise<TestRunRecord[]>;
|
|
281
|
+
requestCoverageInsight(payload: CoverageInsightRequest): Promise<{
|
|
282
|
+
report: CoverageInsight;
|
|
283
|
+
insights: {
|
|
284
|
+
coverageGauge: number;
|
|
285
|
+
featureBreakdown?: CoverageInsightRequest['features'];
|
|
286
|
+
suggestedTests: {
|
|
287
|
+
title: string;
|
|
288
|
+
reason?: string;
|
|
289
|
+
}[];
|
|
290
|
+
};
|
|
291
|
+
}>;
|
|
292
|
+
listCoverageInsights(projectId: string, limit?: number): Promise<CoverageInsight[]>;
|
|
293
|
+
}
|
|
219
294
|
|
|
220
|
-
export { type ApiResponse, CodmirClient, type CodmirClientConfig, CodmirError, type CreateTestCaseInput, type CreateTicketInput, type PaginatedResponse, type TestCase, type TestCasePriority, type TestCaseStatus, type TestCaseStep, type TestCaseTemplate, type Ticket, type TicketPriority, type TicketStatus, type TicketType, type UpdateTestCaseInput, type UpdateTicketInput, type User };
|
|
295
|
+
export { type ApiResponse, CodmirClient, type CodmirClientConfig, CodmirError, type CoverageFeatureBreakdown, type CoverageInsight, type CoverageInsightRequest, type CoverageSuggestedTest, type CreateTestCaseInput, type CreateTicketInput, type PaginatedResponse, type TestCase, type TestCasePriority, type TestCaseStatus, type TestCaseStep, type TestCaseTemplate, type TestRunArtifact, type TestRunRecord, type TestRunSummaryInput, type Ticket, type TicketPriority, type TicketStatus, type TicketType, type UpdateTestCaseInput, type UpdateTicketInput, type User };
|
package/dist/index.js
CHANGED
|
@@ -35,6 +35,7 @@ var CodmirClient = class {
|
|
|
35
35
|
};
|
|
36
36
|
this.tickets = new TicketsAPI(this.config);
|
|
37
37
|
this.testCases = new TestCasesAPI(this.config);
|
|
38
|
+
this.testing = new TestingAPI(this.config);
|
|
38
39
|
}
|
|
39
40
|
/**
|
|
40
41
|
* Make an HTTP request to the codmir API
|
|
@@ -293,6 +294,75 @@ var TestCasesAPI = class {
|
|
|
293
294
|
);
|
|
294
295
|
}
|
|
295
296
|
};
|
|
297
|
+
var TestingAPI = class {
|
|
298
|
+
constructor(config) {
|
|
299
|
+
this.config = config;
|
|
300
|
+
}
|
|
301
|
+
async request(method, path, body) {
|
|
302
|
+
const url = `${this.config.baseUrl}${path}`;
|
|
303
|
+
const headers = {
|
|
304
|
+
"Content-Type": "application/json",
|
|
305
|
+
...this.config.headers
|
|
306
|
+
};
|
|
307
|
+
if (this.config.apiKey) {
|
|
308
|
+
headers["X-API-Key"] = this.config.apiKey;
|
|
309
|
+
}
|
|
310
|
+
const controller = new AbortController();
|
|
311
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
|
|
312
|
+
try {
|
|
313
|
+
const response = await fetch(url, {
|
|
314
|
+
method,
|
|
315
|
+
headers,
|
|
316
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
317
|
+
signal: controller.signal
|
|
318
|
+
});
|
|
319
|
+
clearTimeout(timeoutId);
|
|
320
|
+
if (!response.ok) {
|
|
321
|
+
const errorData = await response.json().catch(() => ({}));
|
|
322
|
+
const error = new Error(errorData.error || `HTTP ${response.status}`);
|
|
323
|
+
error.statusCode = response.status;
|
|
324
|
+
error.response = errorData;
|
|
325
|
+
throw error;
|
|
326
|
+
}
|
|
327
|
+
if (response.status === 204) {
|
|
328
|
+
return {};
|
|
329
|
+
}
|
|
330
|
+
return await response.json();
|
|
331
|
+
} catch (error) {
|
|
332
|
+
clearTimeout(timeoutId);
|
|
333
|
+
if (error.name === "AbortError") {
|
|
334
|
+
const timeoutError = new Error("Request timeout");
|
|
335
|
+
timeoutError.statusCode = 408;
|
|
336
|
+
throw timeoutError;
|
|
337
|
+
}
|
|
338
|
+
throw error;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
async submitTestRun(payload) {
|
|
342
|
+
return this.request("POST", "/api/testing/test-runs", payload);
|
|
343
|
+
}
|
|
344
|
+
async listTestRuns(projectId, options) {
|
|
345
|
+
const params = new URLSearchParams({ projectId });
|
|
346
|
+
if (options?.limit) params.set("limit", String(options.limit));
|
|
347
|
+
if (options?.suite) params.set("suite", options.suite);
|
|
348
|
+
const response = await this.request(
|
|
349
|
+
"GET",
|
|
350
|
+
`/api/testing/test-runs?${params.toString()}`
|
|
351
|
+
);
|
|
352
|
+
return response.runs || [];
|
|
353
|
+
}
|
|
354
|
+
async requestCoverageInsight(payload) {
|
|
355
|
+
return this.request("POST", "/api/testing/coverage-insight", payload);
|
|
356
|
+
}
|
|
357
|
+
async listCoverageInsights(projectId, limit = 5) {
|
|
358
|
+
const params = new URLSearchParams({ projectId, limit: String(limit) });
|
|
359
|
+
const response = await this.request(
|
|
360
|
+
"GET",
|
|
361
|
+
`/api/testing/coverage-insight?${params.toString()}`
|
|
362
|
+
);
|
|
363
|
+
return response.reports || [];
|
|
364
|
+
}
|
|
365
|
+
};
|
|
296
366
|
// Annotate the CommonJS export names for ESM import in node:
|
|
297
367
|
0 && (module.exports = {
|
|
298
368
|
CodmirClient
|