@test-lab-ai/cli 0.2.16 → 0.2.17
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/bin/testlab.mjs +33 -1
- package/package.json +1 -1
package/bin/testlab.mjs
CHANGED
|
@@ -40,6 +40,9 @@ Usage:
|
|
|
40
40
|
(credentials, labels, fixtures, plans)
|
|
41
41
|
testlab plans list List your test plans
|
|
42
42
|
testlab plans create -f plan.json Create one plan from JSON
|
|
43
|
+
testlab plans update <id> [-f patch.json] [--prompt P] [--name N]
|
|
44
|
+
Update an existing plan; only the
|
|
45
|
+
fields you pass change
|
|
43
46
|
testlab projects list List your projects
|
|
44
47
|
testlab credentials set <key> --value <value> Set a credential ({{credentials.<key>}})
|
|
45
48
|
testlab credentials list List credential keys (values never shown)
|
|
@@ -216,6 +219,34 @@ async function cmdPlansCreate(flags) {
|
|
|
216
219
|
log(`✓ Created plan #${r.json.testPlan.id}: ${r.json.testPlan.name}`)
|
|
217
220
|
}
|
|
218
221
|
|
|
222
|
+
async function cmdPlansUpdate(flags, args) {
|
|
223
|
+
const { apiKey, apiUrl } = requireAuth(flags)
|
|
224
|
+
const planId = parsePlanIdArg(args[2] ?? flags.plan)
|
|
225
|
+
if (!Number.isInteger(planId)) {
|
|
226
|
+
errExit("usage: testlab plans update <id> [-f patch.json] [--prompt P] [--name N] (numeric plan id; see `testlab plans list`)")
|
|
227
|
+
}
|
|
228
|
+
// Build a partial patch. A JSON file is the full surface (name, prompt,
|
|
229
|
+
// testType, agentType, devices, paused, projectId); --prompt / --name are
|
|
230
|
+
// quick overrides for the two common edits. Only the fields present are sent,
|
|
231
|
+
// and the server changes only those.
|
|
232
|
+
let patch = {}
|
|
233
|
+
if (flags.file) {
|
|
234
|
+
try {
|
|
235
|
+
patch = JSON.parse(fs.readFileSync(flags.file, "utf8"))
|
|
236
|
+
} catch (e) {
|
|
237
|
+
errExit(`could not read ${flags.file}: ${e.message}`)
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
if (flags.prompt !== undefined) patch.prompt = flags.prompt
|
|
241
|
+
if (flags.name !== undefined) patch.name = flags.name
|
|
242
|
+
if (Object.keys(patch).length === 0) {
|
|
243
|
+
errExit("nothing to update: pass -f <patch.json> and/or --prompt / --name. Editable fields: name, prompt, testType, agentType, devices, paused, projectId")
|
|
244
|
+
}
|
|
245
|
+
const r = await apiFetch(apiUrl, apiKey, "PUT", `/api/v1/test-plans/${planId}`, patch)
|
|
246
|
+
if (!r.ok) errExit(`${r.status}: ${r.json?.error || ""}`)
|
|
247
|
+
log(`✓ Updated plan #${r.json.testPlan.id}: ${r.json.testPlan.name}`)
|
|
248
|
+
}
|
|
249
|
+
|
|
219
250
|
async function cmdCredentialsSet(flags, args) {
|
|
220
251
|
const { apiKey, apiUrl } = requireAuth(flags)
|
|
221
252
|
const key = args[2]
|
|
@@ -639,7 +670,8 @@ async function main() {
|
|
|
639
670
|
case "plans":
|
|
640
671
|
if (args[1] === "list") return cmdPlansList(flags)
|
|
641
672
|
if (args[1] === "create") return cmdPlansCreate(flags)
|
|
642
|
-
|
|
673
|
+
if (args[1] === "update") return cmdPlansUpdate(flags, args)
|
|
674
|
+
return errExit("usage: testlab plans <list|create|update>")
|
|
643
675
|
case "projects":
|
|
644
676
|
if (args[1] === "list") return cmdProjectsList(flags)
|
|
645
677
|
return errExit("usage: testlab projects list")
|