@qawolf/cli 1.37.0 → 1.39.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.
@@ -7111,6 +7111,11 @@ var makeRequestFileDownloadContract = (ids) => {
7111
7111
  readUrl: string2().describe('Fetch the file\'s bytes from here, for example `curl -o journeys.csv "<readUrl>"`. Write it to a file and read that file, rather than printing the contents, so a large file costs one line of output instead of all of it.')
7112
7112
  });
7113
7113
  return {
7114
+ annotationJustifications: {
7115
+ destructiveHint: "Does not change, overwrite or delete the stored file.",
7116
+ openWorldHint: "Access is limited to QA Wolf team storage; the caller cannot supply an arbitrary external destination.",
7117
+ readOnlyHint: "Returns an expiring read URL for an existing file in the authorized workspace storage."
7118
+ },
7114
7119
  annotations: {
7115
7120
  destructiveHint: false,
7116
7121
  openWorldHint: false,
@@ -7137,6 +7142,11 @@ var makeRequestFileUploadContract = (ids) => {
7137
7142
  uploadUrl: string2().describe(`Send the file's bytes here with a single HTTP PUT carrying the returned contentType, for example \`curl -H 'Content-Type: application/octet-stream' --upload-file "journeys.csv" "<uploadUrl>"\`. Upload the bytes from the shell rather than through this API, so a large file never has to be written out as text.`)
7138
7143
  });
7139
7144
  return {
7145
+ annotationJustifications: {
7146
+ destructiveHint: "Using the returned upload URL with an existing file name replaces that stored file.",
7147
+ openWorldHint: "The upload target is QA Wolf team storage, not an arbitrary external service or recipient.",
7148
+ readOnlyHint: "Returns an expiring upload URL that permits writing a file to the authorized workspace storage."
7149
+ },
7140
7150
  annotations: {
7141
7151
  destructiveHint: true,
7142
7152
  openWorldHint: false,
@@ -7252,6 +7262,11 @@ var makeCreateRunContract = (ids) => {
7252
7262
  tracking: _enum(["registered", "failed", "not-requested"]).describe('Whether the conversation named by aiTaskId or chatSessionId will receive run status updates: "registered" when it will, "failed" when the run was created but the registration failed, "not-requested" when neither id was given or the AI task has no conversation to notify.')
7253
7263
  }, { urlFieldDescription: "Absolute URL of the run page." });
7254
7264
  return {
7265
+ annotationJustifications: {
7266
+ destructiveHint: "Test code can overwrite or delete application data.",
7267
+ openWorldHint: "Test execution can submit forms or change the application under test and its connected services.",
7268
+ readOnlyHint: "Creates a run and enqueues execution of selected flows."
7269
+ },
7255
7270
  annotations: {
7256
7271
  destructiveHint: true,
7257
7272
  openWorldHint: true,
@@ -7265,6 +7280,77 @@ var makeCreateRunContract = (ids) => {
7265
7280
  };
7266
7281
  };
7267
7282
 
7283
+ // node_modules/@qawolf/api-contracts/dist/v1/run/listScreenshotComparisons.js
7284
+ var maxListedScreenshotAttempts = 20;
7285
+ var makeListScreenshotComparisonsContract = (ids) => {
7286
+ const input = object({
7287
+ flowIds: array(ids.flow).min(1).max(100).refine((flowIds) => new Set(flowIds).size === flowIds.length, "flowIds must be unique").optional().describe("Only list the comparisons of these flows. Each flow must have a result in the run. Omit to list every failed flow of the run."),
7288
+ runId: ids.run
7289
+ });
7290
+ const imageUrl = (image) => url().describe(`Signed URL of the full-size ${image} PNG. It stops working at expiresAt.`);
7291
+ const previewUrl = (image) => url().optional().describe(`Signed URL of a JPEG copy of the ${image} image, scaled down so its long edge is at most 1568 pixels. ` + "Fetch this one to look at the image: it is small enough to view inline, while the full-size PNG can be too large. " + "It stops working at expiresAt. Absent when QA Wolf could not make the copy, for example because the full-size image is gone.");
7292
+ const passedEnvironment = object({
7293
+ environmentId: ids.environment,
7294
+ lastPassedAt: exports_iso.datetime().describe("When the latest passing comparison in this environment ran.")
7295
+ });
7296
+ const passingElsewhere = discriminatedUnion("status", [
7297
+ object({
7298
+ status: literal("not-tracked").describe("QA Wolf does not record screenshot comparisons for this workspace, so it cannot tell.")
7299
+ }),
7300
+ object({
7301
+ environments: array(passedEnvironment).describe("Other environments where the current baseline passed this screenshot in the last 14 days, most recent first. " + "Empty when it passed nowhere else, or when the baseline no longer exists."),
7302
+ status: literal("tracked")
7303
+ })
7304
+ ]).describe("Whether the current baseline still passes in other environments. " + "A baseline that passes elsewhere points to a difference in this environment rather than an outdated baseline.");
7305
+ const comparison = object({
7306
+ actualPreviewUrl: previewUrl("actual"),
7307
+ actualUrl: imageUrl("actual (the screenshot the flow took)"),
7308
+ attemptCompletedAt: exports_iso.datetime().describe("When the run attempt that made the comparison finished."),
7309
+ baselineStatus: _enum([
7310
+ "unchanged",
7311
+ "accepted",
7312
+ "changed-since-run",
7313
+ "deleted",
7314
+ "unknown"
7315
+ ]).describe('How the current baseline relates to the expected image this comparison used. "unchanged": the baseline is still the expected image. ' + `"accepted": the baseline is now this comparison's actual screenshot, because someone accepted it, so a reattempt should pass. ` + '"changed-since-run": someone replaced the baseline with another image after this run, so rerun the flow before deciding anything. ' + '"deleted": the baseline no longer exists, and the next run will save its screenshot as the new baseline. ' + `"unknown": the run's copy of the expected image is gone, so QA Wolf cannot compare.`),
7316
+ comparisonId: string2().describe("Identifies this comparison: the run attempt id and the position of the comparison in that attempt."),
7317
+ diffPreviewUrl: previewUrl("diff"),
7318
+ diffUrl: imageUrl("diff (the pixels that differ are highlighted)"),
7319
+ expectedPreviewUrl: previewUrl("expected"),
7320
+ expectedUrl: imageUrl("expected (the baseline as it was when the flow ran)"),
7321
+ filePath: string2().optional().describe("The flow file that made the comparison."),
7322
+ flowId: ids.flow,
7323
+ lineNumber: number2().int().optional().describe("The line of filePath that made the comparison."),
7324
+ name: string2().describe("The screenshot name the flow passed to toHaveScreenshot. The baseline is stored as _screenshots_/<name>.png in team storage."),
7325
+ passingElsewhere,
7326
+ runAttemptId: string2(),
7327
+ similarity: number2().describe("How much of the actual image matches the expected image, in percent."),
7328
+ sizeMismatch: boolean2().describe("The actual and expected images have different dimensions. That fails the comparison whatever the pixels show, and similarity reads 0.")
7329
+ });
7330
+ const output = object({
7331
+ comparisons: array(comparison).describe(`Each screenshot comparison that failed its flow, from the ${maxListedScreenshotAttempts} most recent failed attempts of the selected flows, oldest attempt first.`),
7332
+ expiresAt: exports_iso.datetime().describe("When the image URLs stop working. Call run.listScreenshotComparisons again for fresh ones after it."),
7333
+ truncated: boolean2().describe(`True when the selected flows have more than ${maxListedScreenshotAttempts} failed attempts. Only the ${maxListedScreenshotAttempts} most recent are listed, and the older attempts cannot be listed.`)
7334
+ });
7335
+ return {
7336
+ annotationJustifications: {
7337
+ destructiveHint: "Does not change baselines, results or the run.",
7338
+ openWorldHint: "Reads recorded QA Wolf screenshots without changing the application under test.",
7339
+ readOnlyHint: "Creates missing JPEG previews of the compared images and keeps them in team storage."
7340
+ },
7341
+ annotations: {
7342
+ destructiveHint: false,
7343
+ openWorldHint: false,
7344
+ readOnlyHint: false
7345
+ },
7346
+ description: "List the screenshot comparisons that failed a run's flows, with the expected, actual and diff images of each. " + "Only comparisons that caused a failure are listed: a screenshot that differs within tolerance, or that differs on a line that did not fail, is left out. " + "Each comparison tells whether its baseline changed since the run and whether the baseline still passes in other environments. " + "The image URLs expire after a few minutes; fetch the preview URLs to look at the images. " + "The first call for an image makes its missing JPEG preview and keeps it in team storage, so later calls reuse it.",
7347
+ input,
7348
+ kind: "read",
7349
+ name: "run.listScreenshotComparisons",
7350
+ output
7351
+ };
7352
+ };
7353
+
7268
7354
  // node_modules/@qawolf/api-contracts/dist/v1/runner/actionSequence.js
7269
7355
  var maxActionsPerRequest = 10;
7270
7356
  var screenshotModes = ["none", "final", "each"];
@@ -7448,6 +7534,11 @@ var makeInspectOnRunnerContract = (ids) => {
7448
7534
  })
7449
7535
  ]);
7450
7536
  return {
7537
+ annotationJustifications: {
7538
+ destructiveHint: "Does not edit test code or application data, although the activity refresh can extend billed runtime.",
7539
+ openWorldHint: "Inspects the private runner session without submitting application actions.",
7540
+ readOnlyHint: "Retrieves browser inspection data and refreshes activity, which can cancel an inactivity shutdown."
7541
+ },
7451
7542
  annotations: {
7452
7543
  destructiveHint: false,
7453
7544
  openWorldHint: false,
@@ -7613,6 +7704,11 @@ var makeInspectMobileOnRunnerContract = (ids) => {
7613
7704
  ])
7614
7705
  ]);
7615
7706
  return {
7707
+ annotationJustifications: {
7708
+ destructiveHint: "Does not change application data, edit tests, or stop the runner.",
7709
+ openWorldHint: "Inspects the existing QA Wolf mobile runner without submitting application actions or contacting arbitrary services.",
7710
+ readOnlyHint: "Reads mobile session status, contexts, page source, or elements without refreshing the runner's inactivity timer."
7711
+ },
7616
7712
  annotations: {
7617
7713
  destructiveHint: false,
7618
7714
  openWorldHint: false,
@@ -7789,6 +7885,11 @@ var makePerformActionOnRunnerContract = (ids) => {
7789
7885
  failure
7790
7886
  ]);
7791
7887
  return {
7888
+ annotationJustifications: {
7889
+ destructiveHint: "Actions can submit irreversible transactions or delete existing data, so uncertain outcomes must be inspected before retrying.",
7890
+ openWorldHint: "Clicks, typing and navigation can submit external forms or change application state.",
7891
+ readOnlyHint: "Performs a browser or device action and can start a browser when needed."
7892
+ },
7792
7893
  annotations: {
7793
7894
  destructiveHint: true,
7794
7895
  openWorldHint: true,
@@ -7840,6 +7941,7 @@ var failedStepSchema = discriminatedUnion("failureReason", [
7840
7941
  failureReason: _enum([
7841
7942
  ...screenFailureReasons,
7842
7943
  "action-not-supported-on-mobile",
7944
+ "action-not-supported-on-browser",
7843
7945
  outOfTimeFailureReason
7844
7946
  ]),
7845
7947
  index: actionIndexSchema,
@@ -7854,6 +7956,7 @@ var sequenceFailureReasons = [
7854
7956
  "action-failed",
7855
7957
  ...screenFailureReasons,
7856
7958
  "action-not-supported-on-mobile",
7959
+ "action-not-supported-on-browser",
7857
7960
  outOfTimeFailureReason,
7858
7961
  unconfirmedFailureReason,
7859
7962
  runnerUnreachableFailureReason
@@ -7862,11 +7965,11 @@ var sequenceFailureReasons = [
7862
7965
  // node_modules/@qawolf/api-contracts/dist/v1/runner/performActions.js
7863
7966
  var actionsDescription = `The actions to perform, in order, each exactly what \`runner.performAction\` takes: coordinates are whole pixels on the runner's virtual desktop, in the same space as \`runner.takeScreenshot\`, and the shapes follow the computer-use vocabulary. At most ${maxActionsPerRequest} per request. For when the next several steps are already known — click a field, type into it, press Enter — and one look at the screen at the end is enough. They run back to back on the runner, with no pause between them: put in one request only steps whose targets are all on the screen you last saw and are not moved by the steps before them, and when a step changes the page — a submit, a navigation, opening a menu — make it the last one and read the frame.`;
7864
7967
  var screenshotModeDescription = "`final`, the default, answers with one screenshot in `imageJpegBase64`: the screen after the last action, or, after a stop, as it stands. `each` puts a screenshot after every action on its entry in `results`, for when each step must be checked; every frame is a full image, so keep such sequences short. `none` sends no screenshot.";
7865
- var stopOnFailureDescription = "`true`, the default, leaves the remaining actions unperformed once one fails. `false` carries on past an action that reached the runner and did not take effect (`action-failed`, `action-not-supported-on-mobile`), so use it only for actions that do not depend on each other: a `type` after a `click` that failed goes to whatever has focus. A runner that cannot be reached, a screen that cannot serve, or running out of time ends the sequence either way.";
7968
+ var stopOnFailureDescription = "`true`, the default, leaves the remaining actions unperformed once one fails. `false` carries on past an action that reached the runner and did not take effect (`action-failed`, `action-not-supported-on-mobile`, `action-not-supported-on-browser`), so use it only for actions that do not depend on each other: a `type` after a `click` that failed goes to whatever has focus. A runner that cannot be reached, a screen that cannot serve, or running out of time ends the sequence either way.";
7866
7969
  var finalImageDescription = "Present with `screenshotMode: final` when the runner still answered: the screen after the last action performed, or, after a stop, as it stands.";
7867
7970
  var makePerformActionsOnRunnerContract = (ids) => {
7868
7971
  const input = object({
7869
- actions: array(browserActionSchema).min(1).max(maxActionsPerRequest).describe(actionsDescription),
7972
+ actions: array(runnerActionSchema).min(1).max(maxActionsPerRequest).describe(actionsDescription),
7870
7973
  id: runnerIdSchema.describe("Id of the runner to act on."),
7871
7974
  screenshotMode: _enum(screenshotModes).optional().describe(screenshotModeDescription),
7872
7975
  stopOnFailure: boolean2().optional().describe(stopOnFailureDescription),
@@ -7891,12 +7994,17 @@ var makePerformActionsOnRunnerContract = (ids) => {
7891
7994
  })
7892
7995
  ]);
7893
7996
  return {
7997
+ annotationJustifications: {
7998
+ destructiveHint: "Actions can submit irreversible transactions or delete existing data, so uncertain outcomes must be inspected before retrying.",
7999
+ openWorldHint: "Clicks, typing and navigation can submit external forms or change application state.",
8000
+ readOnlyHint: "Performs a sequence of browser or device actions on a runner."
8001
+ },
7894
8002
  annotations: {
7895
8003
  destructiveHint: true,
7896
8004
  openWorldHint: true,
7897
8005
  readOnlyHint: false
7898
8006
  },
7899
- description: "Perform a sequence of raw browser actions on an interactive runner in one request, one after another, and answer with what happened to each. A `success` means every action took effect. A `failure` names the first action that did not (`failedIndex`, `failureReason`), the last one that did (`lastCompletedIndex`), and whether actions were left unperformed (`stoppedEarly`); `results` has one entry per action reached, in order. Read `effect` on an entry before sending its action again: `performed` means the runner did it; `not-performed` means the runner answered that it did not take effect, though a `navigate` that timed out may still be loading; `unknown` means the runner stopped answering with the action in flight (`runner-unreachable`), or its screen went quiet mid-action (`action-unconfirmed`), and it may have taken effect — a click that submitted a form, say — so take a screenshot instead of repeating it. A sequence gets about a minute to start its actions; an action it did not reach in time is `out-of-time`, nothing after it was attempted, and the rest can go in a new request. Everything `runner.performAction` says about a runner that has never run anything, a mobile runner, and the `screen-needs-a-run`, `screen-not-ready`, `runner-has-no-screen` and `action-not-supported-on-mobile` reasons holds for each action here.",
8007
+ description: "Perform a sequence of raw actions on an interactive runner in one request, one after another, and answer with what happened to each. A `success` means every action took effect. A `failure` names the first action that did not (`failedIndex`, `failureReason`), the last one that did (`lastCompletedIndex`), and whether actions were left unperformed (`stoppedEarly`); `results` has one entry per action reached, in order. Read `effect` on an entry before sending its action again: `performed` means the runner did it; `not-performed` means the runner answered that it did not take effect, though a `navigate` that timed out may still be loading; `unknown` means the runner stopped answering with the action in flight (`runner-unreachable`), or its screen went quiet mid-action (`action-unconfirmed`), and it may have taken effect — a click that submitted a form, say — so take a screenshot instead of repeating it. A sequence gets about a minute to start its actions; an action it did not reach in time is `out-of-time`, nothing after it was attempted, and the rest can go in a new request. Everything `runner.performAction` says about a runner that has never run anything, a mobile runner, and the `screen-needs-a-run`, `screen-not-ready`, `runner-has-no-screen`, `action-not-supported-on-mobile` and `action-not-supported-on-browser` reasons holds for each action here.",
7900
8008
  input,
7901
8009
  kind: "write",
7902
8010
  name: "runner.performActions",
@@ -7964,6 +8072,11 @@ var makeRecordOnRunnerContract = (ids) => {
7964
8072
  url: url()
7965
8073
  });
7966
8074
  return {
8075
+ annotationJustifications: {
8076
+ destructiveHint: "Starts or stops a video recording without changing the application under test.",
8077
+ openWorldHint: "Controls recording on a QA Wolf runner without starting external work.",
8078
+ readOnlyHint: "Starts or stops video recording and changes automatic capture settings."
8079
+ },
7967
8080
  annotations: {
7968
8081
  destructiveHint: false,
7969
8082
  openWorldHint: false,
@@ -7991,6 +8104,11 @@ var makeRunnerRecordingsContract = (ids) => {
7991
8104
  }))
7992
8105
  });
7993
8106
  return {
8107
+ annotationJustifications: {
8108
+ destructiveHint: "Does not delete or change any recording.",
8109
+ openWorldHint: "Reads QA Wolf workspace storage without changing the application under test.",
8110
+ readOnlyHint: "Lists or retrieves a runner's finalized recordings."
8111
+ },
7994
8112
  annotations: {
7995
8113
  destructiveHint: false,
7996
8114
  openWorldHint: false,
@@ -8221,6 +8339,11 @@ var makeCreateTriggerContract = (ids) => {
8221
8339
  ]).superRefine(checkTriggerConfiguration);
8222
8340
  const output = object({ trigger: makeTriggerResourceSchema(ids) });
8223
8341
  return {
8342
+ annotationJustifications: {
8343
+ destructiveHint: "Enables automatic execution of test code that may overwrite or delete application data.",
8344
+ openWorldHint: "Triggered runs can change the application under test and update connected integrations.",
8345
+ readOnlyHint: "Creates an active schedule or deployment trigger that can start test runs."
8346
+ },
8224
8347
  annotations: {
8225
8348
  destructiveHint: true,
8226
8349
  openWorldHint: true,
@@ -8244,6 +8367,11 @@ var makeFindTriggersContract = (ids) => {
8244
8367
  triggers: array(makeTriggerResourceSchema(ids)).describe("The team's triggers, newest first.")
8245
8368
  });
8246
8369
  return {
8370
+ annotationJustifications: {
8371
+ destructiveHint: "Does not modify or delete triggers or their runs.",
8372
+ openWorldHint: "Reads private QA Wolf trigger records without changing external systems.",
8373
+ readOnlyHint: "Lists trigger configuration in the authorized workspace without changing it."
8374
+ },
8247
8375
  annotations: {
8248
8376
  destructiveHint: false,
8249
8377
  openWorldHint: false,
@@ -8262,6 +8390,11 @@ var makeGetTriggerContract = (ids) => {
8262
8390
  const input = object({ triggerId: ids.trigger });
8263
8391
  const output = object({ trigger: makeTriggerResourceSchema(ids) });
8264
8392
  return {
8393
+ annotationJustifications: {
8394
+ destructiveHint: "Does not modify or delete the trigger or its runs.",
8395
+ openWorldHint: "Reads a private QA Wolf trigger without changing external systems.",
8396
+ readOnlyHint: "Retrieves one authorized trigger and its configuration without changing it."
8397
+ },
8265
8398
  annotations: {
8266
8399
  destructiveHint: false,
8267
8400
  openWorldHint: false,
@@ -8280,6 +8413,11 @@ var makePauseTriggerContract = (ids) => {
8280
8413
  const input = object({ triggerId: ids.trigger });
8281
8414
  const output = object({ trigger: makeTriggerResourceSchema(ids) });
8282
8415
  return {
8416
+ annotationJustifications: {
8417
+ destructiveHint: "Disables future automatic execution for the selected trigger until it is resumed.",
8418
+ openWorldHint: "Changes private QA Wolf scheduling state without starting external work.",
8419
+ readOnlyHint: "Pauses an existing trigger so it stops starting new work."
8420
+ },
8283
8421
  annotations: {
8284
8422
  destructiveHint: true,
8285
8423
  openWorldHint: false,
@@ -8296,6 +8434,11 @@ var makeResumeTriggerContract = (ids) => {
8296
8434
  const input = object({ triggerId: ids.trigger });
8297
8435
  const output = object({ trigger: makeTriggerResourceSchema(ids) });
8298
8436
  return {
8437
+ annotationJustifications: {
8438
+ destructiveHint: "Enables automatic test execution that may overwrite or delete application data.",
8439
+ openWorldHint: "Resumed execution can change the application under test and update connected integrations.",
8440
+ readOnlyHint: "Reactivates a paused trigger so future matching schedules or deployments can start runs."
8441
+ },
8299
8442
  annotations: {
8300
8443
  destructiveHint: true,
8301
8444
  openWorldHint: true,
@@ -8314,6 +8457,11 @@ var makeDeleteTriggerContract = (ids) => {
8314
8457
  triggerId: ids.trigger.describe("The id of the deleted trigger.")
8315
8458
  });
8316
8459
  return {
8460
+ annotationJustifications: {
8461
+ destructiveHint: "Permanently deletes the selected trigger configuration.",
8462
+ openWorldHint: "Removes private QA Wolf trigger configuration without starting external work.",
8463
+ readOnlyHint: "Permanently removes a trigger while preserving runs it already created."
8464
+ },
8317
8465
  annotations: {
8318
8466
  destructiveHint: true,
8319
8467
  openWorldHint: false,
@@ -8350,6 +8498,11 @@ var makeUpdateTriggerContract = (ids) => {
8350
8498
  ]).superRefine(checkTriggerConfiguration);
8351
8499
  const output = object({ trigger: makeTriggerResourceSchema(ids) });
8352
8500
  return {
8501
+ annotationJustifications: {
8502
+ destructiveHint: "Overwrites trigger configuration and can enable tests that change or delete application data.",
8503
+ openWorldHint: "The updated trigger can execute tests against external applications and update connected integrations.",
8504
+ readOnlyHint: "Replaces an existing trigger configuration and can change future automatic runs."
8505
+ },
8353
8506
  annotations: {
8354
8507
  destructiveHint: true,
8355
8508
  openWorldHint: true,
@@ -8391,6 +8544,11 @@ var makeAgentGetContract = (ids) => {
8391
8544
  urlFieldDescription: "Absolute URL of the live session in the QA Wolf app."
8392
8545
  });
8393
8546
  return {
8547
+ annotationJustifications: {
8548
+ destructiveHint: "Does not cancel work or edit tests and messages.",
8549
+ openWorldHint: "Reads a QA Wolf session without posting to external services.",
8550
+ readOnlyHint: "Retrieves session status, replies and the live link without sending work."
8551
+ },
8394
8552
  annotations: {
8395
8553
  destructiveHint: false,
8396
8554
  openWorldHint: false,
@@ -8422,6 +8580,11 @@ var makeAgentSendContract = (ids) => {
8422
8580
  urlFieldDescription: "Absolute URL of the live session in the QA Wolf app."
8423
8581
  });
8424
8582
  return {
8583
+ annotationJustifications: {
8584
+ destructiveHint: "Delegated execution can overwrite test code or change and delete application data.",
8585
+ openWorldHint: "Delegated work can submit application actions and publish code to connected repositories.",
8586
+ readOnlyHint: "Creates or continues AI work that can implement, run and publish tests."
8587
+ },
8425
8588
  annotations: {
8426
8589
  destructiveHint: true,
8427
8590
  openWorldHint: true,
@@ -8460,6 +8623,11 @@ var makeFindCodeHostIntegrationsContract = (ids) => {
8460
8623
  settingsUrl: url().describe("Absolute URL of the workspace's integrations settings page.")
8461
8624
  });
8462
8625
  return {
8626
+ annotationJustifications: {
8627
+ destructiveHint: "Does not disconnect integrations or change repository access.",
8628
+ openWorldHint: "Reads QA Wolf integration records without contacting or changing GitHub or GitLab.",
8629
+ readOnlyHint: "Lists the workspace's stored code host integrations and settings link without modifying them."
8630
+ },
8463
8631
  annotations: {
8464
8632
  destructiveHint: false,
8465
8633
  openWorldHint: false,
@@ -8492,6 +8660,11 @@ var makeListCodeHostRepositoriesContract = (ids) => {
8492
8660
  repositories: array(makeCodeHostRepositoryResourceSchema()).describe("The repositories the workspace's code host integrations cover, alphabetical by full name.")
8493
8661
  });
8494
8662
  return {
8663
+ annotationJustifications: {
8664
+ destructiveHint: "Does not edit repositories, integration settings, or access permissions.",
8665
+ openWorldHint: "Reads repositories already recorded for the workspace's integrations, without accessing arbitrary external repositories.",
8666
+ readOnlyHint: "Lists repository metadata from the workspace's last code host sync without triggering a new sync."
8667
+ },
8495
8668
  annotations: {
8496
8669
  destructiveHint: false,
8497
8670
  openWorldHint: false,
@@ -8535,6 +8708,11 @@ var makeFindDeploymentsContract = (ids) => {
8535
8708
  nextCursor: nextCursorSchema
8536
8709
  });
8537
8710
  return {
8711
+ annotationJustifications: {
8712
+ destructiveHint: "Does not modify deployments, environments, triggers, or runs.",
8713
+ openWorldHint: "Reads QA Wolf deployment records without contacting deployment providers or starting tests.",
8714
+ readOnlyHint: "Lists stored workspace deployments without reporting or changing their status."
8715
+ },
8538
8716
  annotations: {
8539
8717
  destructiveHint: false,
8540
8718
  openWorldHint: false,
@@ -8609,6 +8787,11 @@ var makeListDeploymentTriggerEvaluationsContract = (ids) => {
8609
8787
  object({ state: literal("not-evaluated") }).describe("Triggers were never evaluated for this deployment. Only a deployment's first success report evaluates triggers, so a deployment that never reported success carries no verdicts.")
8610
8788
  ]);
8611
8789
  return {
8790
+ annotationJustifications: {
8791
+ destructiveHint: "Does not alter recorded verdicts, trigger configuration, or existing runs.",
8792
+ openWorldHint: "Reads stored QA Wolf verdicts without starting tests or updating external services.",
8793
+ readOnlyHint: "Retrieves the recorded trigger verdicts for one deployment without evaluating triggers again."
8794
+ },
8612
8795
  annotations: {
8613
8796
  destructiveHint: false,
8614
8797
  openWorldHint: false,
@@ -8680,6 +8863,11 @@ var makeReportDeploymentStatusContract = (ids) => {
8680
8863
  }, { urlFieldDescription: "Absolute URL of the environment's runs page." });
8681
8864
  const output = object({ deployment });
8682
8865
  return {
8866
+ annotationJustifications: {
8867
+ destructiveHint: "Can replace deployment details and variable overrides, and trigger tests that overwrite or delete application data.",
8868
+ openWorldHint: "Successful deployments can start tests against external applications and update connected integrations.",
8869
+ readOnlyHint: "Creates or updates a deployment, can create an environment, and evaluates triggers on its first success report."
8870
+ },
8683
8871
  annotations: {
8684
8872
  destructiveHint: true,
8685
8873
  openWorldHint: true,
@@ -8716,6 +8904,11 @@ var makeFindEmailsContract = (ids) => {
8716
8904
  nextCursor: nextCursorSchema
8717
8905
  });
8718
8906
  return {
8907
+ annotationJustifications: {
8908
+ destructiveHint: "Does not send, edit, or delete email messages.",
8909
+ openWorldHint: "Reads the workspace's QA Wolf inbox records without contacting recipients or arbitrary mailboxes.",
8910
+ readOnlyHint: "Searches stored workspace emails and returns matching message summaries."
8911
+ },
8719
8912
  annotations: {
8720
8913
  destructiveHint: false,
8721
8914
  openWorldHint: false,
@@ -8737,6 +8930,11 @@ var makeGetEmailContract = (ids) => {
8737
8930
  });
8738
8931
  const output = makeEmailResourceSchema();
8739
8932
  return {
8933
+ annotationJustifications: {
8934
+ destructiveHint: "Does not alter or delete the message or its attachments.",
8935
+ openWorldHint: "Reads a stored workspace message without forwarding it or contacting external recipients.",
8936
+ readOnlyHint: "Retrieves the content of an existing workspace email."
8937
+ },
8740
8938
  annotations: {
8741
8939
  destructiveHint: false,
8742
8940
  openWorldHint: false,
@@ -8765,6 +8963,11 @@ var makeGetEmailAttachmentContract = (ids) => {
8765
8963
  type: string2().optional().describe("The MIME type.")
8766
8964
  }, { urlFieldDescription: emailUrlFieldDescription });
8767
8965
  return {
8966
+ annotationJustifications: {
8967
+ destructiveHint: "Does not modify or delete the email or attachment.",
8968
+ openWorldHint: "Access is limited to attachments of authorized workspace emails, not arbitrary external files.",
8969
+ readOnlyHint: "Reads one attachment from an existing workspace email and returns its content."
8970
+ },
8768
8971
  annotations: {
8769
8972
  destructiveHint: false,
8770
8973
  openWorldHint: false,
@@ -8789,6 +8992,11 @@ var makeListEmailAddressesContract = (ids) => {
8789
8992
  nextCursor: nextCursorSchema
8790
8993
  });
8791
8994
  return {
8995
+ annotationJustifications: {
8996
+ destructiveHint: "Does not register, replace, or remove inbox addresses.",
8997
+ openWorldHint: "Reads QA Wolf inbox configuration without contacting external mail services or recipients.",
8998
+ readOnlyHint: "Lists the workspace's registered inbox addresses without changing them."
8999
+ },
8792
9000
  annotations: {
8793
9001
  destructiveHint: false,
8794
9002
  openWorldHint: false,
@@ -8816,6 +9024,11 @@ var makeRegisterEmailAddressContract = (ids) => {
8816
9024
  });
8817
9025
  const output = makeEmailAddressResourceSchema();
8818
9026
  return {
9027
+ annotationJustifications: {
9028
+ destructiveHint: "Adds an address without replacing or deleting existing inbox addresses or emails.",
9029
+ openWorldHint: "Adds a QA Wolf workspace inbox address without sending messages to external recipients.",
9030
+ readOnlyHint: "Registers an additional inbox address for the workspace."
9031
+ },
8819
9032
  annotations: {
8820
9033
  destructiveHint: false,
8821
9034
  openWorldHint: false,
@@ -8854,6 +9067,11 @@ var makeSendEmailContract = (ids) => {
8854
9067
  urlFieldDescription: emailUrlFieldDescription
8855
9068
  });
8856
9069
  return {
9070
+ annotationJustifications: {
9071
+ destructiveHint: "Sending an email is irreversible; recipients may act on it, and the tool cannot recall it.",
9072
+ openWorldHint: "Delivers message content and attachments to caller-selected email recipients outside QA Wolf.",
9073
+ readOnlyHint: "Sends an email from a workspace inbox and stores the sent message."
9074
+ },
8857
9075
  annotations: {
8858
9076
  destructiveHint: true,
8859
9077
  openWorldHint: true,
@@ -8899,6 +9117,11 @@ var makeCreateEnvironmentContract = (ids) => {
8899
9117
  });
8900
9118
  const output = makeEnvironmentResourceSchema(ids);
8901
9119
  return {
9120
+ annotationJustifications: {
9121
+ destructiveHint: "Adds a new environment and branch rather than deleting or overwriting an existing one.",
9122
+ openWorldHint: "Creates a branch in the connected Git provider rather than changing only QA Wolf records.",
9123
+ readOnlyHint: "Creates a QA Wolf environment and its remote flow-code branch."
9124
+ },
8902
9125
  annotations: {
8903
9126
  destructiveHint: false,
8904
9127
  openWorldHint: true,
@@ -8923,6 +9146,11 @@ var makeDeleteEnvironmentVariableContract = (ids) => {
8923
9146
  name: string2().describe("The canonicalized name that was removed. Returned even when the environment had no such variable.")
8924
9147
  });
8925
9148
  return {
9149
+ annotationJustifications: {
9150
+ destructiveHint: "Deletes an existing variable value, while an already-absent variable is left absent.",
9151
+ openWorldHint: "Changes private test configuration without submitting it to an external application.",
9152
+ readOnlyHint: "Removes a named environment variable from QA Wolf storage."
9153
+ },
8926
9154
  annotations: {
8927
9155
  destructiveHint: true,
8928
9156
  openWorldHint: false,
@@ -8950,6 +9178,11 @@ var makeFindEnvironmentsContract = (ids) => {
8950
9178
  nextCursor: nextCursorSchema
8951
9179
  });
8952
9180
  return {
9181
+ annotationJustifications: {
9182
+ destructiveHint: "Does not edit environments, variables or branches.",
9183
+ openWorldHint: "Reads private QA Wolf environment metadata without publishing changes.",
9184
+ readOnlyHint: "Lists workspace environments and their configuration summaries."
9185
+ },
8953
9186
  annotations: {
8954
9187
  destructiveHint: false,
8955
9188
  openWorldHint: false,
@@ -8978,6 +9211,11 @@ var makeGetEnvironmentVariableContract = (ids) => {
8978
9211
  })).describe("The found variables, sorted by name.")
8979
9212
  });
8980
9213
  return {
9214
+ annotationJustifications: {
9215
+ destructiveHint: "Does not replace or remove variable values.",
9216
+ openWorldHint: "Reads private stored configuration without submitting it to an external application.",
9217
+ readOnlyHint: "Retrieves decrypted values of named environment variables and reports missing names."
9218
+ },
8981
9219
  annotations: {
8982
9220
  destructiveHint: false,
8983
9221
  openWorldHint: false,
@@ -8999,6 +9237,11 @@ var makeGetEnvironmentContract = (ids) => {
8999
9237
  });
9000
9238
  const output = makeEnvironmentResourceSchema(ids);
9001
9239
  return {
9240
+ annotationJustifications: {
9241
+ destructiveHint: "Does not alter environment settings or concurrency limits.",
9242
+ openWorldHint: "Reads QA Wolf environment state without updating the connected Git provider.",
9243
+ readOnlyHint: "Retrieves an environment's configuration, run health and code-reconciliation state."
9244
+ },
9002
9245
  annotations: {
9003
9246
  destructiveHint: false,
9004
9247
  openWorldHint: false,
@@ -9020,6 +9263,11 @@ var makeListEnvironmentVariableNamesContract = (ids) => {
9020
9263
  variableNames: array(string2()).describe("Names of the environment's variables, sorted alphabetically. Values are never returned.")
9021
9264
  });
9022
9265
  return {
9266
+ annotationJustifications: {
9267
+ destructiveHint: "Does not alter variables or expose their stored values.",
9268
+ openWorldHint: "Reads private configuration names without changing external systems.",
9269
+ readOnlyHint: "Lists available environment variable names without retrieving their values."
9270
+ },
9023
9271
  annotations: {
9024
9272
  destructiveHint: false,
9025
9273
  openWorldHint: false,
@@ -9043,6 +9291,11 @@ var makeSetEnvironmentVariableContract = (ids) => {
9043
9291
  name: string2().describe("The stored variable name after whitespace is replaced with underscores and letters are uppercased.")
9044
9292
  });
9045
9293
  return {
9294
+ annotationJustifications: {
9295
+ destructiveHint: "Can overwrite an existing variable value, while an unchanged value is skipped.",
9296
+ openWorldHint: "Changes stored QA Wolf configuration rather than submitting forms or publishing content.",
9297
+ readOnlyHint: "Creates or replaces a named environment variable without returning its value."
9298
+ },
9046
9299
  annotations: {
9047
9300
  destructiveHint: true,
9048
9301
  openWorldHint: false,
@@ -9070,6 +9323,11 @@ var makeUpdateEnvironmentContract = (ids) => {
9070
9323
  });
9071
9324
  const output = makeEnvironmentResourceSchema(ids);
9072
9325
  return {
9326
+ annotationJustifications: {
9327
+ destructiveHint: "Can overwrite existing environment settings and affect future run capacity.",
9328
+ openWorldHint: "Changes private environment settings without publishing code or contacting application users.",
9329
+ readOnlyHint: "Updates an environment's name or run concurrency limit."
9330
+ },
9073
9331
  annotations: {
9074
9332
  destructiveHint: true,
9075
9333
  openWorldHint: false,
@@ -9097,6 +9355,11 @@ var makeCreateTagContract = (ids) => {
9097
9355
  });
9098
9356
  const output = makeTagResourceSchema();
9099
9357
  return {
9358
+ annotationJustifications: {
9359
+ destructiveHint: "Creates a tag without deleting existing tags or flow associations.",
9360
+ openWorldHint: "Adds private QA Wolf metadata without publishing to an external application.",
9361
+ readOnlyHint: "Creates a workspace tag for grouping and selecting flows."
9362
+ },
9100
9363
  annotations: {
9101
9364
  destructiveHint: false,
9102
9365
  openWorldHint: false,
@@ -9130,6 +9393,11 @@ var makeAddTagToFlowsContract = (ids) => {
9130
9393
  })
9131
9394
  });
9132
9395
  return {
9396
+ annotationJustifications: {
9397
+ destructiveHint: "Adds associations without removing existing tags.",
9398
+ openWorldHint: "Changes private flow-tag associations without running flows or publishing code.",
9399
+ readOnlyHint: "Adds an existing tag to selected flows and skips flows already carrying it."
9400
+ },
9133
9401
  annotations: {
9134
9402
  destructiveHint: false,
9135
9403
  openWorldHint: false,
@@ -9184,6 +9452,11 @@ var makeListFlowsContract = (ids) => {
9184
9452
  }))
9185
9453
  });
9186
9454
  return {
9455
+ annotationJustifications: {
9456
+ destructiveHint: "Does not change flow code, readiness or tags.",
9457
+ openWorldHint: "Reads flow records without pushing code or executing application actions.",
9458
+ readOnlyHint: "Lists flows at an environment's reconciled commit or on a selected AI task branch."
9459
+ },
9187
9460
  annotations: {
9188
9461
  destructiveHint: false,
9189
9462
  openWorldHint: false,
@@ -9210,6 +9483,11 @@ var makeRemoveTagFromFlowsContract = (ids) => {
9210
9483
  })
9211
9484
  });
9212
9485
  return {
9486
+ annotationJustifications: {
9487
+ destructiveHint: "Deletes existing tag associations and skips flows that do not carry the tag.",
9488
+ openWorldHint: "Changes private flow-tag associations without updating external services.",
9489
+ readOnlyHint: "Removes a selected tag from specified flows."
9490
+ },
9213
9491
  annotations: {
9214
9492
  destructiveHint: true,
9215
9493
  openWorldHint: false,
@@ -9239,6 +9517,11 @@ var makeUpdateFlowContract = (ids) => {
9239
9517
  })
9240
9518
  });
9241
9519
  return {
9520
+ annotationJustifications: {
9521
+ destructiveHint: "Overwrites readiness and can deactivate a flow that was active.",
9522
+ openWorldHint: "Changes private readiness state without itself executing the flow or publishing code.",
9523
+ readOnlyHint: "Changes a flow between draft and active readiness."
9524
+ },
9242
9525
  annotations: {
9243
9526
  destructiveHint: true,
9244
9527
  openWorldHint: false,
@@ -9261,6 +9544,7 @@ var issuePrioritySchema = _enum([
9261
9544
  "urgent"
9262
9545
  ]);
9263
9546
  var issueStatusSchema = _enum([
9547
+ "backlog",
9264
9548
  "pending",
9265
9549
  "inProgress",
9266
9550
  "paused",
@@ -9269,7 +9553,12 @@ var issueStatusSchema = _enum([
9269
9553
  "archived"
9270
9554
  ]);
9271
9555
  var publicIssueTypeSchema = _enum(["bug", "coverageRequest", "maintenance"]);
9272
- var openIssueStatuses = ["pending", "inProgress", "paused"];
9556
+ var openIssueStatuses = [
9557
+ "backlog",
9558
+ "pending",
9559
+ "inProgress",
9560
+ "paused"
9561
+ ];
9273
9562
  var makeIssueResourceSchema = (ids) => resource({
9274
9563
  coveredFlowIds: array(ids.flow).describe("The flows a coverage request covers. Always empty on bug and maintenance reports, whose flows are listed under reproductions."),
9275
9564
  createdAt: exports_coerce.date().describe("When the issue was created."),
@@ -9291,7 +9580,7 @@ var makeIssueResourceSchema = (ids) => resource({
9291
9580
  var makeFindIssuesContract = (ids) => {
9292
9581
  const input = object({
9293
9582
  ...makePaginationInputFields({ defaultLimit: 20, maxLimit: 100 }),
9294
- statuses: array(issueStatusSchema).min(1).default([...openIssueStatuses]).describe("Issue statuses to include. Defaults to pending, in-progress, and paused issues."),
9583
+ statuses: array(issueStatusSchema).min(1).default([...openIssueStatuses]).describe("Issue statuses to include. Defaults to backlog, pending, in-progress, and paused issues."),
9295
9584
  type: publicIssueTypeSchema.describe("The issue type to include: bug report, maintenance report, or coverage request."),
9296
9585
  workspaceId: ids.workspace.optional().describe("The workspace whose issues to list. Required when authenticating with an organization or user API key.")
9297
9586
  });
@@ -9300,6 +9589,11 @@ var makeFindIssuesContract = (ids) => {
9300
9589
  nextCursor: nextCursorSchema
9301
9590
  });
9302
9591
  return {
9592
+ annotationJustifications: {
9593
+ destructiveHint: "Does not edit issue details, statuses or coverage associations.",
9594
+ openWorldHint: "Reads QA Wolf issue records without publishing updates to linked trackers.",
9595
+ readOnlyHint: "Lists workspace bug reports, maintenance reports or coverage requests."
9596
+ },
9303
9597
  annotations: {
9304
9598
  destructiveHint: false,
9305
9599
  openWorldHint: false,
@@ -9320,6 +9614,11 @@ var makeGetIssueContract = (ids) => {
9320
9614
  issue: makeIssueResourceSchema(ids)
9321
9615
  });
9322
9616
  return {
9617
+ annotationJustifications: {
9618
+ destructiveHint: "Does not modify or remove the issue.",
9619
+ openWorldHint: "Reads the QA Wolf issue without changing linked external systems.",
9620
+ readOnlyHint: "Retrieves one issue and its associated details."
9621
+ },
9323
9622
  annotations: {
9324
9623
  destructiveHint: false,
9325
9624
  openWorldHint: false,
@@ -9337,11 +9636,22 @@ var makeGetIssueContract = (ids) => {
9337
9636
  var investigationFindingStateDescription = 'What the investigation concluded about the cause. Known values: "investigating", "fixed", "fix-proposed", "reported", "report-proposed", "flake", "question" and "dismissed". New values can appear.';
9338
9637
  var makeInvestigationFindingSchema = (ids) => object({
9339
9638
  actual: string2().optional(),
9340
- commitHash: string2().optional(),
9639
+ commitHash: string2().optional().describe("The commit of a commit fix. Same as `fix.commitHash`."),
9341
9640
  decidedBy: _enum(["agent", "user"]).optional().describe("Who decided: the AI on its own, or a person who approved or dismissed it. Absent until someone decides."),
9342
9641
  disputeReason: string2().optional().describe("Why a person disputed what the AI did. Present on a proposal the AI made again after that dispute."),
9343
9642
  expected: string2().optional(),
9344
9643
  findingId: string2(),
9644
+ fix: discriminatedUnion("type", [
9645
+ object({
9646
+ commitHash: string2().describe("The commit that changes the flow code."),
9647
+ type: literal("commit")
9648
+ }),
9649
+ object({
9650
+ baselineChangeId: string2().optional().describe('The baseline change that made the new screenshot the baseline, on a "fixed" finding. `run restoreScreenshotBaseline` undoes it.'),
9651
+ comparisonId: string2().describe("The failed screenshot comparison whose new screenshot becomes the baseline, as `run listScreenshotComparisons` names it."),
9652
+ type: literal("baseline")
9653
+ })
9654
+ ]).optional().describe('The fix of a "fixed" or "fix-proposed" finding: a commit to the flow code, or a new screenshot baseline.'),
9345
9655
  flowIds: array(ids.flow),
9346
9656
  headline: string2().optional(),
9347
9657
  issueId: ids.issue.optional(),
@@ -9352,8 +9662,9 @@ var makeInvestigationFindingSchema = (ids) => object({
9352
9662
  answers: array(object({
9353
9663
  description: string2().optional(),
9354
9664
  title: string2(),
9355
- value: string2().describe('What choosing this answer means. Known values: "apply", "dismiss", "report", "maintenance" and "bug". New values can appear.')
9665
+ value: string2().describe('What choosing this answer means. Known values: "apply", "dismiss", "report", "maintenance", "bug" and "baseline". New values can appear.')
9356
9666
  })),
9667
+ comparisonId: string2().optional().describe('The failed screenshot comparison a screenshot question is about, as `run listScreenshotComparisons` names it. Its answers are "bug" (the old screenshot is right), "maintenance" (both are right) and "baseline" (the new screenshot is right).'),
9357
9668
  text: string2()
9358
9669
  }).optional().describe("The question waiting for a person, with the answers offered."),
9359
9670
  response: object({
@@ -9373,12 +9684,22 @@ var makeInvestigationFindingSchema = (ids) => object({
9373
9684
  var makeGetInvestigationContract = (ids) => {
9374
9685
  const input = object({ runId: ids.run });
9375
9686
  const output = resource({
9687
+ baselineChanges: _enum(["automatic", "needs-approval"]).describe('How the investigation can make a new screenshot the baseline. "automatic": it can accept a baseline on its own. ' + '"needs-approval": it proposes the baseline on a fix-proposed finding, and accepts it only after a person applies the proposal.'),
9376
9688
  findings: array(makeInvestigationFindingSchema(ids)),
9377
9689
  runId: ids.run,
9378
9690
  sessionId: ids.chatSession.optional().describe("The investigation session. Absent when the run has none."),
9379
- status: _enum(["investigating", "finished", "not-investigated"]).describe('Whether the investigation session is still working. "not-investigated" when the run has no investigation.')
9691
+ status: _enum(["investigating", "finished", "not-investigated"]).describe('Whether the lead or any child investigator is still working. "not-investigated" when the run has no investigation.'),
9692
+ subSessions: array(object({
9693
+ sessionId: ids.chatSession,
9694
+ status: agentSessionStatusSchema
9695
+ })).optional().describe("All child investigators, including sessions not attached to findings yet. Send instructions to each sessionId with agent.send.")
9380
9696
  }, { urlFieldDescription: "The run in the QA Wolf app." });
9381
9697
  return {
9698
+ annotationJustifications: {
9699
+ destructiveHint: "Does not answer, dispute or change the investigation.",
9700
+ openWorldHint: "Reads recorded QA Wolf findings without changing the application under test.",
9701
+ readOnlyHint: "Retrieves an investigation's findings, open questions and pending answers."
9702
+ },
9382
9703
  annotations: {
9383
9704
  destructiveHint: false,
9384
9705
  openWorldHint: false,
@@ -9407,6 +9728,11 @@ var makeAddFlowsToIssueContract = (ids) => {
9407
9728
  issue: makeIssueResourceSchema(ids)
9408
9729
  });
9409
9730
  return {
9731
+ annotationJustifications: {
9732
+ destructiveHint: "Adds coverage associations without removing existing ones.",
9733
+ openWorldHint: "Changes private coverage associations without publishing an external issue update.",
9734
+ readOnlyHint: "Adds existing flows to a coverage request's covered-flow set."
9735
+ },
9410
9736
  annotations: {
9411
9737
  destructiveHint: false,
9412
9738
  openWorldHint: false,
@@ -9450,6 +9776,11 @@ var makeCreateIssueContract = (ids) => {
9450
9776
  issue: makeIssueResourceSchema(ids)
9451
9777
  });
9452
9778
  return {
9779
+ annotationJustifications: {
9780
+ destructiveHint: "Configured notifications can send irreversible messages even though the QA Wolf issue itself is new.",
9781
+ openWorldHint: "Issue creation can send messages or synchronize records through connected communication and issue-tracking services.",
9782
+ readOnlyHint: "Creates a bug or coverage request and can start configured issue notifications."
9783
+ },
9453
9784
  annotations: {
9454
9785
  destructiveHint: true,
9455
9786
  openWorldHint: true,
@@ -9466,19 +9797,25 @@ var makeCreateIssueContract = (ids) => {
9466
9797
  // node_modules/@qawolf/api-contracts/dist/v1/issue/removeFlows.js
9467
9798
  var makeRemoveFlowsFromIssueContract = (ids) => {
9468
9799
  const input = object({
9469
- flowIds: array(ids.flow).min(1).max(300).refine((flowIds) => new Set(flowIds).size === flowIds.length, "flowIds must be unique").describe("The flows the coverage request no longer covers."),
9800
+ environmentId: ids.environment.optional().describe("The environment whose bug or maintenance reproductions to remove. Required when a selected flow is linked in more than one environment."),
9801
+ flowIds: array(ids.flow).min(1).max(300).refine((flowIds) => new Set(flowIds).size === flowIds.length, "flowIds must be unique").describe("The flows to remove from the issue."),
9470
9802
  issueId: ids.issue
9471
9803
  });
9472
9804
  const output = object({
9473
9805
  issue: makeIssueResourceSchema(ids)
9474
9806
  });
9475
9807
  return {
9808
+ annotationJustifications: {
9809
+ destructiveHint: "Deletes existing coverage associations while leaving already-unassociated flows unchanged.",
9810
+ openWorldHint: "Changes private coverage associations without publishing to an external tracker.",
9811
+ readOnlyHint: "Removes selected flows from a coverage request's covered-flow set."
9812
+ },
9476
9813
  annotations: {
9477
9814
  destructiveHint: true,
9478
- openWorldHint: false,
9815
+ openWorldHint: true,
9479
9816
  readOnlyHint: false
9480
9817
  },
9481
- description: "Remove flows from a coverage request owned by the caller's team. " + "Flows the request does not cover are left alone. " + "Bug and maintenance reports link to flows through the runs that reproduce them, so their flows cannot be set directly.",
9818
+ description: "Remove flows from a coverage request or remove bug/maintenance reproductions in an environment. " + "Unlinked flows are left alone. Reports auto-close when no active reproductions remain and auto-close is enabled. " + "For reports, omit environmentId only when each selected flow is linked in at most one environment.",
9482
9819
  input,
9483
9820
  kind: "write",
9484
9821
  name: "issue.removeFlows",
@@ -9503,6 +9840,11 @@ var makeUpdateIssueContract = (ids) => {
9503
9840
  issue: makeIssueResourceSchema(ids)
9504
9841
  });
9505
9842
  return {
9843
+ annotationJustifications: {
9844
+ destructiveHint: "Can overwrite existing issue fields or send irreversible integration messages.",
9845
+ openWorldHint: "Issue changes can update connected issue trackers and communication services.",
9846
+ readOnlyHint: "Updates issue details, priority or status and can trigger integration updates."
9847
+ },
9506
9848
  annotations: {
9507
9849
  destructiveHint: true,
9508
9850
  openWorldHint: true,
@@ -9579,6 +9921,11 @@ var makeFindLegacyTriggersContract = (ids) => {
9579
9921
  legacyTriggers: array(makeLegacyTriggerSchema(ids)).describe("The workspace's legacy triggers, by name.")
9580
9922
  });
9581
9923
  return {
9924
+ annotationJustifications: {
9925
+ destructiveHint: "Does not pause, resume or change any trigger.",
9926
+ openWorldHint: "Reads private QA Wolf trigger configuration without starting external work.",
9927
+ readOnlyHint: "Lists a workspace's legacy per-environment triggers."
9928
+ },
9582
9929
  annotations: {
9583
9930
  destructiveHint: false,
9584
9931
  openWorldHint: false,
@@ -9603,6 +9950,11 @@ var makeLifecycleShape = (ids) => ({
9603
9950
  var makePauseLegacyTriggerContract = (ids) => {
9604
9951
  const { input, output } = makeLifecycleShape(ids);
9605
9952
  return {
9953
+ annotationJustifications: {
9954
+ destructiveHint: "Disables future automatic execution for the legacy trigger and its pull request copies until it is resumed.",
9955
+ openWorldHint: "Changes private QA Wolf scheduling state without starting external work.",
9956
+ readOnlyHint: "Pauses an existing legacy trigger so it stops starting new work."
9957
+ },
9606
9958
  annotations: {
9607
9959
  destructiveHint: true,
9608
9960
  openWorldHint: false,
@@ -9618,6 +9970,11 @@ var makePauseLegacyTriggerContract = (ids) => {
9618
9970
  var makeResumeLegacyTriggerContract = (ids) => {
9619
9971
  const { input, output } = makeLifecycleShape(ids);
9620
9972
  return {
9973
+ annotationJustifications: {
9974
+ destructiveHint: "Enables automatic test execution that can overwrite or delete application data.",
9975
+ openWorldHint: "Resumed execution can change the application under test and update connected integrations.",
9976
+ readOnlyHint: "Reactivates a legacy trigger and its pull request copies so future schedules or deployments can start runs."
9977
+ },
9621
9978
  annotations: {
9622
9979
  destructiveHint: true,
9623
9980
  openWorldHint: true,
@@ -9638,6 +9995,54 @@ var makeLegacyTriggerContracts = (ids) => ({
9638
9995
  resume: makeResumeLegacyTriggerContract(ids)
9639
9996
  });
9640
9997
 
9998
+ // node_modules/@qawolf/api-contracts/dist/v1/run/investigationSessionId.js
9999
+ var investigationSessionId = string2().trim().min(1).max(100).optional();
10000
+
10001
+ // node_modules/@qawolf/api-contracts/dist/v1/run/acceptScreenshotBaseline.js
10002
+ var makeAcceptScreenshotBaselineContract = (ids) => {
10003
+ const input = object({
10004
+ chatSessionId: investigationSessionId.describe("The chat session of the investigation that accepts the baseline. A workspace or organization API key acts as an automation, so it must send the session that investigates the run. A person's call ignores it."),
10005
+ comparisonId: string2().trim().min(1).max(100).describe("The failed screenshot comparison whose new screenshot becomes the baseline, as `run.listScreenshotComparisons` names it."),
10006
+ runId: ids.run
10007
+ });
10008
+ const output = discriminatedUnion("outcome", [
10009
+ object({
10010
+ baselineChangeId: string2().describe("The baseline change. Record it on the fixed finding, and pass it to `run.restoreScreenshotBaseline` with this runId to put the old baseline back."),
10011
+ name: string2().describe("The screenshot name whose baseline changed."),
10012
+ outcome: literal("accepted").describe("The new screenshot is now the baseline. The old baseline is kept, so the change can be restored.")
10013
+ }),
10014
+ object({
10015
+ outcome: literal("baseline-changed").describe("The baseline is no longer the one the run compared with: someone changed or deleted it since. Nothing changed. List the comparisons again to see the current baseline.")
10016
+ }),
10017
+ object({
10018
+ outcome: literal("needs-approval").describe("Only a person can approve this change. Nothing changed. Propose the new baseline on a fix-proposed finding and wait for a person to apply it.")
10019
+ }),
10020
+ object({
10021
+ outcome: literal("not-investigation-session").describe("An API key that is not a person's can change a baseline only as the investigation of the run, and chatSessionId is missing or is not the session that investigates the run. Nothing changed.")
10022
+ }),
10023
+ object({
10024
+ outcome: literal("nothing-to-accept").describe("The comparison did not fail, or has no new screenshot to accept. Nothing changed.")
10025
+ })
10026
+ ]);
10027
+ return {
10028
+ annotationJustifications: {
10029
+ destructiveHint: "Replaces the workspace's screenshot baseline, which changes what every later run compares with.",
10030
+ openWorldHint: "Changes private QA Wolf baseline storage without starting external work.",
10031
+ readOnlyHint: "Makes the new screenshot of a failed comparison the baseline."
10032
+ },
10033
+ annotations: {
10034
+ destructiveHint: true,
10035
+ openWorldHint: false,
10036
+ readOnlyHint: false
10037
+ },
10038
+ description: "Make the new screenshot of a failed screenshot comparison the baseline, so later runs compare with it. " + "Use it only when the difference is an intended change of the app, not a bug, noise, or a page that was not ready. " + "Every later run of every environment of the workspace compares with the new baseline. " + "Refuses without changing anything when the baseline changed since the run.",
10039
+ input,
10040
+ kind: "write",
10041
+ name: "run.acceptScreenshotBaseline",
10042
+ output
10043
+ };
10044
+ };
10045
+
9641
10046
  // node_modules/@qawolf/api-contracts/dist/v1/run/diagnose.js
9642
10047
  var makeDiagnoseRunContract = (ids) => {
9643
10048
  const input = object({
@@ -9649,12 +10054,17 @@ var makeDiagnoseRunContract = (ids) => {
9649
10054
  issue: makeIssueResourceSchema(ids)
9650
10055
  });
9651
10056
  return {
10057
+ annotationJustifications: {
10058
+ destructiveHint: "Can replace a flow's existing diagnosis association and change externally reported run information.",
10059
+ openWorldHint: "Recorded diagnosis changes can update run-related messages in configured external integrations.",
10060
+ readOnlyHint: "Records failed flows as reproductions of a selected bug or maintenance issue."
10061
+ },
9652
10062
  annotations: {
9653
10063
  destructiveHint: true,
9654
10064
  openWorldHint: true,
9655
10065
  readOnlyHint: false
9656
10066
  },
9657
- description: "Diagnose failed flows in a run as reproductions of a bug or maintenance report owned by the caller's team. " + "The issue's type selects the diagnosis. " + "Each flow must have failed in the run. " + "A flow that is already diagnosed moves to this issue. " + "The diagnosis appears on the run, and the reproduction appears under the issue's reproductions. " + "Coverage requests cannot be diagnosed; use issue.addFlows to cover flows instead.",
10067
+ description: "Diagnose failed flows in a run as reproductions of a bug or maintenance report owned by the caller's team. " + "The issue's type selects the diagnosis. " + "Each flow must have failed in the run. " + "A flow that is already diagnosed in the run moves to this issue, and may stay linked to other open reports. " + "The diagnosis appears on the run, and the reproduction appears under the issue's reproductions. " + "Coverage requests cannot be diagnosed; use issue.addFlows to cover flows instead.",
9658
10068
  input,
9659
10069
  kind: "write",
9660
10070
  name: "run.diagnose",
@@ -9679,6 +10089,11 @@ var makeFindRunsContract = (ids) => {
9679
10089
  }, { urlFieldDescription: "Absolute URL of the run page." })).describe("The environment's runs, newest first. Per-flow results are available via run.get.")
9680
10090
  });
9681
10091
  return {
10092
+ annotationJustifications: {
10093
+ destructiveHint: "Does not stop runs, overwrite results or change diagnoses.",
10094
+ openWorldHint: "Reads private run records without executing application actions.",
10095
+ readOnlyHint: "Lists recent environment runs without starting or retrying them."
10096
+ },
9682
10097
  annotations: {
9683
10098
  destructiveHint: false,
9684
10099
  openWorldHint: false,
@@ -9692,6 +10107,22 @@ var makeFindRunsContract = (ids) => {
9692
10107
  };
9693
10108
  };
9694
10109
 
10110
+ // node_modules/@qawolf/api-contracts/dist/v1/run/flowFailure.js
10111
+ var makeFlowFailureSchema = (ids) => {
10112
+ const diagnosis = object({
10113
+ issueId: ids.issue,
10114
+ type: _enum(["bug", "maintenance"])
10115
+ }).optional().describe("QA Wolf's investigation verdict for the failure: `bug` means the " + "application is broken, `maintenance` means the test needed an " + "update and the failure does not indicate an application problem. " + "Absent until the investigation reaches a verdict, and absent when " + "the flow was opted out of investigation. Pass issueId to issue.get " + "for details.");
10116
+ const optedOutOfInvestigation = object({
10117
+ by: _enum(["user", "system"]).describe("Who stopped the investigation: `user` is a person, in the app or " + "with a user API key, or the workspace's automation user for a " + "team or organization API key, for example through " + "run.optOutOfInvestigation; `system` is QA Wolf, when the " + "investigation expired.")
10118
+ }).optional().describe('Present when the failure was marked "do not investigate" (DNI): ' + "it will get no bug or maintenance verdict.");
10119
+ return object({
10120
+ diagnosis,
10121
+ error: string2(),
10122
+ optedOutOfInvestigation
10123
+ });
10124
+ };
10125
+
9695
10126
  // node_modules/@qawolf/api-contracts/dist/v1/run/get.js
9696
10127
  var makeGetRunContract = (ids) => {
9697
10128
  const flowStatus = _enum(publicRunStatusValues);
@@ -9724,6 +10155,7 @@ var makeGetRunContract = (ids) => {
9724
10155
  }),
9725
10156
  object({
9726
10157
  attemptId: ids.runAttempt.optional(),
10158
+ canceledReason: string2().min(1).optional().describe("Why the attempt was canceled. userCanceled means a person stopped it; do not immediately retry that activity."),
9727
10159
  completedAt: exports_iso.datetime().optional(),
9728
10160
  kind: automatedKind,
9729
10161
  startedAt: exports_iso.datetime().optional(),
@@ -9739,16 +10171,9 @@ var makeGetRunContract = (ids) => {
9739
10171
  });
9740
10172
  const attempt = union([automatedAttempt, manualAttempt]);
9741
10173
  const attempts = array(attempt).optional().describe("The flow's finished execution attempts, oldest first, including " + "manual Wolf Browser attempts. Present once at least one attempt has " + "finished, so a flow that passed after retries also lists its failed " + "attempts. Artifact URLs appear only on automated attempts that " + "reached a verdict, stay valid for at least a day (call run.get " + "again for fresh ones), and can return 404 when the attempt did not " + "produce that artifact.");
9742
- const diagnosis = object({
9743
- issueId: ids.issue,
9744
- type: _enum(["bug", "maintenance"])
9745
- }).optional().describe("QA Wolf's investigation verdict for the failure: `bug` means the " + "application is broken, `maintenance` means the test needed an " + "update and the failure does not indicate an application problem. " + "Absent until the investigation reaches a verdict. Pass issueId to " + "issue.get for details.");
9746
10174
  const failedFlow = object({
9747
10175
  attempts,
9748
- failure: object({
9749
- diagnosis,
9750
- error: string2()
9751
- }),
10176
+ failure: makeFlowFailureSchema(ids),
9752
10177
  flowId: ids.flow,
9753
10178
  name: string2(),
9754
10179
  status: literal("failed")
@@ -9767,6 +10192,11 @@ var makeGetRunContract = (ids) => {
9767
10192
  runId: ids.run.describe("The run this response describes. Treat it as canonical: it can differ from the id you asked for. A deploy notification returns a run id before the run exists, and if a second notification for the same commit is folded into an earlier run, that id resolves to the earlier run instead.")
9768
10193
  }, { urlFieldDescription: "Absolute URL of the run page." });
9769
10194
  return {
10195
+ annotationJustifications: {
10196
+ destructiveHint: "Does not retry, cancel or alter the run.",
10197
+ openWorldHint: "Reads recorded QA Wolf results without changing the application under test.",
10198
+ readOnlyHint: "Retrieves a run's status, per-flow results and result links."
10199
+ },
9770
10200
  annotations: {
9771
10201
  destructiveHint: false,
9772
10202
  openWorldHint: false,
@@ -9844,6 +10274,11 @@ var makeGetRunAttemptArtifactsContract = (ids) => {
9844
10274
  })
9845
10275
  ]);
9846
10276
  return {
10277
+ annotationJustifications: {
10278
+ destructiveHint: "Does not retry, cancel or alter the run attempt.",
10279
+ openWorldHint: "Reads recorded QA Wolf artifacts without changing the application under test.",
10280
+ readOnlyHint: "Retrieves a finished attempt's metadata and signed artifact URLs."
10281
+ },
9847
10282
  annotations: {
9848
10283
  destructiveHint: false,
9849
10284
  openWorldHint: false,
@@ -9857,6 +10292,35 @@ var makeGetRunAttemptArtifactsContract = (ids) => {
9857
10292
  };
9858
10293
  };
9859
10294
 
10295
+ // node_modules/@qawolf/api-contracts/dist/v1/run/optOutOfInvestigation.js
10296
+ var makeOptOutOfInvestigationRunContract = (ids) => {
10297
+ const input = object({
10298
+ flowIds: array(ids.flow).min(1).max(100).refine((flowIds) => new Set(flowIds).size === flowIds.length, "flowIds must be unique").describe("The failed flows to stop investigating. Every named flow must be " + "eligible or the whole request is rejected."),
10299
+ runId: ids.run
10300
+ });
10301
+ const output = resource({
10302
+ optedOutFlowIds: array(ids.flow).describe("The flows that no longer need investigation."),
10303
+ runId: ids.run
10304
+ }, { urlFieldDescription: "Absolute URL of the run page." });
10305
+ return {
10306
+ annotationJustifications: {
10307
+ destructiveHint: "Ends the investigation of the selected failures and changes externally reported run information.",
10308
+ openWorldHint: "Recorded opt-outs can update run-related messages in configured external integrations.",
10309
+ readOnlyHint: "Records failed flows as needing no bug or maintenance report."
10310
+ },
10311
+ annotations: {
10312
+ destructiveHint: true,
10313
+ openWorldHint: true,
10314
+ readOnlyHint: false
10315
+ },
10316
+ description: 'Mark failed flows in a run as "do not investigate" (DNI): the failures need no bug or maintenance report. ' + "Each flow must have failed in the run and still be under investigation. " + "A flow that already has a diagnosis cannot be opted out. " + "A team or organization key records the opt-out as the workspace's automation user. " + "To link a failure to a report instead, use run.diagnose.",
10317
+ input,
10318
+ kind: "write",
10319
+ name: "run.optOutOfInvestigation",
10320
+ output
10321
+ };
10322
+ };
10323
+
9860
10324
  // node_modules/@qawolf/api-contracts/dist/v1/run/reattempt.js
9861
10325
  var makeReattemptRunContract = (ids) => {
9862
10326
  const input = object({
@@ -9868,6 +10332,11 @@ var makeReattemptRunContract = (ids) => {
9868
10332
  runId: ids.run
9869
10333
  }, { urlFieldDescription: "Absolute URL of the run page." });
9870
10334
  return {
10335
+ annotationJustifications: {
10336
+ destructiveHint: "Repeated execution can overwrite or delete application data and creates additional billed work.",
10337
+ openWorldHint: "New attempts execute against the application under test and can affect connected services.",
10338
+ readOnlyHint: "Enqueues new attempts for eligible failed or canceled flows using the latest code."
10339
+ },
9871
10340
  annotations: {
9872
10341
  destructiveHint: true,
9873
10342
  openWorldHint: true,
@@ -9881,6 +10350,50 @@ var makeReattemptRunContract = (ids) => {
9881
10350
  };
9882
10351
  };
9883
10352
 
10353
+ // node_modules/@qawolf/api-contracts/dist/v1/run/restoreScreenshotBaseline.js
10354
+ var makeRestoreScreenshotBaselineContract = (ids) => {
10355
+ const input = object({
10356
+ baselineChangeId: string2().trim().min(1).max(100).describe("The baseline change to undo, as `run.acceptScreenshotBaseline` returned it for this run."),
10357
+ chatSessionId: investigationSessionId.describe("The chat session of the investigation that restores the baseline. A workspace or organization API key acts as an automation, so it must send the session that investigates the run. A person's call ignores it."),
10358
+ runId: ids.run
10359
+ });
10360
+ const output = discriminatedUnion("outcome", [
10361
+ object({
10362
+ name: string2().describe("The screenshot name whose baseline changed."),
10363
+ outcome: literal("restored").describe("The baseline the change replaced is the baseline again.")
10364
+ }),
10365
+ object({
10366
+ outcome: literal("baseline-changed").describe("The baseline changed again after this change, so restoring it would undo someone else's change. Nothing changed.")
10367
+ }),
10368
+ object({
10369
+ outcome: literal("needs-dispute").describe("Only a person can restore this change, unless a person disputed the finding that made it. Nothing changed.")
10370
+ }),
10371
+ object({
10372
+ outcome: literal("not-investigation-session").describe("An API key that is not a person's can change a baseline only as the investigation of the run, and chatSessionId is missing or is not the session that investigates the run. Nothing changed.")
10373
+ }),
10374
+ object({
10375
+ outcome: literal("nothing-to-restore").describe("The change was already restored, the name had no baseline before it, or the kept copy of the old baseline is missing or is not the baseline the change replaced. Nothing changed.")
10376
+ })
10377
+ ]);
10378
+ return {
10379
+ annotationJustifications: {
10380
+ destructiveHint: "Replaces the current screenshot baseline with the one it replaced, which changes what every later run compares with.",
10381
+ openWorldHint: "Changes private QA Wolf baseline storage without starting external work.",
10382
+ readOnlyHint: "Puts back the screenshot baseline that an accepted comparison replaced."
10383
+ },
10384
+ annotations: {
10385
+ destructiveHint: true,
10386
+ openWorldHint: false,
10387
+ readOnlyHint: false
10388
+ },
10389
+ description: "Undo a screenshot baseline change that accepted a failed comparison of the run: put back the baseline it replaced, so later runs compare with the old baseline again. " + "Use it when a person disputes a baseline the AI accepted. " + "Refuses without changing anything when the baseline changed again since.",
10390
+ input,
10391
+ kind: "write",
10392
+ name: "run.restoreScreenshotBaseline",
10393
+ output
10394
+ };
10395
+ };
10396
+
9884
10397
  // node_modules/@qawolf/api-contracts/dist/v1/run/stop.js
9885
10398
  var makeStopRunContract = (ids) => {
9886
10399
  const input = object({ runId: ids.run });
@@ -9889,6 +10402,11 @@ var makeStopRunContract = (ids) => {
9889
10402
  status: _enum(["accepted", "already-finished", "execution-not-found"]).describe('"accepted" means stopping was requested; poll run.get for the final result. "already-finished" means the run has already finished and its result is unchanged. "execution-not-found" means the run exists but no execution was found to stop; it may still be starting or may no longer be available. No stop request was accepted in that case.')
9890
10403
  }, { urlFieldDescription: "Absolute URL of the run page." });
9891
10404
  return {
10405
+ annotationJustifications: {
10406
+ destructiveHint: "Interrupts unfinished work, while finished results remain intact and repeated stop requests are supported.",
10407
+ openWorldHint: "Run status changes can update messages or commit statuses in configured external integrations.",
10408
+ readOnlyHint: "Requests asynchronous cancellation of a run, queued flows and automatic retries."
10409
+ },
9892
10410
  annotations: {
9893
10411
  destructiveHint: true,
9894
10412
  openWorldHint: true,
@@ -9927,6 +10445,11 @@ var makeEvaluateSnippetOnRunnerContract = (ids) => {
9927
10445
  ])
9928
10446
  ]);
9929
10447
  return {
10448
+ annotationJustifications: {
10449
+ destructiveHint: "Code can overwrite or delete runner or application data, and a timeout does not prove execution stopped.",
10450
+ openWorldHint: "Supplied code can submit application actions or contact and change external services.",
10451
+ readOnlyHint: "Executes supplied code against the interactive runner's current session."
10452
+ },
9930
10453
  annotations: {
9931
10454
  destructiveHint: true,
9932
10455
  openWorldHint: true,
@@ -9960,6 +10483,11 @@ var makeGetRunnerContract = (ids) => {
9960
10483
  })
9961
10484
  ]);
9962
10485
  return {
10486
+ annotationJustifications: {
10487
+ destructiveHint: "Does not stop the runner or change its execution.",
10488
+ openWorldHint: "Reads private runner placement state without acting on external applications.",
10489
+ readOnlyHint: "Checks whether a runner exists without starting it or refreshing its inactivity timer."
10490
+ },
9963
10491
  annotations: {
9964
10492
  destructiveHint: false,
9965
10493
  openWorldHint: false,
@@ -10003,6 +10531,11 @@ var makeHighlightSelectorOnRunnerContract = (ids) => {
10003
10531
  })
10004
10532
  ]);
10005
10533
  return {
10534
+ annotationJustifications: {
10535
+ destructiveHint: "Only replaces or clears the inspection overlay rather than deleting application data.",
10536
+ openWorldHint: "Draws a private inspection overlay without submitting an application form.",
10537
+ readOnlyHint: "Changes the visual selector highlight on the runner's live page."
10538
+ },
10006
10539
  annotations: {
10007
10540
  destructiveHint: false,
10008
10541
  openWorldHint: false,
@@ -10036,6 +10569,11 @@ var makeImportPackageOnRunnerContract = (ids) => {
10036
10569
  })
10037
10570
  ]);
10038
10571
  return {
10572
+ annotationJustifications: {
10573
+ destructiveHint: "Can replace existing dependencies or execute commands that overwrite or delete runner or application data.",
10574
+ openWorldHint: "Installation can contact external services and execute commands that change third-party systems.",
10575
+ readOnlyHint: "Installs caller-selected dependencies into a live runner and can execute commands with the runner's access."
10576
+ },
10039
10577
  annotations: {
10040
10578
  destructiveHint: true,
10041
10579
  openWorldHint: true,
@@ -10065,9 +10603,14 @@ var makeLaunchRunnerContract = (ids) => {
10065
10603
  outcome: literal("success")
10066
10604
  });
10067
10605
  return {
10606
+ annotationJustifications: {
10607
+ destructiveHint: "Starts billable resource consumption that cannot be undone by later termination.",
10608
+ openWorldHint: "Allocates a private QA Wolf runner without itself navigating to an application or submitting forms.",
10609
+ readOnlyHint: "Starts an interactive runner and allocates billed resources unless the requested runner is already running."
10610
+ },
10068
10611
  annotations: {
10069
10612
  destructiveHint: true,
10070
- openWorldHint: false,
10613
+ openWorldHint: true,
10071
10614
  readOnlyHint: false
10072
10615
  },
10073
10616
  description: "Launch an interactive runner on the caller's team under an id the caller chooses. Send `initialUrl` so its browser comes up on the page the work starts from, which saves a separate navigation and the browser's cold start. Launching the same id again returns the runner already running rather than starting a second one, and the same id with a different runnerName is refused. A runner is not permanent: it terminates on its own after a period of inactivity, and launching the same id after that starts and bills a new runner, so read `alreadyRunning` to tell which happened. A success means the runner is answering: the call waits for the pod it started to come up, so the very next call to the runner reaches it. If the pod does not come up in time the call fails instead, leaving the runner running, and launching the same id again attaches to it.",
@@ -10088,6 +10631,11 @@ var makeTerminateRunnerContract = (ids) => {
10088
10631
  wasRunning: boolean2().describe("False when no running runner had this id: it was already terminated, was never launched, or terminated on its own after inactivity. These are not distinguished, because the run system keeps no record of a runner once it is gone. Not an error, and a retry needs no special handling.")
10089
10632
  });
10090
10633
  return {
10634
+ annotationJustifications: {
10635
+ destructiveHint: "Terminates running work and discards the live session, while an absent runner is left absent.",
10636
+ openWorldHint: "Stops a private QA Wolf runner without itself publishing to third-party services.",
10637
+ readOnlyHint: "Ends a selected interactive runner and the resources hosting it."
10638
+ },
10091
10639
  annotations: {
10092
10640
  destructiveHint: true,
10093
10641
  openWorldHint: false,
@@ -10111,6 +10659,11 @@ var makeListRunnersContract = (ids) => {
10111
10659
  runners: array(makeRunnerSchema()).describe("The runners running right now, in no particular order. Each entry carries the same fields a launch reports, so any of them can be addressed like a runner you launched yourself.")
10112
10660
  });
10113
10661
  return {
10662
+ annotationJustifications: {
10663
+ destructiveHint: "Does not interrupt or terminate any listed runner.",
10664
+ openWorldHint: "Reads private runner state without acting on third-party applications.",
10665
+ readOnlyHint: "Lists running workspace runners without starting them or refreshing their inactivity timers."
10666
+ },
10114
10667
  annotations: {
10115
10668
  destructiveHint: false,
10116
10669
  openWorldHint: false,
@@ -10145,6 +10698,11 @@ var makePromoteSnapshotOnRunnerContract = (ids) => {
10145
10698
  })
10146
10699
  ]);
10147
10700
  return {
10701
+ annotationJustifications: {
10702
+ destructiveHint: "Overwrites an existing baseline, while a missing source snapshot leaves it unchanged.",
10703
+ openWorldHint: "Updates a stored test baseline rather than publishing to an external application.",
10704
+ readOnlyHint: "Replaces a named image-diff baseline with a screenshot produced by the runner."
10705
+ },
10148
10706
  annotations: {
10149
10707
  destructiveHint: true,
10150
10708
  openWorldHint: false,
@@ -10170,6 +10728,11 @@ var makeReadRunnerJournalContract = (ids) => {
10170
10728
  makeRunnerFailureSchema([runnerUnreachableFailureReason])
10171
10729
  ]);
10172
10730
  return {
10731
+ annotationJustifications: {
10732
+ destructiveHint: "Does not erase journal entries or change run results, although the activity refresh can extend billed runtime.",
10733
+ openWorldHint: "Reads private runner history without submitting actions to external applications.",
10734
+ readOnlyHint: "Retrieves journal entries and refreshes activity, which can cancel an inactivity shutdown."
10735
+ },
10173
10736
  annotations: {
10174
10737
  destructiveHint: false,
10175
10738
  openWorldHint: false,
@@ -10201,7 +10764,7 @@ var makeRunFlowOnRunnerContract = (ids) => {
10201
10764
  env: runEnvironmentSchema.optional().describe("Environment variables to make available to the run."),
10202
10765
  environmentId: ids.environmentRef.optional().describe("A QA Wolf environment whose variables the run is given, by id or alias. QA Wolf reads and decrypts them itself, so they never travel in the request and the count and length limits on `env` do not apply to them. Send this or `env`, not both."),
10203
10766
  files: runFilesSchema.describe("Every file the run needs keyed by its path — the flow file, everything it imports, package.json and tsconfig.json. A runner holds no copy of your project, so what runs is exactly what is sent here."),
10204
- flowId: ids.flow.optional().describe("The QA Wolf flow this run is for. The run then sees it as `QAWOLF_WORKFLOW_ID`, the same value a platform run of that flow sees, so fixtures named and cleaned up by it match across both. Omit it when the flow is not in QA Wolf yet, and the run has no `QAWOLF_WORKFLOW_ID`."),
10767
+ flowId: ids.flow.optional().describe("The QA Wolf flow this run is for. The run then sees it as `QAWOLF_WORKFLOW_ID`, the same value a platform run of that flow sees, so fixtures named and cleaned up by it match across both. Omitted, the flow whose file is at `entryPointPath` on the named environment's flow-code branch stands in; a file not in QA Wolf yet, or a run given no environment, leaves the run with no `QAWOLF_WORKFLOW_ID`."),
10205
10768
  id: runnerIdSchema.describe("Id of the runner to run the flow on."),
10206
10769
  selection: runSelectionSchema.optional().describe("Run only these lines, inside the page the runner is already on, instead of running the whole flow from a fresh browser. Omit to run the whole entry point."),
10207
10770
  unchangedFiles: unchangedFilesSchema.optional().describe("Files this runner already holds from an earlier run, keyed by path with a hex SHA-256 of the content it should hold. Send this to make `files` only what changed. The runner refuses with `needs-full-sync` if it holds none of a referenced path, so it never runs something other than what was asked for. Omit it to send every file."),
@@ -10248,6 +10811,11 @@ var makeRunFlowOnRunnerContract = (ids) => {
10248
10811
  failure
10249
10812
  ]);
10250
10813
  return {
10814
+ annotationJustifications: {
10815
+ destructiveHint: "Test code can overwrite or delete application data, and uncertain acceptance must be checked before resubmission.",
10816
+ openWorldHint: "Executed tests can submit forms and change the application under test or its connected services.",
10817
+ readOnlyHint: "Submits test files for full-flow or selected-line execution on an interactive runner."
10818
+ },
10251
10819
  annotations: {
10252
10820
  destructiveHint: true,
10253
10821
  openWorldHint: true,
@@ -10275,6 +10843,11 @@ var makeStopRunOnRunnerContract = (ids) => {
10275
10843
  makeRunnerFailureSchema([runnerUnreachableFailureReason])
10276
10844
  ]);
10277
10845
  return {
10846
+ annotationJustifications: {
10847
+ destructiveHint: "Stops unfinished work where it is, while an already-idle runner is left idle.",
10848
+ openWorldHint: "Changes private execution state without itself posting external messages.",
10849
+ readOnlyHint: "Interrupts current execution while leaving the runner available."
10850
+ },
10278
10851
  annotations: {
10279
10852
  destructiveHint: true,
10280
10853
  openWorldHint: false,
@@ -10305,6 +10878,11 @@ var makeTakeScreenshotOnRunnerContract = (ids) => {
10305
10878
  ])
10306
10879
  ]);
10307
10880
  return {
10881
+ annotationJustifications: {
10882
+ destructiveHint: "Does not change application data or stop execution, although the activity refresh can extend billed runtime.",
10883
+ openWorldHint: "Reads the private runner display without submitting an external application action.",
10884
+ readOnlyHint: "Captures the runner screen and refreshes activity, which can cancel an inactivity shutdown."
10885
+ },
10308
10886
  annotations: {
10309
10887
  destructiveHint: false,
10310
10888
  openWorldHint: false,
@@ -10356,6 +10934,11 @@ var makeListSkillsContract = () => {
10356
10934
  skills: array(skillSummary).describe("Every skill the server serves, in catalog order.")
10357
10935
  });
10358
10936
  return {
10937
+ annotationJustifications: {
10938
+ destructiveHint: "Does not change any skill or workspace data.",
10939
+ openWorldHint: "Reads the QA Wolf skill catalog without calling external services.",
10940
+ readOnlyHint: "Lists the QA Wolf skills with their names and descriptions."
10941
+ },
10359
10942
  annotations: readOnlyAnnotations,
10360
10943
  description: "List the QA Wolf skills, each with its name and the description that says when to use it. A skill is the instructions a coding agent follows for one kind of QA Wolf work, such as onboarding an application, creating a flow, repairing a failing flow, or setting up triggers. Call this before any QA Wolf work, pick the skill whose description matches the request, and read it with skill.get.",
10361
10944
  input,
@@ -10374,6 +10957,11 @@ var makeGetSkillContract = () => {
10374
10957
  })).describe("The files the skill links to under its directory.")
10375
10958
  });
10376
10959
  return {
10960
+ annotationJustifications: {
10961
+ destructiveHint: "Does not change any skill or workspace data.",
10962
+ openWorldHint: "Reads the QA Wolf skill catalog without calling external services.",
10963
+ readOnlyHint: "Retrieves one QA Wolf skill's instructions and reference files."
10964
+ },
10377
10965
  annotations: readOnlyAnnotations,
10378
10966
  description: "Read a QA Wolf skill: the instructions a coding agent follows for one kind of QA Wolf work. The reply carries the skill's SKILL.md and every file under its references directory, so nothing else has to be fetched for it. Read the skill before starting the work it covers and follow it. A link in the reply of the form ../<skill>/SKILL.md names another skill, which this call reads by that name.",
10379
10967
  input,
@@ -10402,6 +10990,11 @@ var makeListTagsContract = (ids) => {
10402
10990
  })).describe("The team's tags, alphabetical by name.")
10403
10991
  });
10404
10992
  return {
10993
+ annotationJustifications: {
10994
+ destructiveHint: "Does not create, rename or remove tags.",
10995
+ openWorldHint: "Reads private tag metadata without changing connected services.",
10996
+ readOnlyHint: "Lists existing workspace tags by name."
10997
+ },
10405
10998
  annotations: {
10406
10999
  destructiveHint: false,
10407
11000
  openWorldHint: false,
@@ -10468,12 +11061,16 @@ var makeContractsV1 = (ids) => {
10468
11061
  },
10469
11062
  legacyTrigger: makeLegacyTriggerContracts(resolvedIds),
10470
11063
  run: {
11064
+ acceptScreenshotBaseline: makeAcceptScreenshotBaselineContract(resolvedIds),
10471
11065
  create: makeCreateRunContract(resolvedIds),
10472
11066
  diagnose: makeDiagnoseRunContract(resolvedIds),
10473
11067
  find: makeFindRunsContract(resolvedIds),
10474
11068
  get: makeGetRunContract(resolvedIds),
10475
11069
  getAttemptArtifacts: makeGetRunAttemptArtifactsContract(resolvedIds),
11070
+ listScreenshotComparisons: makeListScreenshotComparisonsContract(resolvedIds),
11071
+ optOutOfInvestigation: makeOptOutOfInvestigationRunContract(resolvedIds),
10476
11072
  reattempt: makeReattemptRunContract(resolvedIds),
11073
+ restoreScreenshotBaseline: makeRestoreScreenshotBaselineContract(resolvedIds),
10477
11074
  stop: makeStopRunContract(resolvedIds)
10478
11075
  },
10479
11076
  runner: makeRunnerContracts(resolvedIds),
@@ -15108,4 +15705,4 @@ export {
15108
15705
  createRunnerSdk
15109
15706
  };
15110
15707
 
15111
- //# debugId=3EFB50CF5F60CF8264756E2164756E21
15708
+ //# debugId=ADFCE2FBF1F4DDA964756E2164756E21