@qawolf/cli 1.14.0 → 1.16.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.js +124 -64
- package/package.json +2 -2
- package/skills/qawolf-cli/SKILL.md +2 -1
package/dist/cli.js
CHANGED
|
@@ -326098,11 +326098,13 @@ var interactMessages = {
|
|
|
326098
326098
|
actionFlagsWithStdin: '"-" reads the whole action from stdin, so an action flag passed alongside it would be ignored. Pipe the action in on its own, or name the action type and use flags.',
|
|
326099
326099
|
actionMayHaveHappened: "The runner could not be reached, which does not mean the action was not performed: it may have stopped answering mid-action. Take a screenshot before repeating it.",
|
|
326100
326100
|
actionNotJson: `Stdin did not hold a JSON action. Pipe one object, for example '{"type":"click","button":"left","x":480,"y":260}'.`,
|
|
326101
|
+
actionNotSupportedOnMobile: (type) => `A mobile runner has a touchscreen, so it cannot perform ${type} as asked. It taps with a left-button click, swipes with drag, and types into whatever the last tap focused.`,
|
|
326101
326102
|
actionPerformed: (type) => `Performed ${type}.`,
|
|
326102
326103
|
actionAnsweredUnknown: (failureReason) => `The runner answered "${failureReason}", which this version of the CLI does not know how to report. Upgrade with npm install -g @qawolf/cli.`,
|
|
326103
326104
|
screenshotAnsweredUnknown: (failureReason) => `The runner answered "${failureReason}", which this version of the CLI does not know how to report. Upgrade with npm install -g @qawolf/cli.`,
|
|
326104
326105
|
runnerHasNoScreen: "This runner does not run a browser on a virtual desktop, so there is nothing about it to see or drive. Retrying will never help: launch a playwright runner instead.",
|
|
326105
326106
|
runnerHasNoScreenToEvaluate: "The runner could not evaluate the snippet. This covers a runner that is still starting or busy, and also one with no live page to evaluate against: a freshly launched runner has no page until a run opens one, so run a flow on it with qawolf runner run first. If it is not a runner that runs a browser at all, this will never clear. It is not proof the snippet did not run, so do not resubmit one that mutates the page without reading qawolf runner events console first.",
|
|
326107
|
+
inspectNeedsABrowserRunner: "This runner is a mobile device, and element and page HTML are a browser's shapes. Retrying will never help. Launch a playwright runner to inspect one.",
|
|
326106
326108
|
nothingToInspect: (errorMessage2) => `The runner had nothing to inspect${errorMessage2 === undefined ? "" : `: ${errorMessage2}`}. There is no live page, nothing matched the selector, or no variable has that name; a runner cannot tell those apart. Run a flow on it first, or check the selector or name.`,
|
|
326107
326109
|
inspectAnsweredUnknown: (failureReason) => `The runner answered "${failureReason}", which this version of the CLI does not know how to report. Upgrade with npm install -g @qawolf/cli.`,
|
|
326108
326110
|
screenNeedsARun: "This runner has not run anything yet, so its screen has never started. Waiting will not clear this and there is nothing to retry: run a flow on it with qawolf runner run, then ask again. Evaluating a snippet does not start a screen.",
|
|
@@ -342183,11 +342185,18 @@ var makeCreateRunContract = (ids) => {
|
|
|
342183
342185
|
aiTaskId: ids.aiTask.describe("The AI task whose conversation should receive run status updates.").optional(),
|
|
342184
342186
|
environmentId: ids.environmentRef,
|
|
342185
342187
|
environmentVariables: exports_external.record(exports_external.string(), exports_external.string()).optional(),
|
|
342186
|
-
ignoreRules: exports_external.boolean().default(false),
|
|
342188
|
+
ignoreRules: exports_external.boolean().describe("Ignore this team's sequencing rules for this run. By default they are honoured: the flows your selection depends on are added to the run, and flows run in the order the rules require. Set this to run exactly what you selected, in any order.").default(false),
|
|
342187
342189
|
pullRequestNumber: exports_external.number().int().positive().describe("The number of the pull request to associate with the run.").optional(),
|
|
342188
342190
|
repository: exports_external.string().min(1).describe('The owner/name of the repository, e.g. "acme/web".').optional()
|
|
342189
342191
|
}).and(makeFlowSelectionSchema(ids));
|
|
342190
|
-
const output = resource({
|
|
342192
|
+
const output = resource({
|
|
342193
|
+
excludedFlows: exports_external.array(exports_external.object({
|
|
342194
|
+
flowId: ids.flow,
|
|
342195
|
+
name: exports_external.string().describe("The name of the flow."),
|
|
342196
|
+
reason: exports_external.enum(["deleted", "not-on-branch"]).describe('Why the flow cannot run: "deleted" means the flow was deleted, "not-on-branch" means the flow has no file at the commit the run was created from.')
|
|
342197
|
+
})).describe("Explicitly requested flows that were left out of the run, each with the reason. Flows selected through tags are not reported here."),
|
|
342198
|
+
runId: ids.run
|
|
342199
|
+
}, { urlFieldDescription: "Absolute URL of the run page." });
|
|
342191
342200
|
return {
|
|
342192
342201
|
description: "Create a run for the selected flows and/or tags in an environment.",
|
|
342193
342202
|
input,
|
|
@@ -342265,7 +342274,7 @@ function refusalForRunEnvironmentVariableName(name) {
|
|
|
342265
342274
|
return `${reservedRunEnvironmentVariableName} is reserved by QA Wolf and set for you.`;
|
|
342266
342275
|
return;
|
|
342267
342276
|
}
|
|
342268
|
-
var maxRunEnvironmentVariables =
|
|
342277
|
+
var maxRunEnvironmentVariables = 200;
|
|
342269
342278
|
var maxRunEnvironmentValueLength = 8 * 1024;
|
|
342270
342279
|
var runEnvironmentSchema = exports_external.record(exports_external.string(), exports_external.string().max(maxRunEnvironmentValueLength)).superRefine((environment, refinementContext) => {
|
|
342271
342280
|
for (const name of Object.keys(environment)) {
|
|
@@ -342359,18 +342368,30 @@ var makeInspectOnRunnerContract = () => {
|
|
|
342359
342368
|
}),
|
|
342360
342369
|
exports_external.object({
|
|
342361
342370
|
errorMessage: exports_external.string().optional().describe("What the runner said, when it said anything."),
|
|
342362
|
-
failureReason: exports_external.enum([
|
|
342371
|
+
failureReason: exports_external.enum([
|
|
342372
|
+
"nothing-to-inspect",
|
|
342373
|
+
"runner-is-not-a-browser",
|
|
342374
|
+
"runner-unreachable"
|
|
342375
|
+
]),
|
|
342363
342376
|
outcome: exports_external.literal("failure")
|
|
342364
342377
|
})
|
|
342365
342378
|
]);
|
|
342366
342379
|
return {
|
|
342367
|
-
description: "Inspect one thing on an interactive runner: an element's HTML, the page's HTML simplified for a model, or a top-level variable's value as JSON. `nothing-to-inspect` means the runner had nothing to answer with: no live page, no element matching the selector, or no variable under that name. A runner cannot tell those apart, so it reports the one reason and puts whatever it did say in `errorMessage`. " + retryableRunnerUnreachableDescription,
|
|
342380
|
+
description: "Inspect one thing on an interactive runner: an element's HTML, the page's HTML simplified for a model, or a top-level variable's value as JSON. `nothing-to-inspect` means the runner had nothing to answer with: no live page, no element matching the selector, or no variable under that name. A runner cannot tell those apart, so it reports the one reason and puts whatever it did say in `errorMessage`. `runner-is-not-a-browser` on a mobile runner — call `runner.inspectMobile` for its equivalent surface instead. " + retryableRunnerUnreachableDescription,
|
|
342368
342381
|
input,
|
|
342369
342382
|
kind: "read",
|
|
342370
342383
|
name: "runner.inspect",
|
|
342371
342384
|
output
|
|
342372
342385
|
};
|
|
342373
342386
|
};
|
|
342387
|
+
// node_modules/@qawolf/api-contracts/dist/v1/runner/outcome.js
|
|
342388
|
+
function makeRunnerFailureSchema(reasons) {
|
|
342389
|
+
return exports_external.object({
|
|
342390
|
+
failureReason: exports_external.enum(reasons),
|
|
342391
|
+
outcome: exports_external.literal("failure")
|
|
342392
|
+
});
|
|
342393
|
+
}
|
|
342394
|
+
|
|
342374
342395
|
// node_modules/@qawolf/api-contracts/dist/v1/runner/journal.js
|
|
342375
342396
|
var journalEntrySchema = exports_external.object({
|
|
342376
342397
|
payload: exports_external.unknown(),
|
|
@@ -342427,14 +342448,6 @@ var runFilesSchema = exports_external.record(exports_external.string(), exports_
|
|
|
342427
342448
|
}).refine((files) => runFilesByteLength(files) <= maxRunFilesByteLength, {
|
|
342428
342449
|
error: `The files in one request may carry at most ${maxRunFilesByteLength} bytes in total.`
|
|
342429
342450
|
});
|
|
342430
|
-
// node_modules/@qawolf/api-contracts/dist/v1/runner/outcome.js
|
|
342431
|
-
function makeRunnerFailureSchema(reasons) {
|
|
342432
|
-
return exports_external.object({
|
|
342433
|
-
failureReason: exports_external.enum(reasons),
|
|
342434
|
-
outcome: exports_external.literal("failure")
|
|
342435
|
-
});
|
|
342436
|
-
}
|
|
342437
|
-
|
|
342438
342451
|
// node_modules/@qawolf/api-contracts/dist/v1/runner/screen.js
|
|
342439
342452
|
var screenFailureReasons = [
|
|
342440
342453
|
"runner-has-no-screen",
|
|
@@ -342447,6 +342460,7 @@ var runnerHasNoScreenDescription = "`runner-has-no-screen` if this runner is not
|
|
|
342447
342460
|
|
|
342448
342461
|
// node_modules/@qawolf/api-contracts/dist/v1/runner/performAction.js
|
|
342449
342462
|
var unreachableDescription = "`runner-unreachable` if the runner could not be reached: it may still be starting, it may have terminated after inactivity, or it may have stopped answering mid-action. This does not mean the action was not performed — take a screenshot before repeating it.";
|
|
342463
|
+
var notSupportedOnMobileDescription = "`action-not-supported-on-mobile` if the runner is a mobile device and this action has no touchscreen equivalent: `double_click`, `scroll`, `move`, `keypress` and `navigate`, and a `click` whose `button` is not `left`, are all pointer-device concepts a touchscreen has nothing to offer for. `click` taps, `drag` swipes between its path's first and last point, and `type` types into whatever the last tap focused.";
|
|
342450
342464
|
var maxActionErrorMessageLength = 1000;
|
|
342451
342465
|
var makePerformActionOnRunnerContract = () => {
|
|
342452
342466
|
const input = exports_external.object({
|
|
@@ -342461,6 +342475,7 @@ var makePerformActionOnRunnerContract = () => {
|
|
|
342461
342475
|
}),
|
|
342462
342476
|
makeRunnerFailureSchema([
|
|
342463
342477
|
...screenFailureReasons,
|
|
342478
|
+
"action-not-supported-on-mobile",
|
|
342464
342479
|
runnerUnreachableFailureReason
|
|
342465
342480
|
])
|
|
342466
342481
|
]);
|
|
@@ -342469,7 +342484,7 @@ var makePerformActionOnRunnerContract = () => {
|
|
|
342469
342484
|
failure
|
|
342470
342485
|
]);
|
|
342471
342486
|
return {
|
|
342472
|
-
description: `Perform one raw browser action on an interactive runner: click, double_click, move, drag, scroll, keypress, type, or navigate. Coordinates are whole pixels on the runner's virtual desktop, in the same space as \`runner.takeScreenshot\`. One action per request, and the runner serves one at a time. The action shapes follow the computer-use vocabulary, minus \`screenshot\` (use \`runner.takeScreenshot\`) and \`wait\` (delay on the caller's side). A success means the action took effect. \`action-failed\`, with a reason, if it reached the runner and did not take effect. On a runner image with a browser, the first action on a runner that has never run anything starts its browser and waits for it, so it can take up to a minute to answer — no \`runner.runFlow\` is needed before acting; if the browser is still starting when the wait runs out, the answer is \`screen-not-ready\` and retrying converges. \`screen-needs-a-run\` if the browser could not be started that way — usually a runner whose runs all finished without starting its desktop; call \`runner.runFlow\` with a flow that opens a browser. ${screenNotReadyDescription} A \`navigate\` does not go through the screen, so a screen that is not ready does not stop it. ${runnerHasNoScreenDescription} ${unreachableDescription}`,
|
|
342487
|
+
description: `Perform one raw browser action on an interactive runner: click, double_click, move, drag, scroll, keypress, type, or navigate. Coordinates are whole pixels on the runner's virtual desktop, in the same space as \`runner.takeScreenshot\`. One action per request, and the runner serves one at a time. The action shapes follow the computer-use vocabulary, minus \`screenshot\` (use \`runner.takeScreenshot\`) and \`wait\` (delay on the caller's side). A success means the action took effect. \`action-failed\`, with a reason, if it reached the runner and did not take effect. On a runner image with a browser, the first action on a runner that has never run anything starts its browser and waits for it, so it can take up to a minute to answer — no \`runner.runFlow\` is needed before acting; if the browser is still starting when the wait runs out, the answer is \`screen-not-ready\` and retrying converges. On a mobile runner, the same \`screen-needs-a-run\` and \`screen-not-ready\` outcomes mean no Appium session has started yet, or it did not answer this instant; \`runner.runFlow\` is what starts one, same as a browser. \`screen-needs-a-run\` if the browser could not be started that way — usually a runner whose runs all finished without starting its desktop; call \`runner.runFlow\` with a flow that opens a browser. ${screenNotReadyDescription} A \`navigate\` does not go through the screen, so a screen that is not ready does not stop it. ${runnerHasNoScreenDescription} ${notSupportedOnMobileDescription} ${unreachableDescription}`,
|
|
342473
342488
|
input,
|
|
342474
342489
|
kind: "write",
|
|
342475
342490
|
name: "runner.performAction",
|
|
@@ -342547,7 +342562,7 @@ var makeEnvironmentResourceSchema = (ids) => resource({
|
|
|
342547
342562
|
kind: exports_external.enum(["static", "preview"]).describe("Whether the environment is static or a preview."),
|
|
342548
342563
|
name: exports_external.string(),
|
|
342549
342564
|
runConcurrencyLimit: exports_external.string().describe('Maximum number of concurrent runs: a whole number, "unlimited", or a concurrency expression.'),
|
|
342550
|
-
status: exports_external.enum(["blocked", "needs-investigation", "ready", "running"]).describe("Standing health across the environment's runs: blocked (open blocking bugs), needs-investigation (failures awaiting triage), running (flows executing), ready (none of the above — the greenlit state)."),
|
|
342565
|
+
status: exports_external.enum(["blocked", "needs-investigation", "ready", "running"]).describe("Standing health across the environment's runs, not its Git reconciliation state: blocked (open blocking bugs), needs-investigation (failures awaiting triage), running (flows executing), ready (none of the above — the greenlit state)."),
|
|
342551
342566
|
terminatedAt: exports_external.iso.datetime().optional().describe("When the environment was terminated, if it has been.")
|
|
342552
342567
|
}, { urlFieldDescription: "Absolute URL of the environment page." });
|
|
342553
342568
|
|
|
@@ -342556,6 +342571,7 @@ var makeFindEnvironmentsContract = (ids) => {
|
|
|
342556
342571
|
const input = exports_external.object({
|
|
342557
342572
|
includeTerminated: exports_external.boolean().default(false).describe("Also list terminated environments. By default only environments that have not been terminated are listed."),
|
|
342558
342573
|
kind: exports_external.enum(["static", "preview"]).optional().describe("Only list environments of this kind. Omit to list both."),
|
|
342574
|
+
workspaceId: ids.workspace.optional().describe("The workspace to list environments from. Required when authenticating with an organization or user API key."),
|
|
342559
342575
|
...makePaginationInputFields({ defaultLimit: 20, maxLimit: 100 })
|
|
342560
342576
|
});
|
|
342561
342577
|
const output = exports_external.object({
|
|
@@ -342601,7 +342617,7 @@ var makeGetEnvironmentContract = (ids) => {
|
|
|
342601
342617
|
});
|
|
342602
342618
|
const output = makeEnvironmentResourceSchema(ids);
|
|
342603
342619
|
return {
|
|
342604
|
-
description: "Read a single environment's name, kind, health
|
|
342620
|
+
description: "Read a single environment's name, kind, standing run health, flow-code branch and reconciliation state, run concurrency limit, and termination state. If flowCodeBranch exists, use its syncStatus for Git reconciliation and read lastSyncedCommitHash only when syncStatus is reconciled.",
|
|
342605
342621
|
input,
|
|
342606
342622
|
kind: "read",
|
|
342607
342623
|
name: "environment.get",
|
|
@@ -342643,7 +342659,7 @@ var makeSetEnvironmentVariableContract = (ids) => {
|
|
|
342643
342659
|
var makeCreateEnvironmentContract = (ids) => {
|
|
342644
342660
|
const input = exports_external.object({
|
|
342645
342661
|
name: exports_external.string().min(1).max(255).regex(/\S/, "Environment name cannot be blank.").describe("Display name of the new environment."),
|
|
342646
|
-
workspaceId: ids.workspace.optional().describe("The workspace to create the environment in. Required when authenticating with an organization API key.")
|
|
342662
|
+
workspaceId: ids.workspace.optional().describe("The workspace to create the environment in. Required when authenticating with an organization or user API key.")
|
|
342647
342663
|
});
|
|
342648
342664
|
const output = makeEnvironmentResourceSchema(ids);
|
|
342649
342665
|
return {
|
|
@@ -342683,9 +342699,10 @@ var makeTagResourceSchema = () => resource({
|
|
|
342683
342699
|
}, {
|
|
342684
342700
|
urlFieldDescription: "Absolute URL of the team's tag settings page."
|
|
342685
342701
|
});
|
|
342686
|
-
var makeCreateTagContract = () => {
|
|
342702
|
+
var makeCreateTagContract = (ids) => {
|
|
342687
342703
|
const input = exports_external.object({
|
|
342688
|
-
name: exports_external.string().trim().min(1).max(255).refine((name) => !name.includes(","), "Tag names cannot include commas.")
|
|
342704
|
+
name: exports_external.string().trim().min(1).max(255).refine((name) => !name.includes(","), "Tag names cannot include commas."),
|
|
342705
|
+
workspaceId: ids.workspace.optional().describe("The workspace to create the tag in. Required when authenticating with an organization or user API key.")
|
|
342689
342706
|
});
|
|
342690
342707
|
const output = makeTagResourceSchema();
|
|
342691
342708
|
return {
|
|
@@ -342809,7 +342826,7 @@ var makeFindIssuesContract = (ids) => {
|
|
|
342809
342826
|
...makePaginationInputFields({ defaultLimit: 20, maxLimit: 100 }),
|
|
342810
342827
|
statuses: exports_external.array(issueStatusSchema).min(1).default([...openIssueStatuses]).describe("Issue statuses to include. Defaults to pending, in-progress, and paused issues."),
|
|
342811
342828
|
type: publicIssueTypeSchema.describe("The issue type to include: bug report, maintenance report, or coverage request."),
|
|
342812
|
-
workspaceId: ids.workspace.optional().describe("The workspace whose issues to list. Required when authenticating with an organization API key.")
|
|
342829
|
+
workspaceId: ids.workspace.optional().describe("The workspace whose issues to list. Required when authenticating with an organization or user API key.")
|
|
342813
342830
|
});
|
|
342814
342831
|
const output = exports_external.object({
|
|
342815
342832
|
issues: exports_external.array(makeIssueResourceSchema(ids)).describe("The team's bug reports, maintenance reports, or coverage requests, newest first."),
|
|
@@ -342863,7 +342880,7 @@ var makeCreateIssueContract = (ids) => {
|
|
|
342863
342880
|
description: exports_external.string().optional().describe("The issue description as plain text; each line becomes a paragraph. Markdown is not parsed."),
|
|
342864
342881
|
name: exports_external.string().trim().min(1).max(255),
|
|
342865
342882
|
priority: issuePrioritySchema.optional().describe('Defaults to "unprioritized".'),
|
|
342866
|
-
workspaceId: ids.workspace.optional().describe("The workspace to create the issue in. Required when authenticating with an organization API key.")
|
|
342883
|
+
workspaceId: ids.workspace.optional().describe("The workspace to create the issue in. Required when authenticating with an organization or user API key.")
|
|
342867
342884
|
};
|
|
342868
342885
|
const input = exports_external.discriminatedUnion("type", [
|
|
342869
342886
|
exports_external.object({
|
|
@@ -343025,6 +343042,25 @@ var makeGetRunContract = (ids) => {
|
|
|
343025
343042
|
};
|
|
343026
343043
|
};
|
|
343027
343044
|
|
|
343045
|
+
// node_modules/@qawolf/api-contracts/dist/v1/run/reattempt.js
|
|
343046
|
+
var makeReattemptRunContract = (ids) => {
|
|
343047
|
+
const input = exports_external.object({
|
|
343048
|
+
flowIds: exports_external.array(ids.flow).min(1).max(300).refine((flowIds) => new Set(flowIds).size === flowIds.length, "flowIds must be unique").optional().describe("The flows to reattempt. Every named flow must be eligible or the " + "whole request is rejected. Omit to reattempt every eligible flow."),
|
|
343049
|
+
runId: ids.run
|
|
343050
|
+
});
|
|
343051
|
+
const output = resource({
|
|
343052
|
+
reattemptedFlowIds: exports_external.array(ids.flow).describe("The flows a new attempt was requested for."),
|
|
343053
|
+
runId: ids.run
|
|
343054
|
+
}, { urlFieldDescription: "Absolute URL of the run page." });
|
|
343055
|
+
return {
|
|
343056
|
+
description: "Request new attempts for a run's flows, in the same run. " + "A flow is eligible once its result is failed or canceled and QA Wolf's " + "automatic retries have finished. " + "A fully investigated run no longer accepts reattempts. " + "Attempts run with the latest flow code. Poll run.get for results.",
|
|
343057
|
+
input,
|
|
343058
|
+
kind: "write",
|
|
343059
|
+
name: "run.reattempt",
|
|
343060
|
+
output
|
|
343061
|
+
};
|
|
343062
|
+
};
|
|
343063
|
+
|
|
343028
343064
|
// node_modules/@qawolf/api-contracts/dist/v1/runner/evaluateSnippet.js
|
|
343029
343065
|
var maxSnippetCodeLength = 64 * 1024;
|
|
343030
343066
|
var makeEvaluateSnippetOnRunnerContract = () => {
|
|
@@ -343240,7 +343276,7 @@ var makeTakeScreenshotOnRunnerContract = () => {
|
|
|
343240
343276
|
])
|
|
343241
343277
|
]);
|
|
343242
343278
|
return {
|
|
343243
|
-
description: `Take one screenshot of an interactive runner's screen.
|
|
343279
|
+
description: `Take one screenshot of an interactive runner's screen. On a runner with a browser the image is the whole virtual desktop, browser window and all. On a mobile runner it is the device's own screen, re-encoded to JPEG on the pod so this contract reads one image format regardless of runner family. ${screenNeedsARunDescription} ${screenNotReadyDescription} ${runnerHasNoScreenDescription} ${retryableRunnerUnreachableDescription}`,
|
|
343244
343280
|
input,
|
|
343245
343281
|
kind: "read",
|
|
343246
343282
|
name: "runner.takeScreenshot",
|
|
@@ -343253,6 +343289,7 @@ var makeListTagsContract = (ids) => {
|
|
|
343253
343289
|
const input = exports_external.object({
|
|
343254
343290
|
includeFlowIds: exports_external.boolean().default(false).describe("Also return the ids of the flows that carry each tag."),
|
|
343255
343291
|
names: exports_external.array(exports_external.string().trim().min(1)).min(1).max(100).optional().describe("Only list tags with these names. Matching is case sensitive. Omit to list all tags."),
|
|
343292
|
+
workspaceId: ids.workspace.optional().describe("The workspace to list tags from. Required when authenticating with an organization or user API key."),
|
|
343256
343293
|
...makePaginationInputFields({ defaultLimit: 20, maxLimit: 100 })
|
|
343257
343294
|
});
|
|
343258
343295
|
const output = exports_external.object({
|
|
@@ -343300,7 +343337,8 @@ var makeContractsV1 = (ids) => {
|
|
|
343300
343337
|
run: {
|
|
343301
343338
|
create: makeCreateRunContract(resolvedIds),
|
|
343302
343339
|
find: makeFindRunsContract(resolvedIds),
|
|
343303
|
-
get: makeGetRunContract(resolvedIds)
|
|
343340
|
+
get: makeGetRunContract(resolvedIds),
|
|
343341
|
+
reattempt: makeReattemptRunContract(resolvedIds)
|
|
343304
343342
|
},
|
|
343305
343343
|
runner: {
|
|
343306
343344
|
evaluateSnippet: makeEvaluateSnippetOnRunnerContract(),
|
|
@@ -343315,7 +343353,7 @@ var makeContractsV1 = (ids) => {
|
|
|
343315
343353
|
terminate: makeTerminateRunnerContract()
|
|
343316
343354
|
},
|
|
343317
343355
|
tag: {
|
|
343318
|
-
create: makeCreateTagContract(),
|
|
343356
|
+
create: makeCreateTagContract(resolvedIds),
|
|
343319
343357
|
list: makeListTagsContract(resolvedIds)
|
|
343320
343358
|
}
|
|
343321
343359
|
};
|
|
@@ -345836,7 +345874,7 @@ function startUpdateCheck(deps) {
|
|
|
345836
345874
|
// package.json
|
|
345837
345875
|
var package_default = {
|
|
345838
345876
|
name: "@qawolf/cli",
|
|
345839
|
-
version: "1.
|
|
345877
|
+
version: "1.16.0",
|
|
345840
345878
|
description: "Run and manage QA Wolf flows from the terminal, CI, or an AI agent",
|
|
345841
345879
|
keywords: [
|
|
345842
345880
|
"automation",
|
|
@@ -345896,7 +345934,7 @@ var package_default = {
|
|
|
345896
345934
|
"@clack/prompts": "1.5.1",
|
|
345897
345935
|
"@napi-rs/keyring": "1.3.0",
|
|
345898
345936
|
"@oxc-node/core": "0.1.0",
|
|
345899
|
-
"@qawolf/api-contracts": "0.
|
|
345937
|
+
"@qawolf/api-contracts": "0.32.0",
|
|
345900
345938
|
"@qawolf/emails": "1.1.1",
|
|
345901
345939
|
"@qawolf/flow-targets": "1.0.0",
|
|
345902
345940
|
"@qawolf/flows": "0.1.4",
|
|
@@ -356432,7 +356470,7 @@ function readNpmDependencies(packageJsonContent) {
|
|
|
356432
356470
|
}
|
|
356433
356471
|
|
|
356434
356472
|
// src/domains/interactiveRunner/runnerCallOptions.ts
|
|
356435
|
-
var runnerCallOptions = { timeoutMs:
|
|
356473
|
+
var runnerCallOptions = { timeoutMs: 90000 };
|
|
356436
356474
|
|
|
356437
356475
|
// src/domains/interactiveRunner/runnerIds.ts
|
|
356438
356476
|
function parseRunnerId(id) {
|
|
@@ -356991,6 +357029,11 @@ async function handleRunnerInspect(ctx, options, deps) {
|
|
|
356991
357029
|
error: interactiveRunnerMessages.nothingToInspect(failure.errorMessage),
|
|
356992
357030
|
exitCode: exitCodes.invalidArgs
|
|
356993
357031
|
};
|
|
357032
|
+
case "runner-is-not-a-browser":
|
|
357033
|
+
return {
|
|
357034
|
+
error: interactiveRunnerMessages.inspectNeedsABrowserRunner,
|
|
357035
|
+
exitCode: exitCodes.invalidArgs
|
|
357036
|
+
};
|
|
356994
357037
|
case "runner-unreachable":
|
|
356995
357038
|
return {
|
|
356996
357039
|
error: interactiveRunnerMessages.runnerUnreachable,
|
|
@@ -357208,6 +357251,50 @@ function parseBrowserAction(candidate) {
|
|
|
357208
357251
|
return { action: parsed.data, ok: true };
|
|
357209
357252
|
}
|
|
357210
357253
|
|
|
357254
|
+
// src/domains/interactiveRunner/performActionFailure.ts
|
|
357255
|
+
function describePerformActionFailure(options) {
|
|
357256
|
+
const { actionType, failure } = options;
|
|
357257
|
+
const { failureReason } = failure;
|
|
357258
|
+
switch (failureReason) {
|
|
357259
|
+
case "action-failed":
|
|
357260
|
+
return {
|
|
357261
|
+
error: interactiveRunnerMessages.actionFailed(failure.errorMessage),
|
|
357262
|
+
exitCode: exitCodes.testFailure
|
|
357263
|
+
};
|
|
357264
|
+
case "action-not-supported-on-mobile":
|
|
357265
|
+
return {
|
|
357266
|
+
error: interactiveRunnerMessages.actionNotSupportedOnMobile(actionType),
|
|
357267
|
+
exitCode: exitCodes.invalidArgs
|
|
357268
|
+
};
|
|
357269
|
+
case "screen-needs-a-run":
|
|
357270
|
+
return {
|
|
357271
|
+
error: interactiveRunnerMessages.screenNeedsARun,
|
|
357272
|
+
exitCode: exitCodes.invalidArgs
|
|
357273
|
+
};
|
|
357274
|
+
case "screen-not-ready":
|
|
357275
|
+
return {
|
|
357276
|
+
error: interactiveRunnerMessages.screenNotReady,
|
|
357277
|
+
exitCode: exitCodes.network
|
|
357278
|
+
};
|
|
357279
|
+
case "runner-has-no-screen":
|
|
357280
|
+
return {
|
|
357281
|
+
error: interactiveRunnerMessages.runnerHasNoScreen,
|
|
357282
|
+
exitCode: exitCodes.invalidArgs
|
|
357283
|
+
};
|
|
357284
|
+
case "runner-unreachable":
|
|
357285
|
+
return {
|
|
357286
|
+
error: interactiveRunnerMessages.actionMayHaveHappened,
|
|
357287
|
+
exitCode: exitCodes.network
|
|
357288
|
+
};
|
|
357289
|
+
default: {
|
|
357290
|
+
return {
|
|
357291
|
+
error: interactiveRunnerMessages.actionAnsweredUnknown(failureReason),
|
|
357292
|
+
exitCode: exitCodes.network
|
|
357293
|
+
};
|
|
357294
|
+
}
|
|
357295
|
+
}
|
|
357296
|
+
}
|
|
357297
|
+
|
|
357211
357298
|
// src/domains/interactiveRunner/performAction.ts
|
|
357212
357299
|
var stdinArgument2 = "-";
|
|
357213
357300
|
async function readAction(type, flags, deps) {
|
|
@@ -357250,41 +357337,10 @@ async function handleRunnerAct(ctx, options, deps) {
|
|
|
357250
357337
|
ctx.ui.output({ action: built.action, outcome: "success" }, interactiveRunnerMessages.actionPerformed(built.action.type));
|
|
357251
357338
|
return;
|
|
357252
357339
|
}
|
|
357253
|
-
|
|
357254
|
-
|
|
357255
|
-
|
|
357256
|
-
|
|
357257
|
-
return {
|
|
357258
|
-
error: interactiveRunnerMessages.actionFailed(failure.errorMessage),
|
|
357259
|
-
exitCode: exitCodes.testFailure
|
|
357260
|
-
};
|
|
357261
|
-
case "screen-needs-a-run":
|
|
357262
|
-
return {
|
|
357263
|
-
error: interactiveRunnerMessages.screenNeedsARun,
|
|
357264
|
-
exitCode: exitCodes.invalidArgs
|
|
357265
|
-
};
|
|
357266
|
-
case "screen-not-ready":
|
|
357267
|
-
return {
|
|
357268
|
-
error: interactiveRunnerMessages.screenNotReady,
|
|
357269
|
-
exitCode: exitCodes.network
|
|
357270
|
-
};
|
|
357271
|
-
case "runner-has-no-screen":
|
|
357272
|
-
return {
|
|
357273
|
-
error: interactiveRunnerMessages.runnerHasNoScreen,
|
|
357274
|
-
exitCode: exitCodes.invalidArgs
|
|
357275
|
-
};
|
|
357276
|
-
case "runner-unreachable":
|
|
357277
|
-
return {
|
|
357278
|
-
error: interactiveRunnerMessages.actionMayHaveHappened,
|
|
357279
|
-
exitCode: exitCodes.network
|
|
357280
|
-
};
|
|
357281
|
-
default: {
|
|
357282
|
-
return {
|
|
357283
|
-
error: interactiveRunnerMessages.actionAnsweredUnknown(failureReason),
|
|
357284
|
-
exitCode: exitCodes.network
|
|
357285
|
-
};
|
|
357286
|
-
}
|
|
357287
|
-
}
|
|
357340
|
+
return describePerformActionFailure({
|
|
357341
|
+
actionType: built.action.type,
|
|
357342
|
+
failure: result.value
|
|
357343
|
+
});
|
|
357288
357344
|
}
|
|
357289
357345
|
|
|
357290
357346
|
// src/domains/interactiveRunner/takeScreenshot.ts
|
|
@@ -357939,6 +357995,9 @@ function buildRunFileDelta(options) {
|
|
|
357939
357995
|
}
|
|
357940
357996
|
const heldHashes = new Map(held.files.map((entry) => [entry.path, entry.contentHash]));
|
|
357941
357997
|
const alwaysSent = new Set([options.entryPointPath, runPackageJsonPath]);
|
|
357998
|
+
if (options.selectionPath !== undefined) {
|
|
357999
|
+
alwaysSent.add(options.selectionPath);
|
|
358000
|
+
}
|
|
357942
358001
|
const files = {};
|
|
357943
358002
|
const unchangedFiles = {};
|
|
357944
358003
|
for (const [path9, content] of Object.entries(options.files)) {
|
|
@@ -358026,7 +358085,8 @@ async function submitRun(ctx, options, deps) {
|
|
|
358026
358085
|
entryPointPath: options.entryPointPath,
|
|
358027
358086
|
files: options.files,
|
|
358028
358087
|
held,
|
|
358029
|
-
runnerId: options.resolved.runnerId
|
|
358088
|
+
runnerId: options.resolved.runnerId,
|
|
358089
|
+
selectionPath: options.selection?.path
|
|
358030
358090
|
});
|
|
358031
358091
|
const first2 = await sendRunFlowRequest(ctx, options, delta);
|
|
358032
358092
|
if (first2.type === "needs-full-sync") {
|
|
@@ -358194,4 +358254,4 @@ createProgram({ signals }).parseAsync().catch(() => {
|
|
|
358194
358254
|
process.exitCode = 1;
|
|
358195
358255
|
}).finally(() => flushAndExit(typeof process.exitCode === "number" ? process.exitCode : 0));
|
|
358196
358256
|
|
|
358197
|
-
//# debugId=
|
|
358257
|
+
//# debugId=A9041D278FF748EF64756E2164756E21
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qawolf/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"description": "Run and manage QA Wolf flows from the terminal, CI, or an AI agent",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"automation",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"@clack/prompts": "1.5.1",
|
|
61
61
|
"@napi-rs/keyring": "1.3.0",
|
|
62
62
|
"@oxc-node/core": "0.1.0",
|
|
63
|
-
"@qawolf/api-contracts": "0.
|
|
63
|
+
"@qawolf/api-contracts": "0.32.0",
|
|
64
64
|
"@qawolf/emails": "1.1.1",
|
|
65
65
|
"@qawolf/flow-targets": "1.0.0",
|
|
66
66
|
"@qawolf/flows": "0.1.4",
|
|
@@ -118,7 +118,7 @@ current branch.
|
|
|
118
118
|
| `qawolf environment create` | write | Create an environment on the caller's team and return it in the environment.get shape. |
|
|
119
119
|
| `qawolf environment deleteVariable` | write | Remove one environment variable by name. Succeeds whether or not the variable existed. |
|
|
120
120
|
| `qawolf environment find` | read | List the team's environments, newest first. |
|
|
121
|
-
| `qawolf environment get` | read | Read a single environment's name, kind, health
|
|
121
|
+
| `qawolf environment get` | read | Read a single environment's name, kind, standing run health, flow-code branch and reconciliation state, run concurrency limit, and termination state. If flowCodeBranch exists, use its syncStatus for Git reconciliation and read lastSyncedCommitHash only when syncStatus is reconciled. |
|
|
122
122
|
| `qawolf environment getVariable` | read | Read the values of named environment variables in one call. Values are secrets. Names that do not exist go to missingNames and do not fail the call. |
|
|
123
123
|
| `qawolf environment listVariableNames` | read | Use this to answer which QA Wolf environment variables are available to test code. Returns names only; values never leave the server. |
|
|
124
124
|
| `qawolf environment setVariable` | write | Create or replace an environment variable. If the user asks to create one for "my email" without naming it, use DEFAULT_EMAIL. The value is never returned. |
|
|
@@ -141,6 +141,7 @@ current branch.
|
|
|
141
141
|
| `qawolf run create` | write | Create a run for the selected flows and/or tags in an environment. |
|
|
142
142
|
| `qawolf run find` | read | List an environment's recent runs, newest first. |
|
|
143
143
|
| `qawolf run get` | read | Get a run's status, per-flow results, and links. |
|
|
144
|
+
| `qawolf run reattempt` | write | Request new attempts for a run's flows, in the same run. A flow is eligible once its result is failed or canceled and QA Wolf's automatic retries have finished. A fully investigated run no longer accepts reattempts. Attempts run with the latest flow code. Poll run.get for results. |
|
|
144
145
|
| `qawolf runner act` | write | Perform one raw action on a runner's screen: click, double_click, scroll, move, drag, keypress, navigate or type. Use - to read a whole action as JSON from stdin |
|
|
145
146
|
| `qawolf runner events` | read | Print a runner's journal, one entry per line. QA Wolf writes console, recorder, run-events, run-logs, run-status |
|
|
146
147
|
| `qawolf runner exec` | write | Evaluate a snippet against a runner's live page. Use - to read the snippet from stdin |
|