@test-lab-ai/cli 0.2.17 → 0.2.18
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/lib/api.mjs +28 -1
- package/package.json +2 -2
package/lib/api.mjs
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs"
|
|
2
|
+
import { fileURLToPath } from "node:url"
|
|
3
|
+
import { dirname, join } from "node:path"
|
|
4
|
+
|
|
1
5
|
/**
|
|
2
6
|
* Tiny fetch wrapper for the test-lab public API. Uses global fetch (Node 18+).
|
|
3
7
|
* Returns { ok, status, json } - json is the parsed body (or { raw } on non-JSON).
|
|
@@ -10,11 +14,34 @@
|
|
|
10
14
|
* short-circuits before the app's JSON error handler) from surfacing as a hard
|
|
11
15
|
* "500: upload failed" when a one-second retry would have gone through.
|
|
12
16
|
*/
|
|
17
|
+
|
|
18
|
+
// Client User-Agent: defaults to the CLI's own name+version so the server's
|
|
19
|
+
// audit log can attribute an action to its source surface. The MCP server reuses
|
|
20
|
+
// this same apiFetch, so it overrides the tag at boot via setClientUserAgent
|
|
21
|
+
// ("testlab-mcp/<ver>"); the browser extension hits the API directly and carries
|
|
22
|
+
// its own UA. Kept module-level (not per-call) so every wrapped call is tagged
|
|
23
|
+
// without threading the value through each higher-level lib function.
|
|
24
|
+
function cliVersion() {
|
|
25
|
+
try {
|
|
26
|
+
const pkgPath = join(dirname(fileURLToPath(import.meta.url)), "..", "package.json")
|
|
27
|
+
return JSON.parse(readFileSync(pkgPath, "utf8")).version || "0.0.0"
|
|
28
|
+
} catch {
|
|
29
|
+
return "0.0.0"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let CLIENT_USER_AGENT = `testlab-cli/${cliVersion()}`
|
|
34
|
+
|
|
35
|
+
/** Override the User-Agent sent on every apiFetch call (MCP calls this at boot). */
|
|
36
|
+
export function setClientUserAgent(ua) {
|
|
37
|
+
if (ua && typeof ua === "string") CLIENT_USER_AGENT = ua
|
|
38
|
+
}
|
|
39
|
+
|
|
13
40
|
export async function apiFetch(apiUrl, apiKey, method, pathname, body, opts = {}) {
|
|
14
41
|
const retries = Number.isInteger(opts.retries) ? opts.retries : method === "GET" ? 2 : 0
|
|
15
42
|
const backoffMs = Number.isInteger(opts.backoffMs) ? opts.backoffMs : 800
|
|
16
43
|
|
|
17
|
-
const headers = {}
|
|
44
|
+
const headers = { "User-Agent": CLIENT_USER_AGENT }
|
|
18
45
|
if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`
|
|
19
46
|
if (body !== undefined) headers["Content-Type"] = "application/json"
|
|
20
47
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@test-lab-ai/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.18",
|
|
4
4
|
"description": "Import existing test plans into test-lab.ai from the command line (or an AI agent).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"AGENTS.md"
|
|
19
19
|
],
|
|
20
20
|
"scripts": {
|
|
21
|
-
"test": "node test/toposort.test.mjs",
|
|
21
|
+
"test": "node test/toposort.test.mjs && node test/api-useragent.test.mjs",
|
|
22
22
|
"prepublishOnly": "node scripts/bundle-skill.mjs && npm test"
|
|
23
23
|
},
|
|
24
24
|
"keywords": [
|