@flowriki/agent 0.1.0-beta.42 → 0.1.0-beta.43

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.
@@ -6,7 +6,7 @@ import os from "os";
6
6
  import path from "path";
7
7
  import { createRequire } from "module";
8
8
  import { spawnSync } from "child_process";
9
- var AGENT_VERSION = "0.1.0-beta.42";
9
+ var AGENT_VERSION = "0.1.0-beta.43";
10
10
  async function prepareBrowsers() {
11
11
  if (browsersReady()) {
12
12
  return { ok: true, already: true, message: "chromium is already installed" };
@@ -1008,6 +1008,7 @@ import { z as z42 } from "zod";
1008
1008
  import { z as z5 } from "zod";
1009
1009
  import { z as z6 } from "zod";
1010
1010
  import { z as z7 } from "zod";
1011
+ import { z as z8 } from "zod";
1011
1012
  var EngineSchema = z4.enum(["chromium", "firefox", "webkit"]);
1012
1013
  var CapabilitySchema = z4.object({
1013
1014
  id: z4.string(),
@@ -1036,18 +1037,44 @@ var ExecutionConfigSchema = z4.object({
1036
1037
  })
1037
1038
  ).default({})
1038
1039
  });
1039
- var FlowOccurrenceSchema = z22.object({
1040
+ var BUSINESS_KEYWORDS = ["Given", "When", "Then", "And", "But"];
1041
+ var BusinessStepSchema = z22.object({
1042
+ keyword: z22.enum(BUSINESS_KEYWORDS),
1043
+ text: z22.string().min(1).max(2e3)
1044
+ }).strict();
1045
+ var TestCaseOriginSchema = z22.object({
1046
+ kind: z22.enum(["import", "assistant"]),
1047
+ at: z22.string(),
1048
+ by: z22.string().default(""),
1049
+ /** The file it was imported from, and its row or id there. */
1050
+ file: z22.string().max(300).optional(),
1051
+ row: z22.string().max(200).optional()
1052
+ }).strict();
1053
+ var KEYWORD = /^\s*(given|when|then|and|but)\b[\s:]*(.*)$/i;
1054
+ var keywordOf = (word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
1055
+ function parseGherkin(text) {
1056
+ const lines = text.split(/\r?\n/).map((l) => l.trim()).filter(Boolean).filter((l) => !/^(scenario|scenario outline|feature|background|examples)\s*:/i.test(l) && !l.startsWith("|"));
1057
+ if (!lines.length) return null;
1058
+ const steps = [];
1059
+ for (const line of lines) {
1060
+ const m = KEYWORD.exec(line);
1061
+ if (!m || !m[2].trim()) return null;
1062
+ steps.push({ keyword: keywordOf(m[1]), text: m[2].trim() });
1063
+ }
1064
+ return steps;
1065
+ }
1066
+ var FlowOccurrenceSchema = z32.object({
1040
1067
  /** This copy's own identity. Not the source flow's — a flow added twice is
1041
1068
  * two occurrences, and editing, breakpoints, results and deletion must be
1042
1069
  * able to tell them apart. */
1043
- occurrenceId: z22.string().min(1),
1044
- actorId: z22.string().optional(),
1070
+ occurrenceId: z32.string().min(1),
1071
+ actorId: z32.string().optional(),
1045
1072
  /** Editable, and initially the source flow's name. */
1046
- name: z22.string().min(1),
1073
+ name: z32.string().min(1),
1047
1074
  /** Where this copy starts, when it is told to navigate before running.
1048
1075
  * Absent means continue from wherever the previous row left the browser. */
1049
- startPath: z22.string().optional(),
1050
- baseUrl: z22.string().url().optional(),
1076
+ startPath: z32.string().optional(),
1077
+ baseUrl: z32.string().url().optional(),
1051
1078
  /** GO SOMEWHERE FIRST, or carry on where the last row ended.
1052
1079
  *
1053
1080
  * SUPERSEDED BY `start`, and still read so that every case written before
@@ -1057,7 +1084,7 @@ var FlowOccurrenceSchema = z22.object({
1057
1084
  * Off by default, because a case is a sequence in one browser: re-entering
1058
1085
  * each flow's original starting URL would sign the tester out between rows
1059
1086
  * and is exactly the behaviour composing flows is meant to avoid. */
1060
- navigateFirst: z22.boolean().default(false),
1087
+ navigateFirst: z32.boolean().default(false),
1061
1088
  /** WHICH BROWSER THIS ROW RUNS IN.
1062
1089
  *
1063
1090
  * Two answers, because there are two: carry on in the browser this
@@ -1080,7 +1107,7 @@ var FlowOccurrenceSchema = z22.object({
1080
1107
  * A participant's FIRST row is always fresh in effect: there is nothing to
1081
1108
  * continue from. That is not stored, because it is a fact about the order
1082
1109
  * rather than about the row — moving the row changes the answer. */
1083
- start: z22.enum(["continue", "navigate", "fresh"]).optional(),
1110
+ start: z32.enum(["continue", "navigate", "fresh"]).optional(),
1084
1111
  /** WHETHER THIS COPY DOES ITS OWN SIGNING IN.
1085
1112
  *
1086
1113
  * A flow recorded with "sign in before recording" keeps that sign-in as its
@@ -1099,28 +1126,28 @@ var FlowOccurrenceSchema = z22.object({
1099
1126
  * the two agree on the account and is refused where they do not — so a case
1100
1127
  * written before this keeps its meaning, and a contradiction stays a
1101
1128
  * contradiction until somebody actually resolves it. */
1102
- ownSignIn: z22.enum(["skip", "run"]).optional(),
1103
- steps: z22.array(RecordedStepSchema),
1129
+ ownSignIn: z32.enum(["skip", "run"]).optional(),
1130
+ steps: z32.array(RecordedStepSchema),
1104
1131
  environment: ExecutionEnvironmentSchema.optional(),
1105
1132
  /** Where this copy came from, so the editor can say whether the source has
1106
1133
  * moved on — informational only, never a trigger to rewrite anything. */
1107
- origin: z22.object({
1108
- flowId: z22.string(),
1134
+ origin: z32.object({
1135
+ flowId: z32.string(),
1109
1136
  /** The schema the source was written in, which may be older than today's. */
1110
- schemaVersion: z22.number().int().nonnegative(),
1137
+ schemaVersion: z32.number().int().nonnegative(),
1111
1138
  /** The source's own revision counter at the moment it was copied. */
1112
- revision: z22.number().int().nonnegative(),
1139
+ revision: z32.number().int().nonnegative(),
1113
1140
  /** The commit the copy was taken from, when one was known. */
1114
- commit: z22.string().optional(),
1115
- featureId: z22.string(),
1141
+ commit: z32.string().optional(),
1142
+ featureId: z32.string(),
1116
1143
  /** Names as they were, so an old case still reads correctly after the
1117
1144
  * source is renamed, moved or deleted. */
1118
- featureName: z22.string(),
1119
- flowName: z22.string(),
1145
+ featureName: z32.string(),
1146
+ flowName: z32.string(),
1120
1147
  /** Source step id → the id it was given here. Kept so a later comparison
1121
1148
  * against the source can line the two up; nothing depends on it to run. */
1122
- stepIds: z22.record(z22.string(), z22.string()).default({}),
1123
- copiedAt: z22.string()
1149
+ stepIds: z32.record(z32.string(), z32.string()).default({}),
1150
+ copiedAt: z32.string()
1124
1151
  }),
1125
1152
  /** WHICH OF THIS ROW'S STEPS ARE WHAT RUNS BEFORE ITS FLOW — the flow's
1126
1153
  * sign-in and the prerequisites copied in with it — so the row can be shown
@@ -1131,24 +1158,24 @@ var FlowOccurrenceSchema = z22.object({
1131
1158
  * id, so editing or deleting one of them leaves the rest still grouped.
1132
1159
  * Absent on every row copied before this existed, which simply show flat.
1133
1160
  * Never sent to a machine — see `withoutFolding`. */
1134
- before: z22.object({
1161
+ before: z32.object({
1135
1162
  /** The flow's own sign-in, when the copy brought one. */
1136
- signInStepId: z22.string().optional(),
1137
- flows: z22.array(z22.object({
1138
- flowId: z22.string(),
1139
- name: z22.string(),
1140
- stepIds: z22.array(z22.string())
1163
+ signInStepId: z32.string().optional(),
1164
+ flows: z32.array(z32.object({
1165
+ flowId: z32.string(),
1166
+ name: z32.string(),
1167
+ stepIds: z32.array(z32.string())
1141
1168
  }).strict()).default([])
1142
1169
  }).strict().optional()
1143
1170
  }).strict();
1144
1171
  var CASE_SCHEMA_VERSION = 1;
1145
- var TestCaseSchema = z22.object({
1146
- schemaVersion: z22.literal(CASE_SCHEMA_VERSION),
1147
- id: z22.string().min(1),
1148
- folderId: z22.string().min(1),
1149
- slug: z22.string().regex(/^[a-z0-9][a-z0-9-]*$/),
1150
- name: z22.string().min(1),
1151
- description: z22.string().default(""),
1172
+ var TestCaseSchema = z32.object({
1173
+ schemaVersion: z32.literal(CASE_SCHEMA_VERSION),
1174
+ id: z32.string().min(1),
1175
+ folderId: z32.string().min(1),
1176
+ slug: z32.string().regex(/^[a-z0-9][a-z0-9-]*$/),
1177
+ name: z32.string().min(1),
1178
+ description: z32.string().default(""),
1152
1179
  /** NO LONGER USED, and kept only so that a case written while they were
1153
1180
  * parses.
1154
1181
  *
@@ -1161,19 +1188,25 @@ var TestCaseSchema = z22.object({
1161
1188
  *
1162
1189
  * Every row now starts where its own flow says, which is the same answer
1163
1190
  * whatever the order. */
1164
- startPath: z22.string().default("/"),
1165
- useStartPath: z22.boolean().default(false),
1166
- baseUrl: z22.string().url().optional(),
1191
+ startPath: z32.string().default("/"),
1192
+ useStartPath: z32.boolean().default(false),
1193
+ baseUrl: z32.string().url().optional(),
1167
1194
  environment: ExecutionEnvironmentSchema.optional(),
1168
- actors: z22.array(ActorDefinitionSchema).optional(),
1169
- defaultActorId: z22.string().optional(),
1170
- occurrences: z22.array(FlowOccurrenceSchema).default([]),
1171
- createdAt: z22.string(),
1172
- createdBy: z22.string().default(""),
1173
- updatedAt: z22.string(),
1195
+ actors: z32.array(ActorDefinitionSchema).optional(),
1196
+ defaultActorId: z32.string().optional(),
1197
+ occurrences: z32.array(FlowOccurrenceSchema).default([]),
1198
+ /** WHAT IT CHECKS, IN WORDS: Given / When / Then. Written for a case that is
1199
+ * not automated yet — imported, or written by the assistant — and kept when
1200
+ * it is. Never sent to a machine — see `withoutFolding`. */
1201
+ businessSteps: z32.array(BusinessStepSchema).optional(),
1202
+ /** Where it came from, when not recorded here. */
1203
+ origin: TestCaseOriginSchema.optional(),
1204
+ createdAt: z32.string(),
1205
+ createdBy: z32.string().default(""),
1206
+ updatedAt: z32.string(),
1174
1207
  /** The same optimistic-concurrency counter a flow carries, so an edit made
1175
1208
  * against a stale copy is refused rather than overwriting. */
1176
- revision: z22.number().int().nonnegative().default(0)
1209
+ revision: z32.number().int().nonnegative().default(0)
1177
1210
  }).strict().superRefine((testCase, ctx) => {
1178
1211
  const seen = /* @__PURE__ */ new Set();
1179
1212
  testCase.occurrences.forEach((occurrence, i) => {
@@ -1202,47 +1235,47 @@ var TestCaseSchema = z22.object({
1202
1235
  const { defaultActorId: _gone, ...rest } = testCase;
1203
1236
  return rest;
1204
1237
  });
1205
- var CaseFolderSchema = z22.object({
1206
- schemaVersion: z22.literal(1),
1207
- id: z22.string().min(1),
1208
- slug: z22.string().regex(/^[a-z0-9][a-z0-9-]*$/),
1209
- name: z22.string().min(1),
1210
- description: z22.string().default(""),
1211
- order: z22.number().int().default(0),
1212
- createdAt: z22.string(),
1213
- createdBy: z22.string().default("")
1238
+ var CaseFolderSchema = z32.object({
1239
+ schemaVersion: z32.literal(1),
1240
+ id: z32.string().min(1),
1241
+ slug: z32.string().regex(/^[a-z0-9][a-z0-9-]*$/),
1242
+ name: z32.string().min(1),
1243
+ description: z32.string().default(""),
1244
+ order: z32.number().int().default(0),
1245
+ createdAt: z32.string(),
1246
+ createdBy: z32.string().default("")
1214
1247
  }).strict();
1215
1248
  var SUITE_SCHEMA_VERSION = 1;
1216
- var SuiteEntrySchema = z22.object({
1217
- entryId: z22.string().min(1),
1218
- kind: z22.enum(["flow", "testCase"]),
1249
+ var SuiteEntrySchema = z32.object({
1250
+ entryId: z32.string().min(1),
1251
+ kind: z32.enum(["flow", "testCase"]),
1219
1252
  /** The document's ID — never its name or path, so renaming or moving what it
1220
1253
  * points at cannot break the reference. */
1221
- ref: z22.string().min(1),
1222
- enabled: z22.boolean().default(true),
1223
- order: z22.number().int().nonnegative(),
1254
+ ref: z32.string().min(1),
1255
+ enabled: z32.boolean().default(true),
1256
+ order: z32.number().int().nonnegative(),
1224
1257
  /** What it was called when it was added, so a result stays readable after the
1225
1258
  * source is renamed or deleted. */
1226
- nameSnapshot: z22.string().default("")
1259
+ nameSnapshot: z32.string().default("")
1227
1260
  }).strict();
1228
- var SuiteSchema = z22.object({
1229
- schemaVersion: z22.literal(SUITE_SCHEMA_VERSION),
1230
- id: z22.string().min(1),
1231
- slug: z22.string().regex(/^[a-z0-9][a-z0-9-]*$/),
1232
- name: z22.string().min(1),
1233
- description: z22.string().default(""),
1234
- entries: z22.array(SuiteEntrySchema).default([]),
1235
- defaults: z22.object({
1236
- headless: z22.boolean().optional(),
1261
+ var SuiteSchema = z32.object({
1262
+ schemaVersion: z32.literal(SUITE_SCHEMA_VERSION),
1263
+ id: z32.string().min(1),
1264
+ slug: z32.string().regex(/^[a-z0-9][a-z0-9-]*$/),
1265
+ name: z32.string().min(1),
1266
+ description: z32.string().default(""),
1267
+ entries: z32.array(SuiteEntrySchema).default([]),
1268
+ defaults: z32.object({
1269
+ headless: z32.boolean().optional(),
1237
1270
  /** Carry on through the remaining entries, or stop at the first failure.
1238
1271
  * Continuing is the default: a suite is a list of independent things and
1239
1272
  * one failure rarely invalidates the rest. */
1240
- failurePolicy: z22.enum(["continue", "stop"]).default("continue")
1273
+ failurePolicy: z32.enum(["continue", "stop"]).default("continue")
1241
1274
  }).default({ failurePolicy: "continue" }),
1242
- createdAt: z22.string(),
1243
- createdBy: z22.string().default(""),
1244
- updatedAt: z22.string(),
1245
- revision: z22.number().int().nonnegative().default(0)
1275
+ createdAt: z32.string(),
1276
+ createdBy: z32.string().default(""),
1277
+ updatedAt: z32.string(),
1278
+ revision: z32.number().int().nonnegative().default(0)
1246
1279
  }).strict().superRefine((suite, ctx) => {
1247
1280
  const seen = /* @__PURE__ */ new Set();
1248
1281
  suite.entries.forEach((entry, i) => {
@@ -1433,19 +1466,19 @@ function restoreDebugCase(testCase, owners, steps) {
1433
1466
  }
1434
1467
  return { ...testCase, occurrences };
1435
1468
  }
1436
- var AuthNavigationSchema = z32.discriminatedUnion("kind", [
1469
+ var AuthNavigationSchema = z42.discriminatedUnion("kind", [
1437
1470
  /** Act from wherever the browser already is — a "Log in" link in the header.
1438
1471
  * The only kind that is safe part-way through a journey. */
1439
- z32.object({ kind: z32.literal("continue") }),
1472
+ z42.object({ kind: z42.literal("continue") }),
1440
1473
  /** Open the procedure's own starting page first. Right when signing in is
1441
1474
  * the first thing that happens; it abandons a journey in progress. */
1442
- z32.object({ kind: z32.literal("open"), path: z32.string().min(1) })
1475
+ z42.object({ kind: z42.literal("open"), path: z42.string().min(1) })
1443
1476
  ]);
1444
- var AuthFieldSchema = z32.object({
1477
+ var AuthFieldSchema = z42.object({
1445
1478
  /** The step in the recorded procedure this value is typed into. Where a
1446
1479
  * recording types into the same box more than once, this is the FIRST of
1447
1480
  * them — the one an account's values are keyed by. */
1448
- stepId: z32.string().min(1),
1481
+ stepId: z42.string().min(1),
1449
1482
  /** EVERY step that types into this box, when there is more than one.
1450
1483
  *
1451
1484
  * A login typed twice — a first attempt with a typo, a page that re-rendered
@@ -1457,47 +1490,47 @@ var AuthFieldSchema = z32.object({
1457
1490
  *
1458
1491
  * Empty means the one step in `stepId`, so every profile written before this
1459
1492
  * reads correctly without being migrated. */
1460
- stepIds: z32.array(z32.string().min(1)).default([]),
1493
+ stepIds: z42.array(z42.string().min(1)).default([]),
1461
1494
  /** What it is called where somebody fills it in — the field's own name on
1462
1495
  * the page, so an account form reads "Username" rather than "st_9f2a". */
1463
- label: z32.string().min(1),
1496
+ label: z42.string().min(1),
1464
1497
  /** A secret arrives as a reference and is never written into a document. */
1465
- secret: z32.boolean().default(false),
1498
+ secret: z42.boolean().default(false),
1466
1499
  /** What the recording typed. Empty for a secret, whose value never travels.
1467
1500
  * Kept so the first account can be made from what was recorded, with
1468
1501
  * nothing to fill in. */
1469
- recorded: z32.string().default("")
1502
+ recorded: z42.string().default("")
1470
1503
  }).strict();
1471
1504
  var AUTH_PROFILE_SCHEMA_VERSION = 2;
1472
- var AuthProfileSchema = z32.object({
1473
- schemaVersion: z32.literal(AUTH_PROFILE_SCHEMA_VERSION),
1474
- id: z32.string().min(1),
1475
- slug: z32.string().regex(/^[a-z0-9][a-z0-9-]*$/),
1476
- name: z32.string().min(1),
1477
- description: z32.string().default(""),
1505
+ var AuthProfileSchema = z42.object({
1506
+ schemaVersion: z42.literal(AUTH_PROFILE_SCHEMA_VERSION),
1507
+ id: z42.string().min(1),
1508
+ slug: z42.string().regex(/^[a-z0-9][a-z0-9-]*$/),
1509
+ name: z42.string().min(1),
1510
+ description: z42.string().default(""),
1478
1511
  /** The recorded sign-in. A flow like any other, so it is edited, debugged
1479
1512
  * and replayed by everything that already knows how. */
1480
- flowId: z32.string().min(1),
1513
+ flowId: z42.string().min(1),
1481
1514
  /** Which of the values it types differ per identity. */
1482
- fields: z32.array(AuthFieldSchema).default([]),
1515
+ fields: z42.array(AuthFieldSchema).default([]),
1483
1516
  /** Optional, and its own procedure with its own proof — most profiles will
1484
1517
  * not have one at first. The proof is read off that flow, the same way. */
1485
- signOutFlowId: z32.string().optional(),
1518
+ signOutFlowId: z42.string().optional(),
1486
1519
  /** Descriptive only — "admin", "staff". Never used to decide anything, so
1487
1520
  * two profiles may share a tag without becoming interchangeable. */
1488
- tags: z32.array(z32.string()).default([]),
1489
- createdAt: z32.string(),
1490
- createdBy: z32.string().default(""),
1491
- updatedAt: z32.string(),
1492
- revision: z32.number().int().nonnegative().default(0)
1521
+ tags: z42.array(z42.string()).default([]),
1522
+ createdAt: z42.string(),
1523
+ createdBy: z42.string().default(""),
1524
+ updatedAt: z42.string(),
1525
+ revision: z42.number().int().nonnegative().default(0)
1493
1526
  }).strict();
1494
1527
  var ACCOUNT_BINDING_SCHEMA_VERSION = 3;
1495
- var AccountBindingSchema = z32.object({
1496
- schemaVersion: z32.literal(ACCOUNT_BINDING_SCHEMA_VERSION),
1497
- id: z32.string().min(1),
1498
- slug: z32.string().regex(/^[a-z0-9][a-z0-9-]*$/),
1499
- name: z32.string().min(1),
1500
- profileId: z32.string().min(1),
1528
+ var AccountBindingSchema = z42.object({
1529
+ schemaVersion: z42.literal(ACCOUNT_BINDING_SCHEMA_VERSION),
1530
+ id: z42.string().min(1),
1531
+ slug: z42.string().regex(/^[a-z0-9][a-z0-9-]*$/),
1532
+ name: z42.string().min(1),
1533
+ profileId: z42.string().min(1),
1501
1534
  /** Which environments of the APPLICATION UNDER TEST these credentials work
1502
1535
  * in — never Flowriki's own dev or staging.
1503
1536
  *
@@ -1509,47 +1542,47 @@ var AccountBindingSchema = z32.object({
1509
1542
  * duplicate account — same name, same password, same everything — for each
1510
1543
  * deployment the identity existed in, or a blank "works anywhere" that also
1511
1544
  * claimed environments it had never been created in. Neither was true. */
1512
- environments: z32.array(z32.string().min(1)).default([]),
1545
+ environments: z42.array(z42.string().min(1)).default([]),
1513
1546
  /** Step id → what this identity types there. Ordinary values: a username is
1514
1547
  * not a credential, and keeping it here is what lets somebody read an
1515
1548
  * account and know who it is. */
1516
- values: z32.record(z32.string(), z32.string()).default({}),
1549
+ values: z42.record(z42.string(), z42.string()).default({}),
1517
1550
  /** Step id → secret REFERENCE. The value is sealed in the vault and never
1518
1551
  * enters the repository, whatever form it was typed into. */
1519
- secrets: z32.record(z32.string(), z32.string().regex(/^[a-z][a-z0-9_]*$/i)).default({}),
1552
+ secrets: z42.record(z42.string(), z42.string().regex(/^[a-z][a-z0-9_]*$/i)).default({}),
1520
1553
  /** What this identity should look like once signed in — a displayed name, a
1521
1554
  * tenant. Not secret, and checked so that an already-authenticated browser
1522
1555
  * holding the WRONG account is reported rather than accepted. */
1523
- identity: z32.object({
1524
- label: z32.string().optional(),
1525
- tenant: z32.string().optional()
1556
+ identity: z42.object({
1557
+ label: z42.string().optional(),
1558
+ tenant: z42.string().optional()
1526
1559
  }).default({}),
1527
- createdAt: z32.string(),
1528
- createdBy: z32.string().default(""),
1529
- updatedAt: z32.string(),
1530
- revision: z32.number().int().nonnegative().default(0)
1560
+ createdAt: z42.string(),
1561
+ createdBy: z42.string().default(""),
1562
+ updatedAt: z42.string(),
1563
+ revision: z42.number().int().nonnegative().default(0)
1531
1564
  }).strict();
1532
- var AuthReferenceSchema = z32.object({
1533
- profileId: z32.string().min(1),
1565
+ var AuthReferenceSchema = z42.object({
1566
+ profileId: z42.string().min(1),
1534
1567
  /** Where this use of it begins. See the step's own field. */
1535
- from: z32.enum(["loginPage", "here"]).optional(),
1568
+ from: z42.enum(["loginPage", "here"]).optional(),
1536
1569
  /** Absent means "the only account bound to this profile for the selected
1537
1570
  * environment", which is resolved before a browser opens and refused when
1538
1571
  * it is ambiguous — a silent choice between two identities is the failure
1539
1572
  * this field exists to prevent. */
1540
- accountId: z32.string().optional()
1573
+ accountId: z42.string().optional()
1541
1574
  }).strict();
1542
1575
  var ActorSchema = ActorDefinitionSchema;
1543
- var DeliveredAuthSchema = z32.object({
1544
- profileId: z32.string().min(1),
1545
- accountId: z32.string().min(1),
1546
- name: z32.string(),
1547
- accountName: z32.string(),
1548
- steps: z32.array(RecordedStepSchema),
1576
+ var DeliveredAuthSchema = z42.object({
1577
+ profileId: z42.string().min(1),
1578
+ accountId: z42.string().min(1),
1579
+ name: z42.string(),
1580
+ accountName: z42.string(),
1581
+ steps: z42.array(RecordedStepSchema),
1549
1582
  navigation: AuthNavigationSchema,
1550
- success: z32.array(RecordedAssertionSchema),
1551
- secretRefs: z32.record(z32.string(), z32.string()),
1552
- signOut: z32.object({ steps: z32.array(RecordedStepSchema), success: z32.array(RecordedAssertionSchema) }).optional()
1583
+ success: z42.array(RecordedAssertionSchema),
1584
+ secretRefs: z42.record(z42.string(), z42.string()),
1585
+ signOut: z42.object({ steps: z42.array(RecordedStepSchema), success: z42.array(RecordedAssertionSchema) }).optional()
1553
1586
  }).strict();
1554
1587
  function actorPreparations(actors = []) {
1555
1588
  return actors.flatMap((actor) => actor.startSignedIn ? [{
@@ -1666,8 +1699,8 @@ function expandForRun(flow, lookup) {
1666
1699
  return { ...rest, steps: [...signIn ? [signIn] : [], ...steps, ...flow.steps] };
1667
1700
  }
1668
1701
  var HELPER_SCHEMA_VERSION = 1;
1669
- var SecretRef = z42.string().regex(/^[a-z][a-z0-9_]*$/i);
1670
- var PatternSchema = z42.string().max(500).refine((source) => {
1702
+ var SecretRef = z5.string().regex(/^[a-z][a-z0-9_]*$/i);
1703
+ var PatternSchema = z5.string().max(500).refine((source) => {
1671
1704
  try {
1672
1705
  new RegExp(source);
1673
1706
  return true;
@@ -1675,88 +1708,88 @@ var PatternSchema = z42.string().max(500).refine((source) => {
1675
1708
  return false;
1676
1709
  }
1677
1710
  }, "that is not a valid pattern");
1678
- var MailboxHelperSchema = z42.object({
1679
- kind: z42.literal("mailbox"),
1711
+ var MailboxHelperSchema = z5.object({
1712
+ kind: z5.literal("mailbox"),
1680
1713
  /** IMAP, which every provider offers: Gmail, Outlook, Zoho, Fastmail… */
1681
- host: z42.string().min(1),
1682
- port: z42.number().int().positive().default(993),
1683
- secure: z42.boolean().default(true),
1684
- username: z42.string().min(1),
1714
+ host: z5.string().min(1),
1715
+ port: z5.number().int().positive().default(993),
1716
+ secure: z5.boolean().default(true),
1717
+ username: z5.string().min(1),
1685
1718
  passwordRef: SecretRef,
1686
- folder: z42.string().min(1).default("INBOX"),
1719
+ folder: z5.string().min(1).default("INBOX"),
1687
1720
  /** Which email. All optional; the newest that matches every one given. */
1688
- match: z42.object({
1689
- to: z42.string().default(""),
1690
- from: z42.string().default(""),
1691
- subject: z42.string().default("")
1721
+ match: z5.object({
1722
+ to: z5.string().default(""),
1723
+ from: z5.string().default(""),
1724
+ subject: z5.string().default("")
1692
1725
  }).strict().default({}),
1693
1726
  /** What to take out of it. */
1694
- extract: z42.object({
1695
- take: z42.enum(["code", "link", "subject", "body"]).default("code"),
1727
+ extract: z5.object({
1728
+ take: z5.enum(["code", "link", "subject", "body"]).default("code"),
1696
1729
  /** For a code: the pattern, first group if it has one. Default: 4–8 digits.
1697
1730
  * For a link: only links containing this text. */
1698
- pattern: z42.string().max(500).default("")
1731
+ pattern: z5.string().max(500).default("")
1699
1732
  }).strict().default({}),
1700
1733
  /** How long to wait for the email to arrive. */
1701
- waitSeconds: z42.number().int().min(0).max(300).default(60)
1734
+ waitSeconds: z5.number().int().min(0).max(300).default(60)
1702
1735
  }).strict();
1703
- var TotpHelperSchema = z42.object({
1704
- kind: z42.literal("totp"),
1736
+ var TotpHelperSchema = z5.object({
1737
+ kind: z5.literal("totp"),
1705
1738
  /** The authenticator secret (base32, from the QR code's "manual entry"). */
1706
1739
  secretRef: SecretRef,
1707
- digits: z42.union([z42.literal(6), z42.literal(8)]).default(6),
1708
- period: z42.number().int().min(10).max(120).default(30),
1709
- algorithm: z42.enum(["SHA1", "SHA256", "SHA512"]).default("SHA1")
1740
+ digits: z5.union([z5.literal(6), z5.literal(8)]).default(6),
1741
+ period: z5.number().int().min(10).max(120).default(30),
1742
+ algorithm: z5.enum(["SHA1", "SHA256", "SHA512"]).default("SHA1")
1710
1743
  }).strict();
1711
- var SmsHelperSchema = z42.object({
1712
- kind: z42.literal("sms"),
1713
- provider: z42.literal("twilio").default("twilio"),
1714
- accountSid: z42.string().regex(/^AC[0-9a-f]{32}$/i, "a Twilio account SID starts with AC followed by 32 characters"),
1744
+ var SmsHelperSchema = z5.object({
1745
+ kind: z5.literal("sms"),
1746
+ provider: z5.literal("twilio").default("twilio"),
1747
+ accountSid: z5.string().regex(/^AC[0-9a-f]{32}$/i, "a Twilio account SID starts with AC followed by 32 characters"),
1715
1748
  authTokenRef: SecretRef,
1716
1749
  /** The Twilio number the application texts. */
1717
- to: z42.string().min(3),
1718
- match: z42.object({
1719
- from: z42.string().default(""),
1720
- contains: z42.string().default("")
1750
+ to: z5.string().min(3),
1751
+ match: z5.object({
1752
+ from: z5.string().default(""),
1753
+ contains: z5.string().default("")
1721
1754
  }).strict().default({}),
1722
- extract: z42.object({ pattern: z42.string().max(500).default("") }).strict().default({}),
1723
- waitSeconds: z42.number().int().min(0).max(300).default(60)
1755
+ extract: z5.object({ pattern: z5.string().max(500).default("") }).strict().default({}),
1756
+ waitSeconds: z5.number().int().min(0).max(300).default(60)
1724
1757
  }).strict();
1725
- var HttpHelperSchema = z42.object({
1726
- kind: z42.literal("http"),
1727
- method: z42.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]).default("POST"),
1728
- url: z42.string().min(1),
1758
+ var HttpHelperSchema = z5.object({
1759
+ kind: z5.literal("http"),
1760
+ method: z5.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]).default("POST"),
1761
+ url: z5.string().min(1),
1729
1762
  /** Plain headers, in the repository. */
1730
- headers: z42.record(z42.string(), z42.string()).default({}),
1763
+ headers: z5.record(z5.string(), z5.string()).default({}),
1731
1764
  /** Header name → vault reference, for tokens and keys. */
1732
- secretHeaders: z42.record(z42.string(), SecretRef).default({}),
1733
- body: z42.string().max(2e4).default(""),
1765
+ secretHeaders: z5.record(z5.string(), SecretRef).default({}),
1766
+ body: z5.string().max(2e4).default(""),
1734
1767
  /** Refused unless the response has this status. 0 means any 2xx. */
1735
- expectStatus: z42.number().int().min(0).max(599).default(0),
1736
- extract: z42.object({
1737
- take: z42.enum(["json", "pattern", "status", "nothing"]).default("nothing"),
1768
+ expectStatus: z5.number().int().min(0).max(599).default(0),
1769
+ extract: z5.object({
1770
+ take: z5.enum(["json", "pattern", "status", "nothing"]).default("nothing"),
1738
1771
  /** For json: a dot path — `data.order.id`, `items.0.code`. */
1739
- path: z42.string().max(300).default(""),
1740
- pattern: z42.string().max(500).default("")
1772
+ path: z5.string().max(300).default(""),
1773
+ pattern: z5.string().max(500).default("")
1741
1774
  }).strict().default({})
1742
1775
  }).strict();
1743
- var HelperConfigSchema = z42.discriminatedUnion("kind", [
1776
+ var HelperConfigSchema = z5.discriminatedUnion("kind", [
1744
1777
  MailboxHelperSchema,
1745
1778
  TotpHelperSchema,
1746
1779
  SmsHelperSchema,
1747
1780
  HttpHelperSchema
1748
1781
  ]);
1749
- var HelperSchema = z42.object({
1750
- schemaVersion: z42.literal(HELPER_SCHEMA_VERSION),
1751
- id: z42.string().min(1),
1752
- slug: z42.string().regex(/^[a-z0-9][a-z0-9-]*$/),
1753
- name: z42.string().min(1).max(120),
1754
- description: z42.string().max(1e3).default(""),
1782
+ var HelperSchema = z5.object({
1783
+ schemaVersion: z5.literal(HELPER_SCHEMA_VERSION),
1784
+ id: z5.string().min(1),
1785
+ slug: z5.string().regex(/^[a-z0-9][a-z0-9-]*$/),
1786
+ name: z5.string().min(1).max(120),
1787
+ description: z5.string().max(1e3).default(""),
1755
1788
  config: HelperConfigSchema,
1756
- createdAt: z42.string(),
1757
- createdBy: z42.string().default(""),
1758
- updatedAt: z42.string(),
1759
- revision: z42.number().int().nonnegative().default(0)
1789
+ createdAt: z5.string(),
1790
+ createdBy: z5.string().default(""),
1791
+ updatedAt: z5.string(),
1792
+ revision: z5.number().int().nonnegative().default(0)
1760
1793
  }).strict().superRefine((helper, ctx) => {
1761
1794
  const patterns = [
1762
1795
  helper.config.kind === "mailbox" && helper.config.extract.take === "code" ? helper.config.extract.pattern : "",
@@ -1769,9 +1802,9 @@ var HelperSchema = z42.object({
1769
1802
  }
1770
1803
  }
1771
1804
  });
1772
- var DeliveredHelperSchema = z42.object({
1773
- id: z42.string().min(1),
1774
- name: z42.string(),
1805
+ var DeliveredHelperSchema = z5.object({
1806
+ id: z5.string().min(1),
1807
+ name: z5.string(),
1775
1808
  config: HelperConfigSchema
1776
1809
  }).strict();
1777
1810
  var LIBRARY_CASE_SCHEMA_VERSION = 1;
@@ -1779,83 +1812,83 @@ var TEST_TYPES = ["functional", "negative", "edge", "regression", "smoke", "acce
1779
1812
  var PRIORITIES = ["P0", "P1", "P2", "P3"];
1780
1813
  var CASE_STATUSES = ["draft", "ready", "deprecated"];
1781
1814
  var AUTOMATION_STATES = ["none", "planned", "automated", "not-automatable"];
1782
- var LibraryStepSchema = z5.object({
1783
- id: z5.string().min(1),
1784
- action: z5.string().min(1),
1815
+ var LibraryStepSchema = z6.object({
1816
+ id: z6.string().min(1),
1817
+ action: z6.string().min(1),
1785
1818
  /** What to type or choose, when the action needs it. */
1786
- data: z5.string().optional(),
1819
+ data: z6.string().optional(),
1787
1820
  /** What should happen. Absent for a step that only gets somewhere. */
1788
- expected: z5.string().optional()
1821
+ expected: z6.string().optional()
1789
1822
  }).strict();
1790
- var AutomationLinkSchema = z5.object({
1791
- automationId: z5.string().min(1),
1792
- caseRevision: z5.number().int().nonnegative(),
1823
+ var AutomationLinkSchema = z6.object({
1824
+ automationId: z6.string().min(1),
1825
+ caseRevision: z6.number().int().nonnegative(),
1793
1826
  /** The automation's revision when the link was made or last confirmed —
1794
1827
  * an automation edited since may no longer check what the case says. */
1795
- automationRevision: z5.number().int().nonnegative().optional(),
1796
- at: z5.string(),
1797
- by: z5.string().default("")
1828
+ automationRevision: z6.number().int().nonnegative().optional(),
1829
+ at: z6.string(),
1830
+ by: z6.string().default("")
1798
1831
  }).strict();
1799
- var CaseOriginSchema = z5.discriminatedUnion("kind", [
1800
- z5.object({ kind: z5.literal("manual") }).strict(),
1801
- z5.object({
1802
- kind: z5.literal("import"),
1832
+ var CaseOriginSchema = z6.discriminatedUnion("kind", [
1833
+ z6.object({ kind: z6.literal("manual") }).strict(),
1834
+ z6.object({
1835
+ kind: z6.literal("import"),
1803
1836
  /** "csv", "xlsx", "testrail", "zephyr", "xray", "text"… */
1804
- format: z5.string().min(1),
1805
- file: z5.string().min(1),
1837
+ format: z6.string().min(1),
1838
+ file: z6.string().min(1),
1806
1839
  /** Row or item in that file, to find it again. */
1807
- row: z5.string().optional()
1840
+ row: z6.string().optional()
1808
1841
  }).strict(),
1809
- z5.object({
1810
- kind: z5.literal("generated"),
1811
- sourceId: z5.string().min(1),
1812
- sourceVersion: z5.number().int().positive(),
1813
- requirementIds: z5.array(z5.string().min(1)).default([])
1842
+ z6.object({
1843
+ kind: z6.literal("generated"),
1844
+ sourceId: z6.string().min(1),
1845
+ sourceVersion: z6.number().int().positive(),
1846
+ requirementIds: z6.array(z6.string().min(1)).default([])
1814
1847
  }).strict()
1815
1848
  ]);
1816
- var TestDataSchema = z5.object({
1817
- name: z5.string().min(1),
1818
- value: z5.string().optional(),
1819
- secretRef: z5.string().regex(/^[a-z][a-z0-9_]*$/i).optional()
1849
+ var TestDataSchema = z6.object({
1850
+ name: z6.string().min(1),
1851
+ value: z6.string().optional(),
1852
+ secretRef: z6.string().regex(/^[a-z][a-z0-9_]*$/i).optional()
1820
1853
  }).strict();
1821
- var LibraryCaseSchema = z5.object({
1822
- schemaVersion: z5.literal(LIBRARY_CASE_SCHEMA_VERSION),
1823
- id: z5.string().regex(/^tcs_[A-Za-z0-9]+$/),
1854
+ var LibraryCaseSchema = z6.object({
1855
+ schemaVersion: z6.literal(LIBRARY_CASE_SCHEMA_VERSION),
1856
+ id: z6.string().regex(/^tcs_[A-Za-z0-9]+$/),
1824
1857
  /** "TC-142": what people say out loud. The id is what links point at. */
1825
- key: z5.string().regex(/^TC-[1-9][0-9]*$/),
1858
+ key: z6.string().regex(/^TC-[1-9][0-9]*$/),
1826
1859
  /** The same features flows are filed under (`f_<slug>`), so one feature
1827
1860
  * holds both what to test and what tests it. */
1828
- featureId: z5.string().min(1),
1829
- slug: z5.string().regex(/^[a-z0-9][a-z0-9-]*$/),
1830
- title: z5.string().min(1).max(300),
1831
- description: z5.string().default(""),
1832
- type: z5.enum(TEST_TYPES).default("functional"),
1833
- priority: z5.enum(PRIORITIES).default("P2"),
1834
- status: z5.enum(CASE_STATUSES).default("draft"),
1835
- preconditions: z5.array(z5.string().min(1)).default([]),
1836
- steps: z5.array(LibraryStepSchema).default([]),
1837
- testData: z5.array(TestDataSchema).default([]),
1838
- tags: z5.array(z5.string().min(1)).default([]),
1861
+ featureId: z6.string().min(1),
1862
+ slug: z6.string().regex(/^[a-z0-9][a-z0-9-]*$/),
1863
+ title: z6.string().min(1).max(300),
1864
+ description: z6.string().default(""),
1865
+ type: z6.enum(TEST_TYPES).default("functional"),
1866
+ priority: z6.enum(PRIORITIES).default("P2"),
1867
+ status: z6.enum(CASE_STATUSES).default("draft"),
1868
+ preconditions: z6.array(z6.string().min(1)).default([]),
1869
+ steps: z6.array(LibraryStepSchema).default([]),
1870
+ testData: z6.array(TestDataSchema).default([]),
1871
+ tags: z6.array(z6.string().min(1)).default([]),
1839
1872
  /** Requirement ids (Flowriki storage). The text is not copied here. */
1840
- covers: z5.array(z5.string().min(1)).default([]),
1841
- automation: z5.object({
1842
- state: z5.enum(AUTOMATION_STATES).default("none"),
1873
+ covers: z6.array(z6.string().min(1)).default([]),
1874
+ automation: z6.object({
1875
+ state: z6.enum(AUTOMATION_STATES).default("none"),
1843
1876
  /** Why it cannot be automated, when it cannot. */
1844
- reason: z5.string().optional(),
1877
+ reason: z6.string().optional(),
1845
1878
  /** The plan for automating it: flows to reuse, flows to record, checks to
1846
1879
  * switch on, accounts and helpers it needs, and what cannot be automated.
1847
1880
  * Written (usually by the assistant) and approved before anything is
1848
1881
  * recorded. */
1849
- plan: z5.string().max(2e4).optional(),
1850
- planApproved: z5.boolean().optional(),
1851
- links: z5.array(AutomationLinkSchema).default([])
1882
+ plan: z6.string().max(2e4).optional(),
1883
+ planApproved: z6.boolean().optional(),
1884
+ links: z6.array(AutomationLinkSchema).default([])
1852
1885
  }).strict().default({}),
1853
1886
  origin: CaseOriginSchema.default({ kind: "manual" }),
1854
- createdAt: z5.string(),
1855
- createdBy: z5.string().default(""),
1856
- updatedAt: z5.string(),
1857
- updatedBy: z5.string().default(""),
1858
- revision: z5.number().int().nonnegative().default(0)
1887
+ createdAt: z6.string(),
1888
+ createdBy: z6.string().default(""),
1889
+ updatedAt: z6.string(),
1890
+ updatedBy: z6.string().default(""),
1891
+ revision: z6.number().int().nonnegative().default(0)
1859
1892
  }).strict().superRefine((doc, ctx) => {
1860
1893
  const seen = /* @__PURE__ */ new Set();
1861
1894
  doc.steps.forEach((step, i) => {
@@ -1874,144 +1907,144 @@ var LibraryCaseSchema = z5.object({
1874
1907
  }
1875
1908
  });
1876
1909
  var SOURCE_KINDS = ["upload", "jira", "figma", "confluence", "linear", "github-issue", "notion", "url"];
1877
- var SourceVersionSchema = z5.object({
1878
- v: z5.number().int().positive(),
1879
- hash: z5.string().min(1),
1880
- extractedText: z5.string(),
1910
+ var SourceVersionSchema = z6.object({
1911
+ v: z6.number().int().positive(),
1912
+ hash: z6.string().min(1),
1913
+ extractedText: z6.string(),
1881
1914
  /** Where an uploaded file WAS kept. Only text is kept since 2026-10-11;
1882
1915
  * read so older records still parse, and cleared at start-up. */
1883
- originalKey: z5.string().optional(),
1884
- mediaType: z5.string().optional(),
1885
- at: z5.string(),
1886
- by: z5.string().default("")
1916
+ originalKey: z6.string().optional(),
1917
+ mediaType: z6.string().optional(),
1918
+ at: z6.string(),
1919
+ by: z6.string().default("")
1887
1920
  }).strict();
1888
- var SourceSchema = z5.object({
1889
- id: z5.string().regex(/^src_[A-Za-z0-9]+$/),
1890
- projectId: z5.string().min(1),
1891
- title: z5.string().min(1).max(300),
1892
- kind: z5.enum(SOURCE_KINDS),
1893
- versions: z5.array(SourceVersionSchema).min(1),
1894
- integrationId: z5.string().optional(),
1895
- externalId: z5.string().optional(),
1896
- externalUrl: z5.string().url().optional(),
1897
- createdAt: z5.string(),
1898
- createdBy: z5.string().default("")
1921
+ var SourceSchema = z6.object({
1922
+ id: z6.string().regex(/^src_[A-Za-z0-9]+$/),
1923
+ projectId: z6.string().min(1),
1924
+ title: z6.string().min(1).max(300),
1925
+ kind: z6.enum(SOURCE_KINDS),
1926
+ versions: z6.array(SourceVersionSchema).min(1),
1927
+ integrationId: z6.string().optional(),
1928
+ externalId: z6.string().optional(),
1929
+ externalUrl: z6.string().url().optional(),
1930
+ createdAt: z6.string(),
1931
+ createdBy: z6.string().default("")
1899
1932
  }).strict();
1900
- var RequirementSchema = z5.object({
1901
- id: z5.string().regex(/^req_[A-Za-z0-9]+$/),
1902
- projectId: z5.string().min(1),
1903
- sourceId: z5.string().min(1),
1904
- sourceVersion: z5.number().int().positive(),
1933
+ var RequirementSchema = z6.object({
1934
+ id: z6.string().regex(/^req_[A-Za-z0-9]+$/),
1935
+ projectId: z6.string().min(1),
1936
+ sourceId: z6.string().min(1),
1937
+ sourceVersion: z6.number().int().positive(),
1905
1938
  /** Where in the source: a heading path, a Jira key, a Figma node. */
1906
- anchor: z5.string().min(1),
1907
- text: z5.string().min(1),
1908
- featureId: z5.string().optional(),
1939
+ anchor: z6.string().min(1),
1940
+ text: z6.string().min(1),
1941
+ featureId: z6.string().optional(),
1909
1942
  /** As of the source's latest version: new in it, changed by it, unchanged
1910
1943
  * ("active"), or gone from it. */
1911
- state: z5.enum(["new", "active", "changed", "removed"]).default("new"),
1912
- history: z5.array(z5.object({
1913
- sourceVersion: z5.number().int().positive(),
1914
- text: z5.string(),
1915
- state: z5.enum(["new", "active", "changed", "removed"])
1944
+ state: z6.enum(["new", "active", "changed", "removed"]).default("new"),
1945
+ history: z6.array(z6.object({
1946
+ sourceVersion: z6.number().int().positive(),
1947
+ text: z6.string(),
1948
+ state: z6.enum(["new", "active", "changed", "removed"])
1916
1949
  }).strict()).default([])
1917
1950
  }).strict();
1918
1951
  var MANUAL_OUTCOMES = ["untested", "passed", "failed", "blocked", "skipped"];
1919
- var EvidenceSchema = z6.object({
1920
- id: z6.string().regex(/^ev_[A-Za-z0-9]+$/),
1952
+ var EvidenceSchema = z7.object({
1953
+ id: z7.string().regex(/^ev_[A-Za-z0-9]+$/),
1921
1954
  /** A file kept in Flowriki's evidence storage, or a link to one elsewhere. */
1922
- kind: z6.enum(["file", "link"]),
1923
- name: z6.string().min(1).max(200),
1924
- mediaType: z6.string().optional(),
1925
- size: z6.number().int().nonnegative().optional(),
1926
- url: z6.string().url().optional(),
1955
+ kind: z7.enum(["file", "link"]),
1956
+ name: z7.string().min(1).max(200),
1957
+ mediaType: z7.string().optional(),
1958
+ size: z7.number().int().nonnegative().optional(),
1959
+ url: z7.string().url().optional(),
1927
1960
  /** The step it shows, when it belongs to one. */
1928
- stepId: z6.string().optional(),
1929
- at: z6.string(),
1930
- by: z6.string().default("")
1961
+ stepId: z7.string().optional(),
1962
+ at: z7.string(),
1963
+ by: z7.string().default("")
1931
1964
  }).strict();
1932
- var StepOutcomeSchema = z6.object({
1933
- stepId: z6.string().min(1),
1934
- outcome: z6.enum(MANUAL_OUTCOMES),
1965
+ var StepOutcomeSchema = z7.object({
1966
+ stepId: z7.string().min(1),
1967
+ outcome: z7.enum(MANUAL_OUTCOMES),
1935
1968
  /** What actually happened, when it was not what was expected. */
1936
- actual: z6.string().max(4e3).optional()
1969
+ actual: z7.string().max(4e3).optional()
1937
1970
  }).strict();
1938
- var ManualResultSchema = z6.object({
1939
- outcome: z6.enum(MANUAL_OUTCOMES),
1940
- steps: z6.array(StepOutcomeSchema).default([]),
1941
- note: z6.string().max(8e3).default(""),
1942
- evidence: z6.array(EvidenceSchema).default([]),
1943
- bugIds: z6.array(z6.string().min(1)).default([]),
1944
- tester: z6.string().default(""),
1945
- at: z6.string()
1971
+ var ManualResultSchema = z7.object({
1972
+ outcome: z7.enum(MANUAL_OUTCOMES),
1973
+ steps: z7.array(StepOutcomeSchema).default([]),
1974
+ note: z7.string().max(8e3).default(""),
1975
+ evidence: z7.array(EvidenceSchema).default([]),
1976
+ bugIds: z7.array(z7.string().min(1)).default([]),
1977
+ tester: z7.string().default(""),
1978
+ at: z7.string()
1946
1979
  }).strict();
1947
- var CycleEntrySchema = z6.object({
1948
- testCaseId: z6.string().min(1),
1949
- key: z6.string().min(1),
1950
- title: z6.string().min(1),
1951
- featureId: z6.string().min(1),
1952
- priority: z6.enum(PRIORITIES),
1980
+ var CycleEntrySchema = z7.object({
1981
+ testCaseId: z7.string().min(1),
1982
+ key: z7.string().min(1),
1983
+ title: z7.string().min(1),
1984
+ featureId: z7.string().min(1),
1985
+ priority: z7.enum(PRIORITIES),
1953
1986
  /** The case revision snapshot, so "the case changed since" is answerable. */
1954
- caseRevision: z6.number().int().nonnegative(),
1955
- preconditions: z6.array(z6.string()).default([]),
1956
- steps: z6.array(z6.object({ id: z6.string(), action: z6.string(), data: z6.string().optional(), expected: z6.string().optional() }).strict()).default([]),
1957
- assignee: z6.string().optional(),
1987
+ caseRevision: z7.number().int().nonnegative(),
1988
+ preconditions: z7.array(z7.string()).default([]),
1989
+ steps: z7.array(z7.object({ id: z7.string(), action: z7.string(), data: z7.string().optional(), expected: z7.string().optional() }).strict()).default([]),
1990
+ assignee: z7.string().optional(),
1958
1991
  result: ManualResultSchema.nullable().default(null),
1959
1992
  /** Earlier results for this case in this cycle, newest last — a retest
1960
1993
  * keeps what the first attempt found. */
1961
- history: z6.array(ManualResultSchema).default([])
1994
+ history: z7.array(ManualResultSchema).default([])
1962
1995
  }).strict();
1963
- var TestCycleSchema = z6.object({
1964
- id: z6.string().regex(/^cyc_[A-Za-z0-9]+$/),
1965
- projectId: z6.string().min(1),
1966
- name: z6.string().min(1).max(200),
1967
- description: z6.string().max(4e3).default(""),
1968
- status: z6.enum(["open", "closed"]).default("open"),
1996
+ var TestCycleSchema = z7.object({
1997
+ id: z7.string().regex(/^cyc_[A-Za-z0-9]+$/),
1998
+ projectId: z7.string().min(1),
1999
+ name: z7.string().min(1).max(200),
2000
+ description: z7.string().max(4e3).default(""),
2001
+ status: z7.enum(["open", "closed"]).default("open"),
1969
2002
  /** Which branch the cases were read from; null for the published tests. */
1970
- changeId: z6.string().nullable().default(null),
1971
- entries: z6.array(CycleEntrySchema).default([]),
1972
- createdAt: z6.string(),
1973
- createdBy: z6.string().default(""),
1974
- updatedAt: z6.string(),
1975
- closedAt: z6.string().nullable().default(null)
2003
+ changeId: z7.string().nullable().default(null),
2004
+ entries: z7.array(CycleEntrySchema).default([]),
2005
+ createdAt: z7.string(),
2006
+ createdBy: z7.string().default(""),
2007
+ updatedAt: z7.string(),
2008
+ closedAt: z7.string().nullable().default(null)
1976
2009
  }).strict();
1977
2010
  var BUG_STATUSES = ["open", "in-progress", "fixed", "verified", "closed", "wont-fix"];
1978
2011
  var SEVERITIES = ["critical", "major", "minor", "trivial"];
1979
- var BugSchema = z6.object({
1980
- id: z6.string().regex(/^bug_[A-Za-z0-9]+$/),
1981
- key: z6.string().regex(/^BUG-[1-9][0-9]*$/),
1982
- projectId: z6.string().min(1),
1983
- title: z6.string().min(1).max(300),
1984
- description: z6.string().max(2e4).default(""),
1985
- severity: z6.enum(SEVERITIES).default("major"),
1986
- status: z6.enum(BUG_STATUSES).default("open"),
1987
- tracker: z6.enum(["flowriki", "jira", "linear", "github"]).default("flowriki"),
1988
- externalKey: z6.string().optional(),
1989
- url: z6.string().url().optional(),
2012
+ var BugSchema = z7.object({
2013
+ id: z7.string().regex(/^bug_[A-Za-z0-9]+$/),
2014
+ key: z7.string().regex(/^BUG-[1-9][0-9]*$/),
2015
+ projectId: z7.string().min(1),
2016
+ title: z7.string().min(1).max(300),
2017
+ description: z7.string().max(2e4).default(""),
2018
+ severity: z7.enum(SEVERITIES).default("major"),
2019
+ status: z7.enum(BUG_STATUSES).default("open"),
2020
+ tracker: z7.enum(["flowriki", "jira", "linear", "github"]).default("flowriki"),
2021
+ externalKey: z7.string().optional(),
2022
+ url: z7.string().url().optional(),
1990
2023
  /** Where it was found: a case, the step in it, the cycle that ran it. */
1991
- testCaseIds: z6.array(z6.string()).default([]),
1992
- cycleIds: z6.array(z6.string()).default([]),
1993
- runIds: z6.array(z6.string()).default([]),
1994
- automationIds: z6.array(z6.string()).default([]),
1995
- foundAt: z6.object({ cycleId: z6.string(), testCaseId: z6.string(), stepId: z6.string().optional() }).strict().optional(),
1996
- createdAt: z6.string(),
1997
- createdBy: z6.string().default(""),
1998
- updatedAt: z6.string()
2024
+ testCaseIds: z7.array(z7.string()).default([]),
2025
+ cycleIds: z7.array(z7.string()).default([]),
2026
+ runIds: z7.array(z7.string()).default([]),
2027
+ automationIds: z7.array(z7.string()).default([]),
2028
+ foundAt: z7.object({ cycleId: z7.string(), testCaseId: z7.string(), stepId: z7.string().optional() }).strict().optional(),
2029
+ createdAt: z7.string(),
2030
+ createdBy: z7.string().default(""),
2031
+ updatedAt: z7.string()
1999
2032
  }).strict();
2000
2033
  var STOP = new Set("a an the and or of to in on for with by is are be as at it this that from user users can should must shall will when then given".split(" "));
2001
- var ConversationSchema = z7.object({
2002
- id: z7.string().regex(/^conv_[A-Za-z0-9]+$/),
2003
- projectId: z7.string().min(1),
2034
+ var ConversationSchema = z8.object({
2035
+ id: z8.string().regex(/^conv_[A-Za-z0-9]+$/),
2036
+ projectId: z8.string().min(1),
2004
2037
  /** Whose: conversations are personal. */
2005
- userId: z7.string().min(1),
2006
- title: z7.string().min(1).max(200),
2007
- mode: z7.enum(["ask", "do"]).default("ask"),
2038
+ userId: z8.string().min(1),
2039
+ title: z8.string().min(1).max(200),
2040
+ mode: z8.enum(["ask", "do"]).default("ask"),
2008
2041
  /** The assistant's own session, to continue where it left off. */
2009
- sessionId: z7.string().optional(),
2042
+ sessionId: z8.string().optional(),
2010
2043
  /** The conversation as the dashboard draws it. Kept as given: the shape
2011
2044
  * belongs to the screen, and the service only stores and returns it. */
2012
- lines: z7.array(z7.unknown()).max(2e3).default([]),
2013
- createdAt: z7.string(),
2014
- updatedAt: z7.string()
2045
+ lines: z8.array(z8.unknown()).max(2e3).default([]),
2046
+ createdAt: z8.string(),
2047
+ updatedAt: z8.string()
2015
2048
  }).strict();
2016
2049
 
2017
2050
  // ../engine-playwright/dist/index.js
@@ -6937,8 +6970,8 @@ async function fieldNames(page) {
6937
6970
  }
6938
6971
 
6939
6972
  // ../results/dist/chunk-LYCTVHPR.js
6940
- import { z as z8 } from "zod";
6941
- var RunStatusSchema = z8.enum([
6973
+ import { z as z9 } from "zod";
6974
+ var RunStatusSchema = z9.enum([
6942
6975
  "queued",
6943
6976
  "running",
6944
6977
  "passed",
@@ -6946,7 +6979,7 @@ var RunStatusSchema = z8.enum([
6946
6979
  "cancelled",
6947
6980
  "errored"
6948
6981
  ]);
6949
- var TaskStatusSchema = z8.enum([
6982
+ var TaskStatusSchema = z9.enum([
6950
6983
  "queued",
6951
6984
  "running",
6952
6985
  "passed",
@@ -6955,7 +6988,7 @@ var TaskStatusSchema = z8.enum([
6955
6988
  "cancelled",
6956
6989
  "errored"
6957
6990
  ]);
6958
- var FailureKindSchema = z8.enum([
6991
+ var FailureKindSchema = z9.enum([
6959
6992
  "not_found",
6960
6993
  "ambiguous",
6961
6994
  "timeout",
@@ -6964,30 +6997,30 @@ var FailureKindSchema = z8.enum([
6964
6997
  "crash",
6965
6998
  "unknown"
6966
6999
  ]);
6967
- var RunCheckSchema = z8.object({
6968
- id: z8.string(),
6969
- assertionId: z8.string().nullable(),
6970
- kind: z8.string(),
6971
- expected: z8.string().nullable(),
6972
- actual: z8.string().nullable(),
6973
- ok: z8.boolean(),
7000
+ var RunCheckSchema = z9.object({
7001
+ id: z9.string(),
7002
+ assertionId: z9.string().nullable(),
7003
+ kind: z9.string(),
7004
+ expected: z9.string().nullable(),
7005
+ actual: z9.string().nullable(),
7006
+ ok: z9.boolean(),
6974
7007
  /** A failed soft check is reported but does not fail its step, so a run can
6975
7008
  * be green and still carry findings. Stored per check rather than derived,
6976
7009
  * because the flow it came from can be edited afterwards and history has to
6977
7010
  * keep saying what actually happened. */
6978
- soft: z8.boolean().default(false),
6979
- detail: z8.string().nullable()
7011
+ soft: z9.boolean().default(false),
7012
+ detail: z9.string().nullable()
6980
7013
  });
6981
- var RunStepSchema = z8.object({
6982
- id: z8.string(),
6983
- ordinal: z8.number().int().nonnegative(),
7014
+ var RunStepSchema = z9.object({
7015
+ id: z9.string(),
7016
+ ordinal: z9.number().int().nonnegative(),
6984
7017
  /** The STABLE document step id — this is what joins runs across time and
6985
7018
  * makes flake-rate a view over existing columns rather than a migration. */
6986
- stepId: z8.string(),
6987
- action: z8.string(),
6988
- targetRole: z8.string().nullable(),
6989
- targetName: z8.string().nullable(),
6990
- targetScope: z8.string().nullable(),
7019
+ stepId: z9.string(),
7020
+ action: z9.string(),
7021
+ targetRole: z9.string().nullable(),
7022
+ targetName: z9.string().nullable(),
7023
+ targetScope: z9.string().nullable(),
6991
7024
  /** What the step typed, chose or pressed.
6992
7025
  *
6993
7026
  * A report that says `fill "Password"` and nothing else cannot tell you
@@ -6996,100 +7029,100 @@ var RunStepSchema = z8.object({
6996
7029
  *
6997
7030
  * NEVER set for a secret — see `secret` below. A run report is the thing
6998
7031
  * people paste into a ticket. */
6999
- value: z8.string().nullable().default(null),
7032
+ value: z9.string().nullable().default(null),
7000
7033
  /** The step typed a secret, so `value` is deliberately absent rather than
7001
7034
  * merely unknown. Stored, because "no value" and "a value withheld" render
7002
7035
  * differently and history has to keep saying which it was. */
7003
- secret: z8.boolean().default(false),
7004
- status: z8.enum(["passed", "failed", "skipped"]),
7036
+ secret: z9.boolean().default(false),
7037
+ status: z9.enum(["passed", "failed", "skipped"]),
7005
7038
  failureKind: FailureKindSchema.nullable(),
7006
- detail: z8.string().nullable(),
7039
+ detail: z9.string().nullable(),
7007
7040
  /** WHICH WAY FOUND IT, when the first way did not.
7008
7041
  *
7009
7042
  * A step carries several routes to its element and takes the first that
7010
7043
  * matches. Passing on a later one is not a failure, but it does mean the
7011
7044
  * page has moved under the step — and a suite that repairs itself quietly
7012
7045
  * drifts away from the application it tests. Null is the ordinary case. */
7013
- foundBy: z8.string().nullable().default(null),
7014
- durationMs: z8.number().int().nonnegative().nullable(),
7046
+ foundBy: z9.string().nullable().default(null),
7047
+ durationMs: z9.number().int().nonnegative().nullable(),
7015
7048
  /** Where the browser was when this step ran. Recorded on failure, and
7016
7049
  * frequently the whole answer — the element is missing because a step
7017
7050
  * before it navigated somewhere unexpected, not because it was renamed. */
7018
- pageUrl: z8.string().nullable().default(null),
7019
- pageTitle: z8.string().nullable().default(null),
7020
- checks: z8.array(RunCheckSchema).default([])
7051
+ pageUrl: z9.string().nullable().default(null),
7052
+ pageTitle: z9.string().nullable().default(null),
7053
+ checks: z9.array(RunCheckSchema).default([])
7021
7054
  });
7022
- var RunTaskSchema = z8.object({
7023
- id: z8.string(),
7024
- ordinal: z8.number().int().nonnegative(),
7025
- caseName: z8.string(),
7026
- rowId: z8.string().nullable(),
7055
+ var RunTaskSchema = z9.object({
7056
+ id: z9.string(),
7057
+ ordinal: z9.number().int().nonnegative(),
7058
+ caseName: z9.string(),
7059
+ rowId: z9.string().nullable(),
7027
7060
  capability: CapabilitySchema,
7028
- provider: z8.string(),
7029
- attempt: z8.number().int().positive().default(1),
7030
- maxAttempts: z8.number().int().positive().default(1),
7061
+ provider: z9.string(),
7062
+ attempt: z9.number().int().positive().default(1),
7063
+ maxAttempts: z9.number().int().positive().default(1),
7031
7064
  status: TaskStatusSchema,
7032
- workerId: z8.string().nullable(),
7065
+ workerId: z9.string().nullable(),
7033
7066
  /** Cloud provider's own session, so a failure is one click from their video. */
7034
- sessionId: z8.string().nullable(),
7035
- sessionUrl: z8.string().nullable(),
7036
- detail: z8.string().nullable(),
7037
- stepsRun: z8.number().int().nonnegative().default(0),
7038
- stepsTotal: z8.number().int().nonnegative().default(0),
7039
- durationMs: z8.number().int().nonnegative().nullable(),
7040
- steps: z8.array(RunStepSchema).default([])
7067
+ sessionId: z9.string().nullable(),
7068
+ sessionUrl: z9.string().nullable(),
7069
+ detail: z9.string().nullable(),
7070
+ stepsRun: z9.number().int().nonnegative().default(0),
7071
+ stepsTotal: z9.number().int().nonnegative().default(0),
7072
+ durationMs: z9.number().int().nonnegative().nullable(),
7073
+ steps: z9.array(RunStepSchema).default([])
7041
7074
  });
7042
- var ArtifactKindSchema = z8.enum(["screenshot", "video", "trace", "console", "har"]);
7043
- var ArtifactSchema = z8.object({
7044
- id: z8.string(),
7045
- runId: z8.string(),
7046
- runStepId: z8.string().nullable(),
7075
+ var ArtifactKindSchema = z9.enum(["screenshot", "video", "trace", "console", "har"]);
7076
+ var ArtifactSchema = z9.object({
7077
+ id: z9.string(),
7078
+ runId: z9.string(),
7079
+ runStepId: z9.string().nullable(),
7047
7080
  kind: ArtifactKindSchema,
7048
- relPath: z8.string(),
7049
- bytes: z8.number().int().nonnegative().nullable(),
7050
- masked: z8.boolean().default(false),
7051
- createdAt: z8.string()
7081
+ relPath: z9.string(),
7082
+ bytes: z9.number().int().nonnegative().nullable(),
7083
+ masked: z9.boolean().default(false),
7084
+ createdAt: z9.string()
7052
7085
  });
7053
- var RunSummarySchema = z8.object({
7054
- id: z8.string(),
7055
- projectId: z8.string(),
7086
+ var RunSummarySchema = z9.object({
7087
+ id: z9.string(),
7088
+ projectId: z9.string(),
7056
7089
  /** What the run was FOR.
7057
7090
  *
7058
7091
  * `flake` is a deliberate repetition of one flow to measure how often it
7059
7092
  * passes. It is kept out of pass-rate statistics: a 98/100 flakiness check is
7060
7093
  * a useful finding, not a failing suite, and counting it as one would make
7061
7094
  * measuring reliability look like losing it. */
7062
- kind: z8.enum(["smoke", "test", "adhoc", "flake"]),
7063
- trigger: z8.enum(["ui", "cli", "ci"]),
7095
+ kind: z9.enum(["smoke", "test", "adhoc", "flake"]),
7096
+ trigger: z9.enum(["ui", "cli", "ci"]),
7064
7097
  status: RunStatusSchema,
7065
- flowId: z8.string().nullable(),
7066
- flowName: z8.string().nullable(),
7067
- gitSha: z8.string().nullable(),
7068
- gitBranch: z8.string().nullable(),
7069
- gitDirty: z8.boolean().default(false),
7070
- env: z8.string().nullable(),
7071
- concurrency: z8.number().int().positive().nullable(),
7072
- tasksTotal: z8.number().int().nonnegative().default(0),
7073
- tasksPassed: z8.number().int().nonnegative().default(0),
7074
- tasksFailed: z8.number().int().nonnegative().default(0),
7098
+ flowId: z9.string().nullable(),
7099
+ flowName: z9.string().nullable(),
7100
+ gitSha: z9.string().nullable(),
7101
+ gitBranch: z9.string().nullable(),
7102
+ gitDirty: z9.boolean().default(false),
7103
+ env: z9.string().nullable(),
7104
+ concurrency: z9.number().int().positive().nullable(),
7105
+ tasksTotal: z9.number().int().nonnegative().default(0),
7106
+ tasksPassed: z9.number().int().nonnegative().default(0),
7107
+ tasksFailed: z9.number().int().nonnegative().default(0),
7075
7108
  /** Rolled up from the run's tasks rather than stored on the run, so they
7076
7109
  * cannot drift from the step rows they describe. "9 of 12" in a list is
7077
7110
  * what tells a reader where a run died; "1 of 1 tasks" tells them nothing
7078
7111
  * until there is more than one browser in play. */
7079
- stepsRun: z8.number().int().nonnegative().default(0),
7080
- stepsTotal: z8.number().int().nonnegative().default(0),
7081
- queuedAt: z8.string(),
7082
- startedAt: z8.string().nullable(),
7083
- finishedAt: z8.string().nullable(),
7084
- durationMs: z8.number().int().nonnegative().nullable()
7112
+ stepsRun: z9.number().int().nonnegative().default(0),
7113
+ stepsTotal: z9.number().int().nonnegative().default(0),
7114
+ queuedAt: z9.string(),
7115
+ startedAt: z9.string().nullable(),
7116
+ finishedAt: z9.string().nullable(),
7117
+ durationMs: z9.number().int().nonnegative().nullable()
7085
7118
  });
7086
7119
  var RunDetailSchema = RunSummarySchema.extend({
7087
- errorMessage: z8.string().nullable(),
7088
- artifactsDir: z8.string().nullable(),
7089
- tasks: z8.array(RunTaskSchema).default([]),
7120
+ errorMessage: z9.string().nullable(),
7121
+ artifactsDir: z9.string().nullable(),
7122
+ tasks: z9.array(RunTaskSchema).default([]),
7090
7123
  /** Screenshots and the like, addressed by `runStepId`. Kept flat rather than
7091
7124
  * nested inside each step: an artifact can belong to the run as a whole. */
7092
- artifacts: z8.array(ArtifactSchema).default([]),
7125
+ artifacts: z9.array(ArtifactSchema).default([]),
7093
7126
  /** The document as it was executed — a flow, or a test case with the copies
7094
7127
  * it held that day.
7095
7128
  *
@@ -7098,7 +7131,7 @@ var RunDetailSchema = RunSummarySchema.extend({
7098
7131
  * edited, and without surfacing it the promise was only half kept: the bytes
7099
7132
  * were there and nothing could reach them. Null for runs recorded before a
7100
7133
  * snapshot was taken. */
7101
- flowSnapshot: z8.unknown().nullable().default(null)
7134
+ flowSnapshot: z9.unknown().nullable().default(null)
7102
7135
  });
7103
7136
 
7104
7137
  // ../results/dist/chunk-IW3PJWP6.js
@@ -11370,6 +11403,7 @@ var ASK_MODE_TOOLS = [
11370
11403
  "project_brief",
11371
11404
  "knowledge_search",
11372
11405
  "knowledge_read",
11406
+ "read_test_cases",
11373
11407
  "list_my_branches"
11374
11408
  ];
11375
11409
  function buildAskArgs(opts) {
@@ -12040,6 +12074,7 @@ export {
12040
12074
  connect,
12041
12075
  RecordedStepSchema,
12042
12076
  mirrorCheckTargets,
12077
+ parseGherkin,
12043
12078
  runtimeValue,
12044
12079
  authenticationResolver,
12045
12080
  checkAssertion,