@qawolf/cli 1.35.0 → 1.36.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 CHANGED
@@ -8816,7 +8816,8 @@ var interactMessages = {
8816
8816
  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.',
8817
8817
  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.",
8818
8818
  actionNotJson: `Stdin did not hold a JSON action. Pipe one object, for example '{"type":"click","button":"left","x":480,"y":260}'.`,
8819
- 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.`,
8819
+ actionNotSupportedOnBrowser: (type) => `Only a mobile runner performs ${type}. On a browser runner, click at --x and --y, drag along a --path, and type into whatever has focus.`,
8820
+ actionNotSupportedOnMobile: (type) => `A mobile runner has a touchscreen, so it cannot perform ${type} as asked. Use tap, swipe, fill, or type into whatever the last tap focused.`,
8820
8821
  actionFailedScreenshotToStdout: "Its screen was written to stdout as a JPEG, so look at that rather than sending the action again.",
8821
8822
  actionFailedScreenshotUnwritten: (detail) => `Its screen could not be written, because ${detail}, so take one with qawolf runner screenshot rather than sending the action again.`,
8822
8823
  actionFailedScreenshotWritten: (path) => `Its screen was written to ${path}, so look at that rather than sending the action again.`,
@@ -10076,7 +10077,6 @@ var bigint = /^-?\d+n?$/;
10076
10077
  var integer = /^-?\d+$/;
10077
10078
  var number = /^-?\d+(?:\.\d+)?$/;
10078
10079
  var boolean = /^(?:true|false)$/i;
10079
- var _null = /^null$/i;
10080
10080
  var lowercase = /^[^A-Z]*$/;
10081
10081
  var uppercase = /^[^a-z]*$/;
10082
10082
 
@@ -10997,23 +10997,6 @@ var $ZodBigInt = /* @__PURE__ */ $constructor("$ZodBigInt", (inst, def) => {
10997
10997
  return payload;
10998
10998
  };
10999
10999
  });
11000
- var $ZodNull = /* @__PURE__ */ $constructor("$ZodNull", (inst, def) => {
11001
- $ZodType.init(inst, def);
11002
- inst._zod.pattern = _null;
11003
- inst._zod.values = new Set([null]);
11004
- inst._zod.parse = (payload, _ctx) => {
11005
- const input = payload.value;
11006
- if (input === null)
11007
- return payload;
11008
- payload.issues.push({
11009
- expected: "null",
11010
- code: "invalid_type",
11011
- input,
11012
- inst
11013
- });
11014
- return payload;
11015
- };
11016
- });
11017
11000
  var $ZodUnknown = /* @__PURE__ */ $constructor("$ZodUnknown", (inst, def) => {
11018
11001
  $ZodType.init(inst, def);
11019
11002
  inst._zod.parse = (payload) => payload;
@@ -12548,12 +12531,6 @@ function _coercedBigint(Class, params) {
12548
12531
  ...normalizeParams(params)
12549
12532
  });
12550
12533
  }
12551
- function _null2(Class, params) {
12552
- return new Class({
12553
- type: "null",
12554
- ...normalizeParams(params)
12555
- });
12556
- }
12557
12534
  function _unknown(Class) {
12558
12535
  return new Class({
12559
12536
  type: "unknown"
@@ -14183,14 +14160,6 @@ var ZodBigInt = /* @__PURE__ */ $constructor("ZodBigInt", (inst, def) => {
14183
14160
  inst.maxValue = bag.maximum ?? null;
14184
14161
  inst.format = bag.format ?? null;
14185
14162
  });
14186
- var ZodNull = /* @__PURE__ */ $constructor("ZodNull", (inst, def) => {
14187
- $ZodNull.init(inst, def);
14188
- ZodType.init(inst, def);
14189
- inst._zod.processJSONSchema = (ctx, json, params) => nullProcessor(inst, ctx, json, params);
14190
- });
14191
- function _null3(params) {
14192
- return _null2(ZodNull, params);
14193
- }
14194
14163
  var ZodUnknown = /* @__PURE__ */ $constructor("ZodUnknown", (inst, def) => {
14195
14164
  $ZodUnknown.init(inst, def);
14196
14165
  ZodType.init(inst, def);
@@ -14642,12 +14611,6 @@ function refine(fn, _params = {}) {
14642
14611
  function superRefine(fn, params) {
14643
14612
  return _superRefine(fn, params);
14644
14613
  }
14645
- function json(params) {
14646
- const jsonSchema = lazy(() => {
14647
- return union([string2(params), number2(), boolean2(), _null3(), array(jsonSchema), record(string2(), jsonSchema)]);
14648
- });
14649
- return jsonSchema;
14650
- }
14651
14614
  // node_modules/zod/v4/classic/coerce.js
14652
14615
  var exports_coerce = {};
14653
14616
  __export(exports_coerce, {
@@ -16646,6 +16609,75 @@ var agentReplySchema = object({
16646
16609
  var maxAgentWaitSeconds = 45;
16647
16610
  var agentWakeReasonSchema = _enum(["reply", "status", "timeout"]).describe('Why a held check answered. "reply" means the AI said something new, "status" means the session settled or needs you, "timeout" means the hold ran out with nothing new.');
16648
16611
 
16612
+ // node_modules/@qawolf/api-contracts/dist/v1/run/summary.js
16613
+ var publicRunStatusValues = [
16614
+ "queued",
16615
+ "running",
16616
+ "passed",
16617
+ "failed",
16618
+ "canceled"
16619
+ ];
16620
+ var makeRunSummaryFields = (ids) => ({
16621
+ completedAt: exports_iso.datetime().optional().describe("When the run finished executing. Absent while queued or running, and also absent for a terminal run that never completed execution (e.g. every flow was canceled or skipped)."),
16622
+ createdAt: exports_iso.datetime(),
16623
+ git: object({
16624
+ branch: string2().optional(),
16625
+ commitMessage: string2().optional(),
16626
+ commitSha: string2().optional(),
16627
+ commitUrl: string2().optional().describe("Link to the commit on the code host.")
16628
+ }).describe("The branch and commit under test. The fields are present when a deploy notification started the run, and absent for runs started another way, for example manually or with run.create."),
16629
+ needsReview: boolean2().optional().describe("True once every flow has finished its attempts and at least one failed flow still has no diagnosis, including one whose investigation carried over to a later run. `status` stays `running` until that failure is diagnosed, so a caller that is not waiting for a diagnosis can stop polling here and read the run's failed flows."),
16630
+ runId: ids.run,
16631
+ status: _enum(publicRunStatusValues).describe("Whole-run status, and the value to gate a pipeline on. Terminal statuses are passed, failed, and canceled; poll until one is reached. `failed` means the run found a bug that is still open and serious enough to block — a lower-priority bug, or one since resolved, reads `passed`, and the per-flow diagnoses are still in `flows`. The run stays `running` while any investigation is unresolved, including one that carried over to a later run, so a terminal status always means a settled answer. `needsReview` tells such a run apart from one that is still executing.")
16632
+ });
16633
+
16634
+ // node_modules/@qawolf/api-contracts/dist/v1/deployment/didNotRunReason.js
16635
+ var didNotRunReasonSchema = _enum([
16636
+ "billing-prevented",
16637
+ "branch-still-syncing",
16638
+ "deployment-no-longer-live",
16639
+ "duplicate-run",
16640
+ "environment-not-linked-to-branch",
16641
+ "environment-not-ready",
16642
+ "environment-terminated",
16643
+ "internal-error",
16644
+ "low-risk-change",
16645
+ "no-flows-to-run",
16646
+ "no-matching-trigger",
16647
+ "no-pull-request",
16648
+ "no-relevant-flows",
16649
+ "rate-limited",
16650
+ "run-not-created",
16651
+ "skipped",
16652
+ "test-configuration-error",
16653
+ "trigger-not-found",
16654
+ "workspace-inactive",
16655
+ "workspace-not-ready"
16656
+ ]).describe([
16657
+ "Why the matched trigger created no run, as a stable value safe to branch on in a CI pipeline. The accompanying `message` is the wording for a person to read and may be reworded at any time; this value will not be.",
16658
+ "billing-prevented: a billing restriction on the workspace stopped the run.",
16659
+ "branch-still-syncing: the environment was still syncing its flows.",
16660
+ "deployment-no-longer-live: the deployment was torn down or replaced by a newer one before the run started.",
16661
+ "duplicate-run: another run already covered this same deployment.",
16662
+ "environment-not-linked-to-branch: the environment has no branch to take flows from yet.",
16663
+ "environment-not-ready: the environment was still being prepared; retrying later can succeed.",
16664
+ "environment-terminated: the environment for the run is terminated.",
16665
+ "internal-error: QA Wolf could not start the run and the cause is on our side.",
16666
+ "low-risk-change: adaptive flow selection assessed the change as low risk, so nothing needed to run.",
16667
+ "no-flows-to-run: no flow was eligible, because the trigger's flows are in maintenance, still drafts, or missing on this branch.",
16668
+ "no-matching-trigger: no deployment trigger matched.",
16669
+ "no-pull-request: the trigger uses adaptive flow selection, which needs an open pull request, and this deployment had none.",
16670
+ "no-relevant-flows: adaptive flow selection found no existing flow covering this change.",
16671
+ "rate-limited: too many runs were requested at once; retrying later can succeed.",
16672
+ "run-not-created: the run never reached a decision.",
16673
+ "skipped: the run was skipped for a reason with no more specific value.",
16674
+ "test-configuration-error: the workspace's flows or dependency rules need fixing before this can run.",
16675
+ "trigger-not-found: the trigger no longer exists.",
16676
+ "workspace-inactive: the workspace is not active.",
16677
+ "workspace-not-ready: the workspace has not finished setting up."
16678
+ ].join(`
16679
+ `));
16680
+
16649
16681
  // node_modules/@qawolf/api-contracts/dist/v1/resource.js
16650
16682
  function resource(fields, { urlFieldDescription = "Absolute URL." } = {}) {
16651
16683
  return object({
@@ -16986,7 +17018,8 @@ var runnerNameSchema = _enum([
16986
17018
  "basic",
16987
17019
  "playwright",
16988
17020
  "android",
16989
- "ios"
17021
+ "ios",
17022
+ "windows"
16990
17023
  ]);
16991
17024
  var runnerWorkspaceRequirement = "Read it from whoami.";
16992
17025
  var runnerWorkspaceIdDescription = `The workspace the runner belongs to. ${runnerWorkspaceRequirement}`;
@@ -17106,7 +17139,11 @@ function makeRunnerFailureSchema(reasons) {
17106
17139
 
17107
17140
  // node_modules/@qawolf/api-contracts/dist/v1/runner/inspectMobile.js
17108
17141
  var maxElementTextLength = 500;
17109
- var selectorStrategySchema = _enum(["ios-predicate", "shadow", "xpath"]);
17142
+ var selectorStrategySchema = _enum([
17143
+ "ios-predicate",
17144
+ "shadow",
17145
+ "xpath"
17146
+ ]);
17110
17147
  var elementsRequestSchema = discriminatedUnion("by", [
17111
17148
  object({
17112
17149
  by: literal("point"),
@@ -17269,6 +17306,65 @@ var runFilesSchema = record(string2(), string2()).superRefine((files, refinement
17269
17306
  }).refine((files) => runFilesByteLength(files) <= maxRunFilesByteLength, {
17270
17307
  error: `The files in one request may carry at most ${maxRunFilesByteLength} bytes in total.`
17271
17308
  });
17309
+ // node_modules/@qawolf/api-contracts/dist/v1/runner/runnerAction.js
17310
+ var maxSwipeDurationMs = 1e4;
17311
+ var selectorSchema2 = string2().min(1).max(maxSelectorLength).describe("The element to act on, resolved the way a screen object's own selector is.");
17312
+ var strategySchema = selectorStrategySchema.optional().describe("How `selector` is resolved. Defaults to `xpath`.");
17313
+ function refuseStrategyWithoutSelector(action, context) {
17314
+ if (action.strategy !== undefined && action.selector === undefined) {
17315
+ context.addIssue({
17316
+ code: "custom",
17317
+ message: "`strategy` says how to resolve a `selector`, so it needs one.",
17318
+ path: ["strategy"]
17319
+ });
17320
+ }
17321
+ }
17322
+ var tapActionSchema = strictObject({
17323
+ selector: selectorSchema2.optional(),
17324
+ strategy: strategySchema,
17325
+ type: literal("tap"),
17326
+ x: screenCoordinateSchema.optional(),
17327
+ y: screenCoordinateSchema.optional()
17328
+ }).superRefine((tap, context) => {
17329
+ refuseStrategyWithoutSelector(tap, context);
17330
+ const hasPoint = tap.x !== undefined || tap.y !== undefined;
17331
+ if (tap.selector !== undefined && hasPoint) {
17332
+ context.addIssue({
17333
+ code: "custom",
17334
+ message: "A tap aims at `x` and `y` or at a `selector`, not both.",
17335
+ path: ["selector"]
17336
+ });
17337
+ }
17338
+ if (tap.selector === undefined && (tap.x === undefined || tap.y === undefined)) {
17339
+ context.addIssue({
17340
+ code: "custom",
17341
+ message: "A tap needs both `x` and `y`, or a `selector`.",
17342
+ path: [tap.x === undefined ? "x" : "y"]
17343
+ });
17344
+ }
17345
+ });
17346
+ var swipeActionSchema = strictObject({
17347
+ duration_ms: int().positive().max(maxSwipeDurationMs).optional().describe("How long the swipe takes, in milliseconds. A slow one scrolls, a fast one flings. The device's default is 300."),
17348
+ from: screenPointSchema,
17349
+ to: screenPointSchema,
17350
+ type: literal("swipe")
17351
+ }).refine(({ from, to }) => from.x !== to.x || from.y !== to.y, {
17352
+ message: "A swipe whose `from` and `to` are the same travels nowhere.",
17353
+ path: ["to"]
17354
+ });
17355
+ var fillActionSchema = strictObject({
17356
+ selector: selectorSchema2,
17357
+ strategy: strategySchema,
17358
+ text: string2().max(maxTypedTextLength).describe("What the field holds afterwards, in place of its old value. Empty clears it."),
17359
+ type: literal("fill")
17360
+ });
17361
+ var runnerActionSchema = discriminatedUnion("type", [
17362
+ ...browserActionSchema.options,
17363
+ tapActionSchema,
17364
+ swipeActionSchema,
17365
+ fillActionSchema
17366
+ ]);
17367
+
17272
17368
  // node_modules/@qawolf/api-contracts/dist/v1/runner/screen.js
17273
17369
  var screenFailureReasons = [
17274
17370
  "runner-has-no-screen",
@@ -17277,17 +17373,18 @@ var screenFailureReasons = [
17277
17373
  ];
17278
17374
  var screenNotReadyDescription = "`screen-not-ready` if the runner has a screen that cannot serve this instant. Retry in a second or two: the desktop restarts when a run changes the display size, and it serves one see-or-act request at a time, so a screenshot or action already in flight is the usual reason. Do not submit a run to clear this — a run may restart the display and discard what is on it.";
17279
17375
  var screenNeedsARunDescription = "`screen-needs-a-run` if the runner's virtual desktop has never started. Waiting will not change this and retrying is pointless — call `runner.runFlow` with a flow that opens a browser, then ask for the screen again. On a runner image with a browser that has never run anything, any `runner.performAction` also starts the browser itself. Evaluating a snippet does not start the desktop.";
17280
- var runnerHasNoScreenDescription = "`runner-has-no-screen` if this runner is not one that runs a browser on a virtual desktop. Nothing about it can be seen or driven, and retrying will never help — launch a `playwright` runner instead.";
17376
+ var runnerHasNoScreenDescription = "`runner-has-no-screen` if this runner has no browser desktop to see or drive, and retrying will never help. Launch a `playwright` runner, or on `windows` use `runner.runFlow`.";
17281
17377
  var screenshotImageSchema = string2().min(1).describe("The screenshot, as a base64-encoded JPEG. Decode it and write the bytes to a `.jpg` file — writing this string to the file leaves you with base64 text rather than an image.");
17282
17378
 
17283
17379
  // node_modules/@qawolf/api-contracts/dist/v1/runner/performAction.js
17284
17380
  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.";
17285
- 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.";
17381
+ 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. `type` types into whatever the last tap focused. Deprecated on mobile and to be removed: `click` taps and `drag` swipes between its path's first and last point; send `tap` and `swipe` instead.";
17382
+ var mobileActionsDescription = "Only a mobile runner performs `tap`, `swipe` and `fill`: `tap` touches a point or the element a `selector` names, `swipe` moves from one point to another over `duration_ms`, and `fill` replaces the value of the field a `selector` names. A browser runner answers them with `action-not-supported-on-browser`.";
17286
17383
  var withScreenshotDescription = "With `withScreenshot: true`, the answer also carries `imageJpegBase64`: a screenshot taken after the action. One call instead of `runner.performAction` followed by `runner.takeScreenshot`. The action itself is performed exactly as without the option; if the screen could serve no frame after it — a display restart, or a `navigate` on a desktop that is still starting — the action's result comes back without `imageJpegBase64`, so take a screenshot separately rather than repeating the action. On a mobile runner the screenshot is the device's own, taken right after a performed action.";
17287
17384
  var maxActionErrorMessageLength = 1000;
17288
17385
  var makePerformActionOnRunnerContract = (ids) => {
17289
17386
  const input = object({
17290
- action: browserActionSchema.describe(`The action to perform. Coordinates are whole pixels on the runner's virtual desktop, in the same space as \`runner.takeScreenshot\`. The action shapes follow the computer-use vocabulary, minus \`screenshot\` (use \`runner.takeScreenshot\`) and \`wait\` (delay on the caller's side). A \`navigate\` does not go through the screen, so a screen that is not ready does not stop it. ${notSupportedOnMobileDescription}`),
17387
+ action: runnerActionSchema.describe(`The action to perform. Coordinates are whole pixels on the runner's virtual desktop, in the same space as \`runner.takeScreenshot\`. The browser action shapes follow the computer-use vocabulary, minus \`screenshot\` (use \`runner.takeScreenshot\`) and \`wait\` (delay on the caller's side). A \`navigate\` does not go through the screen, so a screen that is not ready does not stop it. ${notSupportedOnMobileDescription} ${mobileActionsDescription}`),
17291
17388
  id: runnerIdSchema.describe("Id of the runner to act on."),
17292
17389
  withScreenshot: boolean2().optional().describe(withScreenshotDescription),
17293
17390
  workspaceId: ids.workspace.optional().describe(runnerWorkspaceIdDescription)
@@ -17303,6 +17400,7 @@ var makePerformActionOnRunnerContract = (ids) => {
17303
17400
  makeRunnerFailureSchema([
17304
17401
  ...screenFailureReasons,
17305
17402
  "action-not-supported-on-mobile",
17403
+ "action-not-supported-on-browser",
17306
17404
  runnerUnreachableFailureReason
17307
17405
  ])
17308
17406
  ]);
@@ -17319,7 +17417,7 @@ var makePerformActionOnRunnerContract = (ids) => {
17319
17417
  openWorldHint: true,
17320
17418
  readOnlyHint: false
17321
17419
  },
17322
- description: `Perform one raw browser action on an interactive runner: click, double_click, move, drag, scroll, keypress, type, or navigate. One action per request, and the runner serves one at a time. 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} ${runnerHasNoScreenDescription} ${unreachableDescription}`,
17420
+ description: `Perform one raw action on an interactive runner: click, double_click, move, drag, scroll, keypress, type, or navigate; on mobile, tap, swipe, fill, or type. One action per request, and the runner serves one at a time. 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} ${runnerHasNoScreenDescription} ${unreachableDescription}`,
17323
17421
  input,
17324
17422
  kind: "write",
17325
17423
  name: "runner.performAction",
@@ -17534,7 +17632,6 @@ function makeRecordingContracts(ids) {
17534
17632
  recordings: makeRunnerRecordingsContract(ids)
17535
17633
  };
17536
17634
  }
17537
-
17538
17635
  // node_modules/@qawolf/api-contracts/dist/v1/runner/runSelection.js
17539
17636
  var runSelectionSchema = object({
17540
17637
  endLine: int().positive().describe("Last line to run, 1-indexed and inclusive."),
@@ -17582,7 +17679,7 @@ var makeTriggerScheduleFields = (ids) => ({
17582
17679
  environmentId: ids.environmentId.describe("The environment the scheduled runs happen in."),
17583
17680
  minuteOfHour: number2().int().min(0).max(59).optional().describe("Minutes past the hour an hourly schedule fires. Defaults to 0."),
17584
17681
  timeOfDay: string2().regex(/^([01]\d|2[0-3]):[0-5]\d$/).optional().describe('The wall clock time a daily or weekly schedule fires, as "HH:mm". Required when cadence is daily or weekly.'),
17585
- timezoneId: string2().min(1).refine(isTimezone, "Expected an IANA timezone, such as America/New_York.").optional().describe("The IANA timezone the schedule is read in, such as America/New_York. Required when cadence is daily or weekly, and when an hourly schedule names daysOfWeek, whose day boundaries it sets. An hourly schedule firing on every day needs none, and is read in America/Los_Angeles.")
17682
+ timezoneId: string2().min(1).refine(isTimezone, "Expected an IANA timezone, such as America/New_York.").optional().describe("The IANA timezone the schedule is read in, such as America/New_York. Required for every cadence: it sets the day boundaries daysOfWeek is read against, and the wall clock timeOfDay is read against.")
17586
17683
  });
17587
17684
  var makeTriggerDeploymentFields = (ids) => ({
17588
17685
  action: makeTriggerActionSchema(ids),
@@ -17623,12 +17720,12 @@ var checkAction = (action, ctx) => {
17623
17720
  };
17624
17721
  var requiredScheduleFields = {
17625
17722
  daily: ["timeOfDay", "timezoneId"],
17626
- hourly: [],
17723
+ hourly: ["timezoneId"],
17627
17724
  weekly: ["dayOfWeek", "timeOfDay", "timezoneId"]
17628
17725
  };
17629
17726
  var optionalScheduleFields = {
17630
17727
  daily: ["daysOfWeek"],
17631
- hourly: ["daysOfWeek", "minuteOfHour", "timezoneId"],
17728
+ hourly: ["daysOfWeek", "minuteOfHour"],
17632
17729
  weekly: []
17633
17730
  };
17634
17731
  var cadencesUsingField = {
@@ -17669,18 +17766,8 @@ var checkScheduleFields = (value, ctx) => {
17669
17766
  }
17670
17767
  }
17671
17768
  };
17672
- var checkHourlyZone = (value, ctx) => {
17673
- if (value.cadence !== "hourly" || value.daysOfWeek === undefined || value.timezoneId !== undefined)
17674
- return;
17675
- ctx.addIssue({
17676
- code: "custom",
17677
- message: "timezoneId is required when an hourly cadence names daysOfWeek.",
17678
- path: ["timezoneId"]
17679
- });
17680
- };
17681
17769
  var checkSchedule = (value, ctx) => {
17682
17770
  checkScheduleFields(value, ctx);
17683
- checkHourlyZone(value, ctx);
17684
17771
  if (value.action.kind === "generativeSuite") {
17685
17772
  ctx.addIssue({
17686
17773
  code: "custom",
@@ -18083,53 +18170,6 @@ var makeFindDeploymentsContract = (ids) => {
18083
18170
  };
18084
18171
  };
18085
18172
 
18086
- // node_modules/@qawolf/api-contracts/dist/v1/deployment/didNotRunReason.js
18087
- var didNotRunReasonSchema = _enum([
18088
- "billing-prevented",
18089
- "branch-still-syncing",
18090
- "deployment-no-longer-live",
18091
- "duplicate-run",
18092
- "environment-not-linked-to-branch",
18093
- "environment-not-ready",
18094
- "environment-terminated",
18095
- "internal-error",
18096
- "low-risk-change",
18097
- "no-flows-to-run",
18098
- "no-matching-trigger",
18099
- "no-pull-request",
18100
- "no-relevant-flows",
18101
- "rate-limited",
18102
- "run-not-created",
18103
- "skipped",
18104
- "test-configuration-error",
18105
- "trigger-not-found",
18106
- "workspace-inactive",
18107
- "workspace-not-ready"
18108
- ]).describe([
18109
- "Why the matched trigger created no run, as a stable value safe to branch on in a CI pipeline. The accompanying `message` is the wording for a person to read and may be reworded at any time; this value will not be.",
18110
- "billing-prevented: a billing restriction on the workspace stopped the run.",
18111
- "branch-still-syncing: the environment was still syncing its flows.",
18112
- "deployment-no-longer-live: the deployment was torn down or replaced by a newer one before the run started.",
18113
- "duplicate-run: another run already covered this same deployment.",
18114
- "environment-not-linked-to-branch: the environment has no branch to take flows from yet.",
18115
- "environment-not-ready: the environment was still being prepared; retrying later can succeed.",
18116
- "environment-terminated: the environment for the run is terminated.",
18117
- "internal-error: QA Wolf could not start the run and the cause is on our side.",
18118
- "low-risk-change: adaptive flow selection assessed the change as low risk, so nothing needed to run.",
18119
- "no-flows-to-run: no flow was eligible, because the trigger's flows are in maintenance, still drafts, or missing on this branch.",
18120
- "no-matching-trigger: no deployment trigger matched.",
18121
- "no-pull-request: the trigger uses adaptive flow selection, which needs an open pull request, and this deployment had none.",
18122
- "no-relevant-flows: adaptive flow selection found no existing flow covering this change.",
18123
- "rate-limited: too many runs were requested at once; retrying later can succeed.",
18124
- "run-not-created: the run never reached a decision.",
18125
- "skipped: the run was skipped for a reason with no more specific value.",
18126
- "test-configuration-error: the workspace's flows or dependency rules need fixing before this can run.",
18127
- "trigger-not-found: the trigger no longer exists.",
18128
- "workspace-inactive: the workspace is not active.",
18129
- "workspace-not-ready: the workspace has not finished setting up."
18130
- ].join(`
18131
- `));
18132
-
18133
18173
  // node_modules/@qawolf/api-contracts/dist/v1/deployment/listTriggerEvaluations.js
18134
18174
  var conditionKindSchema = _enum(["environment", "deployTarget", "branch", "service"]).describe("What the condition checks on the deployment: the environment it reported into, the deploy target it serves, the git branch of the deployed commit, or the service it deployed.");
18135
18175
  var conditionVerdictSchema = discriminatedUnion("outcome", [
@@ -19007,7 +19047,7 @@ var makeCreateIssueContract = (ids) => {
19007
19047
  const commonFields = {
19008
19048
  description: string2().optional().describe("The issue description as plain text; each line becomes a paragraph. Markdown is not parsed."),
19009
19049
  name: string2().trim().min(1).max(255),
19010
- priority: issuePrioritySchema.optional().describe('Defaults to "unprioritized".'),
19050
+ priority: issuePrioritySchema.optional().describe('Defaults to "unprioritized" for bug reports and coverage requests.'),
19011
19051
  workspaceId: ids.workspace.optional().describe("The workspace to create the issue in. Required when authenticating with an organization or user API key.")
19012
19052
  };
19013
19053
  const input = discriminatedUnion("type", [
@@ -19019,6 +19059,13 @@ var makeCreateIssueContract = (ids) => {
19019
19059
  ...commonFields,
19020
19060
  estimatedDueDate: exports_iso.date().optional().describe("The calendar date the coverage is estimated to be complete, as YYYY-MM-DD."),
19021
19061
  type: literal("coverageRequest")
19062
+ }),
19063
+ object({
19064
+ ...commonFields,
19065
+ effort: _enum(["extraSmall", "small", "medium", "large", "extraLarge"]).describe("The effort to repair the flows."),
19066
+ priority: _enum(["low", "medium", "high", "urgent"]),
19067
+ reason: _enum(["dataChanged", "flowNeedsWork", "other", "uiChanged"]).describe("Why the flows need maintenance."),
19068
+ type: literal("maintenance")
19022
19069
  })
19023
19070
  ]);
19024
19071
  const output = object({
@@ -19030,7 +19077,7 @@ var makeCreateIssueContract = (ids) => {
19030
19077
  openWorldHint: true,
19031
19078
  readOnlyHint: false
19032
19079
  },
19033
- description: "Create a bug or coverage request issue for the caller's team. " + "Maintenance issues cannot be created through the public API.",
19080
+ description: "Create a bug report, maintenance report, or coverage request issue for the caller's team. " + "A user can create a maintenance report only when they can see the workspace's maintenance reports; " + "a team or organization API key credits it to the workspace's automation user. " + "Link its failed flows afterwards with run.diagnose.",
19034
19081
  input,
19035
19082
  kind: "write",
19036
19083
  name: "issue.create",
@@ -19119,6 +19166,8 @@ var makeLegacyTriggerSchema = (ids) => {
19119
19166
  isPaused: boolean2(),
19120
19167
  name: string2(),
19121
19168
  pausedAt: exports_iso.datetime().optional(),
19169
+ runConcurrencyLimit: string2().describe(`How many of the trigger's runs may execute at once: a whole number, "unlimited", or a concurrency expression. A trigger that stores no limit reads as "unlimited", which leaves the environment's limit in charge. Copy a number or an expression onto the current trigger action's runConcurrencyLimit, and omit that field when this reads "unlimited".`),
19170
+ shouldTriage: boolean2().describe("Whether QA Wolf investigates the failures of the runs this trigger creates. It becomes the current trigger action's investigateFailures, which is on unless the trigger says otherwise."),
19122
19171
  tags: array(namedIdentity)
19123
19172
  };
19124
19173
  return union([
@@ -19235,27 +19284,6 @@ var makeDiagnoseRunContract = (ids) => {
19235
19284
  };
19236
19285
  };
19237
19286
 
19238
- // node_modules/@qawolf/api-contracts/dist/v1/run/summary.js
19239
- var publicRunStatusValues = [
19240
- "queued",
19241
- "running",
19242
- "passed",
19243
- "failed",
19244
- "canceled"
19245
- ];
19246
- var makeRunSummaryFields = (ids) => ({
19247
- completedAt: exports_iso.datetime().optional().describe("When the run finished executing. Absent while queued or running, and also absent for a terminal run that never completed execution (e.g. every flow was canceled or skipped)."),
19248
- createdAt: exports_iso.datetime(),
19249
- git: object({
19250
- branch: string2().optional(),
19251
- commitMessage: string2().optional(),
19252
- commitSha: string2().optional(),
19253
- commitUrl: string2().optional().describe("Link to the commit on the code host.")
19254
- }).describe("The branch and commit under test. The fields are present when a deploy notification started the run, and absent for runs started another way, for example manually or with run.create."),
19255
- runId: ids.run,
19256
- status: _enum(publicRunStatusValues).describe("Whole-run status, and the value to gate a pipeline on. Terminal statuses are passed, failed, and canceled; poll until one is reached. `failed` means the run found a bug that is still open and serious enough to block — a lower-priority bug, or one since resolved, reads `passed`, and the per-flow diagnoses are still in `flows`. The run stays `running` while any investigation is unresolved, including one that carried over to a later run, so a terminal status always means a settled answer.")
19257
- });
19258
-
19259
19287
  // node_modules/@qawolf/api-contracts/dist/v1/run/find.js
19260
19288
  var makeFindRunsContract = (ids) => {
19261
19289
  const input = object({
@@ -19413,54 +19441,6 @@ var makeStopRunContract = (ids) => {
19413
19441
  };
19414
19442
  };
19415
19443
 
19416
- // node_modules/@qawolf/api-contracts/dist/v1/run/triage.js
19417
- var probability = number2().min(0).max(1);
19418
- var verdictAnswer = object({
19419
- choice: _enum(["bug", "maintenance"]),
19420
- confidence: probability,
19421
- probabilities: record(string2(), probability),
19422
- type: literal("choice")
19423
- });
19424
- var makeTriageRunContract = (ids) => {
19425
- const input = object({
19426
- flowId: ids.flow.describe("The flow that failed in the run."),
19427
- runId: ids.run
19428
- });
19429
- const decision = discriminatedUnion("type", [
19430
- object({
19431
- diagnosis: _enum(["bug", "maintenance"]),
19432
- type: literal("diagnose")
19433
- }),
19434
- object({
19435
- diagnosis: _enum(["bug", "maintenance"]),
19436
- type: literal("suggest")
19437
- }),
19438
- object({
19439
- type: literal("needsHuman")
19440
- })
19441
- ]);
19442
- const output = object({
19443
- answers: object({
19444
- verdict: verdictAnswer
19445
- }),
19446
- decision: decision.describe("What the triage would do with the verdict. The prototype records nothing; it only reports."),
19447
- model: string2(),
19448
- state: json().describe("The context that was sent to the model, for inspection.")
19449
- });
19450
- return {
19451
- annotations: {
19452
- destructiveHint: false,
19453
- openWorldHint: false,
19454
- readOnlyHint: true
19455
- },
19456
- description: "Prototype. Ask Jev, a TypeSafe System One model, whether a flow failure in a run is a bug in the product " + "or a test that needs maintenance. Compares the failing attempt with the flow's last passing run in the " + "same environment. Records nothing.",
19457
- input,
19458
- kind: "read",
19459
- name: "run.triage",
19460
- output
19461
- };
19462
- };
19463
-
19464
19444
  // node_modules/@qawolf/api-contracts/dist/v1/runner/evaluateSnippet.js
19465
19445
  var maxSnippetCodeLength = 64 * 1024;
19466
19446
  var makeEvaluateSnippetOnRunnerContract = (ids) => {
@@ -20028,8 +20008,7 @@ var makeContractsV1 = (ids) => {
20028
20008
  find: makeFindRunsContract(resolvedIds),
20029
20009
  get: makeGetRunContract(resolvedIds),
20030
20010
  reattempt: makeReattemptRunContract(resolvedIds),
20031
- stop: makeStopRunContract(resolvedIds),
20032
- triage: makeTriageRunContract(resolvedIds)
20011
+ stop: makeStopRunContract(resolvedIds)
20033
20012
  },
20034
20013
  runner: makeRunnerContracts(resolvedIds),
20035
20014
  skill: makeSkillContracts(),
@@ -22545,7 +22524,7 @@ function startUpdateCheck(deps) {
22545
22524
  // package.json
22546
22525
  var package_default = {
22547
22526
  name: "@qawolf/cli",
22548
- version: "1.35.0",
22527
+ version: "1.36.0",
22549
22528
  description: "Run and manage QA Wolf flows from the terminal, CI, or an AI agent",
22550
22529
  keywords: [
22551
22530
  "automation",
@@ -22616,7 +22595,7 @@ var package_default = {
22616
22595
  "@clack/prompts": "1.5.1",
22617
22596
  "@napi-rs/keyring": "1.3.0",
22618
22597
  "@oxc-node/core": "0.1.0",
22619
- "@qawolf/api-contracts": "0.70.0",
22598
+ "@qawolf/api-contracts": "0.73.0",
22620
22599
  "@qawolf/emails": "1.1.1",
22621
22600
  "@qawolf/flow-targets": "1.0.0",
22622
22601
  "@qawolf/flows": "0.1.4",
@@ -36146,6 +36125,21 @@ async function writeSequenceFrames(options, deps) {
36146
36125
  };
36147
36126
  }
36148
36127
 
36128
+ // src/core/interactiveRunner/flagValues.ts
36129
+ function parsePoint(flag, point) {
36130
+ const [x, y, ...rest] = point.split(",");
36131
+ if (x === undefined || y === undefined || rest.length > 0) {
36132
+ return {
36133
+ error: `${flag} must be one point as x,y in screenshot pixels, for example 200,800.`,
36134
+ ok: false
36135
+ };
36136
+ }
36137
+ return { ok: true, value: { x: toNumber(x), y: toNumber(y) } };
36138
+ }
36139
+ function toNumber(value) {
36140
+ return value.trim() === "" ? Number.NaN : Number(value);
36141
+ }
36142
+
36149
36143
  // src/core/interactiveRunner/browserAction.ts
36150
36144
  function parseJsonPath(path) {
36151
36145
  try {
@@ -36157,34 +36151,48 @@ function parseJsonPath(path) {
36157
36151
  };
36158
36152
  }
36159
36153
  }
36160
- function toNumber(value) {
36161
- return value.trim() === "" ? Number.NaN : Number(value);
36162
- }
36163
- function buildBrowserAction(type, flags) {
36154
+ function buildRunnerAction(type, flags) {
36164
36155
  const parsedPath = flags.path === undefined ? undefined : parseJsonPath(flags.path);
36165
36156
  if (parsedPath !== undefined && !parsedPath.ok)
36166
36157
  return parsedPath;
36158
+ const from = flags.from === undefined ? undefined : parsePoint("--from", flags.from);
36159
+ if (from !== undefined && !from.ok)
36160
+ return from;
36161
+ const to = flags.to === undefined ? undefined : parsePoint("--to", flags.to);
36162
+ if (to !== undefined && !to.ok)
36163
+ return to;
36167
36164
  const candidate = {
36168
36165
  type,
36169
36166
  ...flags.button === undefined ? {} : { button: flags.button },
36167
+ ...flags.durationMs === undefined ? {} : { duration_ms: toNumber(flags.durationMs) },
36168
+ ...from === undefined ? {} : { from: from.value },
36170
36169
  ...flags.keys === undefined ? {} : { keys: flags.keys },
36171
36170
  ...parsedPath === undefined ? {} : { path: parsedPath.value },
36172
36171
  ...flags.scrollX === undefined ? {} : { scroll_x: toNumber(flags.scrollX) },
36173
36172
  ...flags.scrollY === undefined ? {} : { scroll_y: toNumber(flags.scrollY) },
36173
+ ...flags.selector === undefined ? {} : { selector: flags.selector },
36174
+ ...flags.strategy === undefined ? {} : { strategy: flags.strategy },
36174
36175
  ...flags.text === undefined ? {} : { text: flags.text },
36176
+ ...to === undefined ? {} : { to: to.value },
36175
36177
  ...flags.url === undefined ? {} : { url: flags.url },
36176
36178
  ...flags.x === undefined ? {} : { x: toNumber(flags.x) },
36177
36179
  ...flags.y === undefined ? {} : { y: toNumber(flags.y) }
36178
36180
  };
36179
- return parseBrowserAction(candidate);
36181
+ return parseRunnerAction(candidate);
36180
36182
  }
36181
- function parseBrowserAction(candidate) {
36182
- const parsed = browserActionSchema.safeParse(candidate);
36183
+ function parseWith(schema, candidate) {
36184
+ const parsed = schema.safeParse(candidate);
36183
36185
  if (!parsed.success) {
36184
36186
  return { error: prettifyError(parsed.error), ok: false };
36185
36187
  }
36186
36188
  return { action: parsed.data, ok: true };
36187
36189
  }
36190
+ function parseRunnerAction(candidate) {
36191
+ return parseWith(runnerActionSchema, candidate);
36192
+ }
36193
+ function parseBrowserAction(candidate) {
36194
+ return parseWith(browserActionSchema, candidate);
36195
+ }
36188
36196
 
36189
36197
  // src/domains/interactiveRunner/readActions.ts
36190
36198
  var stdinArgument = "-";
@@ -37379,6 +37387,11 @@ function describePerformActionFailure(options) {
37379
37387
  error: interactiveRunnerMessages.actionNotSupportedOnMobile(actionType),
37380
37388
  exitCode: exitCodes.invalidArgs
37381
37389
  };
37390
+ case "action-not-supported-on-browser":
37391
+ return {
37392
+ error: interactiveRunnerMessages.actionNotSupportedOnBrowser(actionType),
37393
+ exitCode: exitCodes.invalidArgs
37394
+ };
37382
37395
  case "screen-needs-a-run":
37383
37396
  return {
37384
37397
  error: interactiveRunnerMessages.screenNeedsARun,
@@ -37462,7 +37475,7 @@ async function describeFailureScreenshot(options, deps) {
37462
37475
  var stdinArgument3 = "-";
37463
37476
  async function readAction(type, flags, deps) {
37464
37477
  if (type !== stdinArgument3)
37465
- return buildBrowserAction(type, flags);
37478
+ return buildRunnerAction(type, flags);
37466
37479
  if (Object.values(flags).some((value) => value !== undefined)) {
37467
37480
  return { error: interactiveRunnerMessages.actionFlagsWithStdin, ok: false };
37468
37481
  }
@@ -37471,7 +37484,7 @@ async function readAction(type, flags, deps) {
37471
37484
  return { error: interactiveRunnerMessages.stdinEmptyAction, ok: false };
37472
37485
  }
37473
37486
  try {
37474
- return parseBrowserAction(JSON.parse(piped));
37487
+ return parseRunnerAction(JSON.parse(piped));
37475
37488
  } catch {
37476
37489
  return { error: interactiveRunnerMessages.actionNotJson, ok: false };
37477
37490
  }
@@ -37607,14 +37620,7 @@ function describeUnwritten(written, out) {
37607
37620
  };
37608
37621
  }
37609
37622
 
37610
- // src/commands/runner/interact.register.ts
37611
- var defaultScreenshotPath = "screenshot.jpg";
37612
- var screenshotExamples = `
37613
- Examples:
37614
- $ qawolf runner screenshot
37615
- $ qawolf runner screenshot --out screens/step-3.jpg
37616
- $ qawolf runner screenshot --out - > step-3.jpg
37617
- $ qawolf runner screenshot --out - | my-vision-tool`;
37623
+ // src/commands/runner/actExamples.ts
37618
37624
  var actExamples = `
37619
37625
  Examples:
37620
37626
  $ qawolf runner act click --button left --x 480 --y 260
@@ -37624,17 +37630,37 @@ Examples:
37624
37630
  $ qawolf runner act drag --path '[{"x":10,"y":20},{"x":80,"y":90}]'
37625
37631
  $ qawolf runner act click --button left --x 480 --y 260 --screenshot step-4.jpg
37626
37632
  $ echo '{"type":"click","button":"left","x":1,"y":2}' | qawolf runner act -
37627
- $ echo '{"type":"click","button":"left","x":1,"y":2}' | qawolf runner act - --screenshot - > step-5.jpg`;
37633
+ $ echo '{"type":"click","button":"left","x":1,"y":2}' | qawolf runner act - --screenshot - > step-5.jpg
37634
+
37635
+ Mobile:
37636
+ $ qawolf runner act tap --x 540 --y 1200
37637
+ $ qawolf runner act tap --selector '//*[@content-desc="Continue"]'
37638
+ $ qawolf runner act fill --selector 'name == "Postal code"' --strategy ios-predicate --text 94107
37639
+ $ qawolf runner act swipe --from 540,1600 --to 540,600 --duration-ms 1500`;
37640
+
37641
+ // src/commands/runner/interact.register.ts
37642
+ var defaultScreenshotPath = "screenshot.jpg";
37643
+ var screenshotExamples = `
37644
+ Examples:
37645
+ $ qawolf runner screenshot
37646
+ $ qawolf runner screenshot --out screens/step-3.jpg
37647
+ $ qawolf runner screenshot --out - > step-3.jpg
37648
+ $ qawolf runner screenshot --out - | my-vision-tool`;
37628
37649
  function registerRunnerInteractCommands(runner, signals) {
37629
37650
  declareCommandKind(runner.command("screenshot"), "read").description("Save a JPEG of an interactive runner's screen to a file, or write it to stdout with --out -").option("--out <path>", "File to write the image to. - writes the JPEG bytes to stdout on their own and moves the confirmation, JSON included, to stderr", defaultScreenshotPath).option("--runner <id>", runnerFlagDescription).addHelpText("after", screenshotExamples).action((opts, command) => withAuthContext(signals, (ctx) => handleRunnerScreenshot(ctx, { out: opts.out, runner: opts.runner }, runnerDeps(ctx)))(opts, command));
37630
- declareCommandKind(runner.command("act <action>"), "write").description("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. On a mobile runner only click (button left), drag and type have a touchscreen equivalent; the rest answer action-not-supported-on-mobile").option("--button <button>", "click: left, right, wheel, back or forward (mobile: left only)").option("--keys <keys...>", "keypress: modifiers and the key, e.g. Control a").option("--path <json>", "drag: JSON array of points to drag through (mobile: only the first and last are used)").option("--runner <id>", runnerFlagDescription).option("--screenshot <path>", "Also save a JPEG of the screen, taken after the action, to this file, in place of a separate screenshot. An action that did not take effect answers with one too. - writes it to stdout and moves the confirmation, JSON included, to stderr").option("--scroll-x <delta>", "scroll: horizontal wheel delta").option("--scroll-y <delta>", "scroll: vertical wheel delta").option("--text <text>", "type: the text to type").option("--url <url>", "navigate: the http or https URL to go to").option("--x <pixels>", "pointer x, in screenshot pixels").option("--y <pixels>", "pointer y, in screenshot pixels").addHelpText("after", actExamples).action((action, opts, command) => withAuthContext(signals, (ctx) => handleRunnerAct(ctx, {
37651
+ declareCommandKind(runner.command("act <action>"), "write").description("Perform one raw action on a runner's screen. A browser runner takes click, double_click, scroll, move, drag, keypress, navigate and type; a mobile runner takes tap, swipe, fill and type. A browser runner answers mobile actions with action-not-supported-on-browser; a mobile runner answers the other browser actions with action-not-supported-on-mobile. Use - to read a whole action as JSON from stdin").option("--button <button>", "click: left, right, wheel, back or forward").option("--duration-ms <ms>", "swipe: how long it takes, up to 10000. Slow scrolls, fast flings").option("--from <x,y>", "swipe: the point it starts at").option("--keys <keys...>", "keypress: modifiers and the key, e.g. Control a").option("--path <json>", "drag: JSON array of points to drag through").option("--runner <id>", runnerFlagDescription).option("--screenshot <path>", "Also save a JPEG of the screen, taken after the action, to this file, in place of a separate screenshot. An action that did not take effect answers with one too. - writes it to stdout and moves the confirmation, JSON included, to stderr").option("--scroll-x <delta>", "scroll: horizontal wheel delta").option("--scroll-y <delta>", "scroll: vertical wheel delta").option("--selector <selector>", "tap or fill: the element to act on, as a screen object would find it. tap takes it in place of --x and --y").option("--strategy <strategy>", "how --selector is resolved: xpath (default), ios-predicate or shadow").option("--text <text>", "type: the text to type into what has focus. fill: the field's new value").option("--to <x,y>", "swipe: the point it ends at").option("--url <url>", "navigate: the http or https URL to go to").option("--x <pixels>", "click, tap and the like: x, in screenshot pixels").option("--y <pixels>", "click, tap and the like: y, in screenshot pixels").addHelpText("after", actExamples).action((action, opts, command) => withAuthContext(signals, (ctx) => handleRunnerAct(ctx, {
37631
37652
  flags: {
37632
37653
  button: opts.button,
37654
+ durationMs: opts.durationMs,
37655
+ from: opts.from,
37633
37656
  keys: opts.keys,
37634
37657
  path: opts.path,
37635
37658
  scrollX: opts.scrollX,
37636
37659
  scrollY: opts.scrollY,
37660
+ selector: opts.selector,
37661
+ strategy: opts.strategy,
37637
37662
  text: opts.text,
37663
+ to: opts.to,
37638
37664
  url: opts.url,
37639
37665
  x: opts.x,
37640
37666
  y: opts.y
@@ -38820,4 +38846,4 @@ createProgram({ signals }).parseAsync().catch(() => {
38820
38846
  process.exitCode = 1;
38821
38847
  }).finally(() => exitWhenIdle(typeof process.exitCode === "number" ? process.exitCode : 0));
38822
38848
 
38823
- //# debugId=DB32E61082C9C27564756E2164756E21
38849
+ //# debugId=9A39ADF2531708B264756E2164756E21